From 2cae2d452c623a3cb380e8defe1ded3e20a2559a Mon Sep 17 00:00:00 2001 From: vdimir Date: Thu, 22 Sep 2022 19:47:32 +0200 Subject: [PATCH 1/4] Full text search --- backend/app/cmd/server.go | 46 +++ backend/app/cmd/server_test.go | 8 +- backend/app/main_test.go | 5 + backend/app/rest/api/rest.go | 9 + backend/app/rest/api/rest_public.go | 68 ++++ backend/app/rest/api/rest_test.go | 96 +++++- backend/app/store/search/bleve.go | 242 ++++++++++++++ backend/app/store/search/engine.go | 21 ++ backend/app/store/search/search_test.go | 310 ++++++++++++++++++ backend/app/store/search/service.go | 146 +++++++++ backend/app/store/search/site_index.go | 79 +++++ backend/app/store/service/service.go | 69 ++++ backend/remark.rest | 3 + .../docs/configuration/parameters/index.md | 3 + site/src/docs/contributing/api/index.md | 20 ++ .../docs/contributing/translations/index.md | 1 + 16 files changed, 1124 insertions(+), 2 deletions(-) create mode 100644 backend/app/store/search/bleve.go create mode 100644 backend/app/store/search/engine.go create mode 100644 backend/app/store/search/search_test.go create mode 100644 backend/app/store/search/service.go create mode 100644 backend/app/store/search/site_index.go diff --git a/backend/app/cmd/server.go b/backend/app/cmd/server.go index ed0380bf9f..2b1c47dd5d 100644 --- a/backend/app/cmd/server.go +++ b/backend/app/cmd/server.go @@ -18,6 +18,7 @@ import ( "github.com/go-pkgz/lcw/eventbus" log "github.com/go-pkgz/lgr" ntf "github.com/go-pkgz/notify" + "github.com/go-pkgz/syncs" "github.com/golang-jwt/jwt" "github.com/kyokomi/emoji/v2" bolt "go.etcd.io/bbolt" @@ -38,6 +39,7 @@ import ( "github.com/umputun/remark42/backend/app/store/admin" "github.com/umputun/remark42/backend/app/store/engine" "github.com/umputun/remark42/backend/app/store/image" + "github.com/umputun/remark42/backend/app/store/search" "github.com/umputun/remark42/backend/app/store/service" "github.com/umputun/remark42/backend/app/templates" ) @@ -57,6 +59,7 @@ type ServerCommand struct { Image ImageGroup `group:"image" namespace:"image" env-namespace:"IMAGE"` SSL SSLGroup `group:"ssl" namespace:"ssl" env-namespace:"SSL"` ImageProxy ImageProxyGroup `group:"image-proxy" namespace:"image-proxy" env-namespace:"IMAGE_PROXY"` + Search SearchGroup `group:"search" namespace:"search" env-namespace:"SEARCH"` Sites []string `long:"site" env:"SITE" default:"remark" description:"site names" env-delim:","` AnonymousVote bool `long:"anon-vote" env:"ANON_VOTE" description:"enable anonymous votes (works only with VOTES_IP enabled)"` @@ -280,6 +283,13 @@ type AdminRPCGroup struct { SecretPerSite bool `long:"secret_per_site" env:"SECRET_PER_SITE" description:"enable JWT secret retrieval per aud, which is site_id in this case"` } +// SearchGroup defines options group for search engine +type SearchGroup struct { + Enable bool `long:"enable" env:"ENABLE" description:"enable search engine"` + IndexPath string `long:"index_path" env:"INDEX_PATH" description:"search index location" default:"./var/search_index"` + Analyzer string `long:"analyzer" env:"ANALYZER" description:"text analyzer type, set language-specific one to improve search quality" choice:"standard" choice:"ar" choice:"de" choice:"en" choice:"es" choice:"fi" choice:"fr" choice:"it" choice:"ru" default:"standard"` //nolint +} + // LoadingCache defines interface for caching type LoadingCache interface { Get(key cache.Key, fn func() ([]byte, error)) (data []byte, err error) // load from cache if found or put to cache and return @@ -574,6 +584,12 @@ func (s *ServerCommand) newServerApp(ctx context.Context) (*serverApp, error) { return nil, fmt.Errorf("failed to make config of ssl server params: %w", err) } + dataService.SearchService, err = s.makeSearchService() + if err != nil { + _ = dataService.Close() + return nil, fmt.Errorf("failed to create search service: %w", err) + } + srv := &api.Rest{ Version: s.Revision, DataService: dataService, @@ -656,6 +672,20 @@ func (a *serverApp) run(ctx context.Context) error { log.Printf("[WARN] failed to resubmit comments with staging images, %s", e) } + numWorkersForIndexing := 8 + grp := syncs.NewErrSizedGroup(numWorkersForIndexing) + for _, siteID := range a.Sites { + a.dataService.RunSiteIndexers(ctx, siteID, grp) // index comments for the first time run + } + + // don't lock here, wait in background to log error if any + go func() { + err := grp.Wait() + if err != nil { + log.Printf("[WARN] background task for indexing existing comments failed: %s", err) + } + }() + go a.imageService.Cleanup(ctx) // pictures cleanup for staging images a.restSrv.Run(a.Address, a.Port) @@ -1195,6 +1225,22 @@ func (s *ServerCommand) getAuthenticator(ds *service.DataStore, avas avatar.Stor }) } +func (s *ServerCommand) makeSearchService() (*search.Service, error) { + if !s.Search.Enable { + return nil, nil + } + log.Printf("[INFO] creating search service") + + if s.Search.IndexPath == "" { + return nil, fmt.Errorf("search index path is not set") + } + + return search.NewService(s.Sites, search.ServiceParams{ + IndexPath: s.Search.IndexPath, + Analyzer: s.Search.Analyzer, + }) +} + func (s *ServerCommand) parseSameSite(ss string) http.SameSite { switch strings.ToLower(ss) { case "default": diff --git a/backend/app/cmd/server_test.go b/backend/app/cmd/server_test.go index 76c4e63575..b511cc06f0 100644 --- a/backend/app/cmd/server_test.go +++ b/backend/app/cmd/server_test.go @@ -828,5 +828,11 @@ func createAppFromCmd(t *testing.T, cmd ServerCommand) (*serverApp, context.Cont func TestMain(m *testing.M) { // ignore is added only for GitHub Actions, can't reproduce locally - goleak.VerifyTestMain(m, goleak.IgnoreTopFunction("net/http.(*Server).Shutdown")) + goleak.VerifyTestMain(m, + goleak.IgnoreTopFunction("net/http.(*Server).Shutdown"), + + // we should call bleve.Config.Shutdown() to close all the workers, + // but we don't do it for each server instance because it's global per application + goleak.IgnoreTopFunction("github.com/blevesearch/bleve_index_api.AnalysisWorker"), + ) } diff --git a/backend/app/main_test.go b/backend/app/main_test.go index 4eeb78bb51..aac73324a9 100644 --- a/backend/app/main_test.go +++ b/backend/app/main_test.go @@ -157,5 +157,10 @@ func TestMain(m *testing.M) { m, goleak.IgnoreTopFunction("github.com/umputun/remark42/backend/app.init.0.func1"), goleak.IgnoreTopFunction("net/http.(*Server).Shutdown"), + + // we should call bleve.Config.Shutdown() to close all the workers, + // but it's global per application and cannot be reinitialized multiple times + // so we do not terminate them, ignore the leak + goleak.IgnoreTopFunction("github.com/blevesearch/bleve_index_api.AnalysisWorker"), ) } diff --git a/backend/app/rest/api/rest.go b/backend/app/rest/api/rest.go index a1942838f7..390b01a2d4 100644 --- a/backend/app/rest/api/rest.go +++ b/backend/app/rest/api/rest.go @@ -91,12 +91,20 @@ type LoadingCache interface { const hardBodyLimit = 1024 * 64 // limit size of body const lastCommentsScope = "last" +const searchScope = "search" type commentsWithInfo struct { Comments []store.Comment `json:"comments"` Info store.PostInfo `json:"info,omitempty"` } +type commentsWithTotal struct { + // List of comments matching the query and selected by `limit` and `skip` parameters. + Comments []store.Comment `json:"comments"` + // Total number of comments in the index matching query. + Total uint64 `json:"total"` +} + // Run the lister and request's router, activate rest server func (s *Rest) Run(address string, port int) { if address == "*" { @@ -263,6 +271,7 @@ func (s *Rest) routes() chi.Router { ropen.Get("/list", s.pubRest.listCtrl) ropen.Get("/info", s.pubRest.infoCtrl) ropen.Get("/img", s.ImageProxy.Handler) + ropen.Get("/search", s.pubRest.searchQueryCtrl) ropen.Route("/rss", func(rrss chi.Router) { rrss.Get("/post", s.rssRest.postCommentsCtrl) diff --git a/backend/app/rest/api/rest_public.go b/backend/app/rest/api/rest_public.go index 6e122dea31..1867cfee27 100644 --- a/backend/app/rest/api/rest_public.go +++ b/backend/app/rest/api/rest_public.go @@ -42,6 +42,7 @@ type pubStore interface { Count(locator store.Locator) (int, error) List(siteID string, limit, skip int) ([]store.PostInfo, error) Info(locator store.Locator, readonlyAge int) (store.PostInfo, error) + Search(siteID, query, sortBy string, limit, skip int) ([]store.Comment, uint64, error) ValidateComment(c *store.Comment) error IsReadOnly(locator store.Locator) bool @@ -386,6 +387,73 @@ func (s *public) telegramQrCtrl(w http.ResponseWriter, r *http.Request) { } } +// GET /search?site=siteID&query=query&limit=20&skip=10&sort=[-]field - search documents +// site - site ID +// query - user-provided search query +// limit - number of documents to return, default is 20, maximum is 100 +// skip - number of documents to skip, default is 0 (do not skip anything), maximum is 1000 +// sort - sort by specified field, can be prefixed with "-" to reverse the order +func (s *public) searchQueryCtrl(w http.ResponseWriter, r *http.Request) { + getIntParamInRange := func(min, max, defaultVal int, name string) (int, error) { + s := r.URL.Query().Get(name) + if s == "" { + return defaultVal, nil + } + + value, err := strconv.Atoi(s) + if err != nil { + return 0, fmt.Errorf("%s parameter should be an integer", name) + } + + if min <= value && value <= max { + return value, nil + } + return 0, fmt.Errorf("%s parameter should be between %d and %d", name, min, max) + } + + var err error + + var limit int + if limit, err = getIntParamInRange(1, 100, 20, "limit"); err != nil { + rest.SendErrorJSON(w, r, http.StatusBadRequest, fmt.Errorf("wrong param"), err.Error(), rest.ErrInternal) + return + } + + var skip int + if skip, err = getIntParamInRange(0, 1000, 0, "skip"); err != nil { + rest.SendErrorJSON(w, r, http.StatusBadRequest, fmt.Errorf("wrong param"), err.Error(), rest.ErrInternal) + return + } + + siteID := r.URL.Query().Get("site") + query := r.URL.Query().Get("query") + sortBy := r.URL.Query().Get("sort") + + if siteID == "" || query == "" { + rest.SendErrorJSON(w, r, http.StatusBadRequest, fmt.Errorf("missing param"), "site and query parameters are required", rest.ErrInternal) + return + } + + key := cache.NewKey(siteID).ID(URLKey(r)).Scopes(siteID, searchScope) + data, err := s.cache.Get(key, func() ([]byte, error) { + comments, total, searchErr := s.dataService.Search(siteID, query, sortBy, limit, skip) + if searchErr != nil { + return nil, searchErr + } + + return encodeJSONWithHTML(commentsWithTotal{Comments: comments, Total: total}) + }) + + if err != nil { + rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't perform search request", rest.ErrInternal) + return + } + + if err = R.RenderJSONFromBytes(w, r, data); err != nil { + log.Printf("[WARN] can't render search results for site %s", siteID) + } +} + func (s *public) applyView(comments []store.Comment, view string) []store.Comment { if strings.EqualFold(view, "user") { projection := make([]store.Comment, 0, len(comments)) diff --git a/backend/app/rest/api/rest_test.go b/backend/app/rest/api/rest_test.go index 590fbe7529..5577965ef4 100644 --- a/backend/app/rest/api/rest_test.go +++ b/backend/app/rest/api/rest_test.go @@ -10,6 +10,7 @@ import ( "net" "net/http" "net/http/httptest" + urlpkg "net/url" "os" "strconv" "strings" @@ -34,6 +35,7 @@ import ( adminstore "github.com/umputun/remark42/backend/app/store/admin" "github.com/umputun/remark42/backend/app/store/engine" "github.com/umputun/remark42/backend/app/store/image" + "github.com/umputun/remark42/backend/app/store/search" "github.com/umputun/remark42/backend/app/store/service" ) @@ -212,6 +214,94 @@ func TestRest_rejectAnonUser(t *testing.T) { assert.Equal(t, http.StatusOK, resp.StatusCode, "real user") } +func TestRest_Search(t *testing.T) { + var searchIndexPath string + ts, _, teardown := startupT(t, func(srv *Rest) { + var err error + searchIndexPath, err = randomPath(srv.WebRoot, "test-search-remark", "") + require.NoError(t, err) + srv.DataService.SearchService, err = search.NewService([]string{"remark42"}, search.ServiceParams{ + IndexPath: searchIndexPath, + Analyzer: "standard", + }) + require.NoError(t, err) + }) + defer teardown() + defer func() { _ = os.RemoveAll(searchIndexPath) }() + + t0 := time.Date(2018, 12, 20, 15, 18, 22, 0, time.Local) + + id1 := addComment(t, store.Comment{Text: "test test", Timestamp: t0.Add(1 * time.Minute), Locator: store.Locator{SiteID: "remark42", URL: "https://radio-t.com/abc"}}, ts) + id2 := addComment(t, store.Comment{Text: "test hello", Timestamp: t0.Add(2 * time.Minute), Locator: store.Locator{SiteID: "remark42", URL: "https://radio-t.com/blah"}}, ts) + id3 := addComment(t, store.Comment{Text: "hello world", Timestamp: t0.Add(3 * time.Minute), Locator: store.Locator{SiteID: "remark42", URL: "https://radio-t.com/blah"}}, ts) + id4 := addComment(t, store.Comment{Text: "# title\n\nok\n", Timestamp: t0.Add(4 * time.Minute), Locator: store.Locator{SiteID: "remark42", URL: "https://radio-t.com/blah"}}, ts) + + idToPos := map[string]int{id1: 1, id2: 2, id3: 3, id4: 4} + tbl := []struct { + query string + extraParams string + ids []int + status int + }{ + {"blah", "", []int{}, http.StatusOK}, + {"h1", "", []int{}, http.StatusOK}, + {"world", "", []int{3}, http.StatusOK}, + {"title", "", []int{4}, http.StatusOK}, + {"\"hello world\"", "", []int{3}, http.StatusOK}, + {"test", "&sort=time", []int{1, 2}, http.StatusOK}, + {"hello", "&sort=-time", []int{3, 2}, http.StatusOK}, + {"hello world", "&sort=time", []int{2, 3}, http.StatusOK}, + {"hello world test", "&sort=time", []int{1, 2, 3}, http.StatusOK}, + {"hello world test", "&sort=time&skip=1", []int{2, 3}, http.StatusOK}, + {"hello world test", "&sort=time&skip=1&limit=1", []int{2}, http.StatusOK}, + {"", "", []int{}, http.StatusBadRequest}, + {"test", "&sort=text", []int{}, http.StatusBadRequest}, + {"test", "&skip=-1", []int{}, http.StatusBadRequest}, + {"test", "&limit=999999", []int{}, http.StatusBadRequest}, + } + + cnt := 0 + for i, tt := range tbl { + tt := tt + + cnt++ + if (cnt % 10) == 0 { + // wait for rate limiter + time.Sleep(1 * time.Second) + } + t.Run(strconv.Itoa(i), func(t *testing.T) { + resp, err := http.Get(fmt.Sprintf("%s/api/v1/search?site=remark42&query=%s%s", + ts.URL, urlpkg.QueryEscape(tt.query), tt.extraParams)) + require.NoError(t, err) + + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + require.NoError(t, err) + assert.Equal(t, tt.status, resp.StatusCode) + + result := commentsWithTotal{} + err = json.Unmarshal(body, &result) + require.NoError(t, err) + + foundIds := make([]int, len(result.Comments)) + for i, c := range result.Comments { + foundIds[i] = idToPos[c.ID] + } + require.Equal(t, tt.ids, foundIds) + }) + } +} + +func TestRest_SearchDisabledFeature(t *testing.T) { + ts, _, teardown := startupT(t) + defer teardown() + + resp, err := http.Get(ts.URL + "/api/v1/search?site=remark42&query=test") + require.NoError(t, err) + require.NoError(t, resp.Body.Close()) + assert.Equal(t, http.StatusBadRequest, resp.StatusCode) +} + func Test_URLKey(t *testing.T) { tbl := []struct { url string @@ -633,5 +723,9 @@ func waitForHTTPSServerStart(port int) { } func TestMain(m *testing.M) { - goleak.VerifyTestMain(m) + goleak.VerifyTestMain(m, + // we should call bleve.Config.Shutdown() to close all the workers, + // but we don't do it for each server instance because it's global per application + goleak.IgnoreTopFunction("github.com/blevesearch/bleve_index_api.AnalysisWorker"), + ) } diff --git a/backend/app/store/search/bleve.go b/backend/app/store/search/bleve.go new file mode 100644 index 0000000000..4a599dff5c --- /dev/null +++ b/backend/app/store/search/bleve.go @@ -0,0 +1,242 @@ +package search + +import ( + "encoding/json" + "fmt" + "io" + "log" + "os" + "time" + + "github.com/blevesearch/bleve/v2" + + analyzerCustom "github.com/blevesearch/bleve/v2/analysis/analyzer/custom" + analyzerStandard "github.com/blevesearch/bleve/v2/analysis/analyzer/standard" + + // not all currently supported locales are supported by bleve, import only those that are + langAr "github.com/blevesearch/bleve/v2/analysis/lang/ar" + langDe "github.com/blevesearch/bleve/v2/analysis/lang/de" + langEn "github.com/blevesearch/bleve/v2/analysis/lang/en" + langEs "github.com/blevesearch/bleve/v2/analysis/lang/es" + langFi "github.com/blevesearch/bleve/v2/analysis/lang/fi" + langFr "github.com/blevesearch/bleve/v2/analysis/lang/fr" + langIt "github.com/blevesearch/bleve/v2/analysis/lang/it" + langRu "github.com/blevesearch/bleve/v2/analysis/lang/ru" + + "github.com/blevesearch/bleve/v2/analysis/token/lowercase" + "github.com/blevesearch/bleve/v2/mapping" + "github.com/umputun/remark42/backend/app/store" +) + +var analyzerNameMapping = map[string]string{ + "standard": analyzerStandard.Name, + "ar": langAr.AnalyzerName, + "de": langDe.AnalyzerName, + "en": langEn.AnalyzerName, + "es": langEs.AnalyzerName, + "fi": langFi.AnalyzerName, + "fr": langFr.AnalyzerName, + "it": langIt.AnalyzerName, + "ru": langRu.AnalyzerName, +} + +type bleveEngine struct { + index bleve.Index + indexPath string +} + +// Index adds set of comments to the index +func (b *bleveEngine) Index(comments []store.Comment) error { + batch := b.index.NewBatch() + for _, comment := range comments { + key := DocumentKey{Locator: comment.Locator, ID: comment.ID} + keyBytes, err := json.Marshal(key) + if err != nil { + return fmt.Errorf("can't marshal key %+v: %w", key, err) + } + + doc := newBleveDoc(comment) + err = batch.Index(string(keyBytes), doc) + if err != nil { + return fmt.Errorf("can't add to indexing batch: %w", err) + } + } + err := b.index.Batch(batch) + if err != nil { + return fmt.Errorf("index error: %w", err) + } + + return nil +} + +// Search performs search request +func (b *bleveEngine) Search(req *Request) (*Result, error) { + bQuery := bleve.NewQueryStringQuery(req.Query) + bReq := bleve.NewSearchRequestOptions(bQuery, req.Limit, req.Skip, false) + + switch { + case req.SortBy == "": + bReq.SortBy([]string{"-time"}) + case req.SortBy == "time" || req.SortBy == "-time" || req.SortBy == "+time": + bReq.SortBy([]string{req.SortBy}) + default: + return nil, fmt.Errorf("unknown sort field %s", req.SortBy) + } + + searchRes, err := b.index.Search(bReq) + if err != nil { + return nil, fmt.Errorf("search error: %w", err) + } + + log.Printf("[INFO] found %d documents for query %q in %s", + searchRes.Total, req.Query, searchRes.Took.String()) + + result := convertResultRepr(searchRes) + return &result, nil +} + +// Size is the number of documents in the index +func (b *bleveEngine) Size() (uint64, error) { + return b.index.DocCount() +} + +// Close closes index +func (b *bleveEngine) Close() error { + return b.index.Close() +} + +func newBleveEngine(indexPath, analyzer string) (*bleveEngine, error) { + indexExists, err := checkIndexPath(indexPath) + if err != nil { + return nil, err + } + + var index bleve.Index + if !indexExists { + log.Printf("[INFO] creating new search index %s", indexPath) + + bleveAnalyzerName, has := analyzerNameMapping[analyzer] + if !has { + return nil, fmt.Errorf("unknown analyzer %q", analyzer) + } + index, err = bleve.New(indexPath, createIndexMapping(bleveAnalyzerName)) + if err != nil { + return nil, fmt.Errorf("cannot open index: %w", err) + } + } else { + log.Printf("[INFO] opening existing search index %s", indexPath) + index, err = bleve.Open(indexPath) + if err != nil { + return nil, fmt.Errorf("cannot open index: %w", err) + } + } + + return &bleveEngine{ + index: index, + indexPath: indexPath, + }, nil +} + +// checkIndexPath creates directories if path is not exists and checks if it is empty +// returns true if there already was some files in index path +func checkIndexPath(path string) (bool, error) { + st, err := os.Stat(path) + + if err != nil && !os.IsNotExist(err) { + return false, err + } + + if os.IsNotExist(err) { + err = os.MkdirAll(path, os.ModePerm) + if err != nil { + return false, err + } + return false, nil + } + + if !st.IsDir() { + return false, fmt.Errorf("index path should be a directory") + } + // check if `path` directory is empty + f, err := os.Open(path) //nolint:gosec // opening directory in `SEARCH_INDEX_PATH` + if err != nil { + return false, err + } + defer func() { _ = f.Close() }() + + names, err := f.Readdirnames(1) + if err != nil && err != io.EOF { + return false, err + } + // some files are found, consider index as not empty + return len(names) > 0, nil +} + +// bleveDoc is the structure that would be indexed. +// We index only these fields from the comment. +// Actually, we can index store.Comment directly. +// but we want to exclude unnecessary fields and +// change the layout of the document, e.g. +// have 'user' field instead of 'user.name'. +// The bleve doen't support mapping of the nested fields to top-level +// see https://github.com/blevesearch/bleve/issues/229 +type bleveDoc struct { + Text string `json:"text"` + User string `json:"user"` + Timestamp time.Time `json:"time"` +} + +func newBleveDoc(comment store.Comment) *bleveDoc { + return &bleveDoc{ + Text: comment.Text, + User: comment.User.Name, + Timestamp: comment.Timestamp, + } +} + +func textMapping(analyzer string, doStore bool) *mapping.FieldMapping { + textFieldMapping := bleve.NewTextFieldMapping() + textFieldMapping.Store = doStore + textFieldMapping.Analyzer = analyzer + return textFieldMapping +} + +func createIndexMapping(textAnalyzer string) mapping.IndexMapping { + indexMapping := bleve.NewIndexMapping() + + err := indexMapping.AddCustomAnalyzer("keyword_lower", map[string]interface{}{ + "type": analyzerCustom.Name, "tokenizer": "single", "token_filters": []string{lowercase.Name}, + }) + if err != nil { + panic(fmt.Sprintf("error adding bleve analyzer %v", err)) + } + + // setup how comments would be indexed + commentMapping := bleve.NewDocumentMapping() + commentMapping.AddFieldMappingsAt("text", textMapping(textAnalyzer, false)) + commentMapping.AddFieldMappingsAt("user", textMapping("keyword_lower", true)) + commentMapping.AddFieldMappingsAt("time", bleve.NewDateTimeFieldMapping()) + + indexMapping.AddDocumentMapping("_default", commentMapping) + + return indexMapping +} + +// convertBleveSerp converts bleve search result to search.Result +func convertResultRepr(bleveResult *bleve.SearchResult) Result { + result := Result{ + Total: bleveResult.Total, + Keys: make([]DocumentKey, 0, len(bleveResult.Hits)), + } + + for _, r := range bleveResult.Hits { + key := DocumentKey{} + err := json.Unmarshal([]byte(r.ID), &key) + if err != nil { + log.Printf("[WARN] can't unmarshal key %s, %s", r.ID, err) + continue + } + result.Keys = append(result.Keys, key) + } + return result +} diff --git a/backend/app/store/search/engine.go b/backend/app/store/search/engine.go new file mode 100644 index 0000000000..28594b5415 --- /dev/null +++ b/backend/app/store/search/engine.go @@ -0,0 +1,21 @@ +package search + +import ( + "github.com/umputun/remark42/backend/app/store" +) + +// Engine provides core functionality for searching used by Service +type Engine interface { + + // Index adds or updates a document in the index + Index(comments []store.Comment) error + + // Search performs search request + Search(req *Request) (*Result, error) + + // Size returns number of documents in the index + Size() (uint64, error) + + // Close closes the index + Close() error +} diff --git a/backend/app/store/search/search_test.go b/backend/app/store/search/search_test.go new file mode 100644 index 0000000000..be31fe4fc3 --- /dev/null +++ b/backend/app/store/search/search_test.go @@ -0,0 +1,310 @@ +package search + +import ( + "context" + "fmt" + "math/rand" + "os" + "testing" + "time" + + "github.com/go-pkgz/syncs" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.etcd.io/bbolt" + + "github.com/umputun/remark42/backend/app/store" + "github.com/umputun/remark42/backend/app/store/engine" +) + +func createTestServiceInDir(t *testing.T, sites []string, idxPath string, keepIdx bool) (searcher *Service, teardown func()) { + searcher, err := NewService(sites, ServiceParams{ + IndexPath: idxPath, + Analyzer: "standard", + }) + + require.NoError(t, err) + + teardown = func() { + err := searcher.Close() + require.NoError(t, err) + if !keepIdx { + _ = os.RemoveAll(idxPath) + } + } + return searcher, teardown +} + +func createTestService(t *testing.T, sites []string) (searcher *Service, teardown func()) { + idxPath := os.TempDir() + "/search-remark42" + _ = os.RemoveAll(idxPath) + return createTestServiceInDir(t, sites, idxPath, false) +} + +func TestSearch_Site(t *testing.T) { + idxPath := os.TempDir() + "/search-remark42" + searcher, teardown := createTestServiceInDir(t, []string{"test-site", "test-site2", "test-site3"}, idxPath, true) + defer teardown() + + err := searcher.Index(store.Comment{ + ID: "123456", + Locator: store.Locator{SiteID: "test-site", URL: "http://example.com/post1"}, + Text: "text 123", + User: store.User{ID: "u1", Name: "user1"}, + Timestamp: time.Date(2017, 12, 20, 15, 18, 24, 0, time.Local), + }) + assert.NoError(t, err) + err = searcher.Index(store.Comment{ + ID: "123456", + Locator: store.Locator{SiteID: "test-site2", URL: "http://example.com/post1"}, + Text: "text 345", + User: store.User{ID: "u1", Name: "user1"}, + Timestamp: time.Date(2017, 12, 20, 15, 20, 24, 0, time.Local), + }) + assert.NoError(t, err) + err = searcher.Index(store.Comment{ + ID: "123457", + Locator: store.Locator{SiteID: "test-site2", URL: "http://example.com/post1"}, + Text: "foobar 345", + User: store.User{ID: "u1", Name: "user1"}, + Timestamp: time.Date(2017, 12, 20, 15, 20, 28, 0, time.Local), + }) + assert.NoError(t, err) + + var res *Result + + res, err = searcher.Search(&Request{SiteID: "test-site", Query: "123", Limit: 3}) + require.NoError(t, err) + require.Len(t, res.Keys, 1) + assert.Equal(t, "123456", res.Keys[0].ID) + + res, err = searcher.Search(&Request{SiteID: "test-site", Query: "345", Limit: 3}) + require.NoError(t, err) + require.Len(t, res.Keys, 0) + + res, err = searcher.Search(&Request{SiteID: "test-site2", Query: "345", SortBy: "-time", Limit: 3}) + require.NoError(t, err) + require.Len(t, res.Keys, 2) + assert.Equal(t, "123457", res.Keys[0].ID) + assert.Equal(t, "123456", res.Keys[1].ID) + + res, err = searcher.Search(&Request{SiteID: "test-site2", Query: "345", SortBy: "-time", Limit: 1}) + require.NoError(t, err) + require.Len(t, res.Keys, 1) + assert.Equal(t, "123457", res.Keys[0].ID) + + res, err = searcher.Search(&Request{SiteID: "test-site2", Query: "345", SortBy: "-time", Limit: 1, Skip: 1}) + require.NoError(t, err) + require.Len(t, res.Keys, 1) + assert.Equal(t, "123456", res.Keys[0].ID) + + res, err = searcher.Search(&Request{SiteID: "test-site2", Query: "123", Limit: 3}) + require.NoError(t, err) + assert.Len(t, res.Keys, 0) + + res, err = searcher.Search(&Request{SiteID: "test-site3", Query: "345", Limit: 3}) + require.NoError(t, err) + assert.Len(t, res.Keys, 0) + + _, err = searcher.Search(&Request{SiteID: "test-site2", Query: "345", SortBy: "badfield"}) + require.Error(t, err) + + res, err = searcher.Search(&Request{SiteID: "test-site3", Query: "345", Limit: 3}) + require.NoError(t, err) + assert.Len(t, res.Keys, 0) + + // restart service to check that saved index is loaded + err = searcher.Close() + require.NoError(t, err) + + searcher2, teardown2 := createTestServiceInDir(t, []string{"test-site", "test-site2", "test-site3"}, idxPath, false) + defer teardown2() + + res, err = searcher2.Search(&Request{SiteID: "test-site2", Query: "345", SortBy: "-time", Limit: 3}) + require.NoError(t, err) + require.Len(t, res.Keys, 2) + assert.Equal(t, "123457", res.Keys[0].ID) + assert.Equal(t, "123456", res.Keys[1].ID) +} + +func TestSearch_Paginate(t *testing.T) { + searcher, teardown := createTestService(t, []string{"test-site"}) + defer teardown() + + t0 := time.Date(2017, 12, 20, 15, 18, 24, 0, time.Local) + for shift := 0; shift < 4; shift++ { + cid := fmt.Sprintf("comment%d", shift) + err := searcher.Index(store.Comment{ + ID: cid, + Locator: store.Locator{SiteID: "test-site", URL: fmt.Sprintf("http://example.com/post%d", shift%2)}, + Text: "text 123", + User: store.User{ID: "u1", Name: "user1"}, + Timestamp: t0.Add(time.Duration(shift) * time.Minute), + }) + assert.NoError(t, err) + } + + { + res, err := searcher.Search(&Request{SiteID: "test-site", Query: "123", Limit: 1, SortBy: "time", Skip: 0}) + require.NoError(t, err) + require.Len(t, res.Keys, 1) + assert.Equal(t, "comment0", res.Keys[0].ID) + } + { + res, err := searcher.Search(&Request{SiteID: "test-site", Query: "123", Limit: 1, SortBy: "+time", Skip: 1}) + require.NoError(t, err) + require.Len(t, res.Keys, 1) + assert.Equal(t, "comment1", res.Keys[0].ID) + } + { + res, err := searcher.Search(&Request{SiteID: "test-site", Query: "123", Limit: 1, SortBy: "+time", Skip: 3}) + require.NoError(t, err) + require.Len(t, res.Keys, 1) + assert.Equal(t, "comment3", res.Keys[0].ID) + } + { + res, err := searcher.Search(&Request{SiteID: "test-site", Query: "123", Limit: 2, Skip: 1, SortBy: "-time"}) + require.NoError(t, err) + require.Len(t, res.Keys, 2) + assert.Equal(t, []string{"comment2", "comment1"}, []string{res.Keys[0].ID, res.Keys[1].ID}) + } +} + +func TestSearch_ExtraFields(t *testing.T) { + searcher, teardown := createTestService(t, []string{"test-site", "test-site2", "test-site3"}) + defer teardown() + + err := searcher.Index(store.Comment{ + ID: "123456", + Locator: store.Locator{SiteID: "test-site", URL: "http://example.com/post1"}, + Text: "text 123", + User: store.User{ID: "u1", Name: "user foo"}, + Timestamp: time.Date(2017, 12, 18, 15, 18, 24, 0, time.Local), + }) + assert.NoError(t, err) + err = searcher.Index(store.Comment{ + ID: "123457", + Locator: store.Locator{SiteID: "test-site", URL: "http://example.com/post1"}, + Text: "text 345", + User: store.User{ID: "u2", Name: "User Bar"}, + Timestamp: time.Date(2017, 12, 21, 15, 20, 24, 0, time.Local), + }) + assert.NoError(t, err) + err = searcher.Index(store.Comment{ + ID: "123458", + Locator: store.Locator{SiteID: "test-site", URL: "http://example.com/post1"}, + Text: "foobar text", + User: store.User{ID: "u2", Name: "User Bar"}, + Timestamp: time.Date(2017, 12, 25, 16, 20, 28, 0, time.Local), + }) + assert.NoError(t, err) + + // username + { + res, err := searcher.Search(&Request{SiteID: "test-site", Query: "text +user:\"user bar\"", Limit: 20}) + require.NoError(t, err) + assert.Len(t, res.Keys, 2) + } + { + res, err := searcher.Search(&Request{SiteID: "test-site", Query: "text +user:\"user foo\"", Limit: 20}) + require.NoError(t, err) + assert.Len(t, res.Keys, 1) + } + { + // order matters in username field, match only whole token + res, err := searcher.Search(&Request{SiteID: "test-site", Query: "text +user:\"foo user\"", Limit: 20}) + require.NoError(t, err) + assert.Len(t, res.Keys, 0) + } + + // time range + { + res, err := searcher.Search(&Request{SiteID: "test-site", Query: "text +time:>\"2017-12-20\"", Limit: 20}) + require.NoError(t, err) + assert.Len(t, res.Keys, 2) + } + { + res, err := searcher.Search(&Request{SiteID: "test-site", Query: "text +time:<\"2017-12-20\"", Limit: 20}) + require.NoError(t, err) + assert.Len(t, res.Keys, 1) + } +} + +func TestSearch_IndexStartup(t *testing.T) { + sites := []string{"test-site", "remark", "test-site42"} + + searcher, serviceTeardown := createTestService(t, sites) + defer serviceTeardown() + + storeEngine, dbTeardown := createDB(t, 42, sites) + defer dbTeardown() + + grp := syncs.NewErrSizedGroup(4) + for _, siteID := range sites { + err := IndexSite(context.Background(), siteID, searcher, storeEngine, grp) + require.NoError(t, err) + } + err := grp.Wait() + require.NoError(t, err) + + for _, siteID := range sites { + serp, err := searcher.Search(&Request{ + SiteID: siteID, + Query: "text", + Limit: 19, + }) + assert.NoError(t, err) + assert.Len(t, serp.Keys, 19) + } +} + +func TestSearch_BadAnalyzerName(t *testing.T) { + sites := []string{"test-site"} + idxPath := os.TempDir() + "/search-remark42" + + _, err := NewService(sites, ServiceParams{ + IndexPath: idxPath, + Analyzer: "badanalyzer", + }) + + require.Error(t, err) +} + +func createDB(t *testing.T, commentsPerSite int, sites []string) (e engine.Interface, teardown func()) { + testDB := os.TempDir() + "/remark-db" + _ = os.RemoveAll(testDB) + err := os.MkdirAll(testDB, 0o700) + require.NoError(t, err) + bsites := []engine.BoltSite{} + for _, s := range sites { + bsites = append(bsites, engine.BoltSite{FileName: testDB + "/" + s, SiteID: s}) + } + b, err := engine.NewBoltDB(bbolt.Options{}, bsites...) + require.NoError(t, err) + teardown = func() { + require.NoError(t, b.Close()) + _ = os.RemoveAll(testDB) + } + + rng := rand.New(rand.NewSource(42)) + + t0 := time.Date(2017, 12, 20, 15, 18, 24, 0, time.Local) + for _, siteID := range sites { + for shift := 0; shift < commentsPerSite; shift++ { + cid := fmt.Sprintf("comment%d", shift) + uid := rng.Intn(15) + comment := store.Comment{ + ID: cid, + Locator: store.Locator{SiteID: siteID, URL: fmt.Sprintf("http://example.com/post%d", rng.Intn(9))}, + Text: fmt.Sprintf("%d text %d", rng.Int63(), rng.Int63()), + User: store.User{ID: fmt.Sprintf("u%d", uid), Name: fmt.Sprintf("user %d", uid)}, + Timestamp: t0.Add(time.Duration(shift) * time.Hour), + } + ccid, err := b.Create(comment) + require.NoError(t, err) + require.Equal(t, cid, ccid) + } + } + + return b, teardown +} diff --git a/backend/app/store/search/service.go b/backend/app/store/search/service.go new file mode 100644 index 0000000000..374daeb6c9 --- /dev/null +++ b/backend/app/store/search/service.go @@ -0,0 +1,146 @@ +package search + +import ( + "encoding/hex" + "fmt" + "hash/fnv" + "log" + "path" + + "github.com/hashicorp/go-multierror" + "github.com/microcosm-cc/bluemonday" + "github.com/umputun/remark42/backend/app/store" +) + +// Service provides high-level API for the search functionality the end consumer (i.e. REST) needs. +// Caller should add documents to the index using Index() and perform search among them using Search(). +// Since there's no Delete() method, it's up to the caller not to show them in the search results (the store should not return their content). +// +// It uses some Engine implementation under the hood. +// Separate engine is used for each site. +// Service is thread-safe (if the engine is so) because after creating sitesEngines is not modified. +type Service struct { + sitesEngines map[string]Engine +} + +// Request for search +type Request struct { + // Request should be sent for a specific site + SiteID string + + // Query contains user input. + // It's a phrase containing some words with additional search operators, + // e.g. search for comments of specific 'user' or with specified 'time'. + // For example: `hello world user:umputun time:>=2019-01-01`. + // It's engine specific to parse and handle it. + Query string + + // Sort by specified field, e.g. "time", "-time" + // Prefix "-" means descending order + SortBy string + + // Pagination + Skip int + Limit int +} + +// DocumentKey is a unique key for a document +type DocumentKey struct { + Locator store.Locator `json:"locator"` + ID string `json:"id"` +} + +// Result is a search result +// Contains only keys of the documents without its content +// Caller should retrieve comment's content from the storage +type Result struct { + // Total is a total number of documents in the index that match the query + Total uint64 `json:"total"` + Keys []DocumentKey `json:"keys"` +} + +// ServiceParams contains parameters for creating a search service +type ServiceParams struct { + IndexPath string + Analyzer string +} + +// NewService creates new search service +func NewService(sites []string, params ServiceParams) (*Service, error) { + s := &Service{ + sitesEngines: map[string]Engine{}, + } + + var err error + for _, site := range sites { + // encode site name to make it safe to use as a file name + idxPath := path.Join(params.IndexPath, hex.EncodeToString(fnv.New32().Sum([]byte(site)))) + + s.sitesEngines[site], err = newBleveEngine(idxPath, params.Analyzer) + if err != nil { + return nil, fmt.Errorf("failed to create search engine: %w", err) + } + } + return s, nil +} + +// Index single document +// It should be called after each comment is created or updated. +func (s *Service) Index(doc store.Comment) error { + return s.indexBatch([]store.Comment{doc}) +} + +// Search performs search query +func (s *Service) Search(req *Request) (*Result, error) { + eng, ok := s.sitesEngines[req.SiteID] + if !ok { + return nil, fmt.Errorf("no search engine for site %q", req.SiteID) + } + return eng.Search(req) +} + +// Close search service +func (s *Service) Close() error { + if s.sitesEngines == nil { + return nil + } + + log.Print("[INFO] closing search service...") + errs := new(multierror.Error) + + for siteID, searcher := range s.sitesEngines { + if err := searcher.Close(); err != nil { + errs = multierror.Append(errs, fmt.Errorf("cannot close searcher for %q: %w", siteID, err)) + } + } + + log.Print("[INFO] search service closed") + + // reset sitesEngines to make it safe to call Close() multiple times + s.sitesEngines = nil + + return errs.ErrorOrNil() +} + +// indexBatch indexes batch of document +func (s *Service) indexBatch(docs []store.Comment) error { + if len(docs) == 0 { + return nil + } + siteID := docs[0].Locator.SiteID + if eng, has := s.sitesEngines[siteID]; has { + for i := range docs { + // remove all html tags from the text, because we want to search only in the text + p := bluemonday.StrictPolicy() + docs[i].Text = p.Sanitize(docs[i].Text) + + // check that all documents from same site + if docs[i].Locator.SiteID != siteID { + return fmt.Errorf("different sites in batch") + } + } + + return eng.Index(docs) + } + return fmt.Errorf("site %q not found", siteID) +} diff --git a/backend/app/store/search/site_index.go b/backend/app/store/search/site_index.go new file mode 100644 index 0000000000..838d202ffa --- /dev/null +++ b/backend/app/store/search/site_index.go @@ -0,0 +1,79 @@ +package search + +import ( + "context" + "fmt" + "log" + "sync/atomic" + "time" + + "github.com/go-pkgz/syncs" + "github.com/umputun/remark42/backend/app/store" + "github.com/umputun/remark42/backend/app/store/engine" +) + +// IndexSite rebuilds search index for the site +// Run indexing of each topic in parallel in a sized group +func IndexSite(ctx context.Context, siteID string, s *Service, e engine.Interface, grp *syncs.ErrSizedGroup) error { + siteIdx, isIndexed := s.sitesEngines[siteID] + if !isIndexed { + log.Printf("[INFO] skipping indexing site %q", siteID) + return nil + } + indexSize, err := siteIdx.Size() + if err != nil { + log.Printf("[WARN] failed to get index size, %s", err) + return nil + } + + // index only it's a first run with enabled search on top of existing comments + if indexSize > 0 { + log.Printf("[INFO] index for site %q already exists, size %d", siteID, indexSize) + return nil + } + + log.Printf("[INFO] indexing site %s", siteID) + startTime := time.Now() + + req := engine.InfoRequest{Locator: store.Locator{SiteID: siteID}} + topics, err := e.Info(req) + + if err != nil { + return fmt.Errorf("failed to get topics for site %q: %w", siteID, err) + } + + var indexedCnt uint64 + worker := func(ctx context.Context, url string) error { + locator := store.Locator{SiteID: siteID, URL: url} + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + + req := engine.FindRequest{Locator: locator, Since: time.Time{}} + comments, findErr := e.Find(req) + if findErr != nil { + return fmt.Errorf("failed to fetch comments: %w", findErr) + } + + indexErr := s.indexBatch(comments) + log.Printf("[INFO] %d documents indexed from site %v", len(comments), locator) + + if indexErr != nil { + return fmt.Errorf("failed to index comments for search: %w", indexErr) + } + + atomic.AddUint64(&indexedCnt, uint64(len(comments))) + + return nil + } + + for i := len(topics) - 1; i >= 0; i-- { + url := topics[i].URL + grp.Go(func() error { return worker(ctx, url) }) + } + + log.Printf("[INFO] total %d documents indexed for site %q in %v", indexedCnt, siteID, time.Since(startTime)) + return nil +} diff --git a/backend/app/store/service/service.go b/backend/app/store/service/service.go index 102cdca9a5..92f3e6c308 100644 --- a/backend/app/store/service/service.go +++ b/backend/app/store/service/service.go @@ -3,6 +3,7 @@ package service import ( + "context" "fmt" "math" "sort" @@ -12,6 +13,7 @@ import ( "github.com/go-pkgz/lcw" log "github.com/go-pkgz/lgr" + "github.com/go-pkgz/syncs" "github.com/google/uuid" "github.com/hashicorp/go-multierror" @@ -19,6 +21,7 @@ import ( "github.com/umputun/remark42/backend/app/store/admin" "github.com/umputun/remark42/backend/app/store/engine" "github.com/umputun/remark42/backend/app/store/image" + "github.com/umputun/remark42/backend/app/store/search" ) // DataStore wraps store.Interface with additional methods @@ -36,6 +39,7 @@ type DataStore struct { TitleExtractor *TitleExtractor RestrictedWordsMatcher *RestrictedWordsMatcher ImageService *image.Service + SearchService *search.Service AdminEdits bool // allow admin unlimited edits // granular locks @@ -104,6 +108,10 @@ func (s *DataStore) Create(comment store.Comment) (commentID string, err error) commentID, err = s.Engine.Create(comment) s.submitImages(comment) + if e := s.indexCommentForSearch(comment); e != nil { + log.Printf("[WARN] failed to index comment for search, %v", e) + } + if e := s.AdminStore.OnEvent(comment.Locator.SiteID, admin.EvCreate); e != nil { log.Printf("[WARN] failed to send create event, %s", e) } @@ -522,6 +530,11 @@ func (s *DataStore) EditComment(locator store.Locator, commentID string, req Edi } err = s.Engine.Update(comment) + + if e := s.indexCommentForSearch(comment); e != nil { + log.Printf("[WARN] failed to update comment index, %v", e) + } + return comment, err } @@ -907,6 +920,49 @@ func (s *DataStore) Last(siteID string, limit int, since time.Time, user store.U return s.alterComments(comments, user), nil } +// Search executes search query and enriches the result with comment content +func (s *DataStore) Search(siteID, query, sortBy string, limit, skip int) ([]store.Comment, uint64, error) { + if s.SearchService == nil { + return []store.Comment{}, 0, fmt.Errorf("search service is not enabled") + } + req := &search.Request{ + SiteID: siteID, + Query: query, + Limit: limit, + Skip: skip, + SortBy: sortBy, + } + + searchRes, err := s.SearchService.Search(req) + if err != nil { + return nil, 0, fmt.Errorf("search failed: %w", err) + } + + comments := make([]store.Comment, 0, len(searchRes.Keys)) + for _, docKey := range searchRes.Keys { + comment, e := s.Get(docKey.Locator, docKey.ID, nonAdminUser) + if e != nil { + // ignore error because comment can be deleted from the store (but we still have it in search index) + continue + } + comments = append(comments, comment) + } + return comments, searchRes.Total, nil +} + +// RunSiteIndexers indexes all comments for siteID in the sized group. +// It's required to call this method at the startup to support "cold start" +// when store contains some data, but search functionality is enabled for the first time. +func (s *DataStore) RunSiteIndexers(ctx context.Context, siteID string, grp *syncs.ErrSizedGroup) { + if s.SearchService == nil { + return + } + err := search.IndexSite(ctx, siteID, s.SearchService, s.Engine, grp) + if err != nil { + log.Printf("[WARN] error occurred during indexing comments for site %q: %e", siteID, err) + } +} + // Close store service func (s *DataStore) Close() error { errs := new(multierror.Error) @@ -916,6 +972,9 @@ func (s *DataStore) Close() error { if s.TitleExtractor != nil { errs = multierror.Append(errs, s.TitleExtractor.Close()) } + if s.SearchService != nil { + errs = multierror.Append(errs, s.SearchService.Close()) + } errs = multierror.Append(errs, s.Engine.Close()) return errs.ErrorOrNil() } @@ -1013,3 +1072,13 @@ func (s *DataStore) getSecret(siteID string) (secret string, err error) { } return secret, nil } + +func (s *DataStore) indexCommentForSearch(comment store.Comment) error { + if s.SearchService != nil { + err := s.SearchService.Index(comment) + if err != nil { + return fmt.Errorf("can't index comment %s: %w", comment.ID, err) + } + } + return nil +} diff --git a/backend/remark.rest b/backend/remark.rest index 7febc2180e..4f7b772b7c 100644 --- a/backend/remark.rest +++ b/backend/remark.rest @@ -118,6 +118,9 @@ GET {{host}}/api/v1/rss/reply?site={{site}}&user={{user}} ### get default avatar GET {{host}}/api/v1/avatar/blah +### search comments +GET {{host}}/api/v1/search?site={{site}}&query=query&limit=20&skip=0&sort=time + ### send confirmation token for current user to specified email. auth token for dev user for secret=12345. ### in case the user logged in with the same email, it will be confirmed right away with "updated" set to "true" in the response, ### and no email will be sent. diff --git a/site/src/docs/configuration/parameters/index.md b/site/src/docs/configuration/parameters/index.md index b3577c12a5..227600406d 100644 --- a/site/src/docs/configuration/parameters/index.md +++ b/site/src/docs/configuration/parameters/index.md @@ -134,6 +134,9 @@ services: | ssl.key | SSL_KEY | | path to the key.pem file | | ssl.acme-location | SSL_ACME_LOCATION | `./var/acme` | dir where obtained le-certs will be stored | | ssl.acme-email | SSL_ACME_EMAIL | | admin email for receiving notifications from LE | +| search.enable | SEARCH_ENABLE | `false` | enable search engine | +| search.index_path | SEARCH_INDEX_PATH | `./var/search_index` | search index location | +| search.analyzer | SEARCH_ANALYZER | `standard` | text analyzer type, set language-specific one to improve search quality (`standard`, `ar`, `de`, `en`, `es`, `fi`, `fr`, `it` or `ru` ) | | max-comment | MAX_COMMENT_SIZE | `2048` | comment's size limit | | max-votes | MAX_VOTES | `-1` | votes limit per comment, `-1` - unlimited | | votes-ip | VOTES_IP | `false` | restrict votes from the same IP | diff --git a/site/src/docs/contributing/api/index.md b/site/src/docs/contributing/api/index.md index 975282d37f..6b3a500269 100644 --- a/site/src/docs/contributing/api/index.md +++ b/site/src/docs/contributing/api/index.md @@ -233,3 +233,23 @@ http://oldsite.com/from-old-page/1 https://newsite.com/to-new-page/1 - `GET /api/v1/admin/deleteme?token=token` - process deleteme user's request _all admin calls require auth and admin privilege_ + +### Search + +* `GET /search?site=siteID&query=query` - search comments for query `query` and returns `ResultPage` +* `GET /search?site=siteID&query=query&sort=time` - sort by time ascending (oldest first) +* `GET /search?site=siteID&query=query&sort=-time` - sort by time descending (newest first) +* `GET /search?site=siteID&query=query&sort=-time&limit=20&skip=10` - pagination, get 20 comments after skiping 10 most newest + + Returns the list of comments matching the query. + Comments are sorted according to the field specified in `sort` parameter. If the filed name is prefixed by `-` then the order will be reversed. + The maximal value for the `limit` parameter is 100 and for the `skip` is 1000. + The field `total` in the result contains the total number of comments matching the query in the index. + Note: this functionality is optional and should be configured. If it's disabled, the `/search` endpoint will return a `Bad Request` error. + +```go +type CommentsWithTotal struct { + Comments []store.Comment `json:"comments"` + Total uint64 `json:"total"` +} +``` diff --git a/site/src/docs/contributing/translations/index.md b/site/src/docs/contributing/translations/index.md index a02ae558e8..9750f9116c 100644 --- a/site/src/docs/contributing/translations/index.md +++ b/site/src/docs/contributing/translations/index.md @@ -36,6 +36,7 @@ below to have your translation available to all remark42 users and included in t 1. Run `npm run translation:generate` in the `frontend` folder 1. Translate all values in the newly created JSON file in [frontend/app/locales/](https://github.com/umputun/remark42/tree/master/frontend/app/locales) +1. Add corresponding analyzer to the list of imports in [backend/app/store/search/bleve.go](https://github.com/umputun/remark42/blob/master/backend/app/store/search/bleve.go) to enable language support in the search engine. You may find the list of supported languages in [github.com/blevesearch/bleve/v2/analysis/lang](https://github.com/blevesearch/bleve/tree/master/analysis/lang). 1. Commit all changes above in your fork 1. Test your changes in the interface: From d61ad0094b8a6cbf555f31ed8278930d547c6e9d Mon Sep 17 00:00:00 2001 From: vdimir Date: Sun, 2 Apr 2023 10:52:26 +0000 Subject: [PATCH 2/4] Add blevesearch to go.mod --- backend/go.mod | 21 +++++++++++++++++++++ backend/go.sum | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/backend/go.mod b/backend/go.mod index 3c70d35bf3..24d3b346a3 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -6,6 +6,7 @@ require ( github.com/Depado/bfchroma/v2 v2.0.0 github.com/PuerkitoBio/goquery v1.8.1 github.com/alecthomas/chroma/v2 v2.7.0 + github.com/blevesearch/bleve/v2 v2.3.7 github.com/didip/tollbooth/v7 v7.0.1 github.com/didip/tollbooth_chi v0.0.0-20220719025231-d662a7f6928f github.com/go-chi/chi/v5 v5.0.8 @@ -40,9 +41,26 @@ require ( require ( cloud.google.com/go/compute v1.14.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect + github.com/RoaringBitmap/roaring v0.9.4 // indirect github.com/ajg/form v1.5.1 // indirect github.com/andybalholm/cascadia v1.3.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect + github.com/bits-and-blooms/bitset v1.2.0 // indirect + github.com/blevesearch/bleve_index_api v1.0.5 // indirect + github.com/blevesearch/geo v0.1.17 // indirect + github.com/blevesearch/go-porterstemmer v1.0.3 // indirect + github.com/blevesearch/gtreap v0.1.1 // indirect + github.com/blevesearch/mmap-go v1.0.4 // indirect + github.com/blevesearch/scorch_segment_api/v2 v2.1.4 // indirect + github.com/blevesearch/segment v0.9.1 // indirect + github.com/blevesearch/snowballstem v0.9.0 // indirect + github.com/blevesearch/upsidedown_store_api v1.0.2 // indirect + github.com/blevesearch/vellum v1.0.9 // indirect + github.com/blevesearch/zapx/v11 v11.3.7 // indirect + github.com/blevesearch/zapx/v12 v12.3.7 // indirect + github.com/blevesearch/zapx/v13 v13.3.7 // indirect + github.com/blevesearch/zapx/v14 v14.3.7 // indirect + github.com/blevesearch/zapx/v15 v15.3.9 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dghubble/oauth1 v0.7.2 // indirect @@ -52,14 +70,17 @@ require ( github.com/go-pkgz/email v0.4.1 // indirect github.com/go-pkgz/expirable-cache v0.1.0 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect + github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.1 // indirect github.com/gorilla/css v1.0.0 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/json-iterator/go v0.0.0-20171115153421-f7279a603ede // indirect github.com/klauspost/compress v1.15.0 // indirect github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect + github.com/mschoch/smat v0.2.0 // indirect github.com/nullrocks/identicon v0.0.0-20180626043057-7875f45b0022 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/backend/go.sum b/backend/go.sum index 3b2b9524e0..a9bd58c608 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -7,6 +7,8 @@ github.com/Depado/bfchroma/v2 v2.0.0 h1:IRpN9BPkNwEpR6w1ectIcNWOuhDSLx+8f1pn83fz github.com/Depado/bfchroma/v2 v2.0.0/go.mod h1:wFwW/Pw8Tnd0irzgO9Zxtxgzp3aPS8qBWlyadxujxmw= github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM= github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ= +github.com/RoaringBitmap/roaring v0.9.4 h1:ckvZSX5gwCRaJYBNe7syNawCU5oruY9gQmjXlp4riwo= +github.com/RoaringBitmap/roaring v0.9.4/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/alecthomas/assert/v2 v2.2.1 h1:XivOgYcduV98QCahG8T5XTezV5bylXe+lBxLG2K2ink= @@ -23,6 +25,40 @@ github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x0 github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= +github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA= +github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/blevesearch/bleve/v2 v2.3.7 h1:nIfIrhv28tvgBpbVF8Dq7/U1zW/YiwSqg/PBgE3x8bo= +github.com/blevesearch/bleve/v2 v2.3.7/go.mod h1:2tToYD6mDeseIA13jcZiEEqYrVLg6xdk0v6+F7dWquU= +github.com/blevesearch/bleve_index_api v1.0.5 h1:Lc986kpC4Z0/n1g3gg8ul7H+lxgOQPcXb9SxvQGu+tw= +github.com/blevesearch/bleve_index_api v1.0.5/go.mod h1:YXMDwaXFFXwncRS8UobWs7nvo0DmusriM1nztTlj1ms= +github.com/blevesearch/geo v0.1.17 h1:AguzI6/5mHXapzB0gE9IKWo+wWPHZmXZoscHcjFgAFA= +github.com/blevesearch/geo v0.1.17/go.mod h1:uRMGWG0HJYfWfFJpK3zTdnnr1K+ksZTuWKhXeSokfnM= +github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo= +github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M= +github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y= +github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk= +github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc= +github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs= +github.com/blevesearch/scorch_segment_api/v2 v2.1.4 h1:LmGmo5twU3gV+natJbKmOktS9eMhokPGKWuR+jX84vk= +github.com/blevesearch/scorch_segment_api/v2 v2.1.4/go.mod h1:PgVnbbg/t1UkgezPDu8EHLi1BHQ17xUwsFdU6NnOYS0= +github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU= +github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw= +github.com/blevesearch/snowballstem v0.9.0 h1:lMQ189YspGP6sXvZQ4WZ+MLawfV8wOmPoD/iWeNXm8s= +github.com/blevesearch/snowballstem v0.9.0/go.mod h1:PivSj3JMc8WuaFkTSRDW2SlrulNWPl4ABg1tC/hlgLs= +github.com/blevesearch/upsidedown_store_api v1.0.2 h1:U53Q6YoWEARVLd1OYNc9kvhBMGZzVrdmaozG2MfoB+A= +github.com/blevesearch/upsidedown_store_api v1.0.2/go.mod h1:M01mh3Gpfy56Ps/UXHjEO/knbqyQ1Oamg8If49gRwrQ= +github.com/blevesearch/vellum v1.0.9 h1:PL+NWVk3dDGPCV0hoDu9XLLJgqU4E5s/dOeEJByQ2uQ= +github.com/blevesearch/vellum v1.0.9/go.mod h1:ul1oT0FhSMDIExNjIxHqJoGpVrBpKCdgDQNxfqgJt7k= +github.com/blevesearch/zapx/v11 v11.3.7 h1:Y6yIAF/DVPiqZUA/jNgSLXmqewfzwHzuwfKyfdG+Xaw= +github.com/blevesearch/zapx/v11 v11.3.7/go.mod h1:Xk9Z69AoAWIOvWudNDMlxJDqSYGf90LS0EfnaAIvXCA= +github.com/blevesearch/zapx/v12 v12.3.7 h1:DfQ6rsmZfEK4PzzJJRXjiM6AObG02+HWvprlXQ1Y7eI= +github.com/blevesearch/zapx/v12 v12.3.7/go.mod h1:SgEtYIBGvM0mgIBn2/tQE/5SdrPXaJUaT/kVqpAPxm0= +github.com/blevesearch/zapx/v13 v13.3.7 h1:igIQg5eKmjw168I7av0Vtwedf7kHnQro/M+ubM4d2l8= +github.com/blevesearch/zapx/v13 v13.3.7/go.mod h1:yyrB4kJ0OT75UPZwT/zS+Ru0/jYKorCOOSY5dBzAy+s= +github.com/blevesearch/zapx/v14 v14.3.7 h1:gfe+fbWslDWP/evHLtp/GOvmNM3sw1BbqD7LhycBX20= +github.com/blevesearch/zapx/v14 v14.3.7/go.mod h1:9J/RbOkqZ1KSjmkOes03AkETX7hrXT0sFMpWH4ewC4w= +github.com/blevesearch/zapx/v15 v15.3.9 h1:/s9zqKxFaZKQTTcMO2b/Tup0ch5MSztlvw+frVDfIBk= +github.com/blevesearch/zapx/v15 v15.3.9/go.mod h1:m7Y6m8soYUvS7MjN9eKlz1xrLCcmqfFadmu7GhWIrLY= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -90,6 +126,8 @@ github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3a github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 h1:gtexQ/VGyN+VVFRXSFiguSNcXmS6rkKT+X7FdIrTtfo= +github.com/golang/geo v0.0.0-20210211234256-740aa86cb551/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -112,6 +150,7 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= @@ -136,6 +175,8 @@ github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/json-iterator/go v0.0.0-20171115153421-f7279a603ede h1:YrgBGwxMRK0Vq0WSCWFaZUnTsrA/PZE/xs1QZh+/edg= +github.com/json-iterator/go v0.0.0-20171115153421-f7279a603ede/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= @@ -156,6 +197,8 @@ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6f github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= +github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= +github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= github.com/nullrocks/identicon v0.0.0-20180626043057-7875f45b0022 h1:Ys0rDzh8s4UMlGaDa1UTA0sfKgvF0hQZzTYX8ktjiDc= github.com/nullrocks/identicon v0.0.0-20180626043057-7875f45b0022/go.mod h1:x4NsS+uc7ecH/Cbm9xKQ6XzmJM57rWTkjywjfB2yQ18= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= From 42d6bcd4893fee4f08ed4def68607f40e7c1e1c5 Mon Sep 17 00:00:00 2001 From: vdimir Date: Sun, 2 Apr 2023 10:52:56 +0000 Subject: [PATCH 3/4] vendor deps for full text search --- .../RoaringBitmap/roaring/.drone.yml | 20 + .../RoaringBitmap/roaring/.gitignore | 5 + .../RoaringBitmap/roaring/.gitmodules | 0 .../RoaringBitmap/roaring/.travis.yml | 32 + .../github.com/RoaringBitmap/roaring/AUTHORS | 11 + .../RoaringBitmap/roaring/CONTRIBUTORS | 18 + .../github.com/RoaringBitmap/roaring/LICENSE | 235 + .../RoaringBitmap/roaring/LICENSE-2.0.txt | 202 + .../github.com/RoaringBitmap/roaring/Makefile | 107 + .../RoaringBitmap/roaring/README.md | 405 + .../RoaringBitmap/roaring/arraycontainer.go | 1022 + .../RoaringBitmap/roaring/bitmapcontainer.go | 1154 + .../github.com/RoaringBitmap/roaring/clz.go | 11 + .../RoaringBitmap/roaring/clz_compat.go | 36 + .../github.com/RoaringBitmap/roaring/ctz.go | 11 + .../RoaringBitmap/roaring/ctz_compat.go | 71 + .../RoaringBitmap/roaring/fastaggregation.go | 309 + .../roaring/internal/byte_input.go | 166 + .../RoaringBitmap/roaring/internal/pools.go | 21 + .../RoaringBitmap/roaring/manyiterator.go | 32 + .../RoaringBitmap/roaring/parallel.go | 612 + .../RoaringBitmap/roaring/popcnt.go | 11 + .../RoaringBitmap/roaring/popcnt_amd64.s | 103 + .../RoaringBitmap/roaring/popcnt_asm.go | 67 + .../RoaringBitmap/roaring/popcnt_compat.go | 17 + .../RoaringBitmap/roaring/popcnt_generic.go | 23 + .../RoaringBitmap/roaring/popcnt_slices.go | 41 + .../RoaringBitmap/roaring/priorityqueue.go | 101 + .../RoaringBitmap/roaring/roaring.go | 1578 + .../RoaringBitmap/roaring/roaringarray.go | 757 + .../RoaringBitmap/roaring/runcontainer.go | 2604 + .../RoaringBitmap/roaring/serialization.go | 19 + .../roaring/serialization_generic.go | 133 + .../roaring/serialization_littleendian.go | 417 + .../roaring/serializationfuzz.go | 21 + .../RoaringBitmap/roaring/setutil.go | 550 + .../RoaringBitmap/roaring/setutil_arm64.go | 6 + .../RoaringBitmap/roaring/setutil_arm64.s | 132 + .../RoaringBitmap/roaring/setutil_generic.go | 63 + .../RoaringBitmap/roaring/shortiterator.go | 52 + .../github.com/RoaringBitmap/roaring/smat.go | 383 + .../github.com/RoaringBitmap/roaring/util.go | 305 + .../bits-and-blooms/bitset/.gitignore | 26 + .../bits-and-blooms/bitset/.travis.yml | 37 + .../github.com/bits-and-blooms/bitset/LICENSE | 27 + .../bits-and-blooms/bitset/README.md | 93 + .../bitset/azure-pipelines.yml | 39 + .../bits-and-blooms/bitset/bitset.go | 952 + .../bits-and-blooms/bitset/popcnt.go | 53 + .../bits-and-blooms/bitset/popcnt_19.go | 45 + .../bits-and-blooms/bitset/popcnt_amd64.go | 68 + .../bits-and-blooms/bitset/popcnt_amd64.s | 104 + .../bits-and-blooms/bitset/popcnt_generic.go | 24 + .../bitset/trailing_zeros_18.go | 14 + .../bitset/trailing_zeros_19.go | 9 + .../blevesearch/bleve/v2/.gitignore | 20 + .../blevesearch/bleve/v2/.travis.yml | 25 + .../blevesearch/bleve/v2/CONTRIBUTING.md | 16 + .../github.com/blevesearch/bleve/v2/LICENSE | 202 + .../github.com/blevesearch/bleve/v2/README.md | 112 + .../blevesearch/bleve/v2/SECURITY.md | 15 + .../v2/analysis/analyzer/custom/custom.go | 145 + .../v2/analysis/analyzer/keyword/keyword.go | 38 + .../v2/analysis/analyzer/standard/standard.go | 52 + .../v2/analysis/datetime/flexible/flexible.go | 64 + .../v2/analysis/datetime/optional/optional.go | 45 + .../blevesearch/bleve/v2/analysis/freq.go | 70 + .../bleve/v2/analysis/lang/ar/analyzer_ar.go | 65 + .../v2/analysis/lang/ar/arabic_normalize.go | 85 + .../bleve/v2/analysis/lang/ar/stemmer_ar.go | 118 + .../v2/analysis/lang/ar/stop_filter_ar.go | 33 + .../v2/analysis/lang/ar/stop_words_ar.go | 149 + .../bleve/v2/analysis/lang/de/analyzer_de.go | 61 + .../v2/analysis/lang/de/german_normalize.go | 95 + .../v2/analysis/lang/de/light_stemmer_de.go | 116 + .../analysis/lang/de/stemmer_de_snowball.go | 49 + .../v2/analysis/lang/de/stop_filter_de.go | 33 + .../v2/analysis/lang/de/stop_words_de.go | 318 + .../bleve/v2/analysis/lang/en/analyzer_en.go | 70 + .../analysis/lang/en/possessive_filter_en.go | 67 + .../analysis/lang/en/stemmer_en_snowball.go | 49 + .../v2/analysis/lang/en/stop_filter_en.go | 33 + .../v2/analysis/lang/en/stop_words_en.go | 344 + .../bleve/v2/analysis/lang/es/analyzer_es.go | 58 + .../v2/analysis/lang/es/light_stemmer_es.go | 91 + .../analysis/lang/es/stemmer_es_snowball.go | 49 + .../v2/analysis/lang/es/stop_filter_es.go | 33 + .../v2/analysis/lang/es/stop_words_es.go | 380 + .../bleve/v2/analysis/lang/fi/analyzer_fi.go | 57 + .../bleve/v2/analysis/lang/fi/stemmer_fi.go | 49 + .../v2/analysis/lang/fi/stop_filter_fi.go | 33 + .../v2/analysis/lang/fi/stop_words_fi.go | 121 + .../bleve/v2/analysis/lang/fr/analyzer_fr.go | 62 + .../bleve/v2/analysis/lang/fr/articles_fr.go | 37 + .../bleve/v2/analysis/lang/fr/elision_fr.go | 37 + .../v2/analysis/lang/fr/light_stemmer_fr.go | 306 + .../v2/analysis/lang/fr/minimal_stemmer_fr.go | 79 + .../analysis/lang/fr/stemmer_fr_snowball.go | 49 + .../v2/analysis/lang/fr/stop_filter_fr.go | 33 + .../v2/analysis/lang/fr/stop_words_fr.go | 210 + .../bleve/v2/analysis/lang/it/analyzer_it.go | 62 + .../bleve/v2/analysis/lang/it/articles_it.go | 45 + .../bleve/v2/analysis/lang/it/elision_it.go | 37 + .../v2/analysis/lang/it/light_stemmer_it.go | 101 + .../analysis/lang/it/stemmer_it_snowball.go | 49 + .../v2/analysis/lang/it/stop_filter_it.go | 33 + .../v2/analysis/lang/it/stop_words_it.go | 327 + .../bleve/v2/analysis/lang/ru/analyzer_ru.go | 57 + .../bleve/v2/analysis/lang/ru/stemmer_ru.go | 49 + .../v2/analysis/lang/ru/stop_filter_ru.go | 33 + .../v2/analysis/lang/ru/stop_words_ru.go | 267 + .../bleve/v2/analysis/test_words.txt | 7 + .../v2/analysis/token/elision/elision.go | 74 + .../v2/analysis/token/lowercase/lowercase.go | 105 + .../bleve/v2/analysis/token/porter/porter.go | 53 + .../bleve/v2/analysis/token/stop/stop.go | 70 + .../analysis/token/unicodenorm/unicodenorm.go | 79 + .../v2/analysis/tokenizer/single/single.go | 49 + .../v2/analysis/tokenizer/unicode/unicode.go | 131 + .../blevesearch/bleve/v2/analysis/tokenmap.go | 76 + .../blevesearch/bleve/v2/analysis/type.go | 108 + .../blevesearch/bleve/v2/analysis/util.go | 92 + .../blevesearch/bleve/v2/builder.go | 94 + .../github.com/blevesearch/bleve/v2/config.go | 95 + .../blevesearch/bleve/v2/config_app.go | 24 + .../blevesearch/bleve/v2/config_disk.go | 26 + .../github.com/blevesearch/bleve/v2/doc.go | 37 + .../blevesearch/bleve/v2/document/document.go | 135 + .../blevesearch/bleve/v2/document/field.go | 45 + .../bleve/v2/document/field_boolean.go | 137 + .../bleve/v2/document/field_composite.go | 135 + .../bleve/v2/document/field_datetime.go | 173 + .../bleve/v2/document/field_geopoint.go | 193 + .../bleve/v2/document/field_geoshape.go | 235 + .../blevesearch/bleve/v2/document/field_ip.go | 132 + .../bleve/v2/document/field_numeric.go | 159 + .../bleve/v2/document/field_text.go | 157 + .../github.com/blevesearch/bleve/v2/error.go | 50 + .../blevesearch/bleve/v2/geo/README.md | 277 + .../blevesearch/bleve/v2/geo/geo.go | 210 + .../blevesearch/bleve/v2/geo/geo_dist.go | 98 + .../bleve/v2/geo/geo_s2plugin_impl.go | 450 + .../blevesearch/bleve/v2/geo/geohash.go | 111 + .../blevesearch/bleve/v2/geo/parse.go | 458 + .../blevesearch/bleve/v2/geo/sloppy.go | 212 + .../github.com/blevesearch/bleve/v2/index.go | 322 + .../bleve/v2/index/scorch/README.md | 367 + .../bleve/v2/index/scorch/builder.go | 332 + .../bleve/v2/index/scorch/empty.go | 41 + .../bleve/v2/index/scorch/event.go | 64 + .../blevesearch/bleve/v2/index/scorch/int.go | 92 + .../bleve/v2/index/scorch/introducer.go | 483 + .../bleve/v2/index/scorch/merge.go | 527 + .../v2/index/scorch/mergeplan/merge_plan.go | 397 + .../bleve/v2/index/scorch/mergeplan/sort.go | 28 + .../bleve/v2/index/scorch/optimize.go | 396 + .../bleve/v2/index/scorch/persister.go | 1267 + .../bleve/v2/index/scorch/regexp.go | 63 + .../bleve/v2/index/scorch/rollback.go | 212 + .../bleve/v2/index/scorch/scorch.go | 760 + .../bleve/v2/index/scorch/segment_plugin.go | 143 + .../bleve/v2/index/scorch/snapshot_index.go | 907 + .../v2/index/scorch/snapshot_index_dict.go | 113 + .../v2/index/scorch/snapshot_index_doc.go | 80 + .../v2/index/scorch/snapshot_index_tfr.go | 214 + .../bleve/v2/index/scorch/snapshot_segment.go | 284 + .../bleve/v2/index/scorch/stats.go | 155 + .../bleve/v2/index/scorch/unadorned.go | 182 + .../bleve/v2/index/upsidedown/analysis.go | 129 + .../v2/index/upsidedown/benchmark_all.sh | 8 + .../bleve/v2/index/upsidedown/dump.go | 174 + .../bleve/v2/index/upsidedown/field_cache.go | 88 + .../bleve/v2/index/upsidedown/field_dict.go | 82 + .../bleve/v2/index/upsidedown/index_reader.go | 228 + .../bleve/v2/index/upsidedown/reader.go | 376 + .../bleve/v2/index/upsidedown/row.go | 1141 + .../bleve/v2/index/upsidedown/row_merge.go | 76 + .../bleve/v2/index/upsidedown/stats.go | 55 + .../index/upsidedown/store/boltdb/iterator.go | 85 + .../index/upsidedown/store/boltdb/reader.go | 73 + .../v2/index/upsidedown/store/boltdb/stats.go | 26 + .../v2/index/upsidedown/store/boltdb/store.go | 181 + .../index/upsidedown/store/boltdb/writer.go | 95 + .../index/upsidedown/store/gtreap/iterator.go | 152 + .../index/upsidedown/store/gtreap/reader.go | 66 + .../v2/index/upsidedown/store/gtreap/store.go | 82 + .../index/upsidedown/store/gtreap/writer.go | 76 + .../bleve/v2/index/upsidedown/upsidedown.go | 1071 + .../v2/index/upsidedown/upsidedown.pb.go | 690 + .../v2/index/upsidedown/upsidedown.proto | 14 + .../blevesearch/bleve/v2/index_alias.go | 37 + .../blevesearch/bleve/v2/index_alias_impl.go | 616 + .../blevesearch/bleve/v2/index_impl.go | 993 + .../blevesearch/bleve/v2/index_meta.go | 115 + .../blevesearch/bleve/v2/index_stats.go | 75 + .../blevesearch/bleve/v2/mapping.go | 79 + .../blevesearch/bleve/v2/mapping/analysis.go | 99 + .../blevesearch/bleve/v2/mapping/document.go | 572 + .../blevesearch/bleve/v2/mapping/field.go | 461 + .../blevesearch/bleve/v2/mapping/index.go | 444 + .../blevesearch/bleve/v2/mapping/mapping.go | 58 + .../blevesearch/bleve/v2/mapping/reflect.go | 92 + .../blevesearch/bleve/v2/numeric/bin.go | 43 + .../blevesearch/bleve/v2/numeric/float.go | 34 + .../bleve/v2/numeric/prefix_coded.go | 111 + .../github.com/blevesearch/bleve/v2/query.go | 227 + .../blevesearch/bleve/v2/registry/analyzer.go | 89 + .../blevesearch/bleve/v2/registry/cache.go | 87 + .../bleve/v2/registry/char_filter.go | 89 + .../bleve/v2/registry/datetime_parser.go | 89 + .../bleve/v2/registry/fragment_formatter.go | 89 + .../bleve/v2/registry/fragmenter.go | 89 + .../bleve/v2/registry/highlighter.go | 89 + .../bleve/v2/registry/index_type.go | 45 + .../blevesearch/bleve/v2/registry/registry.go | 184 + .../blevesearch/bleve/v2/registry/store.go | 51 + .../bleve/v2/registry/token_filter.go | 89 + .../bleve/v2/registry/token_maps.go | 89 + .../bleve/v2/registry/tokenizer.go | 89 + .../github.com/blevesearch/bleve/v2/search.go | 641 + .../blevesearch/bleve/v2/search/collector.go | 52 + .../bleve/v2/search/collector/heap.go | 95 + .../bleve/v2/search/collector/list.go | 86 + .../bleve/v2/search/collector/slice.go | 77 + .../bleve/v2/search/collector/topn.go | 420 + .../bleve/v2/search/explanation.go | 55 + .../bleve/v2/search/facet/benchmark_data.txt | 2909 + .../v2/search/facet/facet_builder_datetime.go | 161 + .../v2/search/facet/facet_builder_numeric.go | 155 + .../v2/search/facet/facet_builder_terms.go | 115 + .../bleve/v2/search/facets_builder.go | 399 + .../v2/search/highlight/format/html/html.go | 91 + .../highlight/fragmenter/simple/simple.go | 153 + .../bleve/v2/search/highlight/highlighter.go | 64 + .../search/highlight/highlighter/html/html.go | 50 + .../simple/fragment_scorer_simple.go | 49 + .../highlighter/simple/highlighter_simple.go | 221 + .../v2/search/highlight/term_locations.go | 105 + .../bleve/v2/search/levenshtein.go | 114 + .../blevesearch/bleve/v2/search/pool.go | 91 + .../bleve/v2/search/query/bool_field.go | 66 + .../bleve/v2/search/query/boolean.go | 249 + .../bleve/v2/search/query/boost.go | 33 + .../bleve/v2/search/query/conjunction.go | 113 + .../bleve/v2/search/query/date_range.go | 192 + .../bleve/v2/search/query/disjunction.go | 125 + .../bleve/v2/search/query/docid.go | 51 + .../bleve/v2/search/query/fuzzy.go | 79 + .../bleve/v2/search/query/geo_boundingbox.go | 114 + .../v2/search/query/geo_boundingpolygon.go | 95 + .../bleve/v2/search/query/geo_distance.go | 101 + .../bleve/v2/search/query/geo_shape.go | 135 + .../bleve/v2/search/query/ip_range.go | 85 + .../bleve/v2/search/query/match.go | 177 + .../bleve/v2/search/query/match_all.go | 56 + .../bleve/v2/search/query/match_none.go | 56 + .../bleve/v2/search/query/match_phrase.go | 114 + .../bleve/v2/search/query/multi_phrase.go | 81 + .../bleve/v2/search/query/numeric_range.go | 88 + .../bleve/v2/search/query/phrase.go | 78 + .../bleve/v2/search/query/prefix.go | 64 + .../bleve/v2/search/query/query.go | 383 + .../bleve/v2/search/query/query_string.go | 69 + .../bleve/v2/search/query/query_string.y | 338 + .../bleve/v2/search/query/query_string.y.go | 833 + .../bleve/v2/search/query/query_string_lex.go | 329 + .../v2/search/query/query_string_parser.go | 85 + .../bleve/v2/search/query/regexp.go | 82 + .../blevesearch/bleve/v2/search/query/term.go | 63 + .../bleve/v2/search/query/term_range.go | 96 + .../bleve/v2/search/query/wildcard.go | 94 + .../v2/search/scorer/scorer_conjunction.go | 72 + .../bleve/v2/search/scorer/scorer_constant.go | 127 + .../v2/search/scorer/scorer_disjunction.go | 83 + .../bleve/v2/search/scorer/scorer_term.go | 202 + .../bleve/v2/search/scorer/sqrt_cache.go | 30 + .../blevesearch/bleve/v2/search/search.go | 382 + .../search/searcher/ordered_searchers_list.go | 35 + .../v2/search/searcher/search_boolean.go | 451 + .../v2/search/searcher/search_conjunction.go | 286 + .../v2/search/searcher/search_disjunction.go | 115 + .../searcher/search_disjunction_heap.go | 346 + .../searcher/search_disjunction_slice.go | 299 + .../bleve/v2/search/searcher/search_docid.go | 110 + .../bleve/v2/search/searcher/search_filter.go | 104 + .../bleve/v2/search/searcher/search_fuzzy.go | 149 + .../search/searcher/search_geoboundingbox.go | 297 + .../searcher/search_geopointdistance.go | 146 + .../v2/search/searcher/search_geopolygon.go | 144 + .../v2/search/searcher/search_geoshape.go | 124 + .../v2/search/searcher/search_ip_range.go | 68 + .../v2/search/searcher/search_match_all.go | 123 + .../v2/search/searcher/search_match_none.go | 76 + .../v2/search/searcher/search_multi_term.go | 217 + .../search/searcher/search_numeric_range.go | 256 + .../bleve/v2/search/searcher/search_phrase.go | 438 + .../bleve/v2/search/searcher/search_regexp.go | 148 + .../bleve/v2/search/searcher/search_term.go | 142 + .../v2/search/searcher/search_term_prefix.go | 56 + .../v2/search/searcher/search_term_range.go | 91 + .../blevesearch/bleve/v2/search/sort.go | 749 + .../blevesearch/bleve/v2/search/util.go | 69 + .../blevesearch/bleve/v2/size/sizes.go | 59 + .../blevesearch/bleve_index_api/.golangci.yml | 37 + .../blevesearch/bleve_index_api/LICENSE | 202 + .../blevesearch/bleve_index_api/README.md | 11 + .../blevesearch/bleve_index_api/analysis.go | 53 + .../blevesearch/bleve_index_api/batch.go | 101 + .../blevesearch/bleve_index_api/directory.go | 23 + .../blevesearch/bleve_index_api/document.go | 93 + .../blevesearch/bleve_index_api/freq.go | 106 + .../blevesearch/bleve_index_api/index.go | 227 + .../bleve_index_api/indexing_options.go | 77 + .../blevesearch/bleve_index_api/optimize.go | 39 + .../blevesearch/bleve_index_api/sizes.go | 35 + .../bleve_index_api/spatial_plugin.go | 47 + .../vendor/github.com/blevesearch/geo/LICENSE | 202 + .../geo/geojson/geojson_s2_util.go | 319 + .../geo/geojson/geojson_shapes_impl.go | 1861 + .../geo/geojson/geojson_shapes_util.go | 586 + .../blevesearch/geo/s2/bits_go18.go | 54 + .../blevesearch/geo/s2/bits_go19.go | 40 + .../github.com/blevesearch/geo/s2/cap.go | 519 + .../github.com/blevesearch/geo/s2/cell.go | 698 + .../blevesearch/geo/s2/cell_index.go | 584 + .../github.com/blevesearch/geo/s2/cellid.go | 944 + .../blevesearch/geo/s2/cellunion.go | 590 + .../blevesearch/geo/s2/centroids.go | 133 + .../geo/s2/contains_point_query.go | 190 + .../geo/s2/contains_vertex_query.go | 63 + .../blevesearch/geo/s2/convex_hull_query.go | 258 + .../blevesearch/geo/s2/crossing_edge_query.go | 409 + .../blevesearch/geo/s2/distance_target.go | 149 + .../github.com/blevesearch/geo/s2/doc.go | 29 + .../blevesearch/geo/s2/edge_clipping.go | 672 + .../blevesearch/geo/s2/edge_crosser.go | 227 + .../blevesearch/geo/s2/edge_crossings.go | 396 + .../blevesearch/geo/s2/edge_distances.go | 408 + .../blevesearch/geo/s2/edge_query.go | 816 + .../blevesearch/geo/s2/edge_tessellator.go | 291 + .../github.com/blevesearch/geo/s2/encode.go | 224 + .../blevesearch/geo/s2/interleave.go | 143 + .../github.com/blevesearch/geo/s2/latlng.go | 101 + .../github.com/blevesearch/geo/s2/lexicon.go | 175 + .../github.com/blevesearch/geo/s2/loop.go | 1833 + .../blevesearch/geo/s2/matrix3x3.go | 127 + .../geo/s2/max_distance_targets.go | 306 + .../github.com/blevesearch/geo/s2/metric.go | 164 + .../geo/s2/min_distance_targets.go | 362 + .../blevesearch/geo/s2/nthderivative.go | 88 + .../blevesearch/geo/s2/paddedcell.go | 252 + .../github.com/blevesearch/geo/s2/point.go | 258 + .../blevesearch/geo/s2/point_measures.go | 149 + .../blevesearch/geo/s2/point_vector.go | 42 + .../blevesearch/geo/s2/pointcompression.go | 319 + .../github.com/blevesearch/geo/s2/polygon.go | 1229 + .../github.com/blevesearch/geo/s2/polyline.go | 589 + .../blevesearch/geo/s2/polyline_measures.go | 53 + .../blevesearch/geo/s2/predicates.go | 701 + .../blevesearch/geo/s2/projections.go | 241 + .../blevesearch/geo/s2/query_entry.go | 93 + .../blevesearch/geo/s2/query_options.go | 196 + .../github.com/blevesearch/geo/s2/rect.go | 726 + .../blevesearch/geo/s2/rect_bounder.go | 352 + .../github.com/blevesearch/geo/s2/region.go | 71 + .../blevesearch/geo/s2/region_term_indexer.go | 441 + .../blevesearch/geo/s2/regioncoverer.go | 615 + .../blevesearch/geo/s2/regionunion.go | 66 + .../github.com/blevesearch/geo/s2/shape.go | 263 + .../blevesearch/geo/s2/shapeindex.go | 1526 + .../blevesearch/geo/s2/shapeutil.go | 228 + .../geo/s2/shapeutil_edge_iterator.go | 72 + .../github.com/blevesearch/geo/s2/stuv.go | 427 + .../github.com/blevesearch/geo/s2/util.go | 125 + .../blevesearch/geo/s2/wedge_relations.go | 97 + .../blevesearch/go-porterstemmer/.gitignore | 8 + .../blevesearch/go-porterstemmer/.travis.yml | 16 + .../blevesearch/go-porterstemmer/LICENSE | 19 + .../blevesearch/go-porterstemmer/README.md | 118 + .../go-porterstemmer/porterstemmer.go | 839 + .../github.com/blevesearch/gtreap/.gitignore | 5 + .../github.com/blevesearch/gtreap/LICENSE | 20 + .../github.com/blevesearch/gtreap/README.md | 90 + .../github.com/blevesearch/gtreap/treap.go | 207 + .../github.com/blevesearch/mmap-go/.gitignore | 10 + .../blevesearch/mmap-go/.travis.yml | 16 + .../github.com/blevesearch/mmap-go/LICENSE | 25 + .../github.com/blevesearch/mmap-go/README.md | 12 + .../github.com/blevesearch/mmap-go/mmap.go | 117 + .../blevesearch/mmap-go/mmap_unix.go | 51 + .../blevesearch/mmap-go/mmap_windows.go | 153 + .../scorch_segment_api/v2/.golangci.yml | 42 + .../blevesearch/scorch_segment_api/v2/LICENSE | 202 + .../scorch_segment_api/v2/README.md | 11 + .../scorch_segment_api/v2/automaton.go | 36 + .../scorch_segment_api/v2/segment.go | 170 + .../github.com/blevesearch/segment/.gitignore | 10 + .../github.com/blevesearch/segment/LICENSE | 202 + .../github.com/blevesearch/segment/README.md | 94 + .../github.com/blevesearch/segment/doc.go | 45 + .../github.com/blevesearch/segment/segment.go | 284 + .../blevesearch/segment/segment_fuzz.go | 22 + .../blevesearch/segment/segment_words.go | 19542 ++ .../blevesearch/segment/segment_words.rl | 285 + .../blevesearch/segment/segment_words_prod.go | 173643 +++++++++++++++ .../blevesearch/snowballstem/COPYING | 29 + .../blevesearch/snowballstem/README.md | 66 + .../blevesearch/snowballstem/among.go | 16 + .../snowballstem/english/english_stemmer.go | 1341 + .../blevesearch/snowballstem/env.go | 389 + .../snowballstem/finnish/finnish_stemmer.go | 994 + .../snowballstem/french/french_stemmer.go | 1535 + .../blevesearch/snowballstem/gen.go | 61 + .../snowballstem/german/german_stemmer.go | 719 + .../snowballstem/italian/italian_stemmer.go | 1182 + .../snowballstem/russian/russian_stemmer.go | 737 + .../snowballstem/spanish/spanish_stemmer.go | 1179 + .../blevesearch/snowballstem/util.go | 34 + .../blevesearch/upsidedown_store_api/LICENSE | 202 + .../upsidedown_store_api/README.md | 7 + .../blevesearch/upsidedown_store_api/batch.go | 62 + .../upsidedown_store_api/kvstore.go | 174 + .../blevesearch/upsidedown_store_api/merge.go | 64 + .../upsidedown_store_api/multiget.go | 33 + .../blevesearch/vellum/CONTRIBUTING.md | 16 + .../github.com/blevesearch/vellum/LICENSE | 202 + .../github.com/blevesearch/vellum/README.md | 183 + .../blevesearch/vellum/automaton.go | 85 + .../github.com/blevesearch/vellum/builder.go | 452 + .../github.com/blevesearch/vellum/common.go | 547 + .../blevesearch/vellum/decoder_v1.go | 314 + .../blevesearch/vellum/encoder_v1.go | 227 + .../github.com/blevesearch/vellum/encoding.go | 87 + .../github.com/blevesearch/vellum/fst.go | 300 + .../blevesearch/vellum/fst_iterator.go | 303 + .../blevesearch/vellum/levenshtein/LICENSE | 203 + .../blevesearch/vellum/levenshtein/README.md | 33 + .../vellum/levenshtein/alphabet.go | 125 + .../blevesearch/vellum/levenshtein/dfa.go | 250 + .../vellum/levenshtein/levenshtein.go | 64 + .../vellum/levenshtein/levenshtein_nfa.go | 292 + .../vellum/levenshtein/parametric_dfa.go | 349 + .../blevesearch/vellum/merge_iterator.go | 188 + .../github.com/blevesearch/vellum/pack.go | 55 + .../blevesearch/vellum/regexp/compile.go | 343 + .../blevesearch/vellum/regexp/dfa.go | 196 + .../blevesearch/vellum/regexp/inst.go | 62 + .../blevesearch/vellum/regexp/regexp.go | 119 + .../blevesearch/vellum/regexp/sparse.go | 54 + .../github.com/blevesearch/vellum/registry.go | 114 + .../blevesearch/vellum/transducer.go | 55 + .../blevesearch/vellum/utf8/utf8.go | 268 + .../github.com/blevesearch/vellum/vellum.go | 111 + .../blevesearch/vellum/vellum_mmap.go | 60 + .../blevesearch/vellum/vellum_nommap.go | 27 + .../github.com/blevesearch/vellum/writer.go | 92 + .../blevesearch/zapx/v11/.gitignore | 12 + .../blevesearch/zapx/v11/.golangci.yml | 28 + .../github.com/blevesearch/zapx/v11/LICENSE | 202 + .../github.com/blevesearch/zapx/v11/README.md | 163 + .../github.com/blevesearch/zapx/v11/build.go | 186 + .../blevesearch/zapx/v11/contentcoder.go | 230 + .../github.com/blevesearch/zapx/v11/count.go | 61 + .../github.com/blevesearch/zapx/v11/dict.go | 158 + .../blevesearch/zapx/v11/docvalues.go | 318 + .../blevesearch/zapx/v11/enumerator.go | 126 + .../blevesearch/zapx/v11/intcoder.go | 172 + .../blevesearch/zapx/v11/memuvarint.go | 103 + .../github.com/blevesearch/zapx/v11/merge.go | 856 + .../github.com/blevesearch/zapx/v11/new.go | 817 + .../github.com/blevesearch/zapx/v11/plugin.go | 27 + .../blevesearch/zapx/v11/posting.go | 949 + .../github.com/blevesearch/zapx/v11/read.go | 43 + .../blevesearch/zapx/v11/segment.go | 600 + .../github.com/blevesearch/zapx/v11/sizes.go | 59 + .../github.com/blevesearch/zapx/v11/write.go | 145 + .../github.com/blevesearch/zapx/v11/zap.md | 177 + .../blevesearch/zapx/v12/.gitignore | 12 + .../blevesearch/zapx/v12/.golangci.yml | 28 + .../github.com/blevesearch/zapx/v12/LICENSE | 202 + .../github.com/blevesearch/zapx/v12/README.md | 163 + .../github.com/blevesearch/zapx/v12/build.go | 186 + .../github.com/blevesearch/zapx/v12/chunk.go | 54 + .../blevesearch/zapx/v12/contentcoder.go | 243 + .../github.com/blevesearch/zapx/v12/count.go | 61 + .../github.com/blevesearch/zapx/v12/dict.go | 158 + .../blevesearch/zapx/v12/docvalues.go | 323 + .../blevesearch/zapx/v12/enumerator.go | 138 + .../blevesearch/zapx/v12/intDecoder.go | 109 + .../blevesearch/zapx/v12/intcoder.go | 203 + .../blevesearch/zapx/v12/memuvarint.go | 103 + .../github.com/blevesearch/zapx/v12/merge.go | 843 + .../github.com/blevesearch/zapx/v12/new.go | 830 + .../github.com/blevesearch/zapx/v12/plugin.go | 27 + .../blevesearch/zapx/v12/posting.go | 837 + .../github.com/blevesearch/zapx/v12/read.go | 43 + .../blevesearch/zapx/v12/segment.go | 600 + .../github.com/blevesearch/zapx/v12/sizes.go | 59 + .../github.com/blevesearch/zapx/v12/write.go | 145 + .../github.com/blevesearch/zapx/v12/zap.md | 177 + .../blevesearch/zapx/v13/.gitignore | 12 + .../blevesearch/zapx/v13/.golangci.yml | 28 + .../github.com/blevesearch/zapx/v13/LICENSE | 202 + .../github.com/blevesearch/zapx/v13/README.md | 163 + .../github.com/blevesearch/zapx/v13/build.go | 186 + .../github.com/blevesearch/zapx/v13/chunk.go | 54 + .../blevesearch/zapx/v13/contentcoder.go | 243 + .../github.com/blevesearch/zapx/v13/count.go | 61 + .../github.com/blevesearch/zapx/v13/dict.go | 158 + .../blevesearch/zapx/v13/docvalues.go | 323 + .../blevesearch/zapx/v13/enumerator.go | 138 + .../blevesearch/zapx/v13/intDecoder.go | 109 + .../blevesearch/zapx/v13/intcoder.go | 206 + .../blevesearch/zapx/v13/memuvarint.go | 103 + .../github.com/blevesearch/zapx/v13/merge.go | 843 + .../github.com/blevesearch/zapx/v13/new.go | 830 + .../github.com/blevesearch/zapx/v13/plugin.go | 27 + .../blevesearch/zapx/v13/posting.go | 837 + .../github.com/blevesearch/zapx/v13/read.go | 43 + .../blevesearch/zapx/v13/segment.go | 600 + .../github.com/blevesearch/zapx/v13/sizes.go | 59 + .../github.com/blevesearch/zapx/v13/write.go | 145 + .../github.com/blevesearch/zapx/v13/zap.md | 177 + .../blevesearch/zapx/v14/.gitignore | 12 + .../blevesearch/zapx/v14/.golangci.yml | 28 + .../github.com/blevesearch/zapx/v14/LICENSE | 202 + .../github.com/blevesearch/zapx/v14/README.md | 163 + .../github.com/blevesearch/zapx/v14/build.go | 186 + .../github.com/blevesearch/zapx/v14/chunk.go | 67 + .../blevesearch/zapx/v14/contentcoder.go | 243 + .../github.com/blevesearch/zapx/v14/count.go | 61 + .../github.com/blevesearch/zapx/v14/dict.go | 158 + .../blevesearch/zapx/v14/docvalues.go | 323 + .../blevesearch/zapx/v14/enumerator.go | 138 + .../blevesearch/zapx/v14/intDecoder.go | 116 + .../blevesearch/zapx/v14/intcoder.go | 206 + .../blevesearch/zapx/v14/memuvarint.go | 103 + .../github.com/blevesearch/zapx/v14/merge.go | 843 + .../github.com/blevesearch/zapx/v14/new.go | 830 + .../github.com/blevesearch/zapx/v14/plugin.go | 27 + .../blevesearch/zapx/v14/posting.go | 835 + .../github.com/blevesearch/zapx/v14/read.go | 43 + .../blevesearch/zapx/v14/segment.go | 600 + .../github.com/blevesearch/zapx/v14/sizes.go | 59 + .../github.com/blevesearch/zapx/v14/write.go | 145 + .../github.com/blevesearch/zapx/v14/zap.md | 177 + .../blevesearch/zapx/v15/.gitignore | 12 + .../blevesearch/zapx/v15/.golangci.yml | 28 + .../github.com/blevesearch/zapx/v15/LICENSE | 202 + .../github.com/blevesearch/zapx/v15/README.md | 163 + .../github.com/blevesearch/zapx/v15/build.go | 186 + .../github.com/blevesearch/zapx/v15/chunk.go | 67 + .../blevesearch/zapx/v15/contentcoder.go | 257 + .../github.com/blevesearch/zapx/v15/count.go | 61 + .../github.com/blevesearch/zapx/v15/dict.go | 176 + .../blevesearch/zapx/v15/docvalues.go | 356 + .../blevesearch/zapx/v15/enumerator.go | 138 + .../blevesearch/zapx/v15/intDecoder.go | 139 + .../blevesearch/zapx/v15/intcoder.go | 220 + .../blevesearch/zapx/v15/memuvarint.go | 103 + .../github.com/blevesearch/zapx/v15/merge.go | 895 + .../github.com/blevesearch/zapx/v15/new.go | 865 + .../github.com/blevesearch/zapx/v15/plugin.go | 27 + .../blevesearch/zapx/v15/posting.go | 936 + .../github.com/blevesearch/zapx/v15/read.go | 43 + .../blevesearch/zapx/v15/segment.go | 625 + .../github.com/blevesearch/zapx/v15/sizes.go | 59 + .../github.com/blevesearch/zapx/v15/write.go | 145 + .../github.com/blevesearch/zapx/v15/zap.md | 177 + backend/vendor/github.com/golang/geo/LICENSE | 202 + .../vendor/github.com/golang/geo/r1/doc.go | 20 + .../github.com/golang/geo/r1/interval.go | 177 + .../vendor/github.com/golang/geo/r2/doc.go | 20 + .../vendor/github.com/golang/geo/r2/rect.go | 255 + .../vendor/github.com/golang/geo/r3/doc.go | 20 + .../github.com/golang/geo/r3/precisevector.go | 198 + .../vendor/github.com/golang/geo/r3/vector.go | 183 + .../vendor/github.com/golang/geo/s1/angle.go | 120 + .../github.com/golang/geo/s1/chordangle.go | 320 + .../vendor/github.com/golang/geo/s1/doc.go | 20 + .../github.com/golang/geo/s1/interval.go | 462 + .../github.com/json-iterator/go/.codecov.yml | 3 + .../github.com/json-iterator/go/.gitignore | 4 + .../github.com/json-iterator/go/.travis.yml | 14 + .../github.com/json-iterator/go/LICENSE | 21 + .../github.com/json-iterator/go/README.md | 86 + .../json-iterator/go/feature_adapter.go | 133 + .../json-iterator/go/feature_any.go | 245 + .../json-iterator/go/feature_any_array.go | 278 + .../json-iterator/go/feature_any_bool.go | 137 + .../json-iterator/go/feature_any_float.go | 83 + .../json-iterator/go/feature_any_int32.go | 74 + .../json-iterator/go/feature_any_int64.go | 74 + .../json-iterator/go/feature_any_invalid.go | 82 + .../json-iterator/go/feature_any_nil.go | 69 + .../json-iterator/go/feature_any_number.go | 104 + .../json-iterator/go/feature_any_object.go | 374 + .../json-iterator/go/feature_any_string.go | 166 + .../json-iterator/go/feature_any_uint32.go | 74 + .../json-iterator/go/feature_any_uint64.go | 74 + .../json-iterator/go/feature_config.go | 347 + .../json-iterator/go/feature_iter.go | 322 + .../json-iterator/go/feature_iter_array.go | 58 + .../json-iterator/go/feature_iter_float.go | 341 + .../json-iterator/go/feature_iter_int.go | 268 + .../json-iterator/go/feature_iter_object.go | 267 + .../json-iterator/go/feature_iter_skip.go | 129 + .../go/feature_iter_skip_sloppy.go | 144 + .../go/feature_iter_skip_strict.go | 89 + .../json-iterator/go/feature_iter_string.go | 215 + .../json-iterator/go/feature_json_number.go | 31 + .../json-iterator/go/feature_pool.go | 59 + .../json-iterator/go/feature_reflect.go | 721 + .../json-iterator/go/feature_reflect_array.go | 99 + .../go/feature_reflect_extension.go | 414 + .../json-iterator/go/feature_reflect_map.go | 244 + .../go/feature_reflect_native.go | 764 + .../go/feature_reflect_object.go | 196 + .../json-iterator/go/feature_reflect_slice.go | 147 + .../go/feature_reflect_struct_decoder.go | 934 + .../json-iterator/go/feature_stream.go | 308 + .../json-iterator/go/feature_stream_float.go | 96 + .../json-iterator/go/feature_stream_int.go | 320 + .../json-iterator/go/feature_stream_string.go | 396 + .../go/fuzzy_mode_convert_table.md | 7 + .../github.com/json-iterator/go/jsoniter.go | 18 + .../github.com/json-iterator/go/test.sh | 12 + .../vendor/github.com/mschoch/smat/.gitignore | 14 + .../github.com/mschoch/smat/.travis.yml | 16 + .../vendor/github.com/mschoch/smat/LICENSE | 202 + .../vendor/github.com/mschoch/smat/README.md | 166 + .../github.com/mschoch/smat/actionseq.go | 61 + .../vendor/github.com/mschoch/smat/smat.go | 161 + backend/vendor/modules.txt | 121 + 634 files changed, 332100 insertions(+) create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/.drone.yml create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/.gitignore create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/.gitmodules create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/.travis.yml create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/AUTHORS create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/CONTRIBUTORS create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/LICENSE create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/LICENSE-2.0.txt create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/Makefile create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/README.md create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/arraycontainer.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/bitmapcontainer.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/clz.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/clz_compat.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/ctz.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/ctz_compat.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/fastaggregation.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/internal/byte_input.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/internal/pools.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/manyiterator.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/parallel.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/popcnt.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/popcnt_amd64.s create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/popcnt_asm.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/popcnt_compat.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/popcnt_generic.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/popcnt_slices.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/priorityqueue.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/roaring.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/roaringarray.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/runcontainer.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/serialization.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/serialization_generic.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/serialization_littleendian.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/serializationfuzz.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/setutil.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/setutil_arm64.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/setutil_arm64.s create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/setutil_generic.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/shortiterator.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/smat.go create mode 100644 backend/vendor/github.com/RoaringBitmap/roaring/util.go create mode 100644 backend/vendor/github.com/bits-and-blooms/bitset/.gitignore create mode 100644 backend/vendor/github.com/bits-and-blooms/bitset/.travis.yml create mode 100644 backend/vendor/github.com/bits-and-blooms/bitset/LICENSE create mode 100644 backend/vendor/github.com/bits-and-blooms/bitset/README.md create mode 100644 backend/vendor/github.com/bits-and-blooms/bitset/azure-pipelines.yml create mode 100644 backend/vendor/github.com/bits-and-blooms/bitset/bitset.go create mode 100644 backend/vendor/github.com/bits-and-blooms/bitset/popcnt.go create mode 100644 backend/vendor/github.com/bits-and-blooms/bitset/popcnt_19.go create mode 100644 backend/vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.go create mode 100644 backend/vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.s create mode 100644 backend/vendor/github.com/bits-and-blooms/bitset/popcnt_generic.go create mode 100644 backend/vendor/github.com/bits-and-blooms/bitset/trailing_zeros_18.go create mode 100644 backend/vendor/github.com/bits-and-blooms/bitset/trailing_zeros_19.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/.gitignore create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/.travis.yml create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/CONTRIBUTING.md create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/LICENSE create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/README.md create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/SECURITY.md create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/analyzer/custom/custom.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/analyzer/keyword/keyword.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/analyzer/standard/standard.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/datetime/flexible/flexible.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/datetime/optional/optional.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/freq.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/analyzer_ar.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/arabic_normalize.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/stemmer_ar.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/stop_filter_ar.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/stop_words_ar.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/analyzer_de.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/german_normalize.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/light_stemmer_de.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/stemmer_de_snowball.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/stop_filter_de.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/stop_words_de.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/analyzer_en.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/possessive_filter_en.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/stemmer_en_snowball.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/stop_filter_en.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/stop_words_en.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/analyzer_es.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/light_stemmer_es.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/stemmer_es_snowball.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/stop_filter_es.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/stop_words_es.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fi/analyzer_fi.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fi/stemmer_fi.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fi/stop_filter_fi.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fi/stop_words_fi.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/analyzer_fr.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/articles_fr.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/elision_fr.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/light_stemmer_fr.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/minimal_stemmer_fr.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/stemmer_fr_snowball.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/stop_filter_fr.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/stop_words_fr.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/analyzer_it.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/articles_it.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/elision_it.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/light_stemmer_it.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/stemmer_it_snowball.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/stop_filter_it.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/stop_words_it.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ru/analyzer_ru.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ru/stemmer_ru.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ru/stop_filter_ru.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ru/stop_words_ru.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/test_words.txt create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/elision/elision.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/lowercase/lowercase.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/porter/porter.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/stop/stop.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/unicodenorm/unicodenorm.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/tokenizer/single/single.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/tokenizer/unicode/unicode.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/tokenmap.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/type.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/analysis/util.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/builder.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/config.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/config_app.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/config_disk.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/doc.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/document/document.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/document/field.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/document/field_boolean.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/document/field_composite.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/document/field_datetime.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/document/field_geopoint.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/document/field_geoshape.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/document/field_ip.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/document/field_numeric.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/document/field_text.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/error.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/geo/README.md create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/geo/geo.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/geo/geo_dist.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/geo/geo_s2plugin_impl.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/geo/geohash.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/geo/parse.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/geo/sloppy.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/README.md create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/builder.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/empty.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/event.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/int.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/introducer.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/merge.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/mergeplan/merge_plan.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/mergeplan/sort.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/optimize.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/persister.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/regexp.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/rollback.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/scorch.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/segment_plugin.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_index.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_index_dict.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_index_doc.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_index_tfr.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_segment.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/stats.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/unadorned.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/analysis.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/benchmark_all.sh create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/dump.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/field_cache.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/field_dict.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/index_reader.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/reader.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/row.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/row_merge.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/stats.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/iterator.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/reader.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/stats.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/store.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/writer.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap/iterator.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap/reader.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap/store.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap/writer.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/upsidedown.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/upsidedown.pb.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/upsidedown.proto create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index_alias.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index_alias_impl.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index_impl.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index_meta.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/index_stats.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/mapping.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/mapping/analysis.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/mapping/document.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/mapping/field.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/mapping/index.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/mapping/mapping.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/mapping/reflect.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/numeric/bin.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/numeric/float.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/numeric/prefix_coded.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/query.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/registry/analyzer.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/registry/cache.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/registry/char_filter.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/registry/datetime_parser.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/registry/fragment_formatter.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/registry/fragmenter.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/registry/highlighter.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/registry/index_type.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/registry/registry.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/registry/store.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/registry/token_filter.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/registry/token_maps.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/registry/tokenizer.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/collector.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/collector/heap.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/collector/list.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/collector/slice.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/collector/topn.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/explanation.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/facet/benchmark_data.txt create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/facet/facet_builder_datetime.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/facet/facet_builder_numeric.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/facet/facet_builder_terms.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/facets_builder.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/format/html/html.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/fragmenter/simple/simple.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/highlighter.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/highlighter/html/html.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/highlighter/simple/fragment_scorer_simple.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/highlighter/simple/highlighter_simple.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/term_locations.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/levenshtein.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/pool.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/bool_field.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/boolean.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/boost.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/conjunction.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/date_range.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/disjunction.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/docid.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/fuzzy.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/geo_boundingbox.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/geo_boundingpolygon.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/geo_distance.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/geo_shape.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/ip_range.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/match.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/match_all.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/match_none.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/match_phrase.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/multi_phrase.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/numeric_range.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/phrase.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/prefix.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/query.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string.y create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string.y.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string_lex.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string_parser.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/regexp.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/term.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/term_range.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/query/wildcard.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/scorer_conjunction.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/scorer_constant.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/scorer_disjunction.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/scorer_term.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/sqrt_cache.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/search.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/ordered_searchers_list.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_boolean.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_conjunction.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_disjunction.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_disjunction_heap.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_disjunction_slice.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_docid.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_filter.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_fuzzy.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_geoboundingbox.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_geopointdistance.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_geopolygon.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_geoshape.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_ip_range.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_match_all.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_match_none.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_multi_term.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_numeric_range.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_phrase.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_regexp.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_term.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_term_prefix.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_term_range.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/sort.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/search/util.go create mode 100644 backend/vendor/github.com/blevesearch/bleve/v2/size/sizes.go create mode 100644 backend/vendor/github.com/blevesearch/bleve_index_api/.golangci.yml create mode 100644 backend/vendor/github.com/blevesearch/bleve_index_api/LICENSE create mode 100644 backend/vendor/github.com/blevesearch/bleve_index_api/README.md create mode 100644 backend/vendor/github.com/blevesearch/bleve_index_api/analysis.go create mode 100644 backend/vendor/github.com/blevesearch/bleve_index_api/batch.go create mode 100644 backend/vendor/github.com/blevesearch/bleve_index_api/directory.go create mode 100644 backend/vendor/github.com/blevesearch/bleve_index_api/document.go create mode 100644 backend/vendor/github.com/blevesearch/bleve_index_api/freq.go create mode 100644 backend/vendor/github.com/blevesearch/bleve_index_api/index.go create mode 100644 backend/vendor/github.com/blevesearch/bleve_index_api/indexing_options.go create mode 100644 backend/vendor/github.com/blevesearch/bleve_index_api/optimize.go create mode 100644 backend/vendor/github.com/blevesearch/bleve_index_api/sizes.go create mode 100644 backend/vendor/github.com/blevesearch/bleve_index_api/spatial_plugin.go create mode 100644 backend/vendor/github.com/blevesearch/geo/LICENSE create mode 100644 backend/vendor/github.com/blevesearch/geo/geojson/geojson_s2_util.go create mode 100644 backend/vendor/github.com/blevesearch/geo/geojson/geojson_shapes_impl.go create mode 100644 backend/vendor/github.com/blevesearch/geo/geojson/geojson_shapes_util.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/bits_go18.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/bits_go19.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/cap.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/cell.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/cell_index.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/cellid.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/cellunion.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/centroids.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/contains_point_query.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/contains_vertex_query.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/convex_hull_query.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/crossing_edge_query.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/distance_target.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/doc.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/edge_clipping.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/edge_crosser.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/edge_crossings.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/edge_distances.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/edge_query.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/edge_tessellator.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/encode.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/interleave.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/latlng.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/lexicon.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/loop.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/matrix3x3.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/max_distance_targets.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/metric.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/min_distance_targets.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/nthderivative.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/paddedcell.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/point.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/point_measures.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/point_vector.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/pointcompression.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/polygon.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/polyline.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/polyline_measures.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/predicates.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/projections.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/query_entry.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/query_options.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/rect.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/rect_bounder.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/region.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/region_term_indexer.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/regioncoverer.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/regionunion.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/shape.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/shapeindex.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/shapeutil.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/shapeutil_edge_iterator.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/stuv.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/util.go create mode 100644 backend/vendor/github.com/blevesearch/geo/s2/wedge_relations.go create mode 100644 backend/vendor/github.com/blevesearch/go-porterstemmer/.gitignore create mode 100644 backend/vendor/github.com/blevesearch/go-porterstemmer/.travis.yml create mode 100644 backend/vendor/github.com/blevesearch/go-porterstemmer/LICENSE create mode 100644 backend/vendor/github.com/blevesearch/go-porterstemmer/README.md create mode 100644 backend/vendor/github.com/blevesearch/go-porterstemmer/porterstemmer.go create mode 100644 backend/vendor/github.com/blevesearch/gtreap/.gitignore create mode 100644 backend/vendor/github.com/blevesearch/gtreap/LICENSE create mode 100644 backend/vendor/github.com/blevesearch/gtreap/README.md create mode 100644 backend/vendor/github.com/blevesearch/gtreap/treap.go create mode 100644 backend/vendor/github.com/blevesearch/mmap-go/.gitignore create mode 100644 backend/vendor/github.com/blevesearch/mmap-go/.travis.yml create mode 100644 backend/vendor/github.com/blevesearch/mmap-go/LICENSE create mode 100644 backend/vendor/github.com/blevesearch/mmap-go/README.md create mode 100644 backend/vendor/github.com/blevesearch/mmap-go/mmap.go create mode 100644 backend/vendor/github.com/blevesearch/mmap-go/mmap_unix.go create mode 100644 backend/vendor/github.com/blevesearch/mmap-go/mmap_windows.go create mode 100644 backend/vendor/github.com/blevesearch/scorch_segment_api/v2/.golangci.yml create mode 100644 backend/vendor/github.com/blevesearch/scorch_segment_api/v2/LICENSE create mode 100644 backend/vendor/github.com/blevesearch/scorch_segment_api/v2/README.md create mode 100644 backend/vendor/github.com/blevesearch/scorch_segment_api/v2/automaton.go create mode 100644 backend/vendor/github.com/blevesearch/scorch_segment_api/v2/segment.go create mode 100644 backend/vendor/github.com/blevesearch/segment/.gitignore create mode 100644 backend/vendor/github.com/blevesearch/segment/LICENSE create mode 100644 backend/vendor/github.com/blevesearch/segment/README.md create mode 100644 backend/vendor/github.com/blevesearch/segment/doc.go create mode 100644 backend/vendor/github.com/blevesearch/segment/segment.go create mode 100644 backend/vendor/github.com/blevesearch/segment/segment_fuzz.go create mode 100644 backend/vendor/github.com/blevesearch/segment/segment_words.go create mode 100644 backend/vendor/github.com/blevesearch/segment/segment_words.rl create mode 100644 backend/vendor/github.com/blevesearch/segment/segment_words_prod.go create mode 100644 backend/vendor/github.com/blevesearch/snowballstem/COPYING create mode 100644 backend/vendor/github.com/blevesearch/snowballstem/README.md create mode 100644 backend/vendor/github.com/blevesearch/snowballstem/among.go create mode 100644 backend/vendor/github.com/blevesearch/snowballstem/english/english_stemmer.go create mode 100644 backend/vendor/github.com/blevesearch/snowballstem/env.go create mode 100644 backend/vendor/github.com/blevesearch/snowballstem/finnish/finnish_stemmer.go create mode 100644 backend/vendor/github.com/blevesearch/snowballstem/french/french_stemmer.go create mode 100644 backend/vendor/github.com/blevesearch/snowballstem/gen.go create mode 100644 backend/vendor/github.com/blevesearch/snowballstem/german/german_stemmer.go create mode 100644 backend/vendor/github.com/blevesearch/snowballstem/italian/italian_stemmer.go create mode 100644 backend/vendor/github.com/blevesearch/snowballstem/russian/russian_stemmer.go create mode 100644 backend/vendor/github.com/blevesearch/snowballstem/spanish/spanish_stemmer.go create mode 100644 backend/vendor/github.com/blevesearch/snowballstem/util.go create mode 100644 backend/vendor/github.com/blevesearch/upsidedown_store_api/LICENSE create mode 100644 backend/vendor/github.com/blevesearch/upsidedown_store_api/README.md create mode 100644 backend/vendor/github.com/blevesearch/upsidedown_store_api/batch.go create mode 100644 backend/vendor/github.com/blevesearch/upsidedown_store_api/kvstore.go create mode 100644 backend/vendor/github.com/blevesearch/upsidedown_store_api/merge.go create mode 100644 backend/vendor/github.com/blevesearch/upsidedown_store_api/multiget.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/CONTRIBUTING.md create mode 100644 backend/vendor/github.com/blevesearch/vellum/LICENSE create mode 100644 backend/vendor/github.com/blevesearch/vellum/README.md create mode 100644 backend/vendor/github.com/blevesearch/vellum/automaton.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/builder.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/common.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/decoder_v1.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/encoder_v1.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/encoding.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/fst.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/fst_iterator.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/levenshtein/LICENSE create mode 100644 backend/vendor/github.com/blevesearch/vellum/levenshtein/README.md create mode 100644 backend/vendor/github.com/blevesearch/vellum/levenshtein/alphabet.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/levenshtein/dfa.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/levenshtein/levenshtein.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/levenshtein/levenshtein_nfa.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/levenshtein/parametric_dfa.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/merge_iterator.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/pack.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/regexp/compile.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/regexp/dfa.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/regexp/inst.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/regexp/regexp.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/regexp/sparse.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/registry.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/transducer.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/utf8/utf8.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/vellum.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/vellum_mmap.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/vellum_nommap.go create mode 100644 backend/vendor/github.com/blevesearch/vellum/writer.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/.gitignore create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/.golangci.yml create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/LICENSE create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/README.md create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/build.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/contentcoder.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/count.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/dict.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/docvalues.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/enumerator.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/intcoder.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/memuvarint.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/merge.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/new.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/plugin.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/posting.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/read.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/segment.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/sizes.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/write.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v11/zap.md create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/.gitignore create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/.golangci.yml create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/LICENSE create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/README.md create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/build.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/chunk.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/contentcoder.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/count.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/dict.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/docvalues.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/enumerator.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/intDecoder.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/intcoder.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/memuvarint.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/merge.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/new.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/plugin.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/posting.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/read.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/segment.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/sizes.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/write.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v12/zap.md create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/.gitignore create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/.golangci.yml create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/LICENSE create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/README.md create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/build.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/chunk.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/contentcoder.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/count.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/dict.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/docvalues.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/enumerator.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/intDecoder.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/intcoder.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/memuvarint.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/merge.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/new.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/plugin.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/posting.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/read.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/segment.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/sizes.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/write.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v13/zap.md create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/.gitignore create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/.golangci.yml create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/LICENSE create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/README.md create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/build.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/chunk.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/contentcoder.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/count.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/dict.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/docvalues.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/enumerator.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/intDecoder.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/intcoder.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/memuvarint.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/merge.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/new.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/plugin.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/posting.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/read.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/segment.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/sizes.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/write.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v14/zap.md create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/.gitignore create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/.golangci.yml create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/LICENSE create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/README.md create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/build.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/chunk.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/contentcoder.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/count.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/dict.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/docvalues.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/enumerator.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/intDecoder.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/intcoder.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/memuvarint.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/merge.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/new.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/plugin.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/posting.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/read.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/segment.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/sizes.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/write.go create mode 100644 backend/vendor/github.com/blevesearch/zapx/v15/zap.md create mode 100644 backend/vendor/github.com/golang/geo/LICENSE create mode 100644 backend/vendor/github.com/golang/geo/r1/doc.go create mode 100644 backend/vendor/github.com/golang/geo/r1/interval.go create mode 100644 backend/vendor/github.com/golang/geo/r2/doc.go create mode 100644 backend/vendor/github.com/golang/geo/r2/rect.go create mode 100644 backend/vendor/github.com/golang/geo/r3/doc.go create mode 100644 backend/vendor/github.com/golang/geo/r3/precisevector.go create mode 100644 backend/vendor/github.com/golang/geo/r3/vector.go create mode 100644 backend/vendor/github.com/golang/geo/s1/angle.go create mode 100644 backend/vendor/github.com/golang/geo/s1/chordangle.go create mode 100644 backend/vendor/github.com/golang/geo/s1/doc.go create mode 100644 backend/vendor/github.com/golang/geo/s1/interval.go create mode 100644 backend/vendor/github.com/json-iterator/go/.codecov.yml create mode 100644 backend/vendor/github.com/json-iterator/go/.gitignore create mode 100644 backend/vendor/github.com/json-iterator/go/.travis.yml create mode 100644 backend/vendor/github.com/json-iterator/go/LICENSE create mode 100644 backend/vendor/github.com/json-iterator/go/README.md create mode 100644 backend/vendor/github.com/json-iterator/go/feature_adapter.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_any.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_any_array.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_any_bool.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_any_float.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_any_int32.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_any_int64.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_any_invalid.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_any_nil.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_any_number.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_any_object.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_any_string.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_any_uint32.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_any_uint64.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_config.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_iter.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_iter_array.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_iter_float.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_iter_int.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_iter_object.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_iter_skip.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_iter_skip_sloppy.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_iter_skip_strict.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_iter_string.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_json_number.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_pool.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_reflect.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_reflect_array.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_reflect_extension.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_reflect_map.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_reflect_native.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_reflect_object.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_reflect_slice.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_reflect_struct_decoder.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_stream.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_stream_float.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_stream_int.go create mode 100644 backend/vendor/github.com/json-iterator/go/feature_stream_string.go create mode 100644 backend/vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md create mode 100644 backend/vendor/github.com/json-iterator/go/jsoniter.go create mode 100644 backend/vendor/github.com/json-iterator/go/test.sh create mode 100644 backend/vendor/github.com/mschoch/smat/.gitignore create mode 100644 backend/vendor/github.com/mschoch/smat/.travis.yml create mode 100644 backend/vendor/github.com/mschoch/smat/LICENSE create mode 100644 backend/vendor/github.com/mschoch/smat/README.md create mode 100644 backend/vendor/github.com/mschoch/smat/actionseq.go create mode 100644 backend/vendor/github.com/mschoch/smat/smat.go diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/.drone.yml b/backend/vendor/github.com/RoaringBitmap/roaring/.drone.yml new file mode 100644 index 0000000000..698cd0e7a7 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/.drone.yml @@ -0,0 +1,20 @@ +kind: pipeline +name: default + +workspace: + base: /go + path: src/github.com/RoaringBitmap/roaring + +steps: +- name: test + image: golang + commands: + - go get -t + - go test + - go test -race -run TestConcurrent* + - go build -tags appengine + - go test -tags appengine + - GOARCH=386 go build + - GOARCH=386 go test + - GOARCH=arm go build + - GOARCH=arm64 go build diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/.gitignore b/backend/vendor/github.com/RoaringBitmap/roaring/.gitignore new file mode 100644 index 0000000000..851f323dba --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/.gitignore @@ -0,0 +1,5 @@ +*~ +roaring-fuzz.zip +workdir +coverage.out +testdata/all3.classic diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/.gitmodules b/backend/vendor/github.com/RoaringBitmap/roaring/.gitmodules new file mode 100644 index 0000000000..e69de29bb2 diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/.travis.yml b/backend/vendor/github.com/RoaringBitmap/roaring/.travis.yml new file mode 100644 index 0000000000..0a4c4e918f --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/.travis.yml @@ -0,0 +1,32 @@ +language: go +sudo: false +install: +- go get -t github.com/RoaringBitmap/roaring +- go get -t golang.org/x/tools/cmd/cover +- go get -t github.com/mattn/goveralls +- go get -t github.com/mschoch/smat +notifications: + email: false +go: +- "1.13.x" +- "1.14.x" +- tip + +# whitelist +branches: + only: + - master +script: +- goveralls -v -service travis-ci -ignore rle16_gen.go,rle_gen.go,rle.go || go test +- go test -race -run TestConcurrent* +- go build -tags appengine +- go test -tags appengine +- GOARCH=arm64 go build +- GOARCH=386 go build +- GOARCH=386 go test +- GOARCH=arm go build +- GOARCH=arm64 go build + +matrix: + allow_failures: + - go: tip diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/AUTHORS b/backend/vendor/github.com/RoaringBitmap/roaring/AUTHORS new file mode 100644 index 0000000000..26ec99de9d --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/AUTHORS @@ -0,0 +1,11 @@ +# This is the official list of roaring authors for copyright purposes. + +Todd Gruben (@tgruben), +Daniel Lemire (@lemire), +Elliot Murphy (@statik), +Bob Potter (@bpot), +Tyson Maly (@tvmaly), +Will Glynn (@willglynn), +Brent Pedersen (@brentp) +Maciej Biłas (@maciej), +Joe Nall (@joenall) diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/CONTRIBUTORS b/backend/vendor/github.com/RoaringBitmap/roaring/CONTRIBUTORS new file mode 100644 index 0000000000..1a8da9cc0f --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/CONTRIBUTORS @@ -0,0 +1,18 @@ +# This is the official list of roaring contributors + +Todd Gruben (@tgruben), +Daniel Lemire (@lemire), +Elliot Murphy (@statik), +Bob Potter (@bpot), +Tyson Maly (@tvmaly), +Will Glynn (@willglynn), +Brent Pedersen (@brentp), +Jason E. Aten (@glycerine), +Vali Malinoiu (@0x4139), +Forud Ghafouri (@fzerorubigd), +Joe Nall (@joenall), +(@fredim), +Edd Robinson (@e-dard), +Alexander Petrov (@alldroll), +Guy Molinari (@guymolinari), +Ling Jin (@JinLingChristopher) diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/LICENSE b/backend/vendor/github.com/RoaringBitmap/roaring/LICENSE new file mode 100644 index 0000000000..3ccdd00084 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/LICENSE @@ -0,0 +1,235 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016 by the authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +================================================================================ + +Portions of runcontainer.go are from the Go standard library, which is licensed +under: + +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/LICENSE-2.0.txt b/backend/vendor/github.com/RoaringBitmap/roaring/LICENSE-2.0.txt new file mode 100644 index 0000000000..aff5f9999b --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/LICENSE-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016 by the authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/Makefile b/backend/vendor/github.com/RoaringBitmap/roaring/Makefile new file mode 100644 index 0000000000..0a4f9f0aae --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/Makefile @@ -0,0 +1,107 @@ +.PHONY: help all test format fmtcheck vet lint qa deps clean nuke ser fetch-real-roaring-datasets + + + + + + + + +# Display general help about this command +help: + @echo "" + @echo "The following commands are available:" + @echo "" + @echo " make qa : Run all the tests" + @echo " make test : Run the unit tests" + @echo "" + @echo " make format : Format the source code" + @echo " make fmtcheck : Check if the source code has been formatted" + @echo " make vet : Check for suspicious constructs" + @echo " make lint : Check for style errors" + @echo "" + @echo " make deps : Get the dependencies" + @echo " make clean : Remove any build artifact" + @echo " make nuke : Deletes any intermediate file" + @echo "" + @echo " make fuzz-smat : Fuzzy testing with smat" + @echo " make fuzz-stream : Fuzzy testing with stream deserialization" + @echo " make fuzz-buffer : Fuzzy testing with buffer deserialization" + @echo "" + +# Alias for help target +all: help +test: + go test + go test -race -run TestConcurrent* +# Format the source code +format: + @find ./ -type f -name "*.go" -exec gofmt -w {} \; + +# Check if the source code has been formatted +fmtcheck: + @mkdir -p target + @find ./ -type f -name "*.go" -exec gofmt -d {} \; | tee target/format.diff + @test ! -s target/format.diff || { echo "ERROR: the source code has not been formatted - please use 'make format' or 'gofmt'"; exit 1; } + +# Check for syntax errors +vet: + GOPATH=$(GOPATH) go vet ./... + +# Check for style errors +lint: + GOPATH=$(GOPATH) PATH=$(GOPATH)/bin:$(PATH) golint ./... + + + + + +# Alias to run all quality-assurance checks +qa: fmtcheck test vet lint + +# --- INSTALL --- + +# Get the dependencies +deps: + GOPATH=$(GOPATH) go get github.com/stretchr/testify + GOPATH=$(GOPATH) go get github.com/bits-and-blooms/bitset + GOPATH=$(GOPATH) go get github.com/golang/lint/golint + GOPATH=$(GOPATH) go get github.com/mschoch/smat + GOPATH=$(GOPATH) go get github.com/dvyukov/go-fuzz/go-fuzz + GOPATH=$(GOPATH) go get github.com/dvyukov/go-fuzz/go-fuzz-build + GOPATH=$(GOPATH) go get github.com/glycerine/go-unsnap-stream + GOPATH=$(GOPATH) go get github.com/philhofer/fwd + GOPATH=$(GOPATH) go get github.com/jtolds/gls + +fuzz-smat: + go test -tags=gofuzz -run=TestGenerateSmatCorpus + go-fuzz-build -func FuzzSmat github.com/RoaringBitmap/roaring + go-fuzz -bin=./roaring-fuzz.zip -workdir=workdir/ -timeout=200 + + +fuzz-stream: + go-fuzz-build -func FuzzSerializationStream github.com/RoaringBitmap/roaring + go-fuzz -bin=./roaring-fuzz.zip -workdir=workdir/ -timeout=200 + + +fuzz-buffer: + go-fuzz-build -func FuzzSerializationBuffer github.com/RoaringBitmap/roaring + go-fuzz -bin=./roaring-fuzz.zip -workdir=workdir/ -timeout=200 + +# Remove any build artifact +clean: + GOPATH=$(GOPATH) go clean ./... + +# Deletes any intermediate file +nuke: + rm -rf ./target + GOPATH=$(GOPATH) go clean -i ./... + +cover: + go test -coverprofile=coverage.out + go tool cover -html=coverage.out + +fetch-real-roaring-datasets: + # pull github.com/RoaringBitmap/real-roaring-datasets -> testdata/real-roaring-datasets + git submodule init + git submodule update diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/README.md b/backend/vendor/github.com/RoaringBitmap/roaring/README.md new file mode 100644 index 0000000000..2a7a129060 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/README.md @@ -0,0 +1,405 @@ +roaring [![Build Status](https://travis-ci.org/RoaringBitmap/roaring.png)](https://travis-ci.org/RoaringBitmap/roaring) [![GoDoc](https://godoc.org/github.com/RoaringBitmap/roaring/roaring64?status.svg)](https://godoc.org/github.com/RoaringBitmap/roaring/roaring64) [![Go Report Card](https://goreportcard.com/badge/RoaringBitmap/roaring)](https://goreportcard.com/report/github.com/RoaringBitmap/roaring) +[![Build Status](https://cloud.drone.io/api/badges/RoaringBitmap/roaring/status.svg)](https://cloud.drone.io/RoaringBitmap/roaring) +![Go-CI](https://github.com/RoaringBitmap/roaring/workflows/Go-CI/badge.svg) +![Go-ARM-CI](https://github.com/RoaringBitmap/roaring/workflows/Go-ARM-CI/badge.svg) +![Go-Windows-CI](https://github.com/RoaringBitmap/roaring/workflows/Go-Windows-CI/badge.svg) +============= + +This is a go version of the Roaring bitmap data structure. + + + +Roaring bitmaps are used by several major systems such as [Apache Lucene][lucene] and derivative systems such as [Solr][solr] and +[Elasticsearch][elasticsearch], [Apache Druid (Incubating)][druid], [LinkedIn Pinot][pinot], [Netflix Atlas][atlas], [Apache Spark][spark], [OpenSearchServer][opensearchserver], [Cloud Torrent][cloudtorrent], [Whoosh][whoosh], [Pilosa][pilosa], [Microsoft Visual Studio Team Services (VSTS)][vsts], and eBay's [Apache Kylin][kylin]. The YouTube SQL Engine, [Google Procella](https://research.google/pubs/pub48388/), uses Roaring bitmaps for indexing. + +[lucene]: https://lucene.apache.org/ +[solr]: https://lucene.apache.org/solr/ +[elasticsearch]: https://www.elastic.co/products/elasticsearch +[druid]: https://druid.apache.org/ +[spark]: https://spark.apache.org/ +[opensearchserver]: http://www.opensearchserver.com +[cloudtorrent]: https://github.com/jpillora/cloud-torrent +[whoosh]: https://bitbucket.org/mchaput/whoosh/wiki/Home +[pilosa]: https://www.pilosa.com/ +[kylin]: http://kylin.apache.org/ +[pinot]: http://github.com/linkedin/pinot/wiki +[vsts]: https://www.visualstudio.com/team-services/ +[atlas]: https://github.com/Netflix/atlas + +Roaring bitmaps are found to work well in many important applications: + +> Use Roaring for bitmap compression whenever possible. Do not use other bitmap compression methods ([Wang et al., SIGMOD 2017](http://db.ucsd.edu/wp-content/uploads/2017/03/sidm338-wangA.pdf)) + + +The ``roaring`` Go library is used by +* [Cloud Torrent](https://github.com/jpillora/cloud-torrent) +* [runv](https://github.com/hyperhq/runv) +* [InfluxDB](https://www.influxdata.com) +* [Pilosa](https://www.pilosa.com/) +* [Bleve](http://www.blevesearch.com) +* [lindb](https://github.com/lindb/lindb) +* [Elasticell](https://github.com/deepfabric/elasticell) +* [SourceGraph](https://github.com/sourcegraph/sourcegraph) +* [M3](https://github.com/m3db/m3) +* [trident](https://github.com/NetApp/trident) + + +This library is used in production in several systems, it is part of the [Awesome Go collection](https://awesome-go.com). + + +There are also [Java](https://github.com/RoaringBitmap/RoaringBitmap) and [C/C++](https://github.com/RoaringBitmap/CRoaring) versions. The Java, C, C++ and Go version are binary compatible: e.g, you can save bitmaps +from a Java program and load them back in Go, and vice versa. We have a [format specification](https://github.com/RoaringBitmap/RoaringFormatSpec). + + +This code is licensed under Apache License, Version 2.0 (ASL2.0). + +Copyright 2016-... by the authors. + +When should you use a bitmap? +=================================== + + +Sets are a fundamental abstraction in +software. They can be implemented in various +ways, as hash sets, as trees, and so forth. +In databases and search engines, sets are often an integral +part of indexes. For example, we may need to maintain a set +of all documents or rows (represented by numerical identifier) +that satisfy some property. Besides adding or removing +elements from the set, we need fast functions +to compute the intersection, the union, the difference between sets, and so on. + + +To implement a set +of integers, a particularly appealing strategy is the +bitmap (also called bitset or bit vector). Using n bits, +we can represent any set made of the integers from the range +[0,n): the ith bit is set to one if integer i is present in the set. +Commodity processors use words of W=32 or W=64 bits. By combining many such words, we can +support large values of n. Intersections, unions and differences can then be implemented + as bitwise AND, OR and ANDNOT operations. +More complicated set functions can also be implemented as bitwise operations. + +When the bitset approach is applicable, it can be orders of +magnitude faster than other possible implementation of a set (e.g., as a hash set) +while using several times less memory. + +However, a bitset, even a compressed one is not always applicable. For example, if +you have 1000 random-looking integers, then a simple array might be the best representation. +We refer to this case as the "sparse" scenario. + +When should you use compressed bitmaps? +=================================== + +An uncompressed BitSet can use a lot of memory. For example, if you take a BitSet +and set the bit at position 1,000,000 to true and you have just over 100kB. That is over 100kB +to store the position of one bit. This is wasteful even if you do not care about memory: +suppose that you need to compute the intersection between this BitSet and another one +that has a bit at position 1,000,001 to true, then you need to go through all these zeroes, +whether you like it or not. That can become very wasteful. + +This being said, there are definitively cases where attempting to use compressed bitmaps is wasteful. +For example, if you have a small universe size. E.g., your bitmaps represent sets of integers +from [0,n) where n is small (e.g., n=64 or n=128). If you are able to uncompressed BitSet and +it does not blow up your memory usage, then compressed bitmaps are probably not useful +to you. In fact, if you do not need compression, then a BitSet offers remarkable speed. + +The sparse scenario is another use case where compressed bitmaps should not be used. +Keep in mind that random-looking data is usually not compressible. E.g., if you have a small set of +32-bit random integers, it is not mathematically possible to use far less than 32 bits per integer, +and attempts at compression can be counterproductive. + +How does Roaring compares with the alternatives? +================================================== + + +Most alternatives to Roaring are part of a larger family of compressed bitmaps that are run-length-encoded +bitmaps. They identify long runs of 1s or 0s and they represent them with a marker word. +If you have a local mix of 1s and 0, you use an uncompressed word. + +There are many formats in this family: + +* Oracle's BBC is an obsolete format at this point: though it may provide good compression, +it is likely much slower than more recent alternatives due to excessive branching. +* WAH is a patented variation on BBC that provides better performance. +* Concise is a variation on the patented WAH. It some specific instances, it can compress +much better than WAH (up to 2x better), but it is generally slower. +* EWAH is both free of patent, and it is faster than all the above. On the downside, it +does not compress quite as well. It is faster because it allows some form of "skipping" +over uncompressed words. So though none of these formats are great at random access, EWAH +is better than the alternatives. + + + +There is a big problem with these formats however that can hurt you badly in some cases: there is no random access. If you want to check whether a given value is present in the set, you have to start from the beginning and "uncompress" the whole thing. This means that if you want to intersect a big set with a large set, you still have to uncompress the whole big set in the worst case... + +Roaring solves this problem. It works in the following manner. It divides the data into chunks of 216 integers +(e.g., [0, 216), [216, 2 x 216), ...). Within a chunk, it can use an uncompressed bitmap, a simple list of integers, +or a list of runs. Whatever format it uses, they all allow you to check for the present of any one value quickly +(e.g., with a binary search). The net result is that Roaring can compute many operations much faster than run-length-encoded +formats like WAH, EWAH, Concise... Maybe surprisingly, Roaring also generally offers better compression ratios. + + + + + +### References + +- Daniel Lemire, Owen Kaser, Nathan Kurz, Luca Deri, Chris O'Hara, François Saint-Jacques, Gregory Ssi-Yan-Kai, Roaring Bitmaps: Implementation of an Optimized Software Library, Software: Practice and Experience 48 (4), 2018 [arXiv:1709.07821](https://arxiv.org/abs/1709.07821) +- Samy Chambi, Daniel Lemire, Owen Kaser, Robert Godin, +Better bitmap performance with Roaring bitmaps, +Software: Practice and Experience 46 (5), 2016. +http://arxiv.org/abs/1402.6407 This paper used data from http://lemire.me/data/realroaring2014.html +- Daniel Lemire, Gregory Ssi-Yan-Kai, Owen Kaser, Consistently faster and smaller compressed bitmaps with Roaring, Software: Practice and Experience 46 (11), 2016. http://arxiv.org/abs/1603.06549 + + +### Dependencies + +Dependencies are fetched automatically by giving the `-t` flag to `go get`. + +they include + - github.com/bits-and-blooms/bitset + - github.com/mschoch/smat + - github.com/glycerine/go-unsnap-stream + - github.com/philhofer/fwd + - github.com/jtolds/gls + +Note that the smat library requires Go 1.6 or better. + +#### Installation + + - go get -t github.com/RoaringBitmap/roaring + + +### Example + +Here is a simplified but complete example: + +```go +package main + +import ( + "fmt" + "github.com/RoaringBitmap/roaring" + "bytes" +) + + +func main() { + // example inspired by https://github.com/fzandona/goroar + fmt.Println("==roaring==") + rb1 := roaring.BitmapOf(1, 2, 3, 4, 5, 100, 1000) + fmt.Println(rb1.String()) + + rb2 := roaring.BitmapOf(3, 4, 1000) + fmt.Println(rb2.String()) + + rb3 := roaring.New() + fmt.Println(rb3.String()) + + fmt.Println("Cardinality: ", rb1.GetCardinality()) + + fmt.Println("Contains 3? ", rb1.Contains(3)) + + rb1.And(rb2) + + rb3.Add(1) + rb3.Add(5) + + rb3.Or(rb1) + + // computes union of the three bitmaps in parallel using 4 workers + roaring.ParOr(4, rb1, rb2, rb3) + // computes intersection of the three bitmaps in parallel using 4 workers + roaring.ParAnd(4, rb1, rb2, rb3) + + + // prints 1, 3, 4, 5, 1000 + i := rb3.Iterator() + for i.HasNext() { + fmt.Println(i.Next()) + } + fmt.Println() + + // next we include an example of serialization + buf := new(bytes.Buffer) + rb1.WriteTo(buf) // we omit error handling + newrb:= roaring.New() + newrb.ReadFrom(buf) + if rb1.Equals(newrb) { + fmt.Println("I wrote the content to a byte stream and read it back.") + } + // you can iterate over bitmaps using ReverseIterator(), Iterator, ManyIterator() +} +``` + +If you wish to use serialization and handle errors, you might want to +consider the following sample of code: + +```go + rb := BitmapOf(1, 2, 3, 4, 5, 100, 1000) + buf := new(bytes.Buffer) + size,err:=rb.WriteTo(buf) + if err != nil { + t.Errorf("Failed writing") + } + newrb:= New() + size,err=newrb.ReadFrom(buf) + if err != nil { + t.Errorf("Failed reading") + } + if ! rb.Equals(newrb) { + t.Errorf("Cannot retrieve serialized version") + } +``` + +Given N integers in [0,x), then the serialized size in bytes of +a Roaring bitmap should never exceed this bound: + +`` 8 + 9 * ((long)x+65535)/65536 + 2 * N `` + +That is, given a fixed overhead for the universe size (x), Roaring +bitmaps never use more than 2 bytes per integer. You can call +``BoundSerializedSizeInBytes`` for a more precise estimate. + +### 64-bit Roaring + +By default, roaring is used to stored unsigned 32-bit integers. However, we also offer +an extension dedicated to 64-bit integers. It supports roughly the same functions: + +```go +package main + +import ( + "fmt" + "github.com/RoaringBitmap/roaring/roaring64" + "bytes" +) + + +func main() { + // example inspired by https://github.com/fzandona/goroar + fmt.Println("==roaring64==") + rb1 := roaring64.BitmapOf(1, 2, 3, 4, 5, 100, 1000) + fmt.Println(rb1.String()) + + rb2 := roaring64.BitmapOf(3, 4, 1000) + fmt.Println(rb2.String()) + + rb3 := roaring64.New() + fmt.Println(rb3.String()) + + fmt.Println("Cardinality: ", rb1.GetCardinality()) + + fmt.Println("Contains 3? ", rb1.Contains(3)) + + rb1.And(rb2) + + rb3.Add(1) + rb3.Add(5) + + rb3.Or(rb1) + + + + // prints 1, 3, 4, 5, 1000 + i := rb3.Iterator() + for i.HasNext() { + fmt.Println(i.Next()) + } + fmt.Println() + + // next we include an example of serialization + buf := new(bytes.Buffer) + rb1.WriteTo(buf) // we omit error handling + newrb:= roaring64.New() + newrb.ReadFrom(buf) + if rb1.Equals(newrb) { + fmt.Println("I wrote the content to a byte stream and read it back.") + } + // you can iterate over bitmaps using ReverseIterator(), Iterator, ManyIterator() +} +``` + +Only the 32-bit roaring format is standard and cross-operable between Java, C++, C and Go. There is no guarantee that the 64-bit versions are compatible. + +### Documentation + +Current documentation is available at http://godoc.org/github.com/RoaringBitmap/roaring and http://godoc.org/github.com/RoaringBitmap/roaring64 + +### Goroutine safety + +In general, it should not generally be considered safe to access +the same bitmaps using different goroutines--they are left +unsynchronized for performance. Should you want to access +a Bitmap from more than one goroutine, you should +provide synchronization. Typically this is done by using channels to pass +the *Bitmap around (in Go style; so there is only ever one owner), +or by using `sync.Mutex` to serialize operations on Bitmaps. + +### Coverage + +We test our software. For a report on our test coverage, see + +https://coveralls.io/github/RoaringBitmap/roaring?branch=master + +### Benchmark + +Type + + go test -bench Benchmark -run - + +To run benchmarks on [Real Roaring Datasets](https://github.com/RoaringBitmap/real-roaring-datasets) +run the following: + +```sh +go get github.com/RoaringBitmap/real-roaring-datasets +BENCH_REAL_DATA=1 go test -bench BenchmarkRealData -run - +``` + +### Iterative use + +You can use roaring with gore: + +- go get -u github.com/motemen/gore +- Make sure that ``$GOPATH/bin`` is in your ``$PATH``. +- go get github.com/RoaringBitmap/roaring + +```go +$ gore +gore version 0.2.6 :help for help +gore> :import github.com/RoaringBitmap/roaring +gore> x:=roaring.New() +gore> x.Add(1) +gore> x.String() +"{1}" +``` + + +### Fuzzy testing + +You can help us test further the library with fuzzy testing: + + go get github.com/dvyukov/go-fuzz/go-fuzz + go get github.com/dvyukov/go-fuzz/go-fuzz-build + go test -tags=gofuzz -run=TestGenerateSmatCorpus + go-fuzz-build github.com/RoaringBitmap/roaring + go-fuzz -bin=./roaring-fuzz.zip -workdir=workdir/ -timeout=200 -func FuzzSmat + +Let it run, and if the # of crashers is > 0, check out the reports in +the workdir where you should be able to find the panic goroutine stack +traces. + +You may also replace `-func FuzzSmat` by `-func FuzzSerializationBuffer` or `-func FuzzSerializationStream`. + +### Alternative in Go + +There is a Go version wrapping the C/C++ implementation https://github.com/RoaringBitmap/gocroaring + +For an alternative implementation in Go, see https://github.com/fzandona/goroar +The two versions were written independently. + + +### Mailing list/discussion group + +https://groups.google.com/forum/#!forum/roaring-bitmaps diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/arraycontainer.go b/backend/vendor/github.com/RoaringBitmap/roaring/arraycontainer.go new file mode 100644 index 0000000000..80b7eecf7e --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/arraycontainer.go @@ -0,0 +1,1022 @@ +package roaring + +import ( + "fmt" +) + +type arrayContainer struct { + content []uint16 +} + +func (ac *arrayContainer) String() string { + s := "{" + for it := ac.getShortIterator(); it.hasNext(); { + s += fmt.Sprintf("%v, ", it.next()) + } + return s + "}" +} + +func (ac *arrayContainer) fillLeastSignificant16bits(x []uint32, i int, mask uint32) int { + for k := 0; k < len(ac.content); k++ { + x[k+i] = uint32(ac.content[k]) | mask + } + return i + len(ac.content) +} + +func (ac *arrayContainer) iterate(cb func(x uint16) bool) bool { + iterator := shortIterator{ac.content, 0} + + for iterator.hasNext() { + if !cb(iterator.next()) { + return false + } + } + + return true +} + +func (ac *arrayContainer) getShortIterator() shortPeekable { + return &shortIterator{ac.content, 0} +} + +func (ac *arrayContainer) getReverseIterator() shortIterable { + return &reverseIterator{ac.content, len(ac.content) - 1} +} + +func (ac *arrayContainer) getManyIterator() manyIterable { + return &shortIterator{ac.content, 0} +} + +func (ac *arrayContainer) minimum() uint16 { + return ac.content[0] // assume not empty +} + +func (ac *arrayContainer) maximum() uint16 { + return ac.content[len(ac.content)-1] // assume not empty +} + +func (ac *arrayContainer) getSizeInBytes() int { + return ac.getCardinality() * 2 +} + +func (ac *arrayContainer) serializedSizeInBytes() int { + return ac.getCardinality() * 2 +} + +func arrayContainerSizeInBytes(card int) int { + return card * 2 +} + +// add the values in the range [firstOfRange,endx) +func (ac *arrayContainer) iaddRange(firstOfRange, endx int) container { + if firstOfRange >= endx { + return ac + } + indexstart := binarySearch(ac.content, uint16(firstOfRange)) + if indexstart < 0 { + indexstart = -indexstart - 1 + } + indexend := binarySearch(ac.content, uint16(endx-1)) + if indexend < 0 { + indexend = -indexend - 1 + } else { + indexend++ + } + rangelength := endx - firstOfRange + newcardinality := indexstart + (ac.getCardinality() - indexend) + rangelength + if newcardinality > arrayDefaultMaxSize { + a := ac.toBitmapContainer() + return a.iaddRange(firstOfRange, endx) + } + if cap(ac.content) < newcardinality { + tmp := make([]uint16, newcardinality, newcardinality) + copy(tmp[:indexstart], ac.content[:indexstart]) + copy(tmp[indexstart+rangelength:], ac.content[indexend:]) + + ac.content = tmp + } else { + ac.content = ac.content[:newcardinality] + copy(ac.content[indexstart+rangelength:], ac.content[indexend:]) + + } + for k := 0; k < rangelength; k++ { + ac.content[k+indexstart] = uint16(firstOfRange + k) + } + return ac +} + +// remove the values in the range [firstOfRange,endx) +func (ac *arrayContainer) iremoveRange(firstOfRange, endx int) container { + if firstOfRange >= endx { + return ac + } + indexstart := binarySearch(ac.content, uint16(firstOfRange)) + if indexstart < 0 { + indexstart = -indexstart - 1 + } + indexend := binarySearch(ac.content, uint16(endx-1)) + if indexend < 0 { + indexend = -indexend - 1 + } else { + indexend++ + } + rangelength := indexend - indexstart + answer := ac + copy(answer.content[indexstart:], ac.content[indexstart+rangelength:]) + answer.content = answer.content[:ac.getCardinality()-rangelength] + return answer +} + +// flip the values in the range [firstOfRange,endx) +func (ac *arrayContainer) not(firstOfRange, endx int) container { + if firstOfRange >= endx { + return ac.clone() + } + return ac.notClose(firstOfRange, endx-1) // remove everything in [firstOfRange,endx-1] +} + +// flip the values in the range [firstOfRange,lastOfRange] +func (ac *arrayContainer) notClose(firstOfRange, lastOfRange int) container { + if firstOfRange > lastOfRange { // unlike add and remove, not uses an inclusive range [firstOfRange,lastOfRange] + return ac.clone() + } + + // determine the span of array indices to be affected^M + startIndex := binarySearch(ac.content, uint16(firstOfRange)) + if startIndex < 0 { + startIndex = -startIndex - 1 + } + lastIndex := binarySearch(ac.content, uint16(lastOfRange)) + if lastIndex < 0 { + lastIndex = -lastIndex - 2 + } + currentValuesInRange := lastIndex - startIndex + 1 + spanToBeFlipped := lastOfRange - firstOfRange + 1 + newValuesInRange := spanToBeFlipped - currentValuesInRange + cardinalityChange := newValuesInRange - currentValuesInRange + newCardinality := len(ac.content) + cardinalityChange + if newCardinality > arrayDefaultMaxSize { + return ac.toBitmapContainer().not(firstOfRange, lastOfRange+1) + } + answer := newArrayContainer() + answer.content = make([]uint16, newCardinality, newCardinality) //a hack for sure + + copy(answer.content, ac.content[:startIndex]) + outPos := startIndex + inPos := startIndex + valInRange := firstOfRange + for ; valInRange <= lastOfRange && inPos <= lastIndex; valInRange++ { + if uint16(valInRange) != ac.content[inPos] { + answer.content[outPos] = uint16(valInRange) + outPos++ + } else { + inPos++ + } + } + + for ; valInRange <= lastOfRange; valInRange++ { + answer.content[outPos] = uint16(valInRange) + outPos++ + } + + for i := lastIndex + 1; i < len(ac.content); i++ { + answer.content[outPos] = ac.content[i] + outPos++ + } + answer.content = answer.content[:newCardinality] + return answer + +} + +func (ac *arrayContainer) equals(o container) bool { + + srb, ok := o.(*arrayContainer) + if ok { + // Check if the containers are the same object. + if ac == srb { + return true + } + + if len(srb.content) != len(ac.content) { + return false + } + + for i, v := range ac.content { + if v != srb.content[i] { + return false + } + } + return true + } + + // use generic comparison + bCard := o.getCardinality() + aCard := ac.getCardinality() + if bCard != aCard { + return false + } + + ait := ac.getShortIterator() + bit := o.getShortIterator() + for ait.hasNext() { + if bit.next() != ait.next() { + return false + } + } + return true +} + +func (ac *arrayContainer) toBitmapContainer() *bitmapContainer { + bc := newBitmapContainer() + bc.loadData(ac) + return bc + +} +func (ac *arrayContainer) iadd(x uint16) (wasNew bool) { + // Special case adding to the end of the container. + l := len(ac.content) + if l > 0 && l < arrayDefaultMaxSize && ac.content[l-1] < x { + ac.content = append(ac.content, x) + return true + } + + loc := binarySearch(ac.content, x) + + if loc < 0 { + s := ac.content + i := -loc - 1 + s = append(s, 0) + copy(s[i+1:], s[i:]) + s[i] = x + ac.content = s + return true + } + return false +} + +func (ac *arrayContainer) iaddReturnMinimized(x uint16) container { + // Special case adding to the end of the container. + l := len(ac.content) + if l > 0 && l < arrayDefaultMaxSize && ac.content[l-1] < x { + ac.content = append(ac.content, x) + return ac + } + + loc := binarySearch(ac.content, x) + + if loc < 0 { + if len(ac.content) >= arrayDefaultMaxSize { + a := ac.toBitmapContainer() + a.iadd(x) + return a + } + s := ac.content + i := -loc - 1 + s = append(s, 0) + copy(s[i+1:], s[i:]) + s[i] = x + ac.content = s + } + return ac +} + +// iremoveReturnMinimized is allowed to change the return type to minimize storage. +func (ac *arrayContainer) iremoveReturnMinimized(x uint16) container { + ac.iremove(x) + return ac +} + +func (ac *arrayContainer) iremove(x uint16) bool { + loc := binarySearch(ac.content, x) + if loc >= 0 { + s := ac.content + s = append(s[:loc], s[loc+1:]...) + ac.content = s + return true + } + return false +} + +func (ac *arrayContainer) remove(x uint16) container { + out := &arrayContainer{make([]uint16, len(ac.content))} + copy(out.content, ac.content[:]) + + loc := binarySearch(out.content, x) + if loc >= 0 { + s := out.content + s = append(s[:loc], s[loc+1:]...) + out.content = s + } + return out +} + +func (ac *arrayContainer) or(a container) container { + switch x := a.(type) { + case *arrayContainer: + return ac.orArray(x) + case *bitmapContainer: + return x.orArray(ac) + case *runContainer16: + if x.isFull() { + return x.clone() + } + return x.orArray(ac) + } + panic("unsupported container type") +} + +func (ac *arrayContainer) orCardinality(a container) int { + switch x := a.(type) { + case *arrayContainer: + return ac.orArrayCardinality(x) + case *bitmapContainer: + return x.orArrayCardinality(ac) + case *runContainer16: + return x.orArrayCardinality(ac) + } + panic("unsupported container type") +} + +func (ac *arrayContainer) ior(a container) container { + switch x := a.(type) { + case *arrayContainer: + return ac.iorArray(x) + case *bitmapContainer: + return a.(*bitmapContainer).orArray(ac) + //return ac.iorBitmap(x) // note: this does not make sense + case *runContainer16: + if x.isFull() { + return x.clone() + } + return ac.iorRun16(x) + } + panic("unsupported container type") +} + +func (ac *arrayContainer) iorArray(value2 *arrayContainer) container { + value1 := ac + len1 := value1.getCardinality() + len2 := value2.getCardinality() + maxPossibleCardinality := len1 + len2 + if maxPossibleCardinality > cap(value1.content) { + // doubling the capacity reduces new slice allocations in the case of + // repeated calls to iorArray(). + newSize := 2 * maxPossibleCardinality + // the second check is to handle overly large array containers + // and should not occur in normal usage, + // as all array containers should be at most arrayDefaultMaxSize + if newSize > 2*arrayDefaultMaxSize && maxPossibleCardinality <= 2*arrayDefaultMaxSize { + newSize = 2 * arrayDefaultMaxSize + } + newcontent := make([]uint16, 0, newSize) + copy(newcontent[len2:maxPossibleCardinality], ac.content[0:len1]) + ac.content = newcontent + } else { + copy(ac.content[len2:maxPossibleCardinality], ac.content[0:len1]) + } + nl := union2by2(value1.content[len2:maxPossibleCardinality], value2.content, ac.content) + ac.content = ac.content[:nl] // reslice to match actual used capacity + + if nl > arrayDefaultMaxSize { + // Only converting to a bitmap when arrayDefaultMaxSize + // is actually exceeded minimizes conversions in the case of repeated + // calls to iorArray(). + return ac.toBitmapContainer() + } + return ac +} + +// Note: such code does not make practical sense, except for lazy evaluations +func (ac *arrayContainer) iorBitmap(bc2 *bitmapContainer) container { + bc1 := ac.toBitmapContainer() + bc1.iorBitmap(bc2) + *ac = *newArrayContainerFromBitmap(bc1) + return ac +} + +func (ac *arrayContainer) iorRun16(rc *runContainer16) container { + runCardinality := rc.getCardinality() + // heuristic for if the container should maybe be an + // array container. + if runCardinality < ac.getCardinality() && + runCardinality+ac.getCardinality() < arrayDefaultMaxSize { + var result container + result = ac + for _, run := range rc.iv { + result = result.iaddRange(int(run.start), int(run.start)+int(run.length)+1) + } + return result + } + return rc.orArray(ac) +} + +func (ac *arrayContainer) lazyIOR(a container) container { + switch x := a.(type) { + case *arrayContainer: + return ac.lazyIorArray(x) + case *bitmapContainer: + return ac.lazyIorBitmap(x) + case *runContainer16: + if x.isFull() { + return x.clone() + } + return ac.lazyIorRun16(x) + + } + panic("unsupported container type") +} + +func (ac *arrayContainer) lazyIorArray(ac2 *arrayContainer) container { + // TODO actually make this lazy + return ac.iorArray(ac2) +} + +func (ac *arrayContainer) lazyIorBitmap(bc *bitmapContainer) container { + // TODO actually make this lazy + return ac.iorBitmap(bc) +} + +func (ac *arrayContainer) lazyIorRun16(rc *runContainer16) container { + // TODO actually make this lazy + return ac.iorRun16(rc) +} + +func (ac *arrayContainer) lazyOR(a container) container { + switch x := a.(type) { + case *arrayContainer: + return ac.lazyorArray(x) + case *bitmapContainer: + return a.lazyOR(ac) + case *runContainer16: + if x.isFull() { + return x.clone() + } + return x.orArray(ac) + } + panic("unsupported container type") +} + +func (ac *arrayContainer) orArray(value2 *arrayContainer) container { + value1 := ac + maxPossibleCardinality := value1.getCardinality() + value2.getCardinality() + if maxPossibleCardinality > arrayDefaultMaxSize { // it could be a bitmap! + bc := newBitmapContainer() + for k := 0; k < len(value2.content); k++ { + v := value2.content[k] + i := uint(v) >> 6 + mask := uint64(1) << (v % 64) + bc.bitmap[i] |= mask + } + for k := 0; k < len(ac.content); k++ { + v := ac.content[k] + i := uint(v) >> 6 + mask := uint64(1) << (v % 64) + bc.bitmap[i] |= mask + } + bc.cardinality = int(popcntSlice(bc.bitmap)) + if bc.cardinality <= arrayDefaultMaxSize { + return bc.toArrayContainer() + } + return bc + } + answer := newArrayContainerCapacity(maxPossibleCardinality) + nl := union2by2(value1.content, value2.content, answer.content) + answer.content = answer.content[:nl] // reslice to match actual used capacity + return answer +} + +func (ac *arrayContainer) orArrayCardinality(value2 *arrayContainer) int { + return union2by2Cardinality(ac.content, value2.content) +} + +func (ac *arrayContainer) lazyorArray(value2 *arrayContainer) container { + value1 := ac + maxPossibleCardinality := value1.getCardinality() + value2.getCardinality() + if maxPossibleCardinality > arrayLazyLowerBound { // it could be a bitmap! + bc := newBitmapContainer() + for k := 0; k < len(value2.content); k++ { + v := value2.content[k] + i := uint(v) >> 6 + mask := uint64(1) << (v % 64) + bc.bitmap[i] |= mask + } + for k := 0; k < len(ac.content); k++ { + v := ac.content[k] + i := uint(v) >> 6 + mask := uint64(1) << (v % 64) + bc.bitmap[i] |= mask + } + bc.cardinality = invalidCardinality + return bc + } + answer := newArrayContainerCapacity(maxPossibleCardinality) + nl := union2by2(value1.content, value2.content, answer.content) + answer.content = answer.content[:nl] // reslice to match actual used capacity + return answer +} + +func (ac *arrayContainer) and(a container) container { + switch x := a.(type) { + case *arrayContainer: + return ac.andArray(x) + case *bitmapContainer: + return x.and(ac) + case *runContainer16: + if x.isFull() { + return ac.clone() + } + return x.andArray(ac) + } + panic("unsupported container type") +} + +func (ac *arrayContainer) andCardinality(a container) int { + switch x := a.(type) { + case *arrayContainer: + return ac.andArrayCardinality(x) + case *bitmapContainer: + return x.andCardinality(ac) + case *runContainer16: + return x.andArrayCardinality(ac) + } + panic("unsupported container type") +} + +func (ac *arrayContainer) intersects(a container) bool { + switch x := a.(type) { + case *arrayContainer: + return ac.intersectsArray(x) + case *bitmapContainer: + return x.intersects(ac) + case *runContainer16: + return x.intersects(ac) + } + panic("unsupported container type") +} + +func (ac *arrayContainer) iand(a container) container { + switch x := a.(type) { + case *arrayContainer: + return ac.iandArray(x) + case *bitmapContainer: + return ac.iandBitmap(x) + case *runContainer16: + if x.isFull() { + return ac + } + return x.andArray(ac) + } + panic("unsupported container type") +} + +func (ac *arrayContainer) iandBitmap(bc *bitmapContainer) container { + pos := 0 + c := ac.getCardinality() + for k := 0; k < c; k++ { + // branchless + v := ac.content[k] + ac.content[pos] = v + pos += int(bc.bitValue(v)) + } + ac.content = ac.content[:pos] + return ac + +} + +func (ac *arrayContainer) xor(a container) container { + switch x := a.(type) { + case *arrayContainer: + return ac.xorArray(x) + case *bitmapContainer: + return a.xor(ac) + case *runContainer16: + return x.xorArray(ac) + } + panic("unsupported container type") +} + +func (ac *arrayContainer) xorArray(value2 *arrayContainer) container { + value1 := ac + totalCardinality := value1.getCardinality() + value2.getCardinality() + if totalCardinality > arrayDefaultMaxSize { // it could be a bitmap! + bc := newBitmapContainer() + for k := 0; k < len(value2.content); k++ { + v := value2.content[k] + i := uint(v) >> 6 + bc.bitmap[i] ^= (uint64(1) << (v % 64)) + } + for k := 0; k < len(ac.content); k++ { + v := ac.content[k] + i := uint(v) >> 6 + bc.bitmap[i] ^= (uint64(1) << (v % 64)) + } + bc.computeCardinality() + if bc.cardinality <= arrayDefaultMaxSize { + return bc.toArrayContainer() + } + return bc + } + desiredCapacity := totalCardinality + answer := newArrayContainerCapacity(desiredCapacity) + length := exclusiveUnion2by2(value1.content, value2.content, answer.content) + answer.content = answer.content[:length] + return answer + +} + +func (ac *arrayContainer) andNot(a container) container { + switch x := a.(type) { + case *arrayContainer: + return ac.andNotArray(x) + case *bitmapContainer: + return ac.andNotBitmap(x) + case *runContainer16: + return ac.andNotRun16(x) + } + panic("unsupported container type") +} + +func (ac *arrayContainer) andNotRun16(rc *runContainer16) container { + acb := ac.toBitmapContainer() + rcb := rc.toBitmapContainer() + return acb.andNotBitmap(rcb) +} + +func (ac *arrayContainer) iandNot(a container) container { + switch x := a.(type) { + case *arrayContainer: + return ac.iandNotArray(x) + case *bitmapContainer: + return ac.iandNotBitmap(x) + case *runContainer16: + return ac.iandNotRun16(x) + } + panic("unsupported container type") +} + +func (ac *arrayContainer) iandNotRun16(rc *runContainer16) container { + rcb := rc.toBitmapContainer() + acb := ac.toBitmapContainer() + acb.iandNotBitmapSurely(rcb) + *ac = *(acb.toArrayContainer()) + return ac +} + +func (ac *arrayContainer) andNotArray(value2 *arrayContainer) container { + value1 := ac + desiredcapacity := value1.getCardinality() + answer := newArrayContainerCapacity(desiredcapacity) + length := difference(value1.content, value2.content, answer.content) + answer.content = answer.content[:length] + return answer +} + +func (ac *arrayContainer) iandNotArray(value2 *arrayContainer) container { + length := difference(ac.content, value2.content, ac.content) + ac.content = ac.content[:length] + return ac +} + +func (ac *arrayContainer) andNotBitmap(value2 *bitmapContainer) container { + desiredcapacity := ac.getCardinality() + answer := newArrayContainerCapacity(desiredcapacity) + answer.content = answer.content[:desiredcapacity] + pos := 0 + for _, v := range ac.content { + answer.content[pos] = v + pos += 1 - int(value2.bitValue(v)) + } + answer.content = answer.content[:pos] + return answer +} + +func (ac *arrayContainer) andBitmap(value2 *bitmapContainer) container { + desiredcapacity := ac.getCardinality() + answer := newArrayContainerCapacity(desiredcapacity) + answer.content = answer.content[:desiredcapacity] + pos := 0 + for _, v := range ac.content { + answer.content[pos] = v + pos += int(value2.bitValue(v)) + } + answer.content = answer.content[:pos] + return answer +} + +func (ac *arrayContainer) iandNotBitmap(value2 *bitmapContainer) container { + pos := 0 + for _, v := range ac.content { + ac.content[pos] = v + pos += 1 - int(value2.bitValue(v)) + } + ac.content = ac.content[:pos] + return ac +} + +func copyOf(array []uint16, size int) []uint16 { + result := make([]uint16, size) + for i, x := range array { + if i == size { + break + } + result[i] = x + } + return result +} + +// flip the values in the range [firstOfRange,endx) +func (ac *arrayContainer) inot(firstOfRange, endx int) container { + if firstOfRange >= endx { + return ac + } + return ac.inotClose(firstOfRange, endx-1) // remove everything in [firstOfRange,endx-1] +} + +// flip the values in the range [firstOfRange,lastOfRange] +func (ac *arrayContainer) inotClose(firstOfRange, lastOfRange int) container { + if firstOfRange > lastOfRange { // unlike add and remove, not uses an inclusive range [firstOfRange,lastOfRange] + return ac + } + // determine the span of array indices to be affected + startIndex := binarySearch(ac.content, uint16(firstOfRange)) + if startIndex < 0 { + startIndex = -startIndex - 1 + } + lastIndex := binarySearch(ac.content, uint16(lastOfRange)) + if lastIndex < 0 { + lastIndex = -lastIndex - 1 - 1 + } + currentValuesInRange := lastIndex - startIndex + 1 + spanToBeFlipped := lastOfRange - firstOfRange + 1 + + newValuesInRange := spanToBeFlipped - currentValuesInRange + buffer := make([]uint16, newValuesInRange) + cardinalityChange := newValuesInRange - currentValuesInRange + newCardinality := len(ac.content) + cardinalityChange + if cardinalityChange > 0 { + if newCardinality > len(ac.content) { + if newCardinality > arrayDefaultMaxSize { + bcRet := ac.toBitmapContainer() + bcRet.inot(firstOfRange, lastOfRange+1) + *ac = *bcRet.toArrayContainer() + return bcRet + } + ac.content = copyOf(ac.content, newCardinality) + } + base := lastIndex + 1 + copy(ac.content[lastIndex+1+cardinalityChange:], ac.content[base:base+len(ac.content)-1-lastIndex]) + ac.negateRange(buffer, startIndex, lastIndex, firstOfRange, lastOfRange+1) + } else { // no expansion needed + ac.negateRange(buffer, startIndex, lastIndex, firstOfRange, lastOfRange+1) + if cardinalityChange < 0 { + + for i := startIndex + newValuesInRange; i < newCardinality; i++ { + ac.content[i] = ac.content[i-cardinalityChange] + } + } + } + ac.content = ac.content[:newCardinality] + return ac +} + +func (ac *arrayContainer) negateRange(buffer []uint16, startIndex, lastIndex, startRange, lastRange int) { + // compute the negation into buffer + outPos := 0 + inPos := startIndex // value here always >= valInRange, + // until it is exhausted + // n.b., we can start initially exhausted. + + valInRange := startRange + for ; valInRange < lastRange && inPos <= lastIndex; valInRange++ { + if uint16(valInRange) != ac.content[inPos] { + buffer[outPos] = uint16(valInRange) + outPos++ + } else { + inPos++ + } + } + + // if there are extra items (greater than the biggest + // pre-existing one in range), buffer them + for ; valInRange < lastRange; valInRange++ { + buffer[outPos] = uint16(valInRange) + outPos++ + } + + if outPos != len(buffer) { + panic("negateRange: internal bug") + } + + for i, item := range buffer { + ac.content[i+startIndex] = item + } +} + +func (ac *arrayContainer) isFull() bool { + return false +} + +func (ac *arrayContainer) andArray(value2 *arrayContainer) container { + desiredcapacity := minOfInt(ac.getCardinality(), value2.getCardinality()) + answer := newArrayContainerCapacity(desiredcapacity) + length := intersection2by2( + ac.content, + value2.content, + answer.content) + answer.content = answer.content[:length] + return answer +} + +func (ac *arrayContainer) andArrayCardinality(value2 *arrayContainer) int { + return intersection2by2Cardinality( + ac.content, + value2.content) +} + +func (ac *arrayContainer) intersectsArray(value2 *arrayContainer) bool { + return intersects2by2( + ac.content, + value2.content) +} + +func (ac *arrayContainer) iandArray(value2 *arrayContainer) container { + length := intersection2by2( + ac.content, + value2.content, + ac.content) + ac.content = ac.content[:length] + return ac +} + +func (ac *arrayContainer) getCardinality() int { + return len(ac.content) +} + +func (ac *arrayContainer) isEmpty() bool { + return len(ac.content) == 0 +} + +func (ac *arrayContainer) rank(x uint16) int { + answer := binarySearch(ac.content, x) + if answer >= 0 { + return answer + 1 + } + return -answer - 1 + +} + +func (ac *arrayContainer) selectInt(x uint16) int { + return int(ac.content[x]) +} + +func (ac *arrayContainer) clone() container { + ptr := arrayContainer{make([]uint16, len(ac.content))} + copy(ptr.content, ac.content[:]) + return &ptr +} + +func (ac *arrayContainer) contains(x uint16) bool { + return binarySearch(ac.content, x) >= 0 +} + +func (ac *arrayContainer) loadData(bitmapContainer *bitmapContainer) { + ac.content = make([]uint16, bitmapContainer.cardinality, bitmapContainer.cardinality) + bitmapContainer.fillArray(ac.content) +} + +func (ac *arrayContainer) resetTo(a container) { + switch x := a.(type) { + case *arrayContainer: + ac.realloc(len(x.content)) + copy(ac.content, x.content) + + case *bitmapContainer: + ac.realloc(x.cardinality) + x.fillArray(ac.content) + + case *runContainer16: + card := int(x.getCardinality()) + ac.realloc(card) + cur := 0 + for _, r := range x.iv { + for val := r.start; val <= r.last(); val++ { + ac.content[cur] = val + cur++ + } + } + + default: + panic("unsupported container type") + } +} + +func (ac *arrayContainer) realloc(size int) { + if cap(ac.content) < size { + ac.content = make([]uint16, size) + } else { + ac.content = ac.content[:size] + } +} + +func newArrayContainer() *arrayContainer { + p := new(arrayContainer) + return p +} + +func newArrayContainerFromBitmap(bc *bitmapContainer) *arrayContainer { + ac := &arrayContainer{} + ac.loadData(bc) + return ac +} + +func newArrayContainerCapacity(size int) *arrayContainer { + p := new(arrayContainer) + p.content = make([]uint16, 0, size) + return p +} + +func newArrayContainerSize(size int) *arrayContainer { + p := new(arrayContainer) + p.content = make([]uint16, size, size) + return p +} + +func newArrayContainerRange(firstOfRun, lastOfRun int) *arrayContainer { + valuesInRange := lastOfRun - firstOfRun + 1 + this := newArrayContainerCapacity(valuesInRange) + for i := 0; i < valuesInRange; i++ { + this.content = append(this.content, uint16(firstOfRun+i)) + } + return this +} + +func (ac *arrayContainer) numberOfRuns() (nr int) { + n := len(ac.content) + var runlen uint16 + var cur, prev uint16 + + switch n { + case 0: + return 0 + case 1: + return 1 + default: + for i := 1; i < n; i++ { + prev = ac.content[i-1] + cur = ac.content[i] + + if cur == prev+1 { + runlen++ + } else { + if cur < prev { + panic("the fundamental arrayContainer assumption of sorted ac.content was broken") + } + if cur == prev { + panic("the fundamental arrayContainer assumption of deduplicated content was broken") + } else { + nr++ + runlen = 0 + } + } + } + nr++ + } + return +} + +// convert to run or array *if needed* +func (ac *arrayContainer) toEfficientContainer() container { + + numRuns := ac.numberOfRuns() + + sizeAsRunContainer := runContainer16SerializedSizeInBytes(numRuns) + sizeAsBitmapContainer := bitmapContainerSizeInBytes() + card := ac.getCardinality() + sizeAsArrayContainer := arrayContainerSizeInBytes(card) + + if sizeAsRunContainer <= minOfInt(sizeAsBitmapContainer, sizeAsArrayContainer) { + return newRunContainer16FromArray(ac) + } + if card <= arrayDefaultMaxSize { + return ac + } + return ac.toBitmapContainer() +} + +func (ac *arrayContainer) containerType() contype { + return arrayContype +} + +func (ac *arrayContainer) addOffset(x uint16) []container { + low := &arrayContainer{} + high := &arrayContainer{} + for _, val := range ac.content { + y := uint32(val) + uint32(x) + if highbits(y) > 0 { + high.content = append(high.content, lowbits(y)) + } else { + low.content = append(low.content, lowbits(y)) + } + } + return []container{low, high} +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/bitmapcontainer.go b/backend/vendor/github.com/RoaringBitmap/roaring/bitmapcontainer.go new file mode 100644 index 0000000000..f8367da0e5 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/bitmapcontainer.go @@ -0,0 +1,1154 @@ +package roaring + +import ( + "fmt" + "unsafe" +) + +type bitmapContainer struct { + cardinality int + bitmap []uint64 +} + +func (bc bitmapContainer) String() string { + var s string + for it := bc.getShortIterator(); it.hasNext(); { + s += fmt.Sprintf("%v, ", it.next()) + } + return s +} + +func newBitmapContainer() *bitmapContainer { + p := new(bitmapContainer) + size := (1 << 16) / 64 + p.bitmap = make([]uint64, size, size) + return p +} + +func newBitmapContainerwithRange(firstOfRun, lastOfRun int) *bitmapContainer { + bc := newBitmapContainer() + bc.cardinality = lastOfRun - firstOfRun + 1 + if bc.cardinality == maxCapacity { + fill(bc.bitmap, uint64(0xffffffffffffffff)) + } else { + firstWord := firstOfRun / 64 + lastWord := lastOfRun / 64 + zeroPrefixLength := uint64(firstOfRun & 63) + zeroSuffixLength := uint64(63 - (lastOfRun & 63)) + + fillRange(bc.bitmap, firstWord, lastWord+1, uint64(0xffffffffffffffff)) + bc.bitmap[firstWord] ^= ((uint64(1) << zeroPrefixLength) - 1) + blockOfOnes := (uint64(1) << zeroSuffixLength) - 1 + maskOnLeft := blockOfOnes << (uint64(64) - zeroSuffixLength) + bc.bitmap[lastWord] ^= maskOnLeft + } + return bc +} + +func (bc *bitmapContainer) minimum() uint16 { + for i := 0; i < len(bc.bitmap); i++ { + w := bc.bitmap[i] + if w != 0 { + r := countTrailingZeros(w) + return uint16(r + i*64) + } + } + return MaxUint16 +} + +// i should be non-zero +func clz(i uint64) int { + n := 1 + x := uint32(i >> 32) + if x == 0 { + n += 32 + x = uint32(i) + } + if x>>16 == 0 { + n += 16 + x = x << 16 + } + if x>>24 == 0 { + n += 8 + x = x << 8 + } + if x>>28 == 0 { + n += 4 + x = x << 4 + } + if x>>30 == 0 { + n += 2 + x = x << 2 + } + return n - int(x>>31) +} + +func (bc *bitmapContainer) maximum() uint16 { + for i := len(bc.bitmap); i > 0; i-- { + w := bc.bitmap[i-1] + if w != 0 { + r := clz(w) + return uint16((i-1)*64 + 63 - r) + } + } + return uint16(0) +} + +func (bc *bitmapContainer) iterate(cb func(x uint16) bool) bool { + iterator := bitmapContainerShortIterator{bc, bc.NextSetBit(0)} + + for iterator.hasNext() { + if !cb(iterator.next()) { + return false + } + } + + return true +} + +type bitmapContainerShortIterator struct { + ptr *bitmapContainer + i int +} + +func (bcsi *bitmapContainerShortIterator) next() uint16 { + j := bcsi.i + bcsi.i = bcsi.ptr.NextSetBit(uint(bcsi.i) + 1) + return uint16(j) +} +func (bcsi *bitmapContainerShortIterator) hasNext() bool { + return bcsi.i >= 0 +} + +func (bcsi *bitmapContainerShortIterator) peekNext() uint16 { + return uint16(bcsi.i) +} + +func (bcsi *bitmapContainerShortIterator) advanceIfNeeded(minval uint16) { + if bcsi.hasNext() && bcsi.peekNext() < minval { + bcsi.i = bcsi.ptr.NextSetBit(uint(minval)) + } +} + +func newBitmapContainerShortIterator(a *bitmapContainer) *bitmapContainerShortIterator { + return &bitmapContainerShortIterator{a, a.NextSetBit(0)} +} + +func (bc *bitmapContainer) getShortIterator() shortPeekable { + return newBitmapContainerShortIterator(bc) +} + +type reverseBitmapContainerShortIterator struct { + ptr *bitmapContainer + i int +} + +func (bcsi *reverseBitmapContainerShortIterator) next() uint16 { + if bcsi.i == -1 { + panic("reverseBitmapContainerShortIterator.next() going beyond what is available") + } + + j := bcsi.i + bcsi.i = bcsi.ptr.PrevSetBit(bcsi.i - 1) + return uint16(j) +} + +func (bcsi *reverseBitmapContainerShortIterator) hasNext() bool { + return bcsi.i >= 0 +} + +func newReverseBitmapContainerShortIterator(a *bitmapContainer) *reverseBitmapContainerShortIterator { + if a.cardinality == 0 { + return &reverseBitmapContainerShortIterator{a, -1} + } + return &reverseBitmapContainerShortIterator{a, int(a.maximum())} +} + +func (bc *bitmapContainer) getReverseIterator() shortIterable { + return newReverseBitmapContainerShortIterator(bc) +} + +type bitmapContainerManyIterator struct { + ptr *bitmapContainer + base int + bitset uint64 +} + +func (bcmi *bitmapContainerManyIterator) nextMany(hs uint32, buf []uint32) int { + n := 0 + base := bcmi.base + bitset := bcmi.bitset + + for n < len(buf) { + if bitset == 0 { + base++ + if base >= len(bcmi.ptr.bitmap) { + bcmi.base = base + bcmi.bitset = bitset + return n + } + bitset = bcmi.ptr.bitmap[base] + continue + } + t := bitset & -bitset + buf[n] = uint32(((base * 64) + int(popcount(t-1)))) | hs + n = n + 1 + bitset ^= t + } + + bcmi.base = base + bcmi.bitset = bitset + return n +} + +func (bcmi *bitmapContainerManyIterator) nextMany64(hs uint64, buf []uint64) int { + n := 0 + base := bcmi.base + bitset := bcmi.bitset + + for n < len(buf) { + if bitset == 0 { + base++ + if base >= len(bcmi.ptr.bitmap) { + bcmi.base = base + bcmi.bitset = bitset + return n + } + bitset = bcmi.ptr.bitmap[base] + continue + } + t := bitset & -bitset + buf[n] = uint64(((base * 64) + int(popcount(t-1)))) | hs + n = n + 1 + bitset ^= t + } + + bcmi.base = base + bcmi.bitset = bitset + return n +} + +func newBitmapContainerManyIterator(a *bitmapContainer) *bitmapContainerManyIterator { + return &bitmapContainerManyIterator{a, -1, 0} +} + +func (bc *bitmapContainer) getManyIterator() manyIterable { + return newBitmapContainerManyIterator(bc) +} + +func (bc *bitmapContainer) getSizeInBytes() int { + return len(bc.bitmap) * 8 // + bcBaseBytes +} + +func (bc *bitmapContainer) serializedSizeInBytes() int { + //return bc.Msgsize()// NOO! This breaks GetSerializedSizeInBytes + return len(bc.bitmap) * 8 +} + +const bcBaseBytes = int(unsafe.Sizeof(bitmapContainer{})) + +// bitmapContainer doesn't depend on card, always fully allocated +func bitmapContainerSizeInBytes() int { + return bcBaseBytes + (1<<16)/8 +} + +func bitmapEquals(a, b []uint64) bool { + if len(a) != len(b) { + return false + } + for i, v := range a { + if v != b[i] { + return false + } + } + return true +} + +func (bc *bitmapContainer) fillLeastSignificant16bits(x []uint32, i int, mask uint32) int { + // TODO: should be written as optimized assembly + pos := i + base := mask + for k := 0; k < len(bc.bitmap); k++ { + bitset := bc.bitmap[k] + for bitset != 0 { + t := bitset & -bitset + x[pos] = base + uint32(popcount(t-1)) + pos++ + bitset ^= t + } + base += 64 + } + return pos +} + +func (bc *bitmapContainer) equals(o container) bool { + srb, ok := o.(*bitmapContainer) + if ok { + if srb.cardinality != bc.cardinality { + return false + } + return bitmapEquals(bc.bitmap, srb.bitmap) + } + + // use generic comparison + if bc.getCardinality() != o.getCardinality() { + return false + } + ait := o.getShortIterator() + bit := bc.getShortIterator() + + for ait.hasNext() { + if bit.next() != ait.next() { + return false + } + } + return true +} + +func (bc *bitmapContainer) iaddReturnMinimized(i uint16) container { + bc.iadd(i) + if bc.isFull() { + return newRunContainer16Range(0, MaxUint16) + } + return bc +} + +func (bc *bitmapContainer) iadd(i uint16) bool { + x := int(i) + previous := bc.bitmap[x/64] + mask := uint64(1) << (uint(x) % 64) + newb := previous | mask + bc.bitmap[x/64] = newb + bc.cardinality += int((previous ^ newb) >> (uint(x) % 64)) + return newb != previous +} + +func (bc *bitmapContainer) iremoveReturnMinimized(i uint16) container { + if bc.iremove(i) { + if bc.cardinality == arrayDefaultMaxSize { + return bc.toArrayContainer() + } + } + return bc +} + +// iremove returns true if i was found. +func (bc *bitmapContainer) iremove(i uint16) bool { + if bc.contains(i) { + bc.cardinality-- + bc.bitmap[i/64] &^= (uint64(1) << (i % 64)) + return true + } + return false +} + +func (bc *bitmapContainer) isFull() bool { + return bc.cardinality == int(MaxUint16)+1 +} + +func (bc *bitmapContainer) getCardinality() int { + return bc.cardinality +} + + +func (bc *bitmapContainer) isEmpty() bool { + return bc.cardinality == 0 +} + +func (bc *bitmapContainer) clone() container { + ptr := bitmapContainer{bc.cardinality, make([]uint64, len(bc.bitmap))} + copy(ptr.bitmap, bc.bitmap[:]) + return &ptr +} + +// add all values in range [firstOfRange,lastOfRange) +func (bc *bitmapContainer) iaddRange(firstOfRange, lastOfRange int) container { + bc.cardinality += setBitmapRangeAndCardinalityChange(bc.bitmap, firstOfRange, lastOfRange) + return bc +} + +// remove all values in range [firstOfRange,lastOfRange) +func (bc *bitmapContainer) iremoveRange(firstOfRange, lastOfRange int) container { + bc.cardinality += resetBitmapRangeAndCardinalityChange(bc.bitmap, firstOfRange, lastOfRange) + if bc.getCardinality() <= arrayDefaultMaxSize { + return bc.toArrayContainer() + } + return bc +} + +// flip all values in range [firstOfRange,endx) +func (bc *bitmapContainer) inot(firstOfRange, endx int) container { + if endx-firstOfRange == maxCapacity { + flipBitmapRange(bc.bitmap, firstOfRange, endx) + bc.cardinality = maxCapacity - bc.cardinality + } else if endx-firstOfRange > maxCapacity/2 { + flipBitmapRange(bc.bitmap, firstOfRange, endx) + bc.computeCardinality() + } else { + bc.cardinality += flipBitmapRangeAndCardinalityChange(bc.bitmap, firstOfRange, endx) + } + if bc.getCardinality() <= arrayDefaultMaxSize { + return bc.toArrayContainer() + } + return bc +} + +// flip all values in range [firstOfRange,endx) +func (bc *bitmapContainer) not(firstOfRange, endx int) container { + answer := bc.clone() + return answer.inot(firstOfRange, endx) +} + +func (bc *bitmapContainer) or(a container) container { + switch x := a.(type) { + case *arrayContainer: + return bc.orArray(x) + case *bitmapContainer: + return bc.orBitmap(x) + case *runContainer16: + if x.isFull() { + return x.clone() + } + return x.orBitmapContainer(bc) + } + panic("unsupported container type") +} + +func (bc *bitmapContainer) orCardinality(a container) int { + switch x := a.(type) { + case *arrayContainer: + return bc.orArrayCardinality(x) + case *bitmapContainer: + return bc.orBitmapCardinality(x) + case *runContainer16: + return x.orBitmapContainerCardinality(bc) + } + panic("unsupported container type") +} + +func (bc *bitmapContainer) ior(a container) container { + switch x := a.(type) { + case *arrayContainer: + return bc.iorArray(x) + case *bitmapContainer: + return bc.iorBitmap(x) + case *runContainer16: + if x.isFull() { + return x.clone() + } + for i := range x.iv { + bc.iaddRange(int(x.iv[i].start), int(x.iv[i].last())+1) + } + if bc.isFull() { + return newRunContainer16Range(0, MaxUint16) + } + //bc.computeCardinality() + return bc + } + panic(fmt.Errorf("unsupported container type %T", a)) +} + +func (bc *bitmapContainer) lazyIOR(a container) container { + switch x := a.(type) { + case *arrayContainer: + return bc.lazyIORArray(x) + case *bitmapContainer: + return bc.lazyIORBitmap(x) + case *runContainer16: + if x.isFull() { + return x.clone() + } + + // Manually inlined setBitmapRange function + bitmap := bc.bitmap + for _, iv := range x.iv { + start := int(iv.start) + end := int(iv.last()) + 1 + if start >= end { + continue + } + firstword := start / 64 + endword := (end - 1) / 64 + if firstword == endword { + bitmap[firstword] |= (^uint64(0) << uint(start%64)) & (^uint64(0) >> (uint(-end) % 64)) + continue + } + bitmap[firstword] |= ^uint64(0) << uint(start%64) + for i := firstword + 1; i < endword; i++ { + bitmap[i] = ^uint64(0) + } + bitmap[endword] |= ^uint64(0) >> (uint(-end) % 64) + } + bc.cardinality = invalidCardinality + return bc + } + panic("unsupported container type") +} + +func (bc *bitmapContainer) lazyOR(a container) container { + switch x := a.(type) { + case *arrayContainer: + return bc.lazyORArray(x) + case *bitmapContainer: + return bc.lazyORBitmap(x) + case *runContainer16: + if x.isFull() { + return x.clone() + } + // TODO: implement lazy OR + return x.orBitmapContainer(bc) + + } + panic("unsupported container type") +} + +func (bc *bitmapContainer) orArray(value2 *arrayContainer) container { + answer := bc.clone().(*bitmapContainer) + c := value2.getCardinality() + for k := 0; k < c; k++ { + v := value2.content[k] + i := uint(v) >> 6 + bef := answer.bitmap[i] + aft := bef | (uint64(1) << (v % 64)) + answer.bitmap[i] = aft + answer.cardinality += int((bef - aft) >> 63) + } + return answer +} + +func (bc *bitmapContainer) orArrayCardinality(value2 *arrayContainer) int { + answer := 0 + c := value2.getCardinality() + for k := 0; k < c; k++ { + // branchless: + v := value2.content[k] + i := uint(v) >> 6 + bef := bc.bitmap[i] + aft := bef | (uint64(1) << (v % 64)) + answer += int((bef - aft) >> 63) + } + return answer +} + +func (bc *bitmapContainer) orBitmap(value2 *bitmapContainer) container { + answer := newBitmapContainer() + for k := 0; k < len(answer.bitmap); k++ { + answer.bitmap[k] = bc.bitmap[k] | value2.bitmap[k] + } + answer.computeCardinality() + if answer.isFull() { + return newRunContainer16Range(0, MaxUint16) + } + return answer +} + +func (bc *bitmapContainer) orBitmapCardinality(value2 *bitmapContainer) int { + return int(popcntOrSlice(bc.bitmap, value2.bitmap)) +} + +func (bc *bitmapContainer) andBitmapCardinality(value2 *bitmapContainer) int { + return int(popcntAndSlice(bc.bitmap, value2.bitmap)) +} + +func (bc *bitmapContainer) computeCardinality() { + bc.cardinality = int(popcntSlice(bc.bitmap)) +} + +func (bc *bitmapContainer) iorArray(ac *arrayContainer) container { + for k := range ac.content { + vc := ac.content[k] + i := uint(vc) >> 6 + bef := bc.bitmap[i] + aft := bef | (uint64(1) << (vc % 64)) + bc.bitmap[i] = aft + bc.cardinality += int((bef - aft) >> 63) + } + if bc.isFull() { + return newRunContainer16Range(0, MaxUint16) + } + return bc +} + +func (bc *bitmapContainer) iorBitmap(value2 *bitmapContainer) container { + answer := bc + answer.cardinality = 0 + for k := 0; k < len(answer.bitmap); k++ { + answer.bitmap[k] = bc.bitmap[k] | value2.bitmap[k] + } + answer.computeCardinality() + if bc.isFull() { + return newRunContainer16Range(0, MaxUint16) + } + return answer +} + +func (bc *bitmapContainer) lazyIORArray(value2 *arrayContainer) container { + answer := bc + c := value2.getCardinality() + for k := 0; k+3 < c; k += 4 { + content := (*[4]uint16)(unsafe.Pointer(&value2.content[k])) + vc0 := content[0] + i0 := uint(vc0) >> 6 + answer.bitmap[i0] = answer.bitmap[i0] | (uint64(1) << (vc0 % 64)) + + vc1 := content[1] + i1 := uint(vc1) >> 6 + answer.bitmap[i1] = answer.bitmap[i1] | (uint64(1) << (vc1 % 64)) + + vc2 := content[2] + i2 := uint(vc2) >> 6 + answer.bitmap[i2] = answer.bitmap[i2] | (uint64(1) << (vc2 % 64)) + + vc3 := content[3] + i3 := uint(vc3) >> 6 + answer.bitmap[i3] = answer.bitmap[i3] | (uint64(1) << (vc3 % 64)) + } + + for k := c &^ 3; k < c; k++ { + vc := value2.content[k] + i := uint(vc) >> 6 + answer.bitmap[i] = answer.bitmap[i] | (uint64(1) << (vc % 64)) + } + + answer.cardinality = invalidCardinality + return answer +} + +func (bc *bitmapContainer) lazyORArray(value2 *arrayContainer) container { + answer := bc.clone().(*bitmapContainer) + return answer.lazyIORArray(value2) +} + +func (bc *bitmapContainer) lazyIORBitmap(value2 *bitmapContainer) container { + answer := bc + for k := 0; k < len(answer.bitmap); k++ { + answer.bitmap[k] = bc.bitmap[k] | value2.bitmap[k] + } + bc.cardinality = invalidCardinality + return answer +} + +func (bc *bitmapContainer) lazyORBitmap(value2 *bitmapContainer) container { + answer := bc.clone().(*bitmapContainer) + return answer.lazyIORBitmap(value2) +} + +func (bc *bitmapContainer) xor(a container) container { + switch x := a.(type) { + case *arrayContainer: + return bc.xorArray(x) + case *bitmapContainer: + return bc.xorBitmap(x) + case *runContainer16: + return x.xorBitmap(bc) + } + panic("unsupported container type") +} + +func (bc *bitmapContainer) xorArray(value2 *arrayContainer) container { + answer := bc.clone().(*bitmapContainer) + c := value2.getCardinality() + for k := 0; k < c; k++ { + vc := value2.content[k] + index := uint(vc) >> 6 + abi := answer.bitmap[index] + mask := uint64(1) << (vc % 64) + answer.cardinality += 1 - 2*int((abi&mask)>>(vc%64)) + answer.bitmap[index] = abi ^ mask + } + if answer.cardinality <= arrayDefaultMaxSize { + return answer.toArrayContainer() + } + return answer +} + +func (bc *bitmapContainer) rank(x uint16) int { + // TODO: rewrite in assembly + leftover := (uint(x) + 1) & 63 + if leftover == 0 { + return int(popcntSlice(bc.bitmap[:(uint(x)+1)/64])) + } + return int(popcntSlice(bc.bitmap[:(uint(x)+1)/64]) + popcount(bc.bitmap[(uint(x)+1)/64]<<(64-leftover))) +} + +func (bc *bitmapContainer) selectInt(x uint16) int { + remaining := x + for k := 0; k < len(bc.bitmap); k++ { + w := popcount(bc.bitmap[k]) + if uint16(w) > remaining { + return k*64 + selectBitPosition(bc.bitmap[k], int(remaining)) + } + remaining -= uint16(w) + } + return -1 +} + +func (bc *bitmapContainer) xorBitmap(value2 *bitmapContainer) container { + newCardinality := int(popcntXorSlice(bc.bitmap, value2.bitmap)) + + if newCardinality > arrayDefaultMaxSize { + answer := newBitmapContainer() + for k := 0; k < len(answer.bitmap); k++ { + answer.bitmap[k] = bc.bitmap[k] ^ value2.bitmap[k] + } + answer.cardinality = newCardinality + if answer.isFull() { + return newRunContainer16Range(0, MaxUint16) + } + return answer + } + ac := newArrayContainerSize(newCardinality) + fillArrayXOR(ac.content, bc.bitmap, value2.bitmap) + ac.content = ac.content[:newCardinality] + return ac +} + +func (bc *bitmapContainer) and(a container) container { + switch x := a.(type) { + case *arrayContainer: + return bc.andArray(x) + case *bitmapContainer: + return bc.andBitmap(x) + case *runContainer16: + if x.isFull() { + return bc.clone() + } + return x.andBitmapContainer(bc) + } + panic("unsupported container type") +} + +func (bc *bitmapContainer) andCardinality(a container) int { + switch x := a.(type) { + case *arrayContainer: + return bc.andArrayCardinality(x) + case *bitmapContainer: + return bc.andBitmapCardinality(x) + case *runContainer16: + return x.andBitmapContainerCardinality(bc) + } + panic("unsupported container type") +} + +func (bc *bitmapContainer) intersects(a container) bool { + switch x := a.(type) { + case *arrayContainer: + return bc.intersectsArray(x) + case *bitmapContainer: + return bc.intersectsBitmap(x) + case *runContainer16: + return x.intersects(bc) + + } + panic("unsupported container type") +} + +func (bc *bitmapContainer) iand(a container) container { + switch x := a.(type) { + case *arrayContainer: + return bc.iandArray(x) + case *bitmapContainer: + return bc.iandBitmap(x) + case *runContainer16: + if x.isFull() { + return bc.clone() + } + return bc.iandRun16(x) + } + panic("unsupported container type") +} + +func (bc *bitmapContainer) iandRun16(rc *runContainer16) container { + rcb := newBitmapContainerFromRun(rc) + return bc.iandBitmap(rcb) +} + +func (bc *bitmapContainer) iandArray(ac *arrayContainer) container { + acb := ac.toBitmapContainer() + return bc.iandBitmap(acb) +} + +func (bc *bitmapContainer) andArray(value2 *arrayContainer) *arrayContainer { + answer := newArrayContainerCapacity(len(value2.content)) + answer.content = answer.content[:cap(answer.content)] + c := value2.getCardinality() + pos := 0 + for k := 0; k < c; k++ { + v := value2.content[k] + answer.content[pos] = v + pos += int(bc.bitValue(v)) + } + answer.content = answer.content[:pos] + return answer +} + +func (bc *bitmapContainer) andArrayCardinality(value2 *arrayContainer) int { + c := value2.getCardinality() + pos := 0 + for k := 0; k < c; k++ { + v := value2.content[k] + pos += int(bc.bitValue(v)) + } + return pos +} + +func (bc *bitmapContainer) getCardinalityInRange(start, end uint) int { + if start >= end { + return 0 + } + firstword := start / 64 + endword := (end - 1) / 64 + const allones = ^uint64(0) + if firstword == endword { + return int(popcount(bc.bitmap[firstword] & ((allones << (start % 64)) & (allones >> ((64 - end) & 63))))) + } + answer := popcount(bc.bitmap[firstword] & (allones << (start % 64))) + answer += popcntSlice(bc.bitmap[firstword+1 : endword]) + answer += popcount(bc.bitmap[endword] & (allones >> ((64 - end) & 63))) + return int(answer) +} + +func (bc *bitmapContainer) andBitmap(value2 *bitmapContainer) container { + newcardinality := int(popcntAndSlice(bc.bitmap, value2.bitmap)) + if newcardinality > arrayDefaultMaxSize { + answer := newBitmapContainer() + for k := 0; k < len(answer.bitmap); k++ { + answer.bitmap[k] = bc.bitmap[k] & value2.bitmap[k] + } + answer.cardinality = newcardinality + return answer + } + ac := newArrayContainerSize(newcardinality) + fillArrayAND(ac.content, bc.bitmap, value2.bitmap) + ac.content = ac.content[:newcardinality] //not sure why i need this + return ac + +} + +func (bc *bitmapContainer) intersectsArray(value2 *arrayContainer) bool { + c := value2.getCardinality() + for k := 0; k < c; k++ { + v := value2.content[k] + if bc.contains(v) { + return true + } + } + return false +} + +func (bc *bitmapContainer) intersectsBitmap(value2 *bitmapContainer) bool { + for k := 0; k < len(bc.bitmap); k++ { + if (bc.bitmap[k] & value2.bitmap[k]) != 0 { + return true + } + } + return false + +} + +func (bc *bitmapContainer) iandBitmap(value2 *bitmapContainer) container { + newcardinality := int(popcntAndSlice(bc.bitmap, value2.bitmap)) + for k := 0; k < len(bc.bitmap); k++ { + bc.bitmap[k] = bc.bitmap[k] & value2.bitmap[k] + } + bc.cardinality = newcardinality + + if newcardinality <= arrayDefaultMaxSize { + return newArrayContainerFromBitmap(bc) + } + return bc +} + +func (bc *bitmapContainer) andNot(a container) container { + switch x := a.(type) { + case *arrayContainer: + return bc.andNotArray(x) + case *bitmapContainer: + return bc.andNotBitmap(x) + case *runContainer16: + return bc.andNotRun16(x) + } + panic("unsupported container type") +} + +func (bc *bitmapContainer) andNotRun16(rc *runContainer16) container { + rcb := rc.toBitmapContainer() + return bc.andNotBitmap(rcb) +} + +func (bc *bitmapContainer) iandNot(a container) container { + switch x := a.(type) { + case *arrayContainer: + return bc.iandNotArray(x) + case *bitmapContainer: + return bc.iandNotBitmapSurely(x) + case *runContainer16: + return bc.iandNotRun16(x) + } + panic("unsupported container type") +} + +func (bc *bitmapContainer) iandNotArray(ac *arrayContainer) container { + acb := ac.toBitmapContainer() + return bc.iandNotBitmapSurely(acb) +} + +func (bc *bitmapContainer) iandNotRun16(rc *runContainer16) container { + rcb := rc.toBitmapContainer() + return bc.iandNotBitmapSurely(rcb) +} + +func (bc *bitmapContainer) andNotArray(value2 *arrayContainer) container { + answer := bc.clone().(*bitmapContainer) + c := value2.getCardinality() + for k := 0; k < c; k++ { + vc := value2.content[k] + i := uint(vc) >> 6 + oldv := answer.bitmap[i] + newv := oldv &^ (uint64(1) << (vc % 64)) + answer.bitmap[i] = newv + answer.cardinality -= int((oldv ^ newv) >> (vc % 64)) + } + if answer.cardinality <= arrayDefaultMaxSize { + return answer.toArrayContainer() + } + return answer +} + +func (bc *bitmapContainer) andNotBitmap(value2 *bitmapContainer) container { + newCardinality := int(popcntMaskSlice(bc.bitmap, value2.bitmap)) + if newCardinality > arrayDefaultMaxSize { + answer := newBitmapContainer() + for k := 0; k < len(answer.bitmap); k++ { + answer.bitmap[k] = bc.bitmap[k] &^ value2.bitmap[k] + } + answer.cardinality = newCardinality + return answer + } + ac := newArrayContainerSize(newCardinality) + fillArrayANDNOT(ac.content, bc.bitmap, value2.bitmap) + return ac +} + +func (bc *bitmapContainer) iandNotBitmapSurely(value2 *bitmapContainer) container { + newCardinality := int(popcntMaskSlice(bc.bitmap, value2.bitmap)) + for k := 0; k < len(bc.bitmap); k++ { + bc.bitmap[k] = bc.bitmap[k] &^ value2.bitmap[k] + } + bc.cardinality = newCardinality + if bc.getCardinality() <= arrayDefaultMaxSize { + return bc.toArrayContainer() + } + return bc +} + +func (bc *bitmapContainer) contains(i uint16) bool { //testbit + x := uint(i) + w := bc.bitmap[x>>6] + mask := uint64(1) << (x & 63) + return (w & mask) != 0 +} + +func (bc *bitmapContainer) bitValue(i uint16) uint64 { + x := uint(i) + w := bc.bitmap[x>>6] + return (w >> (x & 63)) & 1 +} + +func (bc *bitmapContainer) loadData(arrayContainer *arrayContainer) { + bc.cardinality = arrayContainer.getCardinality() + c := arrayContainer.getCardinality() + for k := 0; k < c; k++ { + x := arrayContainer.content[k] + i := int(x) / 64 + bc.bitmap[i] |= (uint64(1) << uint(x%64)) + } +} + +func (bc *bitmapContainer) resetTo(a container) { + switch x := a.(type) { + case *arrayContainer: + fill(bc.bitmap, 0) + bc.loadData(x) + + case *bitmapContainer: + bc.cardinality = x.cardinality + copy(bc.bitmap, x.bitmap) + + case *runContainer16: + bc.cardinality = len(x.iv) + lastEnd := 0 + for _, r := range x.iv { + bc.cardinality += int(r.length) + resetBitmapRange(bc.bitmap, lastEnd, int(r.start)) + lastEnd = int(r.start+r.length) + 1 + setBitmapRange(bc.bitmap, int(r.start), lastEnd) + } + resetBitmapRange(bc.bitmap, lastEnd, maxCapacity) + + default: + panic("unsupported container type") + } +} + +func (bc *bitmapContainer) toArrayContainer() *arrayContainer { + ac := &arrayContainer{} + ac.loadData(bc) + return ac +} + +func (bc *bitmapContainer) fillArray(container []uint16) { + //TODO: rewrite in assembly + pos := 0 + base := 0 + for k := 0; k < len(bc.bitmap); k++ { + bitset := bc.bitmap[k] + for bitset != 0 { + t := bitset & -bitset + container[pos] = uint16((base + int(popcount(t-1)))) + pos = pos + 1 + bitset ^= t + } + base += 64 + } +} + +func (bc *bitmapContainer) NextSetBit(i uint) int { + var ( + x = i / 64 + length = uint(len(bc.bitmap)) + ) + if x >= length { + return -1 + } + w := bc.bitmap[x] + w = w >> uint(i%64) + if w != 0 { + return int(i) + countTrailingZeros(w) + } + x++ + for ; x < length; x++ { + if bc.bitmap[x] != 0 { + return int(x*64) + countTrailingZeros(bc.bitmap[x]) + } + } + return -1 +} + +func (bc *bitmapContainer) PrevSetBit(i int) int { + if i < 0 { + return -1 + } + x := i / 64 + if x >= len(bc.bitmap) { + return -1 + } + + w := bc.bitmap[x] + + b := i % 64 + + w = w << uint(63-b) + if w != 0 { + return i - countLeadingZeros(w) + } + x-- + for ; x >= 0; x-- { + if bc.bitmap[x] != 0 { + return (x * 64) + 63 - countLeadingZeros(bc.bitmap[x]) + } + } + return -1 +} + +// reference the java implementation +// https://github.com/RoaringBitmap/RoaringBitmap/blob/master/src/main/java/org/roaringbitmap/BitmapContainer.java#L875-L892 +// +func (bc *bitmapContainer) numberOfRuns() int { + if bc.cardinality == 0 { + return 0 + } + + var numRuns uint64 + nextWord := bc.bitmap[0] + + for i := 0; i < len(bc.bitmap)-1; i++ { + word := nextWord + nextWord = bc.bitmap[i+1] + numRuns += popcount((^word)&(word<<1)) + ((word >> 63) &^ nextWord) + } + + word := nextWord + numRuns += popcount((^word) & (word << 1)) + if (word & 0x8000000000000000) != 0 { + numRuns++ + } + + return int(numRuns) +} + +// convert to run or array *if needed* +func (bc *bitmapContainer) toEfficientContainer() container { + + numRuns := bc.numberOfRuns() + + sizeAsRunContainer := runContainer16SerializedSizeInBytes(numRuns) + sizeAsBitmapContainer := bitmapContainerSizeInBytes() + card := bc.getCardinality() + sizeAsArrayContainer := arrayContainerSizeInBytes(card) + + if sizeAsRunContainer <= minOfInt(sizeAsBitmapContainer, sizeAsArrayContainer) { + return newRunContainer16FromBitmapContainer(bc) + } + if card <= arrayDefaultMaxSize { + return bc.toArrayContainer() + } + return bc +} + +func newBitmapContainerFromRun(rc *runContainer16) *bitmapContainer { + + if len(rc.iv) == 1 { + return newBitmapContainerwithRange(int(rc.iv[0].start), int(rc.iv[0].last())) + } + + bc := newBitmapContainer() + for i := range rc.iv { + setBitmapRange(bc.bitmap, int(rc.iv[i].start), int(rc.iv[i].last())+1) + bc.cardinality += int(rc.iv[i].last()) + 1 - int(rc.iv[i].start) + } + //bc.computeCardinality() + return bc +} + +func (bc *bitmapContainer) containerType() contype { + return bitmapContype +} + +func (bc *bitmapContainer) addOffset(x uint16) []container { + low := newBitmapContainer() + high := newBitmapContainer() + b := uint32(x) >> 6 + i := uint32(x) % 64 + end := uint32(1024) - b + if i == 0 { + copy(low.bitmap[b:], bc.bitmap[:end]) + copy(high.bitmap[:b], bc.bitmap[end:]) + } else { + low.bitmap[b] = bc.bitmap[0] << i + for k := uint32(1); k < end; k++ { + newval := bc.bitmap[k] << i + newval |= bc.bitmap[k-1] >> (64 - i) + low.bitmap[b+k] = newval + } + for k := end; k < 1024; k++ { + newval := bc.bitmap[k] << i + newval |= bc.bitmap[k-1] >> (64 - i) + high.bitmap[k-end] = newval + } + high.bitmap[b] = bc.bitmap[1023] >> (64 - i) + } + low.computeCardinality() + high.computeCardinality() + return []container{low, high} +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/clz.go b/backend/vendor/github.com/RoaringBitmap/roaring/clz.go new file mode 100644 index 0000000000..bcd80d32f0 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/clz.go @@ -0,0 +1,11 @@ +// +build go1.9 +// "go1.9", from Go version 1.9 onward +// See https://golang.org/pkg/go/build/#hdr-Build_Constraints + +package roaring + +import "math/bits" + +func countLeadingZeros(x uint64) int { + return bits.LeadingZeros64(x) +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/clz_compat.go b/backend/vendor/github.com/RoaringBitmap/roaring/clz_compat.go new file mode 100644 index 0000000000..eeef4de35b --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/clz_compat.go @@ -0,0 +1,36 @@ +// +build !go1.9 + +package roaring + +// LeadingZeroBits returns the number of consecutive most significant zero +// bits of x. +func countLeadingZeros(i uint64) int { + if i == 0 { + return 64 + } + n := 1 + x := uint32(i >> 32) + if x == 0 { + n += 32 + x = uint32(i) + } + if (x >> 16) == 0 { + n += 16 + x <<= 16 + } + if (x >> 24) == 0 { + n += 8 + x <<= 8 + } + if x>>28 == 0 { + n += 4 + x <<= 4 + } + if x>>30 == 0 { + n += 2 + x <<= 2 + + } + n -= int(x >> 31) + return n +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/ctz.go b/backend/vendor/github.com/RoaringBitmap/roaring/ctz.go new file mode 100644 index 0000000000..e399dddebd --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/ctz.go @@ -0,0 +1,11 @@ +// +build go1.9 +// "go1.9", from Go version 1.9 onward +// See https://golang.org/pkg/go/build/#hdr-Build_Constraints + +package roaring + +import "math/bits" + +func countTrailingZeros(x uint64) int { + return bits.TrailingZeros64(x) +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/ctz_compat.go b/backend/vendor/github.com/RoaringBitmap/roaring/ctz_compat.go new file mode 100644 index 0000000000..80220e6bee --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/ctz_compat.go @@ -0,0 +1,71 @@ +// +build !go1.9 + +package roaring + +// Reuse of portions of go/src/math/big standard lib code +// under this license: +/* +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +const deBruijn32 = 0x077CB531 + +var deBruijn32Lookup = []byte{ + 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9, +} + +const deBruijn64 = 0x03f79d71b4ca8b09 + +var deBruijn64Lookup = []byte{ + 0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4, + 62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5, + 63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11, + 54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6, +} + +// trailingZeroBits returns the number of consecutive least significant zero +// bits of x. +func countTrailingZeros(x uint64) int { + // x & -x leaves only the right-most bit set in the word. Let k be the + // index of that bit. Since only a single bit is set, the value is two + // to the power of k. Multiplying by a power of two is equivalent to + // left shifting, in this case by k bits. The de Bruijn constant is + // such that all six bit, consecutive substrings are distinct. + // Therefore, if we have a left shifted version of this constant we can + // find by how many bits it was shifted by looking at which six bit + // substring ended up at the top of the word. + // (Knuth, volume 4, section 7.3.1) + if x == 0 { + // We have to special case 0; the fomula + // below doesn't work for 0. + return 64 + } + return int(deBruijn64Lookup[((x&-x)*(deBruijn64))>>58]) +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/fastaggregation.go b/backend/vendor/github.com/RoaringBitmap/roaring/fastaggregation.go new file mode 100644 index 0000000000..47bda7125d --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/fastaggregation.go @@ -0,0 +1,309 @@ +package roaring + +import ( + "container/heap" +) + +// Or function that requires repairAfterLazy +func lazyOR(x1, x2 *Bitmap) *Bitmap { + answer := NewBitmap() + pos1 := 0 + pos2 := 0 + length1 := x1.highlowcontainer.size() + length2 := x2.highlowcontainer.size() +main: + for (pos1 < length1) && (pos2 < length2) { + s1 := x1.highlowcontainer.getKeyAtIndex(pos1) + s2 := x2.highlowcontainer.getKeyAtIndex(pos2) + + for { + if s1 < s2 { + answer.highlowcontainer.appendCopy(x1.highlowcontainer, pos1) + pos1++ + if pos1 == length1 { + break main + } + s1 = x1.highlowcontainer.getKeyAtIndex(pos1) + } else if s1 > s2 { + answer.highlowcontainer.appendCopy(x2.highlowcontainer, pos2) + pos2++ + if pos2 == length2 { + break main + } + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } else { + c1 := x1.highlowcontainer.getContainerAtIndex(pos1) + answer.highlowcontainer.appendContainer(s1, c1.lazyOR(x2.highlowcontainer.getContainerAtIndex(pos2)), false) + pos1++ + pos2++ + if (pos1 == length1) || (pos2 == length2) { + break main + } + s1 = x1.highlowcontainer.getKeyAtIndex(pos1) + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } + } + } + if pos1 == length1 { + answer.highlowcontainer.appendCopyMany(x2.highlowcontainer, pos2, length2) + } else if pos2 == length2 { + answer.highlowcontainer.appendCopyMany(x1.highlowcontainer, pos1, length1) + } + return answer +} + +// In-place Or function that requires repairAfterLazy +func (x1 *Bitmap) lazyOR(x2 *Bitmap) *Bitmap { + pos1 := 0 + pos2 := 0 + length1 := x1.highlowcontainer.size() + length2 := x2.highlowcontainer.size() +main: + for (pos1 < length1) && (pos2 < length2) { + s1 := x1.highlowcontainer.getKeyAtIndex(pos1) + s2 := x2.highlowcontainer.getKeyAtIndex(pos2) + + for { + if s1 < s2 { + pos1++ + if pos1 == length1 { + break main + } + s1 = x1.highlowcontainer.getKeyAtIndex(pos1) + } else if s1 > s2 { + x1.highlowcontainer.insertNewKeyValueAt(pos1, s2, x2.highlowcontainer.getContainerAtIndex(pos2).clone()) + pos2++ + pos1++ + length1++ + if pos2 == length2 { + break main + } + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } else { + c1 := x1.highlowcontainer.getWritableContainerAtIndex(pos1) + x1.highlowcontainer.containers[pos1] = c1.lazyIOR(x2.highlowcontainer.getContainerAtIndex(pos2)) + x1.highlowcontainer.needCopyOnWrite[pos1] = false + pos1++ + pos2++ + if (pos1 == length1) || (pos2 == length2) { + break main + } + s1 = x1.highlowcontainer.getKeyAtIndex(pos1) + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } + } + } + if pos1 == length1 { + x1.highlowcontainer.appendCopyMany(x2.highlowcontainer, pos2, length2) + } + return x1 +} + +// to be called after lazy aggregates +func (x1 *Bitmap) repairAfterLazy() { + for pos := 0; pos < x1.highlowcontainer.size(); pos++ { + c := x1.highlowcontainer.getContainerAtIndex(pos) + switch c.(type) { + case *bitmapContainer: + if c.(*bitmapContainer).cardinality == invalidCardinality { + c = x1.highlowcontainer.getWritableContainerAtIndex(pos) + c.(*bitmapContainer).computeCardinality() + if c.(*bitmapContainer).getCardinality() <= arrayDefaultMaxSize { + x1.highlowcontainer.setContainerAtIndex(pos, c.(*bitmapContainer).toArrayContainer()) + } else if c.(*bitmapContainer).isFull() { + x1.highlowcontainer.setContainerAtIndex(pos, newRunContainer16Range(0, MaxUint16)) + } + } + } + } +} + +// FastAnd computes the intersection between many bitmaps quickly +// Compared to the And function, it can take many bitmaps as input, thus saving the trouble +// of manually calling "And" many times. +func FastAnd(bitmaps ...*Bitmap) *Bitmap { + if len(bitmaps) == 0 { + return NewBitmap() + } else if len(bitmaps) == 1 { + return bitmaps[0].Clone() + } + answer := And(bitmaps[0], bitmaps[1]) + for _, bm := range bitmaps[2:] { + answer.And(bm) + } + return answer +} + +// FastOr computes the union between many bitmaps quickly, as opposed to having to call Or repeatedly. +// It might also be faster than calling Or repeatedly. +func FastOr(bitmaps ...*Bitmap) *Bitmap { + if len(bitmaps) == 0 { + return NewBitmap() + } else if len(bitmaps) == 1 { + return bitmaps[0].Clone() + } + answer := lazyOR(bitmaps[0], bitmaps[1]) + for _, bm := range bitmaps[2:] { + answer = answer.lazyOR(bm) + } + // here is where repairAfterLazy is called. + answer.repairAfterLazy() + return answer +} + +// HeapOr computes the union between many bitmaps quickly using a heap. +// It might be faster than calling Or repeatedly. +func HeapOr(bitmaps ...*Bitmap) *Bitmap { + if len(bitmaps) == 0 { + return NewBitmap() + } + // TODO: for better speed, we could do the operation lazily, see Java implementation + pq := make(priorityQueue, len(bitmaps)) + for i, bm := range bitmaps { + pq[i] = &item{bm, i} + } + heap.Init(&pq) + + for pq.Len() > 1 { + x1 := heap.Pop(&pq).(*item) + x2 := heap.Pop(&pq).(*item) + heap.Push(&pq, &item{Or(x1.value, x2.value), 0}) + } + return heap.Pop(&pq).(*item).value +} + +// HeapXor computes the symmetric difference between many bitmaps quickly (as opposed to calling Xor repeated). +// Internally, this function uses a heap. +// It might be faster than calling Xor repeatedly. +func HeapXor(bitmaps ...*Bitmap) *Bitmap { + if len(bitmaps) == 0 { + return NewBitmap() + } + + pq := make(priorityQueue, len(bitmaps)) + for i, bm := range bitmaps { + pq[i] = &item{bm, i} + } + heap.Init(&pq) + + for pq.Len() > 1 { + x1 := heap.Pop(&pq).(*item) + x2 := heap.Pop(&pq).(*item) + heap.Push(&pq, &item{Xor(x1.value, x2.value), 0}) + } + return heap.Pop(&pq).(*item).value +} + +// AndAny provides a result equivalent to x1.And(FastOr(bitmaps)). +// It's optimized to minimize allocations. It also might be faster than separate calls. +func (x1 *Bitmap) AndAny(bitmaps ...*Bitmap) { + if len(bitmaps) == 0 { + return + } else if len(bitmaps) == 1 { + x1.And(bitmaps[0]) + return + } + + type withPos struct { + bitmap *roaringArray + pos int + key uint16 + } + filters := make([]withPos, 0, len(bitmaps)) + + for _, b := range bitmaps { + if b.highlowcontainer.size() > 0 { + filters = append(filters, withPos{ + bitmap: &b.highlowcontainer, + pos: 0, + key: b.highlowcontainer.getKeyAtIndex(0), + }) + } + } + + basePos := 0 + intersections := 0 + keyContainers := make([]container, 0, len(filters)) + var ( + tmpArray *arrayContainer + tmpBitmap *bitmapContainer + minNextKey uint16 + ) + + for basePos < x1.highlowcontainer.size() && len(filters) > 0 { + baseKey := x1.highlowcontainer.getKeyAtIndex(basePos) + + // accumulate containers for current key, find next minimal key in filters + // and exclude filters that do not have related values anymore + i := 0 + maxPossibleOr := 0 + minNextKey = MaxUint16 + for _, f := range filters { + if f.key < baseKey { + f.pos = f.bitmap.advanceUntil(baseKey, f.pos) + if f.pos == f.bitmap.size() { + continue + } + f.key = f.bitmap.getKeyAtIndex(f.pos) + } + + if f.key == baseKey { + cont := f.bitmap.getContainerAtIndex(f.pos) + keyContainers = append(keyContainers, cont) + maxPossibleOr += cont.getCardinality() + + f.pos++ + if f.pos == f.bitmap.size() { + continue + } + f.key = f.bitmap.getKeyAtIndex(f.pos) + } + + minNextKey = minOfUint16(minNextKey, f.key) + filters[i] = f + i++ + } + filters = filters[:i] + + if len(keyContainers) == 0 { + basePos = x1.highlowcontainer.advanceUntil(minNextKey, basePos) + continue + } + + var ored container + + if len(keyContainers) == 1 { + ored = keyContainers[0] + } else { + //TODO: special case for run containers? + if maxPossibleOr > arrayDefaultMaxSize { + if tmpBitmap == nil { + tmpBitmap = newBitmapContainer() + } + tmpBitmap.resetTo(keyContainers[0]) + ored = tmpBitmap + } else { + if tmpArray == nil { + tmpArray = newArrayContainerCapacity(maxPossibleOr) + } + tmpArray.realloc(maxPossibleOr) + tmpArray.resetTo(keyContainers[0]) + ored = tmpArray + } + for _, c := range keyContainers[1:] { + ored = ored.ior(c) + } + } + + result := x1.highlowcontainer.getWritableContainerAtIndex(basePos).iand(ored) + if !result.isEmpty() { + x1.highlowcontainer.replaceKeyAndContainerAtIndex(intersections, baseKey, result, false) + intersections++ + } + + keyContainers = keyContainers[:0] + basePos = x1.highlowcontainer.advanceUntil(minNextKey, basePos) + } + + x1.highlowcontainer.resize(intersections) +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/internal/byte_input.go b/backend/vendor/github.com/RoaringBitmap/roaring/internal/byte_input.go new file mode 100644 index 0000000000..3e5490a9df --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/internal/byte_input.go @@ -0,0 +1,166 @@ +package internal + +import ( + "encoding/binary" + "io" +) + +// ByteInput typed interface around io.Reader or raw bytes +type ByteInput interface { + // Next returns a slice containing the next n bytes from the buffer, + // advancing the buffer as if the bytes had been returned by Read. + Next(n int) ([]byte, error) + // ReadUInt32 reads uint32 with LittleEndian order + ReadUInt32() (uint32, error) + // ReadUInt16 reads uint16 with LittleEndian order + ReadUInt16() (uint16, error) + // GetReadBytes returns read bytes + GetReadBytes() int64 + // SkipBytes skips exactly n bytes + SkipBytes(n int) error +} + +// NewByteInputFromReader creates reader wrapper +func NewByteInputFromReader(reader io.Reader) ByteInput { + return &ByteInputAdapter{ + r: reader, + readBytes: 0, + } +} + +// NewByteInput creates raw bytes wrapper +func NewByteInput(buf []byte) ByteInput { + return &ByteBuffer{ + buf: buf, + off: 0, + } +} + +// ByteBuffer raw bytes wrapper +type ByteBuffer struct { + buf []byte + off int +} + +// Next returns a slice containing the next n bytes from the reader +// If there are fewer bytes than the given n, io.ErrUnexpectedEOF will be returned +func (b *ByteBuffer) Next(n int) ([]byte, error) { + m := len(b.buf) - b.off + + if n > m { + return nil, io.ErrUnexpectedEOF + } + + data := b.buf[b.off : b.off+n] + b.off += n + + return data, nil +} + +// ReadUInt32 reads uint32 with LittleEndian order +func (b *ByteBuffer) ReadUInt32() (uint32, error) { + if len(b.buf)-b.off < 4 { + return 0, io.ErrUnexpectedEOF + } + + v := binary.LittleEndian.Uint32(b.buf[b.off:]) + b.off += 4 + + return v, nil +} + +// ReadUInt16 reads uint16 with LittleEndian order +func (b *ByteBuffer) ReadUInt16() (uint16, error) { + if len(b.buf)-b.off < 2 { + return 0, io.ErrUnexpectedEOF + } + + v := binary.LittleEndian.Uint16(b.buf[b.off:]) + b.off += 2 + + return v, nil +} + +// GetReadBytes returns read bytes +func (b *ByteBuffer) GetReadBytes() int64 { + return int64(b.off) +} + +// SkipBytes skips exactly n bytes +func (b *ByteBuffer) SkipBytes(n int) error { + m := len(b.buf) - b.off + + if n > m { + return io.ErrUnexpectedEOF + } + + b.off += n + + return nil +} + +// Reset resets the given buffer with a new byte slice +func (b *ByteBuffer) Reset(buf []byte) { + b.buf = buf + b.off = 0 +} + +// ByteInputAdapter reader wrapper +type ByteInputAdapter struct { + r io.Reader + readBytes int +} + +// Next returns a slice containing the next n bytes from the buffer, +// advancing the buffer as if the bytes had been returned by Read. +func (b *ByteInputAdapter) Next(n int) ([]byte, error) { + buf := make([]byte, n) + m, err := io.ReadAtLeast(b.r, buf, n) + b.readBytes += m + + if err != nil { + return nil, err + } + + return buf, nil +} + +// ReadUInt32 reads uint32 with LittleEndian order +func (b *ByteInputAdapter) ReadUInt32() (uint32, error) { + buf, err := b.Next(4) + + if err != nil { + return 0, err + } + + return binary.LittleEndian.Uint32(buf), nil +} + +// ReadUInt16 reads uint16 with LittleEndian order +func (b *ByteInputAdapter) ReadUInt16() (uint16, error) { + buf, err := b.Next(2) + + if err != nil { + return 0, err + } + + return binary.LittleEndian.Uint16(buf), nil +} + +// GetReadBytes returns read bytes +func (b *ByteInputAdapter) GetReadBytes() int64 { + return int64(b.readBytes) +} + +// SkipBytes skips exactly n bytes +func (b *ByteInputAdapter) SkipBytes(n int) error { + _, err := b.Next(n) + + return err +} + +// Reset resets the given buffer with a new stream +func (b *ByteInputAdapter) Reset(stream io.Reader) { + b.r = stream + b.readBytes = 0 +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/internal/pools.go b/backend/vendor/github.com/RoaringBitmap/roaring/internal/pools.go new file mode 100644 index 0000000000..d2583568d0 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/internal/pools.go @@ -0,0 +1,21 @@ +package internal + +import ( + "sync" +) + +var ( + // ByteInputAdapterPool shared pool + ByteInputAdapterPool = sync.Pool{ + New: func() interface{} { + return &ByteInputAdapter{} + }, + } + + // ByteBufferPool shared pool + ByteBufferPool = sync.Pool{ + New: func() interface{} { + return &ByteBuffer{} + }, + } +) diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/manyiterator.go b/backend/vendor/github.com/RoaringBitmap/roaring/manyiterator.go new file mode 100644 index 0000000000..eaa5b79507 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/manyiterator.go @@ -0,0 +1,32 @@ +package roaring + +type manyIterable interface { + nextMany(hs uint32, buf []uint32) int + nextMany64(hs uint64, buf []uint64) int +} + +func (si *shortIterator) nextMany(hs uint32, buf []uint32) int { + n := 0 + l := si.loc + s := si.slice + for n < len(buf) && l < len(s) { + buf[n] = uint32(s[l]) | hs + l++ + n++ + } + si.loc = l + return n +} + +func (si *shortIterator) nextMany64(hs uint64, buf []uint64) int { + n := 0 + l := si.loc + s := si.slice + for n < len(buf) && l < len(s) { + buf[n] = uint64(s[l]) | hs + l++ + n++ + } + si.loc = l + return n +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/parallel.go b/backend/vendor/github.com/RoaringBitmap/roaring/parallel.go new file mode 100644 index 0000000000..9208e3e380 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/parallel.go @@ -0,0 +1,612 @@ +package roaring + +import ( + "container/heap" + "fmt" + "runtime" + "sync" +) + +var defaultWorkerCount = runtime.NumCPU() + +type bitmapContainerKey struct { + key uint16 + idx int + bitmap *Bitmap +} + +type multipleContainers struct { + key uint16 + containers []container + idx int +} + +type keyedContainer struct { + key uint16 + container container + idx int +} + +type bitmapContainerHeap []bitmapContainerKey + +func (h bitmapContainerHeap) Len() int { return len(h) } +func (h bitmapContainerHeap) Less(i, j int) bool { return h[i].key < h[j].key } +func (h bitmapContainerHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } + +func (h *bitmapContainerHeap) Push(x interface{}) { + // Push and Pop use pointer receivers because they modify the slice's length, + // not just its contents. + *h = append(*h, x.(bitmapContainerKey)) +} + +func (h *bitmapContainerHeap) Pop() interface{} { + old := *h + n := len(old) + x := old[n-1] + *h = old[0 : n-1] + return x +} + +func (h bitmapContainerHeap) Peek() bitmapContainerKey { + return h[0] +} + +func (h *bitmapContainerHeap) popIncrementing() (key uint16, container container) { + k := h.Peek() + key = k.key + container = k.bitmap.highlowcontainer.containers[k.idx] + + newIdx := k.idx + 1 + if newIdx < k.bitmap.highlowcontainer.size() { + k = bitmapContainerKey{ + k.bitmap.highlowcontainer.keys[newIdx], + newIdx, + k.bitmap, + } + (*h)[0] = k + heap.Fix(h, 0) + } else { + heap.Pop(h) + } + + return +} + +func (h *bitmapContainerHeap) Next(containers []container) multipleContainers { + if h.Len() == 0 { + return multipleContainers{} + } + + key, container := h.popIncrementing() + containers = append(containers, container) + + for h.Len() > 0 && key == h.Peek().key { + _, container = h.popIncrementing() + containers = append(containers, container) + } + + return multipleContainers{ + key, + containers, + -1, + } +} + +func newBitmapContainerHeap(bitmaps ...*Bitmap) bitmapContainerHeap { + // Initialize heap + var h bitmapContainerHeap = make([]bitmapContainerKey, 0, len(bitmaps)) + for _, bitmap := range bitmaps { + if !bitmap.IsEmpty() { + key := bitmapContainerKey{ + bitmap.highlowcontainer.keys[0], + 0, + bitmap, + } + h = append(h, key) + } + } + + heap.Init(&h) + + return h +} + +func repairAfterLazy(c container) container { + switch t := c.(type) { + case *bitmapContainer: + if t.cardinality == invalidCardinality { + t.computeCardinality() + } + + if t.getCardinality() <= arrayDefaultMaxSize { + return t.toArrayContainer() + } else if c.(*bitmapContainer).isFull() { + return newRunContainer16Range(0, MaxUint16) + } + } + + return c +} + +func toBitmapContainer(c container) container { + switch t := c.(type) { + case *arrayContainer: + return t.toBitmapContainer() + case *runContainer16: + if !t.isFull() { + return t.toBitmapContainer() + } + } + return c +} + +func appenderRoutine(bitmapChan chan<- *Bitmap, resultChan <-chan keyedContainer, expectedKeysChan <-chan int) { + expectedKeys := -1 + appendedKeys := 0 + var keys []uint16 + var containers []container + for appendedKeys != expectedKeys { + select { + case item := <-resultChan: + if len(keys) <= item.idx { + keys = append(keys, make([]uint16, item.idx-len(keys)+1)...) + containers = append(containers, make([]container, item.idx-len(containers)+1)...) + } + keys[item.idx] = item.key + containers[item.idx] = item.container + + appendedKeys++ + case msg := <-expectedKeysChan: + expectedKeys = msg + } + } + answer := &Bitmap{ + roaringArray{ + make([]uint16, 0, expectedKeys), + make([]container, 0, expectedKeys), + make([]bool, 0, expectedKeys), + false, + }, + } + for i := range keys { + if containers[i] != nil { // in case a resulting container was empty, see ParAnd function + answer.highlowcontainer.appendContainer(keys[i], containers[i], false) + } + } + + bitmapChan <- answer +} + +// ParHeapOr computes the union (OR) of all provided bitmaps in parallel, +// where the parameter "parallelism" determines how many workers are to be used +// (if it is set to 0, a default number of workers is chosen) +// ParHeapOr uses a heap to compute the union. For rare cases it might be faster than ParOr +func ParHeapOr(parallelism int, bitmaps ...*Bitmap) *Bitmap { + + bitmapCount := len(bitmaps) + if bitmapCount == 0 { + return NewBitmap() + } else if bitmapCount == 1 { + return bitmaps[0].Clone() + } + + if parallelism == 0 { + parallelism = defaultWorkerCount + } + + h := newBitmapContainerHeap(bitmaps...) + + bitmapChan := make(chan *Bitmap) + inputChan := make(chan multipleContainers, 128) + resultChan := make(chan keyedContainer, 32) + expectedKeysChan := make(chan int) + + pool := sync.Pool{ + New: func() interface{} { + return make([]container, 0, len(bitmaps)) + }, + } + + orFunc := func() { + // Assumes only structs with >=2 containers are passed + for input := range inputChan { + c := toBitmapContainer(input.containers[0]).lazyOR(input.containers[1]) + for _, next := range input.containers[2:] { + c = c.lazyIOR(next) + } + c = repairAfterLazy(c) + kx := keyedContainer{ + input.key, + c, + input.idx, + } + resultChan <- kx + pool.Put(input.containers[:0]) + } + } + + go appenderRoutine(bitmapChan, resultChan, expectedKeysChan) + + for i := 0; i < parallelism; i++ { + go orFunc() + } + + idx := 0 + for h.Len() > 0 { + ck := h.Next(pool.Get().([]container)) + if len(ck.containers) == 1 { + resultChan <- keyedContainer{ + ck.key, + ck.containers[0], + idx, + } + pool.Put(ck.containers[:0]) + } else { + ck.idx = idx + inputChan <- ck + } + idx++ + } + expectedKeysChan <- idx + + bitmap := <-bitmapChan + + close(inputChan) + close(resultChan) + close(expectedKeysChan) + + return bitmap +} + +// ParAnd computes the intersection (AND) of all provided bitmaps in parallel, +// where the parameter "parallelism" determines how many workers are to be used +// (if it is set to 0, a default number of workers is chosen) +func ParAnd(parallelism int, bitmaps ...*Bitmap) *Bitmap { + bitmapCount := len(bitmaps) + if bitmapCount == 0 { + return NewBitmap() + } else if bitmapCount == 1 { + return bitmaps[0].Clone() + } + + if parallelism == 0 { + parallelism = defaultWorkerCount + } + + h := newBitmapContainerHeap(bitmaps...) + + bitmapChan := make(chan *Bitmap) + inputChan := make(chan multipleContainers, 128) + resultChan := make(chan keyedContainer, 32) + expectedKeysChan := make(chan int) + + andFunc := func() { + // Assumes only structs with >=2 containers are passed + for input := range inputChan { + c := input.containers[0].and(input.containers[1]) + for _, next := range input.containers[2:] { + if c.isEmpty() { + break + } + c = c.iand(next) + } + + // Send a nil explicitly if the result of the intersection is an empty container + if c.isEmpty() { + c = nil + } + + kx := keyedContainer{ + input.key, + c, + input.idx, + } + resultChan <- kx + } + } + + go appenderRoutine(bitmapChan, resultChan, expectedKeysChan) + + for i := 0; i < parallelism; i++ { + go andFunc() + } + + idx := 0 + for h.Len() > 0 { + ck := h.Next(make([]container, 0, 4)) + if len(ck.containers) == bitmapCount { + ck.idx = idx + inputChan <- ck + idx++ + } + } + expectedKeysChan <- idx + + bitmap := <-bitmapChan + + close(inputChan) + close(resultChan) + close(expectedKeysChan) + + return bitmap +} + +// ParOr computes the union (OR) of all provided bitmaps in parallel, +// where the parameter "parallelism" determines how many workers are to be used +// (if it is set to 0, a default number of workers is chosen) +func ParOr(parallelism int, bitmaps ...*Bitmap) *Bitmap { + var lKey uint16 = MaxUint16 + var hKey uint16 + + bitmapsFiltered := bitmaps[:0] + for _, b := range bitmaps { + if !b.IsEmpty() { + bitmapsFiltered = append(bitmapsFiltered, b) + } + } + bitmaps = bitmapsFiltered + + for _, b := range bitmaps { + lKey = minOfUint16(lKey, b.highlowcontainer.keys[0]) + hKey = maxOfUint16(hKey, b.highlowcontainer.keys[b.highlowcontainer.size()-1]) + } + + if lKey == MaxUint16 && hKey == 0 { + return New() + } else if len(bitmaps) == 1 { + return bitmaps[0].Clone() + } + + keyRange := int(hKey) - int(lKey) + 1 + if keyRange == 1 { + // revert to FastOr. Since the key range is 0 + // no container-level aggregation parallelism is achievable + return FastOr(bitmaps...) + } + + if parallelism == 0 { + parallelism = defaultWorkerCount + } + + var chunkSize int + var chunkCount int + if parallelism*4 > int(keyRange) { + chunkSize = 1 + chunkCount = int(keyRange) + } else { + chunkCount = parallelism * 4 + chunkSize = (int(keyRange) + chunkCount - 1) / chunkCount + } + + if chunkCount*chunkSize < int(keyRange) { + // it's fine to panic to indicate an implementation error + panic(fmt.Sprintf("invariant check failed: chunkCount * chunkSize < keyRange, %d * %d < %d", chunkCount, chunkSize, keyRange)) + } + + chunks := make([]*roaringArray, chunkCount) + + chunkSpecChan := make(chan parChunkSpec, minOfInt(maxOfInt(64, 2*parallelism), int(chunkCount))) + chunkChan := make(chan parChunk, minOfInt(32, int(chunkCount))) + + orFunc := func() { + for spec := range chunkSpecChan { + ra := lazyOrOnRange(&bitmaps[0].highlowcontainer, &bitmaps[1].highlowcontainer, spec.start, spec.end) + for _, b := range bitmaps[2:] { + ra = lazyIOrOnRange(ra, &b.highlowcontainer, spec.start, spec.end) + } + + for i, c := range ra.containers { + ra.containers[i] = repairAfterLazy(c) + } + + chunkChan <- parChunk{ra, spec.idx} + } + } + + for i := 0; i < parallelism; i++ { + go orFunc() + } + + go func() { + for i := 0; i < chunkCount; i++ { + spec := parChunkSpec{ + start: uint16(int(lKey) + i*chunkSize), + end: uint16(minOfInt(int(lKey)+(i+1)*chunkSize-1, int(hKey))), + idx: int(i), + } + chunkSpecChan <- spec + } + }() + + chunksRemaining := chunkCount + for chunk := range chunkChan { + chunks[chunk.idx] = chunk.ra + chunksRemaining-- + if chunksRemaining == 0 { + break + } + } + close(chunkChan) + close(chunkSpecChan) + + containerCount := 0 + for _, chunk := range chunks { + containerCount += chunk.size() + } + + result := Bitmap{ + roaringArray{ + containers: make([]container, containerCount), + keys: make([]uint16, containerCount), + needCopyOnWrite: make([]bool, containerCount), + }, + } + + resultOffset := 0 + for _, chunk := range chunks { + copy(result.highlowcontainer.containers[resultOffset:], chunk.containers) + copy(result.highlowcontainer.keys[resultOffset:], chunk.keys) + copy(result.highlowcontainer.needCopyOnWrite[resultOffset:], chunk.needCopyOnWrite) + resultOffset += chunk.size() + } + + return &result +} + +type parChunkSpec struct { + start uint16 + end uint16 + idx int +} + +type parChunk struct { + ra *roaringArray + idx int +} + +func (c parChunk) size() int { + return c.ra.size() +} + +func parNaiveStartAt(ra *roaringArray, start uint16, last uint16) int { + for idx, key := range ra.keys { + if key >= start && key <= last { + return idx + } else if key > last { + break + } + } + return ra.size() +} + +func lazyOrOnRange(ra1, ra2 *roaringArray, start, last uint16) *roaringArray { + answer := newRoaringArray() + length1 := ra1.size() + length2 := ra2.size() + + idx1 := parNaiveStartAt(ra1, start, last) + idx2 := parNaiveStartAt(ra2, start, last) + + var key1 uint16 + var key2 uint16 + if idx1 < length1 && idx2 < length2 { + key1 = ra1.getKeyAtIndex(idx1) + key2 = ra2.getKeyAtIndex(idx2) + + for key1 <= last && key2 <= last { + + if key1 < key2 { + answer.appendCopy(*ra1, idx1) + idx1++ + if idx1 == length1 { + break + } + key1 = ra1.getKeyAtIndex(idx1) + } else if key1 > key2 { + answer.appendCopy(*ra2, idx2) + idx2++ + if idx2 == length2 { + break + } + key2 = ra2.getKeyAtIndex(idx2) + } else { + c1 := ra1.getFastContainerAtIndex(idx1, false) + + answer.appendContainer(key1, c1.lazyOR(ra2.getContainerAtIndex(idx2)), false) + idx1++ + idx2++ + if idx1 == length1 || idx2 == length2 { + break + } + + key1 = ra1.getKeyAtIndex(idx1) + key2 = ra2.getKeyAtIndex(idx2) + } + } + } + + if idx2 < length2 { + key2 = ra2.getKeyAtIndex(idx2) + for key2 <= last { + answer.appendCopy(*ra2, idx2) + idx2++ + if idx2 == length2 { + break + } + key2 = ra2.getKeyAtIndex(idx2) + } + } + + if idx1 < length1 { + key1 = ra1.getKeyAtIndex(idx1) + for key1 <= last { + answer.appendCopy(*ra1, idx1) + idx1++ + if idx1 == length1 { + break + } + key1 = ra1.getKeyAtIndex(idx1) + } + } + return answer +} + +func lazyIOrOnRange(ra1, ra2 *roaringArray, start, last uint16) *roaringArray { + length1 := ra1.size() + length2 := ra2.size() + + idx1 := 0 + idx2 := parNaiveStartAt(ra2, start, last) + + var key1 uint16 + var key2 uint16 + if idx1 < length1 && idx2 < length2 { + key1 = ra1.getKeyAtIndex(idx1) + key2 = ra2.getKeyAtIndex(idx2) + + for key1 <= last && key2 <= last { + if key1 < key2 { + idx1++ + if idx1 >= length1 { + break + } + key1 = ra1.getKeyAtIndex(idx1) + } else if key1 > key2 { + ra1.insertNewKeyValueAt(idx1, key2, ra2.getContainerAtIndex(idx2)) + ra1.needCopyOnWrite[idx1] = true + idx2++ + idx1++ + length1++ + if idx2 >= length2 { + break + } + key2 = ra2.getKeyAtIndex(idx2) + } else { + c1 := ra1.getFastContainerAtIndex(idx1, true) + + ra1.containers[idx1] = c1.lazyIOR(ra2.getContainerAtIndex(idx2)) + ra1.needCopyOnWrite[idx1] = false + idx1++ + idx2++ + if idx1 >= length1 || idx2 >= length2 { + break + } + + key1 = ra1.getKeyAtIndex(idx1) + key2 = ra2.getKeyAtIndex(idx2) + } + } + } + if idx2 < length2 { + key2 = ra2.getKeyAtIndex(idx2) + for key2 <= last { + ra1.appendCopy(*ra2, idx2) + idx2++ + if idx2 >= length2 { + break + } + key2 = ra2.getKeyAtIndex(idx2) + } + } + return ra1 +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/popcnt.go b/backend/vendor/github.com/RoaringBitmap/roaring/popcnt.go new file mode 100644 index 0000000000..9d99508ce0 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/popcnt.go @@ -0,0 +1,11 @@ +// +build go1.9 +// "go1.9", from Go version 1.9 onward +// See https://golang.org/pkg/go/build/#hdr-Build_Constraints + +package roaring + +import "math/bits" + +func popcount(x uint64) uint64 { + return uint64(bits.OnesCount64(x)) +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/popcnt_amd64.s b/backend/vendor/github.com/RoaringBitmap/roaring/popcnt_amd64.s new file mode 100644 index 0000000000..1f13fa2eca --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/popcnt_amd64.s @@ -0,0 +1,103 @@ +// +build amd64,!appengine,!go1.9 + +TEXT ·hasAsm(SB),4,$0-1 +MOVQ $1, AX +CPUID +SHRQ $23, CX +ANDQ $1, CX +MOVB CX, ret+0(FP) +RET + +#define POPCNTQ_DX_DX BYTE $0xf3; BYTE $0x48; BYTE $0x0f; BYTE $0xb8; BYTE $0xd2 + +TEXT ·popcntSliceAsm(SB),4,$0-32 +XORQ AX, AX +MOVQ s+0(FP), SI +MOVQ s_len+8(FP), CX +TESTQ CX, CX +JZ popcntSliceEnd +popcntSliceLoop: +BYTE $0xf3; BYTE $0x48; BYTE $0x0f; BYTE $0xb8; BYTE $0x16 // POPCNTQ (SI), DX +ADDQ DX, AX +ADDQ $8, SI +LOOP popcntSliceLoop +popcntSliceEnd: +MOVQ AX, ret+24(FP) +RET + +TEXT ·popcntMaskSliceAsm(SB),4,$0-56 +XORQ AX, AX +MOVQ s+0(FP), SI +MOVQ s_len+8(FP), CX +TESTQ CX, CX +JZ popcntMaskSliceEnd +MOVQ m+24(FP), DI +popcntMaskSliceLoop: +MOVQ (DI), DX +NOTQ DX +ANDQ (SI), DX +POPCNTQ_DX_DX +ADDQ DX, AX +ADDQ $8, SI +ADDQ $8, DI +LOOP popcntMaskSliceLoop +popcntMaskSliceEnd: +MOVQ AX, ret+48(FP) +RET + +TEXT ·popcntAndSliceAsm(SB),4,$0-56 +XORQ AX, AX +MOVQ s+0(FP), SI +MOVQ s_len+8(FP), CX +TESTQ CX, CX +JZ popcntAndSliceEnd +MOVQ m+24(FP), DI +popcntAndSliceLoop: +MOVQ (DI), DX +ANDQ (SI), DX +POPCNTQ_DX_DX +ADDQ DX, AX +ADDQ $8, SI +ADDQ $8, DI +LOOP popcntAndSliceLoop +popcntAndSliceEnd: +MOVQ AX, ret+48(FP) +RET + +TEXT ·popcntOrSliceAsm(SB),4,$0-56 +XORQ AX, AX +MOVQ s+0(FP), SI +MOVQ s_len+8(FP), CX +TESTQ CX, CX +JZ popcntOrSliceEnd +MOVQ m+24(FP), DI +popcntOrSliceLoop: +MOVQ (DI), DX +ORQ (SI), DX +POPCNTQ_DX_DX +ADDQ DX, AX +ADDQ $8, SI +ADDQ $8, DI +LOOP popcntOrSliceLoop +popcntOrSliceEnd: +MOVQ AX, ret+48(FP) +RET + +TEXT ·popcntXorSliceAsm(SB),4,$0-56 +XORQ AX, AX +MOVQ s+0(FP), SI +MOVQ s_len+8(FP), CX +TESTQ CX, CX +JZ popcntXorSliceEnd +MOVQ m+24(FP), DI +popcntXorSliceLoop: +MOVQ (DI), DX +XORQ (SI), DX +POPCNTQ_DX_DX +ADDQ DX, AX +ADDQ $8, SI +ADDQ $8, DI +LOOP popcntXorSliceLoop +popcntXorSliceEnd: +MOVQ AX, ret+48(FP) +RET diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/popcnt_asm.go b/backend/vendor/github.com/RoaringBitmap/roaring/popcnt_asm.go new file mode 100644 index 0000000000..882d7f4ecf --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/popcnt_asm.go @@ -0,0 +1,67 @@ +// +build amd64,!appengine,!go1.9 + +package roaring + +// *** the following functions are defined in popcnt_amd64.s + +//go:noescape + +func hasAsm() bool + +// useAsm is a flag used to select the GO or ASM implementation of the popcnt function +var useAsm = hasAsm() + +//go:noescape + +func popcntSliceAsm(s []uint64) uint64 + +//go:noescape + +func popcntMaskSliceAsm(s, m []uint64) uint64 + +//go:noescape + +func popcntAndSliceAsm(s, m []uint64) uint64 + +//go:noescape + +func popcntOrSliceAsm(s, m []uint64) uint64 + +//go:noescape + +func popcntXorSliceAsm(s, m []uint64) uint64 + +func popcntSlice(s []uint64) uint64 { + if useAsm { + return popcntSliceAsm(s) + } + return popcntSliceGo(s) +} + +func popcntMaskSlice(s, m []uint64) uint64 { + if useAsm { + return popcntMaskSliceAsm(s, m) + } + return popcntMaskSliceGo(s, m) +} + +func popcntAndSlice(s, m []uint64) uint64 { + if useAsm { + return popcntAndSliceAsm(s, m) + } + return popcntAndSliceGo(s, m) +} + +func popcntOrSlice(s, m []uint64) uint64 { + if useAsm { + return popcntOrSliceAsm(s, m) + } + return popcntOrSliceGo(s, m) +} + +func popcntXorSlice(s, m []uint64) uint64 { + if useAsm { + return popcntXorSliceAsm(s, m) + } + return popcntXorSliceGo(s, m) +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/popcnt_compat.go b/backend/vendor/github.com/RoaringBitmap/roaring/popcnt_compat.go new file mode 100644 index 0000000000..7ae82d4c83 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/popcnt_compat.go @@ -0,0 +1,17 @@ +// +build !go1.9 + +package roaring + +// bit population count, take from +// https://code.google.com/p/go/issues/detail?id=4988#c11 +// credit: https://code.google.com/u/arnehormann/ +// credit: https://play.golang.org/p/U7SogJ7psJ +// credit: http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel +func popcount(x uint64) uint64 { + x -= (x >> 1) & 0x5555555555555555 + x = (x>>2)&0x3333333333333333 + x&0x3333333333333333 + x += x >> 4 + x &= 0x0f0f0f0f0f0f0f0f + x *= 0x0101010101010101 + return x >> 56 +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/popcnt_generic.go b/backend/vendor/github.com/RoaringBitmap/roaring/popcnt_generic.go new file mode 100644 index 0000000000..edf2083f19 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/popcnt_generic.go @@ -0,0 +1,23 @@ +// +build !amd64 appengine go1.9 + +package roaring + +func popcntSlice(s []uint64) uint64 { + return popcntSliceGo(s) +} + +func popcntMaskSlice(s, m []uint64) uint64 { + return popcntMaskSliceGo(s, m) +} + +func popcntAndSlice(s, m []uint64) uint64 { + return popcntAndSliceGo(s, m) +} + +func popcntOrSlice(s, m []uint64) uint64 { + return popcntOrSliceGo(s, m) +} + +func popcntXorSlice(s, m []uint64) uint64 { + return popcntXorSliceGo(s, m) +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/popcnt_slices.go b/backend/vendor/github.com/RoaringBitmap/roaring/popcnt_slices.go new file mode 100644 index 0000000000..d27c5f383d --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/popcnt_slices.go @@ -0,0 +1,41 @@ +package roaring + +func popcntSliceGo(s []uint64) uint64 { + cnt := uint64(0) + for _, x := range s { + cnt += popcount(x) + } + return cnt +} + +func popcntMaskSliceGo(s, m []uint64) uint64 { + cnt := uint64(0) + for i := range s { + cnt += popcount(s[i] &^ m[i]) + } + return cnt +} + +func popcntAndSliceGo(s, m []uint64) uint64 { + cnt := uint64(0) + for i := range s { + cnt += popcount(s[i] & m[i]) + } + return cnt +} + +func popcntOrSliceGo(s, m []uint64) uint64 { + cnt := uint64(0) + for i := range s { + cnt += popcount(s[i] | m[i]) + } + return cnt +} + +func popcntXorSliceGo(s, m []uint64) uint64 { + cnt := uint64(0) + for i := range s { + cnt += popcount(s[i] ^ m[i]) + } + return cnt +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/priorityqueue.go b/backend/vendor/github.com/RoaringBitmap/roaring/priorityqueue.go new file mode 100644 index 0000000000..9259a68163 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/priorityqueue.go @@ -0,0 +1,101 @@ +package roaring + +import "container/heap" + +///////////// +// The priorityQueue is used to keep Bitmaps sorted. +//////////// + +type item struct { + value *Bitmap + index int +} + +type priorityQueue []*item + +func (pq priorityQueue) Len() int { return len(pq) } + +func (pq priorityQueue) Less(i, j int) bool { + return pq[i].value.GetSizeInBytes() < pq[j].value.GetSizeInBytes() +} + +func (pq priorityQueue) Swap(i, j int) { + pq[i], pq[j] = pq[j], pq[i] + pq[i].index = i + pq[j].index = j +} + +func (pq *priorityQueue) Push(x interface{}) { + n := len(*pq) + item := x.(*item) + item.index = n + *pq = append(*pq, item) +} + +func (pq *priorityQueue) Pop() interface{} { + old := *pq + n := len(old) + item := old[n-1] + item.index = -1 // for safety + *pq = old[0 : n-1] + return item +} + +func (pq *priorityQueue) update(item *item, value *Bitmap) { + item.value = value + heap.Fix(pq, item.index) +} + +///////////// +// The containerPriorityQueue is used to keep the containers of various Bitmaps sorted. +//////////// + +type containeritem struct { + value *Bitmap + keyindex int + index int +} + +type containerPriorityQueue []*containeritem + +func (pq containerPriorityQueue) Len() int { return len(pq) } + +func (pq containerPriorityQueue) Less(i, j int) bool { + k1 := pq[i].value.highlowcontainer.getKeyAtIndex(pq[i].keyindex) + k2 := pq[j].value.highlowcontainer.getKeyAtIndex(pq[j].keyindex) + if k1 != k2 { + return k1 < k2 + } + c1 := pq[i].value.highlowcontainer.getContainerAtIndex(pq[i].keyindex) + c2 := pq[j].value.highlowcontainer.getContainerAtIndex(pq[j].keyindex) + + return c1.getCardinality() > c2.getCardinality() +} + +func (pq containerPriorityQueue) Swap(i, j int) { + pq[i], pq[j] = pq[j], pq[i] + pq[i].index = i + pq[j].index = j +} + +func (pq *containerPriorityQueue) Push(x interface{}) { + n := len(*pq) + item := x.(*containeritem) + item.index = n + *pq = append(*pq, item) +} + +func (pq *containerPriorityQueue) Pop() interface{} { + old := *pq + n := len(old) + item := old[n-1] + item.index = -1 // for safety + *pq = old[0 : n-1] + return item +} + +//func (pq *containerPriorityQueue) update(item *containeritem, value *Bitmap, keyindex int) { +// item.value = value +// item.keyindex = keyindex +// heap.Fix(pq, item.index) +//} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/roaring.go b/backend/vendor/github.com/RoaringBitmap/roaring/roaring.go new file mode 100644 index 0000000000..53068e4d93 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/roaring.go @@ -0,0 +1,1578 @@ +// Package roaring is an implementation of Roaring Bitmaps in Go. +// They provide fast compressed bitmap data structures (also called bitset). +// They are ideally suited to represent sets of integers over +// relatively small ranges. +// See http://roaringbitmap.org for details. +package roaring + +import ( + "bytes" + "encoding/base64" + "fmt" + "io" + "strconv" + + "github.com/RoaringBitmap/roaring/internal" +) + +// Bitmap represents a compressed bitmap where you can add integers. +type Bitmap struct { + highlowcontainer roaringArray +} + +// ToBase64 serializes a bitmap as Base64 +func (rb *Bitmap) ToBase64() (string, error) { + buf := new(bytes.Buffer) + _, err := rb.WriteTo(buf) + return base64.StdEncoding.EncodeToString(buf.Bytes()), err + +} + +// FromBase64 deserializes a bitmap from Base64 +func (rb *Bitmap) FromBase64(str string) (int64, error) { + data, err := base64.StdEncoding.DecodeString(str) + if err != nil { + return 0, err + } + buf := bytes.NewBuffer(data) + + return rb.ReadFrom(buf) +} + +// WriteTo writes a serialized version of this bitmap to stream. +// The format is compatible with other RoaringBitmap +// implementations (Java, C) and is documented here: +// https://github.com/RoaringBitmap/RoaringFormatSpec +func (rb *Bitmap) WriteTo(stream io.Writer) (int64, error) { + return rb.highlowcontainer.writeTo(stream) +} + +// ToBytes returns an array of bytes corresponding to what is written +// when calling WriteTo +func (rb *Bitmap) ToBytes() ([]byte, error) { + return rb.highlowcontainer.toBytes() +} + +// ReadFrom reads a serialized version of this bitmap from stream. +// The format is compatible with other RoaringBitmap +// implementations (Java, C) and is documented here: +// https://github.com/RoaringBitmap/RoaringFormatSpec +// Since io.Reader is regarded as a stream and cannot be read twice. +// So add cookieHeader to accept the 4-byte data that has been read in roaring64.ReadFrom. +// It is not necessary to pass cookieHeader when call roaring.ReadFrom to read the roaring32 data directly. +func (rb *Bitmap) ReadFrom(reader io.Reader, cookieHeader ...byte) (p int64, err error) { + stream := internal.ByteInputAdapterPool.Get().(*internal.ByteInputAdapter) + stream.Reset(reader) + + p, err = rb.highlowcontainer.readFrom(stream, cookieHeader...) + internal.ByteInputAdapterPool.Put(stream) + + return +} + +// FromBuffer creates a bitmap from its serialized version stored in buffer +// +// The format specification is available here: +// https://github.com/RoaringBitmap/RoaringFormatSpec +// +// The provided byte array (buf) is expected to be a constant. +// The function makes the best effort attempt not to copy data. +// You should take care not to modify buff as it will +// likely result in unexpected program behavior. +// +// Resulting bitmaps are effectively immutable in the following sense: +// a copy-on-write marker is used so that when you modify the resulting +// bitmap, copies of selected data (containers) are made. +// You should *not* change the copy-on-write status of the resulting +// bitmaps (SetCopyOnWrite). +// +// If buf becomes unavailable, then a bitmap created with +// FromBuffer would be effectively broken. Furthermore, any +// bitmap derived from this bitmap (e.g., via Or, And) might +// also be broken. Thus, before making buf unavailable, you should +// call CloneCopyOnWriteContainers on all such bitmaps. +// +func (rb *Bitmap) FromBuffer(buf []byte) (p int64, err error) { + stream := internal.ByteBufferPool.Get().(*internal.ByteBuffer) + stream.Reset(buf) + + p, err = rb.highlowcontainer.readFrom(stream) + internal.ByteBufferPool.Put(stream) + + return +} + +// RunOptimize attempts to further compress the runs of consecutive values found in the bitmap +func (rb *Bitmap) RunOptimize() { + rb.highlowcontainer.runOptimize() +} + +// HasRunCompression returns true if the bitmap benefits from run compression +func (rb *Bitmap) HasRunCompression() bool { + return rb.highlowcontainer.hasRunCompression() +} + +// MarshalBinary implements the encoding.BinaryMarshaler interface for the bitmap +// (same as ToBytes) +func (rb *Bitmap) MarshalBinary() ([]byte, error) { + return rb.ToBytes() +} + +// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface for the bitmap +func (rb *Bitmap) UnmarshalBinary(data []byte) error { + r := bytes.NewReader(data) + _, err := rb.ReadFrom(r) + return err +} + +// NewBitmap creates a new empty Bitmap (see also New) +func NewBitmap() *Bitmap { + return &Bitmap{} +} + +// New creates a new empty Bitmap (same as NewBitmap) +func New() *Bitmap { + return &Bitmap{} +} + +// Clear resets the Bitmap to be logically empty, but may retain +// some memory allocations that may speed up future operations +func (rb *Bitmap) Clear() { + rb.highlowcontainer.clear() +} + +// ToArray creates a new slice containing all of the integers stored in the Bitmap in sorted order +func (rb *Bitmap) ToArray() []uint32 { + array := make([]uint32, rb.GetCardinality()) + pos := 0 + pos2 := 0 + + for pos < rb.highlowcontainer.size() { + hs := uint32(rb.highlowcontainer.getKeyAtIndex(pos)) << 16 + c := rb.highlowcontainer.getContainerAtIndex(pos) + pos++ + pos2 = c.fillLeastSignificant16bits(array, pos2, hs) + } + return array +} + +// GetSizeInBytes estimates the memory usage of the Bitmap. Note that this +// might differ slightly from the amount of bytes required for persistent storage +func (rb *Bitmap) GetSizeInBytes() uint64 { + size := uint64(8) + for _, c := range rb.highlowcontainer.containers { + size += uint64(2) + uint64(c.getSizeInBytes()) + } + return size +} + +// GetSerializedSizeInBytes computes the serialized size in bytes +// of the Bitmap. It should correspond to the +// number of bytes written when invoking WriteTo. You can expect +// that this function is much cheaper computationally than WriteTo. +func (rb *Bitmap) GetSerializedSizeInBytes() uint64 { + return rb.highlowcontainer.serializedSizeInBytes() +} + +// BoundSerializedSizeInBytes returns an upper bound on the serialized size in bytes +// assuming that one wants to store "cardinality" integers in [0, universe_size) +func BoundSerializedSizeInBytes(cardinality uint64, universeSize uint64) uint64 { + contnbr := (universeSize + uint64(65535)) / uint64(65536) + if contnbr > cardinality { + contnbr = cardinality + // we can't have more containers than we have values + } + headermax := 8*contnbr + 4 + if 4 > (contnbr+7)/8 { + headermax += 4 + } else { + headermax += (contnbr + 7) / 8 + } + valsarray := uint64(arrayContainerSizeInBytes(int(cardinality))) + valsbitmap := contnbr * uint64(bitmapContainerSizeInBytes()) + valsbest := valsarray + if valsbest > valsbitmap { + valsbest = valsbitmap + } + return valsbest + headermax +} + +// IntIterable allows you to iterate over the values in a Bitmap +type IntIterable interface { + HasNext() bool + Next() uint32 +} + +// IntPeekable allows you to look at the next value without advancing and +// advance as long as the next value is smaller than minval +type IntPeekable interface { + IntIterable + // PeekNext peeks the next value without advancing the iterator + PeekNext() uint32 + // AdvanceIfNeeded advances as long as the next value is smaller than minval + AdvanceIfNeeded(minval uint32) +} + +type intIterator struct { + pos int + hs uint32 + iter shortPeekable + highlowcontainer *roaringArray +} + +// HasNext returns true if there are more integers to iterate over +func (ii *intIterator) HasNext() bool { + return ii.pos < ii.highlowcontainer.size() +} + +func (ii *intIterator) init() { + if ii.highlowcontainer.size() > ii.pos { + ii.iter = ii.highlowcontainer.getContainerAtIndex(ii.pos).getShortIterator() + ii.hs = uint32(ii.highlowcontainer.getKeyAtIndex(ii.pos)) << 16 + } +} + +// Next returns the next integer +func (ii *intIterator) Next() uint32 { + x := uint32(ii.iter.next()) | ii.hs + if !ii.iter.hasNext() { + ii.pos = ii.pos + 1 + ii.init() + } + return x +} + +// PeekNext peeks the next value without advancing the iterator +func (ii *intIterator) PeekNext() uint32 { + return uint32(ii.iter.peekNext()&maxLowBit) | ii.hs +} + +// AdvanceIfNeeded advances as long as the next value is smaller than minval +func (ii *intIterator) AdvanceIfNeeded(minval uint32) { + to := minval >> 16 + + for ii.HasNext() && (ii.hs>>16) < to { + ii.pos++ + ii.init() + } + + if ii.HasNext() && (ii.hs>>16) == to { + ii.iter.advanceIfNeeded(lowbits(minval)) + + if !ii.iter.hasNext() { + ii.pos++ + ii.init() + } + } +} + +func newIntIterator(a *Bitmap) *intIterator { + p := new(intIterator) + p.pos = 0 + p.highlowcontainer = &a.highlowcontainer + p.init() + return p +} + +type intReverseIterator struct { + pos int + hs uint32 + iter shortIterable + highlowcontainer *roaringArray +} + +// HasNext returns true if there are more integers to iterate over +func (ii *intReverseIterator) HasNext() bool { + return ii.pos >= 0 +} + +func (ii *intReverseIterator) init() { + if ii.pos >= 0 { + ii.iter = ii.highlowcontainer.getContainerAtIndex(ii.pos).getReverseIterator() + ii.hs = uint32(ii.highlowcontainer.getKeyAtIndex(ii.pos)) << 16 + } else { + ii.iter = nil + } +} + +// Next returns the next integer +func (ii *intReverseIterator) Next() uint32 { + x := uint32(ii.iter.next()) | ii.hs + if !ii.iter.hasNext() { + ii.pos = ii.pos - 1 + ii.init() + } + return x +} + +func newIntReverseIterator(a *Bitmap) *intReverseIterator { + p := new(intReverseIterator) + p.highlowcontainer = &a.highlowcontainer + p.pos = a.highlowcontainer.size() - 1 + p.init() + return p +} + +// ManyIntIterable allows you to iterate over the values in a Bitmap +type ManyIntIterable interface { + // NextMany fills buf up with values, returns how many values were returned + NextMany(buf []uint32) int + // NextMany64 fills up buf with 64 bit values, uses hs as a mask (OR), returns how many values were returned + NextMany64(hs uint64, buf []uint64) int +} + +type manyIntIterator struct { + pos int + hs uint32 + iter manyIterable + highlowcontainer *roaringArray +} + +func (ii *manyIntIterator) init() { + if ii.highlowcontainer.size() > ii.pos { + ii.iter = ii.highlowcontainer.getContainerAtIndex(ii.pos).getManyIterator() + ii.hs = uint32(ii.highlowcontainer.getKeyAtIndex(ii.pos)) << 16 + } else { + ii.iter = nil + } +} + +func (ii *manyIntIterator) NextMany(buf []uint32) int { + n := 0 + for n < len(buf) { + if ii.iter == nil { + break + } + moreN := ii.iter.nextMany(ii.hs, buf[n:]) + n += moreN + if moreN == 0 { + ii.pos = ii.pos + 1 + ii.init() + } + } + + return n +} + +func (ii *manyIntIterator) NextMany64(hs64 uint64, buf []uint64) int { + n := 0 + for n < len(buf) { + if ii.iter == nil { + break + } + + hs := uint64(ii.hs) | hs64 + moreN := ii.iter.nextMany64(hs, buf[n:]) + n += moreN + if moreN == 0 { + ii.pos = ii.pos + 1 + ii.init() + } + } + + return n +} + +func newManyIntIterator(a *Bitmap) *manyIntIterator { + p := new(manyIntIterator) + p.pos = 0 + p.highlowcontainer = &a.highlowcontainer + p.init() + return p +} + +// String creates a string representation of the Bitmap +func (rb *Bitmap) String() string { + // inspired by https://github.com/fzandona/goroar/ + var buffer bytes.Buffer + start := []byte("{") + buffer.Write(start) + i := rb.Iterator() + counter := 0 + if i.HasNext() { + counter = counter + 1 + buffer.WriteString(strconv.FormatInt(int64(i.Next()), 10)) + } + for i.HasNext() { + buffer.WriteString(",") + counter = counter + 1 + // to avoid exhausting the memory + if counter > 0x40000 { + buffer.WriteString("...") + break + } + buffer.WriteString(strconv.FormatInt(int64(i.Next()), 10)) + } + buffer.WriteString("}") + return buffer.String() +} + +// Iterate iterates over the bitmap, calling the given callback with each value in the bitmap. If the callback returns +// false, the iteration is halted. +// The iteration results are undefined if the bitmap is modified (e.g., with Add or Remove). +// There is no guarantee as to what order the values will be iterated +func (rb *Bitmap) Iterate(cb func(x uint32) bool) { + for i := 0; i < rb.highlowcontainer.size(); i++ { + hs := uint32(rb.highlowcontainer.getKeyAtIndex(i)) << 16 + c := rb.highlowcontainer.getContainerAtIndex(i) + + var shouldContinue bool + // This is hacky but it avoids allocations from invoking an interface method with a closure + switch t := c.(type) { + case *arrayContainer: + shouldContinue = t.iterate(func(x uint16) bool { + return cb(uint32(x) | hs) + }) + case *runContainer16: + shouldContinue = t.iterate(func(x uint16) bool { + return cb(uint32(x) | hs) + }) + case *bitmapContainer: + shouldContinue = t.iterate(func(x uint16) bool { + return cb(uint32(x) | hs) + }) + } + + if !shouldContinue { + break + } + } +} + +// Iterator creates a new IntPeekable to iterate over the integers contained in the bitmap, in sorted order; +// the iterator becomes invalid if the bitmap is modified (e.g., with Add or Remove). +func (rb *Bitmap) Iterator() IntPeekable { + return newIntIterator(rb) +} + +// ReverseIterator creates a new IntIterable to iterate over the integers contained in the bitmap, in sorted order; +// the iterator becomes invalid if the bitmap is modified (e.g., with Add or Remove). +func (rb *Bitmap) ReverseIterator() IntIterable { + return newIntReverseIterator(rb) +} + +// ManyIterator creates a new ManyIntIterable to iterate over the integers contained in the bitmap, in sorted order; +// the iterator becomes invalid if the bitmap is modified (e.g., with Add or Remove). +func (rb *Bitmap) ManyIterator() ManyIntIterable { + return newManyIntIterator(rb) +} + +// Clone creates a copy of the Bitmap +func (rb *Bitmap) Clone() *Bitmap { + ptr := new(Bitmap) + ptr.highlowcontainer = *rb.highlowcontainer.clone() + return ptr +} + +// Minimum get the smallest value stored in this roaring bitmap, assumes that it is not empty +func (rb *Bitmap) Minimum() uint32 { + return uint32(rb.highlowcontainer.containers[0].minimum()) | (uint32(rb.highlowcontainer.keys[0]) << 16) +} + +// Maximum get the largest value stored in this roaring bitmap, assumes that it is not empty +func (rb *Bitmap) Maximum() uint32 { + lastindex := len(rb.highlowcontainer.containers) - 1 + return uint32(rb.highlowcontainer.containers[lastindex].maximum()) | (uint32(rb.highlowcontainer.keys[lastindex]) << 16) +} + +// Contains returns true if the integer is contained in the bitmap +func (rb *Bitmap) Contains(x uint32) bool { + hb := highbits(x) + c := rb.highlowcontainer.getContainer(hb) + return c != nil && c.contains(lowbits(x)) +} + +// ContainsInt returns true if the integer is contained in the bitmap (this is a convenience method, the parameter is casted to uint32 and Contains is called) +func (rb *Bitmap) ContainsInt(x int) bool { + return rb.Contains(uint32(x)) +} + +// Equals returns true if the two bitmaps contain the same integers +func (rb *Bitmap) Equals(o interface{}) bool { + srb, ok := o.(*Bitmap) + if ok { + return srb.highlowcontainer.equals(rb.highlowcontainer) + } + return false +} + +// AddOffset adds the value 'offset' to each and every value in a bitmap, generating a new bitmap in the process +func AddOffset(x *Bitmap, offset uint32) (answer *Bitmap) { + return AddOffset64(x, int64(offset)) +} + +// AddOffset64 adds the value 'offset' to each and every value in a bitmap, generating a new bitmap in the process +// If offset + element is outside of the range [0,2^32), that the element will be dropped +func AddOffset64(x *Bitmap, offset int64) (answer *Bitmap) { + // we need "offset" to be a long because we want to support values + // between -0xFFFFFFFF up to +-0xFFFFFFFF + var containerOffset64 int64 + + if offset < 0 { + containerOffset64 = (offset - (1 << 16) + 1) / (1 << 16) + } else { + containerOffset64 = offset >> 16 + } + + if containerOffset64 >= (1<<16) || containerOffset64 <= -(1<<16) { + return New() + } + + containerOffset := int32(containerOffset64) + inOffset := (uint16)(offset - containerOffset64*(1<<16)) + + if inOffset == 0 { + answer = x.Clone() + for pos := 0; pos < answer.highlowcontainer.size(); pos++ { + key := int32(answer.highlowcontainer.getKeyAtIndex(pos)) + key += containerOffset + + if key >= 0 && key <= MaxUint16 { + answer.highlowcontainer.keys[pos] = uint16(key) + } + } + } else { + answer = New() + + for pos := 0; pos < x.highlowcontainer.size(); pos++ { + key := int32(x.highlowcontainer.getKeyAtIndex(pos)) + key += containerOffset + + c := x.highlowcontainer.getContainerAtIndex(pos) + offsetted := c.addOffset(inOffset) + + if !offsetted[0].isEmpty() && (key >= 0 && key <= MaxUint16) { + curSize := answer.highlowcontainer.size() + lastkey := int32(0) + + if curSize > 0 { + lastkey = int32(answer.highlowcontainer.getKeyAtIndex(curSize - 1)) + } + + if curSize > 0 && lastkey == key { + prev := answer.highlowcontainer.getContainerAtIndex(curSize - 1) + orrseult := prev.ior(offsetted[0]) + answer.highlowcontainer.setContainerAtIndex(curSize-1, orrseult) + } else { + answer.highlowcontainer.appendContainer(uint16(key), offsetted[0], false) + } + } + + if !offsetted[1].isEmpty() && ((key+1) >= 0 && (key+1) <= MaxUint16) { + answer.highlowcontainer.appendContainer(uint16(key+1), offsetted[1], false) + } + } + } + + return answer +} + +// Add the integer x to the bitmap +func (rb *Bitmap) Add(x uint32) { + hb := highbits(x) + ra := &rb.highlowcontainer + i := ra.getIndex(hb) + if i >= 0 { + var c container + c = ra.getWritableContainerAtIndex(i).iaddReturnMinimized(lowbits(x)) + rb.highlowcontainer.setContainerAtIndex(i, c) + } else { + newac := newArrayContainer() + rb.highlowcontainer.insertNewKeyValueAt(-i-1, hb, newac.iaddReturnMinimized(lowbits(x))) + } +} + +// add the integer x to the bitmap, return the container and its index +func (rb *Bitmap) addwithptr(x uint32) (int, container) { + hb := highbits(x) + ra := &rb.highlowcontainer + i := ra.getIndex(hb) + var c container + if i >= 0 { + c = ra.getWritableContainerAtIndex(i).iaddReturnMinimized(lowbits(x)) + rb.highlowcontainer.setContainerAtIndex(i, c) + return i, c + } + newac := newArrayContainer() + c = newac.iaddReturnMinimized(lowbits(x)) + rb.highlowcontainer.insertNewKeyValueAt(-i-1, hb, c) + return -i - 1, c +} + +// CheckedAdd adds the integer x to the bitmap and return true if it was added (false if the integer was already present) +func (rb *Bitmap) CheckedAdd(x uint32) bool { + // TODO: add unit tests for this method + hb := highbits(x) + i := rb.highlowcontainer.getIndex(hb) + if i >= 0 { + C := rb.highlowcontainer.getWritableContainerAtIndex(i) + oldcard := C.getCardinality() + C = C.iaddReturnMinimized(lowbits(x)) + rb.highlowcontainer.setContainerAtIndex(i, C) + return C.getCardinality() > oldcard + } + newac := newArrayContainer() + rb.highlowcontainer.insertNewKeyValueAt(-i-1, hb, newac.iaddReturnMinimized(lowbits(x))) + return true + +} + +// AddInt adds the integer x to the bitmap (convenience method: the parameter is casted to uint32 and we call Add) +func (rb *Bitmap) AddInt(x int) { + rb.Add(uint32(x)) +} + +// Remove the integer x from the bitmap +func (rb *Bitmap) Remove(x uint32) { + hb := highbits(x) + i := rb.highlowcontainer.getIndex(hb) + if i >= 0 { + c := rb.highlowcontainer.getWritableContainerAtIndex(i).iremoveReturnMinimized(lowbits(x)) + rb.highlowcontainer.setContainerAtIndex(i, c) + if rb.highlowcontainer.getContainerAtIndex(i).isEmpty() { + rb.highlowcontainer.removeAtIndex(i) + } + } +} + +// CheckedRemove removes the integer x from the bitmap and return true if the integer was effectively removed (and false if the integer was not present) +func (rb *Bitmap) CheckedRemove(x uint32) bool { + // TODO: add unit tests for this method + hb := highbits(x) + i := rb.highlowcontainer.getIndex(hb) + if i >= 0 { + C := rb.highlowcontainer.getWritableContainerAtIndex(i) + oldcard := C.getCardinality() + C = C.iremoveReturnMinimized(lowbits(x)) + rb.highlowcontainer.setContainerAtIndex(i, C) + if rb.highlowcontainer.getContainerAtIndex(i).isEmpty() { + rb.highlowcontainer.removeAtIndex(i) + return true + } + return C.getCardinality() < oldcard + } + return false + +} + +// IsEmpty returns true if the Bitmap is empty (it is faster than doing (GetCardinality() == 0)) +func (rb *Bitmap) IsEmpty() bool { + return rb.highlowcontainer.size() == 0 +} + +// GetCardinality returns the number of integers contained in the bitmap +func (rb *Bitmap) GetCardinality() uint64 { + size := uint64(0) + for _, c := range rb.highlowcontainer.containers { + size += uint64(c.getCardinality()) + } + return size +} + +// Rank returns the number of integers that are smaller or equal to x (Rank(infinity) would be GetCardinality()). +// If you pass the smallest value, you get the value 1. If you pass a value that is smaller than the smallest +// value, you get 0. Note that this function differs in convention from the Select function since it +// return 1 and not 0 on the smallest value. +func (rb *Bitmap) Rank(x uint32) uint64 { + size := uint64(0) + for i := 0; i < rb.highlowcontainer.size(); i++ { + key := rb.highlowcontainer.getKeyAtIndex(i) + if key > highbits(x) { + return size + } + if key < highbits(x) { + size += uint64(rb.highlowcontainer.getContainerAtIndex(i).getCardinality()) + } else { + return size + uint64(rb.highlowcontainer.getContainerAtIndex(i).rank(lowbits(x))) + } + } + return size +} + +// Select returns the xth integer in the bitmap. If you pass 0, you get +// the smallest element. Note that this function differs in convention from +// the Rank function which returns 1 on the smallest value. +func (rb *Bitmap) Select(x uint32) (uint32, error) { + if rb.GetCardinality() <= uint64(x) { + return 0, fmt.Errorf("can't find %dth integer in a bitmap with only %d items", x, rb.GetCardinality()) + } + + remaining := x + for i := 0; i < rb.highlowcontainer.size(); i++ { + c := rb.highlowcontainer.getContainerAtIndex(i) + card := uint32(c.getCardinality()) + if remaining >= card { + remaining -= card + } else { + key := rb.highlowcontainer.getKeyAtIndex(i) + return uint32(key)<<16 + uint32(c.selectInt(uint16(remaining))), nil + } + } + return 0, fmt.Errorf("can't find %dth integer in a bitmap with only %d items", x, rb.GetCardinality()) +} + +// And computes the intersection between two bitmaps and stores the result in the current bitmap +func (rb *Bitmap) And(x2 *Bitmap) { + pos1 := 0 + pos2 := 0 + intersectionsize := 0 + length1 := rb.highlowcontainer.size() + length2 := x2.highlowcontainer.size() + +main: + for { + if pos1 < length1 && pos2 < length2 { + s1 := rb.highlowcontainer.getKeyAtIndex(pos1) + s2 := x2.highlowcontainer.getKeyAtIndex(pos2) + for { + if s1 == s2 { + c1 := rb.highlowcontainer.getWritableContainerAtIndex(pos1) + c2 := x2.highlowcontainer.getContainerAtIndex(pos2) + diff := c1.iand(c2) + if !diff.isEmpty() { + rb.highlowcontainer.replaceKeyAndContainerAtIndex(intersectionsize, s1, diff, false) + intersectionsize++ + } + pos1++ + pos2++ + if (pos1 == length1) || (pos2 == length2) { + break main + } + s1 = rb.highlowcontainer.getKeyAtIndex(pos1) + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } else if s1 < s2 { + pos1 = rb.highlowcontainer.advanceUntil(s2, pos1) + if pos1 == length1 { + break main + } + s1 = rb.highlowcontainer.getKeyAtIndex(pos1) + } else { //s1 > s2 + pos2 = x2.highlowcontainer.advanceUntil(s1, pos2) + if pos2 == length2 { + break main + } + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } + } + } else { + break + } + } + rb.highlowcontainer.resize(intersectionsize) +} + +// OrCardinality returns the cardinality of the union between two bitmaps, bitmaps are not modified +func (rb *Bitmap) OrCardinality(x2 *Bitmap) uint64 { + pos1 := 0 + pos2 := 0 + length1 := rb.highlowcontainer.size() + length2 := x2.highlowcontainer.size() + answer := uint64(0) +main: + for { + if (pos1 < length1) && (pos2 < length2) { + s1 := rb.highlowcontainer.getKeyAtIndex(pos1) + s2 := x2.highlowcontainer.getKeyAtIndex(pos2) + + for { + if s1 < s2 { + answer += uint64(rb.highlowcontainer.getContainerAtIndex(pos1).getCardinality()) + pos1++ + if pos1 == length1 { + break main + } + s1 = rb.highlowcontainer.getKeyAtIndex(pos1) + } else if s1 > s2 { + answer += uint64(x2.highlowcontainer.getContainerAtIndex(pos2).getCardinality()) + pos2++ + if pos2 == length2 { + break main + } + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } else { + // TODO: could be faster if we did not have to materialize the container + answer += uint64(rb.highlowcontainer.getContainerAtIndex(pos1).or(x2.highlowcontainer.getContainerAtIndex(pos2)).getCardinality()) + pos1++ + pos2++ + if (pos1 == length1) || (pos2 == length2) { + break main + } + s1 = rb.highlowcontainer.getKeyAtIndex(pos1) + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } + } + } else { + break + } + } + for ; pos1 < length1; pos1++ { + answer += uint64(rb.highlowcontainer.getContainerAtIndex(pos1).getCardinality()) + } + for ; pos2 < length2; pos2++ { + answer += uint64(x2.highlowcontainer.getContainerAtIndex(pos2).getCardinality()) + } + return answer +} + +// AndCardinality returns the cardinality of the intersection between two bitmaps, bitmaps are not modified +func (rb *Bitmap) AndCardinality(x2 *Bitmap) uint64 { + pos1 := 0 + pos2 := 0 + answer := uint64(0) + length1 := rb.highlowcontainer.size() + length2 := x2.highlowcontainer.size() + +main: + for { + if pos1 < length1 && pos2 < length2 { + s1 := rb.highlowcontainer.getKeyAtIndex(pos1) + s2 := x2.highlowcontainer.getKeyAtIndex(pos2) + for { + if s1 == s2 { + c1 := rb.highlowcontainer.getContainerAtIndex(pos1) + c2 := x2.highlowcontainer.getContainerAtIndex(pos2) + answer += uint64(c1.andCardinality(c2)) + pos1++ + pos2++ + if (pos1 == length1) || (pos2 == length2) { + break main + } + s1 = rb.highlowcontainer.getKeyAtIndex(pos1) + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } else if s1 < s2 { + pos1 = rb.highlowcontainer.advanceUntil(s2, pos1) + if pos1 == length1 { + break main + } + s1 = rb.highlowcontainer.getKeyAtIndex(pos1) + } else { //s1 > s2 + pos2 = x2.highlowcontainer.advanceUntil(s1, pos2) + if pos2 == length2 { + break main + } + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } + } + } else { + break + } + } + return answer +} + +// Intersects checks whether two bitmap intersects, bitmaps are not modified +func (rb *Bitmap) Intersects(x2 *Bitmap) bool { + pos1 := 0 + pos2 := 0 + length1 := rb.highlowcontainer.size() + length2 := x2.highlowcontainer.size() + +main: + for { + if pos1 < length1 && pos2 < length2 { + s1 := rb.highlowcontainer.getKeyAtIndex(pos1) + s2 := x2.highlowcontainer.getKeyAtIndex(pos2) + for { + if s1 == s2 { + c1 := rb.highlowcontainer.getContainerAtIndex(pos1) + c2 := x2.highlowcontainer.getContainerAtIndex(pos2) + if c1.intersects(c2) { + return true + } + pos1++ + pos2++ + if (pos1 == length1) || (pos2 == length2) { + break main + } + s1 = rb.highlowcontainer.getKeyAtIndex(pos1) + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } else if s1 < s2 { + pos1 = rb.highlowcontainer.advanceUntil(s2, pos1) + if pos1 == length1 { + break main + } + s1 = rb.highlowcontainer.getKeyAtIndex(pos1) + } else { //s1 > s2 + pos2 = x2.highlowcontainer.advanceUntil(s1, pos2) + if pos2 == length2 { + break main + } + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } + } + } else { + break + } + } + return false +} + +// Xor computes the symmetric difference between two bitmaps and stores the result in the current bitmap +func (rb *Bitmap) Xor(x2 *Bitmap) { + pos1 := 0 + pos2 := 0 + length1 := rb.highlowcontainer.size() + length2 := x2.highlowcontainer.size() + for { + if (pos1 < length1) && (pos2 < length2) { + s1 := rb.highlowcontainer.getKeyAtIndex(pos1) + s2 := x2.highlowcontainer.getKeyAtIndex(pos2) + if s1 < s2 { + pos1 = rb.highlowcontainer.advanceUntil(s2, pos1) + if pos1 == length1 { + break + } + } else if s1 > s2 { + c := x2.highlowcontainer.getWritableContainerAtIndex(pos2) + rb.highlowcontainer.insertNewKeyValueAt(pos1, x2.highlowcontainer.getKeyAtIndex(pos2), c) + length1++ + pos1++ + pos2++ + } else { + // TODO: couple be computed in-place for reduced memory usage + c := rb.highlowcontainer.getContainerAtIndex(pos1).xor(x2.highlowcontainer.getContainerAtIndex(pos2)) + if !c.isEmpty() { + rb.highlowcontainer.setContainerAtIndex(pos1, c) + pos1++ + } else { + rb.highlowcontainer.removeAtIndex(pos1) + length1-- + } + pos2++ + } + } else { + break + } + } + if pos1 == length1 { + rb.highlowcontainer.appendCopyMany(x2.highlowcontainer, pos2, length2) + } +} + +// Or computes the union between two bitmaps and stores the result in the current bitmap +func (rb *Bitmap) Or(x2 *Bitmap) { + pos1 := 0 + pos2 := 0 + length1 := rb.highlowcontainer.size() + length2 := x2.highlowcontainer.size() +main: + for (pos1 < length1) && (pos2 < length2) { + s1 := rb.highlowcontainer.getKeyAtIndex(pos1) + s2 := x2.highlowcontainer.getKeyAtIndex(pos2) + + for { + if s1 < s2 { + pos1++ + if pos1 == length1 { + break main + } + s1 = rb.highlowcontainer.getKeyAtIndex(pos1) + } else if s1 > s2 { + rb.highlowcontainer.insertNewKeyValueAt(pos1, s2, x2.highlowcontainer.getContainerAtIndex(pos2).clone()) + pos1++ + length1++ + pos2++ + if pos2 == length2 { + break main + } + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } else { + rb.highlowcontainer.replaceKeyAndContainerAtIndex(pos1, s1, rb.highlowcontainer.getUnionedWritableContainer(pos1, x2.highlowcontainer.getContainerAtIndex(pos2)), false) + pos1++ + pos2++ + if (pos1 == length1) || (pos2 == length2) { + break main + } + s1 = rb.highlowcontainer.getKeyAtIndex(pos1) + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } + } + } + if pos1 == length1 { + rb.highlowcontainer.appendCopyMany(x2.highlowcontainer, pos2, length2) + } +} + +// AndNot computes the difference between two bitmaps and stores the result in the current bitmap +func (rb *Bitmap) AndNot(x2 *Bitmap) { + pos1 := 0 + pos2 := 0 + intersectionsize := 0 + length1 := rb.highlowcontainer.size() + length2 := x2.highlowcontainer.size() + +main: + for { + if pos1 < length1 && pos2 < length2 { + s1 := rb.highlowcontainer.getKeyAtIndex(pos1) + s2 := x2.highlowcontainer.getKeyAtIndex(pos2) + for { + if s1 == s2 { + c1 := rb.highlowcontainer.getWritableContainerAtIndex(pos1) + c2 := x2.highlowcontainer.getContainerAtIndex(pos2) + diff := c1.iandNot(c2) + if !diff.isEmpty() { + rb.highlowcontainer.replaceKeyAndContainerAtIndex(intersectionsize, s1, diff, false) + intersectionsize++ + } + pos1++ + pos2++ + if (pos1 == length1) || (pos2 == length2) { + break main + } + s1 = rb.highlowcontainer.getKeyAtIndex(pos1) + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } else if s1 < s2 { + c1 := rb.highlowcontainer.getContainerAtIndex(pos1) + mustCopyOnWrite := rb.highlowcontainer.needsCopyOnWrite(pos1) + rb.highlowcontainer.replaceKeyAndContainerAtIndex(intersectionsize, s1, c1, mustCopyOnWrite) + intersectionsize++ + pos1++ + if pos1 == length1 { + break main + } + s1 = rb.highlowcontainer.getKeyAtIndex(pos1) + } else { //s1 > s2 + pos2 = x2.highlowcontainer.advanceUntil(s1, pos2) + if pos2 == length2 { + break main + } + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } + } + } else { + break + } + } + // TODO:implement as a copy + for pos1 < length1 { + c1 := rb.highlowcontainer.getContainerAtIndex(pos1) + s1 := rb.highlowcontainer.getKeyAtIndex(pos1) + mustCopyOnWrite := rb.highlowcontainer.needsCopyOnWrite(pos1) + rb.highlowcontainer.replaceKeyAndContainerAtIndex(intersectionsize, s1, c1, mustCopyOnWrite) + intersectionsize++ + pos1++ + } + rb.highlowcontainer.resize(intersectionsize) +} + +// Or computes the union between two bitmaps and returns the result +func Or(x1, x2 *Bitmap) *Bitmap { + answer := NewBitmap() + pos1 := 0 + pos2 := 0 + length1 := x1.highlowcontainer.size() + length2 := x2.highlowcontainer.size() +main: + for (pos1 < length1) && (pos2 < length2) { + s1 := x1.highlowcontainer.getKeyAtIndex(pos1) + s2 := x2.highlowcontainer.getKeyAtIndex(pos2) + + for { + if s1 < s2 { + answer.highlowcontainer.appendCopy(x1.highlowcontainer, pos1) + pos1++ + if pos1 == length1 { + break main + } + s1 = x1.highlowcontainer.getKeyAtIndex(pos1) + } else if s1 > s2 { + answer.highlowcontainer.appendCopy(x2.highlowcontainer, pos2) + pos2++ + if pos2 == length2 { + break main + } + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } else { + + answer.highlowcontainer.appendContainer(s1, x1.highlowcontainer.getContainerAtIndex(pos1).or(x2.highlowcontainer.getContainerAtIndex(pos2)), false) + pos1++ + pos2++ + if (pos1 == length1) || (pos2 == length2) { + break main + } + s1 = x1.highlowcontainer.getKeyAtIndex(pos1) + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } + } + } + if pos1 == length1 { + answer.highlowcontainer.appendCopyMany(x2.highlowcontainer, pos2, length2) + } else if pos2 == length2 { + answer.highlowcontainer.appendCopyMany(x1.highlowcontainer, pos1, length1) + } + return answer +} + +// And computes the intersection between two bitmaps and returns the result +func And(x1, x2 *Bitmap) *Bitmap { + answer := NewBitmap() + pos1 := 0 + pos2 := 0 + length1 := x1.highlowcontainer.size() + length2 := x2.highlowcontainer.size() +main: + for pos1 < length1 && pos2 < length2 { + s1 := x1.highlowcontainer.getKeyAtIndex(pos1) + s2 := x2.highlowcontainer.getKeyAtIndex(pos2) + for { + if s1 == s2 { + C := x1.highlowcontainer.getContainerAtIndex(pos1) + C = C.and(x2.highlowcontainer.getContainerAtIndex(pos2)) + + if !C.isEmpty() { + answer.highlowcontainer.appendContainer(s1, C, false) + } + pos1++ + pos2++ + if (pos1 == length1) || (pos2 == length2) { + break main + } + s1 = x1.highlowcontainer.getKeyAtIndex(pos1) + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } else if s1 < s2 { + pos1 = x1.highlowcontainer.advanceUntil(s2, pos1) + if pos1 == length1 { + break main + } + s1 = x1.highlowcontainer.getKeyAtIndex(pos1) + } else { // s1 > s2 + pos2 = x2.highlowcontainer.advanceUntil(s1, pos2) + if pos2 == length2 { + break main + } + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } + } + } + return answer +} + +// Xor computes the symmetric difference between two bitmaps and returns the result +func Xor(x1, x2 *Bitmap) *Bitmap { + answer := NewBitmap() + pos1 := 0 + pos2 := 0 + length1 := x1.highlowcontainer.size() + length2 := x2.highlowcontainer.size() + for { + if (pos1 < length1) && (pos2 < length2) { + s1 := x1.highlowcontainer.getKeyAtIndex(pos1) + s2 := x2.highlowcontainer.getKeyAtIndex(pos2) + if s1 < s2 { + answer.highlowcontainer.appendCopy(x1.highlowcontainer, pos1) + pos1++ + } else if s1 > s2 { + answer.highlowcontainer.appendCopy(x2.highlowcontainer, pos2) + pos2++ + } else { + c := x1.highlowcontainer.getContainerAtIndex(pos1).xor(x2.highlowcontainer.getContainerAtIndex(pos2)) + if !c.isEmpty() { + answer.highlowcontainer.appendContainer(s1, c, false) + } + pos1++ + pos2++ + } + } else { + break + } + } + if pos1 == length1 { + answer.highlowcontainer.appendCopyMany(x2.highlowcontainer, pos2, length2) + } else if pos2 == length2 { + answer.highlowcontainer.appendCopyMany(x1.highlowcontainer, pos1, length1) + } + return answer +} + +// AndNot computes the difference between two bitmaps and returns the result +func AndNot(x1, x2 *Bitmap) *Bitmap { + answer := NewBitmap() + pos1 := 0 + pos2 := 0 + length1 := x1.highlowcontainer.size() + length2 := x2.highlowcontainer.size() + +main: + for { + if pos1 < length1 && pos2 < length2 { + s1 := x1.highlowcontainer.getKeyAtIndex(pos1) + s2 := x2.highlowcontainer.getKeyAtIndex(pos2) + for { + if s1 < s2 { + answer.highlowcontainer.appendCopy(x1.highlowcontainer, pos1) + pos1++ + if pos1 == length1 { + break main + } + s1 = x1.highlowcontainer.getKeyAtIndex(pos1) + } else if s1 == s2 { + c1 := x1.highlowcontainer.getContainerAtIndex(pos1) + c2 := x2.highlowcontainer.getContainerAtIndex(pos2) + diff := c1.andNot(c2) + if !diff.isEmpty() { + answer.highlowcontainer.appendContainer(s1, diff, false) + } + pos1++ + pos2++ + if (pos1 == length1) || (pos2 == length2) { + break main + } + s1 = x1.highlowcontainer.getKeyAtIndex(pos1) + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } else { //s1 > s2 + pos2 = x2.highlowcontainer.advanceUntil(s1, pos2) + if pos2 == length2 { + break main + } + s2 = x2.highlowcontainer.getKeyAtIndex(pos2) + } + } + } else { + break + } + } + if pos2 == length2 { + answer.highlowcontainer.appendCopyMany(x1.highlowcontainer, pos1, length1) + } + return answer +} + +// AddMany add all of the values in dat +func (rb *Bitmap) AddMany(dat []uint32) { + if len(dat) == 0 { + return + } + prev := dat[0] + idx, c := rb.addwithptr(prev) + for _, i := range dat[1:] { + if highbits(prev) == highbits(i) { + c = c.iaddReturnMinimized(lowbits(i)) + rb.highlowcontainer.setContainerAtIndex(idx, c) + } else { + idx, c = rb.addwithptr(i) + } + prev = i + } +} + +// BitmapOf generates a new bitmap filled with the specified integers +func BitmapOf(dat ...uint32) *Bitmap { + ans := NewBitmap() + ans.AddMany(dat) + return ans +} + +// Flip negates the bits in the given range (i.e., [rangeStart,rangeEnd)), any integer present in this range and in the bitmap is removed, +// and any integer present in the range and not in the bitmap is added. +// The function uses 64-bit parameters even though a Bitmap stores 32-bit values because it is allowed and meaningful to use [0,uint64(0x100000000)) as a range +// while uint64(0x100000000) cannot be represented as a 32-bit value. +func (rb *Bitmap) Flip(rangeStart, rangeEnd uint64) { + + if rangeEnd > MaxUint32+1 { + panic("rangeEnd > MaxUint32+1") + } + if rangeStart > MaxUint32+1 { + panic("rangeStart > MaxUint32+1") + } + + if rangeStart >= rangeEnd { + return + } + + hbStart := uint32(highbits(uint32(rangeStart))) + lbStart := uint32(lowbits(uint32(rangeStart))) + hbLast := uint32(highbits(uint32(rangeEnd - 1))) + lbLast := uint32(lowbits(uint32(rangeEnd - 1))) + + var max uint32 = maxLowBit + for hb := hbStart; hb <= hbLast; hb++ { + var containerStart uint32 + if hb == hbStart { + containerStart = uint32(lbStart) + } + containerLast := max + if hb == hbLast { + containerLast = uint32(lbLast) + } + + i := rb.highlowcontainer.getIndex(uint16(hb)) + + if i >= 0 { + c := rb.highlowcontainer.getWritableContainerAtIndex(i).inot(int(containerStart), int(containerLast)+1) + if !c.isEmpty() { + rb.highlowcontainer.setContainerAtIndex(i, c) + } else { + rb.highlowcontainer.removeAtIndex(i) + } + } else { // *think* the range of ones must never be + // empty. + rb.highlowcontainer.insertNewKeyValueAt(-i-1, uint16(hb), rangeOfOnes(int(containerStart), int(containerLast))) + } + } +} + +// FlipInt calls Flip after casting the parameters (convenience method) +func (rb *Bitmap) FlipInt(rangeStart, rangeEnd int) { + rb.Flip(uint64(rangeStart), uint64(rangeEnd)) +} + +// AddRange adds the integers in [rangeStart, rangeEnd) to the bitmap. +// The function uses 64-bit parameters even though a Bitmap stores 32-bit values because it is allowed and meaningful to use [0,uint64(0x100000000)) as a range +// while uint64(0x100000000) cannot be represented as a 32-bit value. +func (rb *Bitmap) AddRange(rangeStart, rangeEnd uint64) { + if rangeStart >= rangeEnd { + return + } + if rangeEnd-1 > MaxUint32 { + panic("rangeEnd-1 > MaxUint32") + } + hbStart := uint32(highbits(uint32(rangeStart))) + lbStart := uint32(lowbits(uint32(rangeStart))) + hbLast := uint32(highbits(uint32(rangeEnd - 1))) + lbLast := uint32(lowbits(uint32(rangeEnd - 1))) + + var max uint32 = maxLowBit + for hb := hbStart; hb <= hbLast; hb++ { + containerStart := uint32(0) + if hb == hbStart { + containerStart = lbStart + } + containerLast := max + if hb == hbLast { + containerLast = lbLast + } + + i := rb.highlowcontainer.getIndex(uint16(hb)) + + if i >= 0 { + c := rb.highlowcontainer.getWritableContainerAtIndex(i).iaddRange(int(containerStart), int(containerLast)+1) + rb.highlowcontainer.setContainerAtIndex(i, c) + } else { // *think* the range of ones must never be + // empty. + rb.highlowcontainer.insertNewKeyValueAt(-i-1, uint16(hb), rangeOfOnes(int(containerStart), int(containerLast))) + } + } +} + +// RemoveRange removes the integers in [rangeStart, rangeEnd) from the bitmap. +// The function uses 64-bit parameters even though a Bitmap stores 32-bit values because it is allowed and meaningful to use [0,uint64(0x100000000)) as a range +// while uint64(0x100000000) cannot be represented as a 32-bit value. +func (rb *Bitmap) RemoveRange(rangeStart, rangeEnd uint64) { + if rangeStart >= rangeEnd { + return + } + if rangeEnd-1 > MaxUint32 { + // logically, we should assume that the user wants to + // remove all values from rangeStart to infinity + // see https://github.com/RoaringBitmap/roaring/issues/141 + rangeEnd = uint64(0x100000000) + } + hbStart := uint32(highbits(uint32(rangeStart))) + lbStart := uint32(lowbits(uint32(rangeStart))) + hbLast := uint32(highbits(uint32(rangeEnd - 1))) + lbLast := uint32(lowbits(uint32(rangeEnd - 1))) + + var max uint32 = maxLowBit + + if hbStart == hbLast { + i := rb.highlowcontainer.getIndex(uint16(hbStart)) + if i < 0 { + return + } + c := rb.highlowcontainer.getWritableContainerAtIndex(i).iremoveRange(int(lbStart), int(lbLast+1)) + if !c.isEmpty() { + rb.highlowcontainer.setContainerAtIndex(i, c) + } else { + rb.highlowcontainer.removeAtIndex(i) + } + return + } + ifirst := rb.highlowcontainer.getIndex(uint16(hbStart)) + ilast := rb.highlowcontainer.getIndex(uint16(hbLast)) + + if ifirst >= 0 { + if lbStart != 0 { + c := rb.highlowcontainer.getWritableContainerAtIndex(ifirst).iremoveRange(int(lbStart), int(max+1)) + if !c.isEmpty() { + rb.highlowcontainer.setContainerAtIndex(ifirst, c) + ifirst++ + } + } + } else { + ifirst = -ifirst - 1 + } + if ilast >= 0 { + if lbLast != max { + c := rb.highlowcontainer.getWritableContainerAtIndex(ilast).iremoveRange(int(0), int(lbLast+1)) + if !c.isEmpty() { + rb.highlowcontainer.setContainerAtIndex(ilast, c) + } else { + ilast++ + } + } else { + ilast++ + } + } else { + ilast = -ilast - 1 + } + rb.highlowcontainer.removeIndexRange(ifirst, ilast) +} + +// Flip negates the bits in the given range (i.e., [rangeStart,rangeEnd)), any integer present in this range and in the bitmap is removed, +// and any integer present in the range and not in the bitmap is added, a new bitmap is returned leaving +// the current bitmap unchanged. +// The function uses 64-bit parameters even though a Bitmap stores 32-bit values because it is allowed and meaningful to use [0,uint64(0x100000000)) as a range +// while uint64(0x100000000) cannot be represented as a 32-bit value. +func Flip(bm *Bitmap, rangeStart, rangeEnd uint64) *Bitmap { + if rangeStart >= rangeEnd { + return bm.Clone() + } + + if rangeStart > MaxUint32 { + panic("rangeStart > MaxUint32") + } + if rangeEnd-1 > MaxUint32 { + panic("rangeEnd-1 > MaxUint32") + } + + answer := NewBitmap() + hbStart := uint32(highbits(uint32(rangeStart))) + lbStart := uint32(lowbits(uint32(rangeStart))) + hbLast := uint32(highbits(uint32(rangeEnd - 1))) + lbLast := uint32(lowbits(uint32(rangeEnd - 1))) + + // copy the containers before the active area + answer.highlowcontainer.appendCopiesUntil(bm.highlowcontainer, uint16(hbStart)) + + var max uint32 = maxLowBit + for hb := hbStart; hb <= hbLast; hb++ { + var containerStart uint32 + if hb == hbStart { + containerStart = uint32(lbStart) + } + containerLast := max + if hb == hbLast { + containerLast = uint32(lbLast) + } + + i := bm.highlowcontainer.getIndex(uint16(hb)) + j := answer.highlowcontainer.getIndex(uint16(hb)) + + if i >= 0 { + c := bm.highlowcontainer.getContainerAtIndex(i).not(int(containerStart), int(containerLast)+1) + if !c.isEmpty() { + answer.highlowcontainer.insertNewKeyValueAt(-j-1, uint16(hb), c) + } + + } else { // *think* the range of ones must never be + // empty. + answer.highlowcontainer.insertNewKeyValueAt(-j-1, uint16(hb), + rangeOfOnes(int(containerStart), int(containerLast))) + } + } + // copy the containers after the active area. + answer.highlowcontainer.appendCopiesAfter(bm.highlowcontainer, uint16(hbLast)) + + return answer +} + +// SetCopyOnWrite sets this bitmap to use copy-on-write so that copies are fast and memory conscious +// if the parameter is true, otherwise we leave the default where hard copies are made +// (copy-on-write requires extra care in a threaded context). +// Calling SetCopyOnWrite(true) on a bitmap created with FromBuffer is unsafe. +func (rb *Bitmap) SetCopyOnWrite(val bool) { + rb.highlowcontainer.copyOnWrite = val +} + +// GetCopyOnWrite gets this bitmap's copy-on-write property +func (rb *Bitmap) GetCopyOnWrite() (val bool) { + return rb.highlowcontainer.copyOnWrite +} + +// CloneCopyOnWriteContainers clones all containers which have +// needCopyOnWrite set to true. +// This can be used to make sure it is safe to munmap a []byte +// that the roaring array may still have a reference to, after +// calling FromBuffer. +// More generally this function is useful if you call FromBuffer +// to construct a bitmap with a backing array buf +// and then later discard the buf array. Note that you should call +// CloneCopyOnWriteContainers on all bitmaps that were derived +// from the 'FromBuffer' bitmap since they map have dependencies +// on the buf array as well. +func (rb *Bitmap) CloneCopyOnWriteContainers() { + rb.highlowcontainer.cloneCopyOnWriteContainers() +} + +// FlipInt calls Flip after casting the parameters (convenience method) +func FlipInt(bm *Bitmap, rangeStart, rangeEnd int) *Bitmap { + return Flip(bm, uint64(rangeStart), uint64(rangeEnd)) +} + +// Statistics provides details on the container types in use. +type Statistics struct { + Cardinality uint64 + Containers uint64 + + ArrayContainers uint64 + ArrayContainerBytes uint64 + ArrayContainerValues uint64 + + BitmapContainers uint64 + BitmapContainerBytes uint64 + BitmapContainerValues uint64 + + RunContainers uint64 + RunContainerBytes uint64 + RunContainerValues uint64 +} + +// Stats returns details on container type usage in a Statistics struct. +func (rb *Bitmap) Stats() Statistics { + stats := Statistics{} + stats.Containers = uint64(len(rb.highlowcontainer.containers)) + for _, c := range rb.highlowcontainer.containers { + stats.Cardinality += uint64(c.getCardinality()) + + switch c.(type) { + case *arrayContainer: + stats.ArrayContainers++ + stats.ArrayContainerBytes += uint64(c.getSizeInBytes()) + stats.ArrayContainerValues += uint64(c.getCardinality()) + case *bitmapContainer: + stats.BitmapContainers++ + stats.BitmapContainerBytes += uint64(c.getSizeInBytes()) + stats.BitmapContainerValues += uint64(c.getCardinality()) + case *runContainer16: + stats.RunContainers++ + stats.RunContainerBytes += uint64(c.getSizeInBytes()) + stats.RunContainerValues += uint64(c.getCardinality()) + } + } + return stats +} + +func (rb *Bitmap) checkValidity() bool { + for _, c := range rb.highlowcontainer.containers { + + switch c.(type) { + case *arrayContainer: + if c.getCardinality() > arrayDefaultMaxSize { + fmt.Println("Array containers are limited to size ", arrayDefaultMaxSize) + return false + } + case *bitmapContainer: + if c.getCardinality() <= arrayDefaultMaxSize { + fmt.Println("Bitmaps would be more concise as an array!") + return false + } + case *runContainer16: + if c.getSizeInBytes() > minOfInt(bitmapContainerSizeInBytes(), arrayContainerSizeInBytes(c.getCardinality())) { + fmt.Println("Inefficient run container!") + return false + } + } + } + return true +} \ No newline at end of file diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/roaringarray.go b/backend/vendor/github.com/RoaringBitmap/roaring/roaringarray.go new file mode 100644 index 0000000000..f7b7d732bf --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/roaringarray.go @@ -0,0 +1,757 @@ +package roaring + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" + "github.com/RoaringBitmap/roaring/internal" +) + +type container interface { + addOffset(uint16) []container + + clone() container + and(container) container + andCardinality(container) int + iand(container) container // i stands for inplace + andNot(container) container + iandNot(container) container // i stands for inplace + isEmpty() bool + getCardinality() int + // rank returns the number of integers that are + // smaller or equal to x. rank(infinity) would be getCardinality(). + rank(uint16) int + + iadd(x uint16) bool // inplace, returns true if x was new. + iaddReturnMinimized(uint16) container // may change return type to minimize storage. + + //addRange(start, final int) container // range is [firstOfRange,lastOfRange) (unused) + iaddRange(start, endx int) container // i stands for inplace, range is [firstOfRange,endx) + + iremove(x uint16) bool // inplace, returns true if x was present. + iremoveReturnMinimized(uint16) container // may change return type to minimize storage. + + not(start, final int) container // range is [firstOfRange,lastOfRange) + inot(firstOfRange, endx int) container // i stands for inplace, range is [firstOfRange,endx) + xor(r container) container + getShortIterator() shortPeekable + iterate(cb func(x uint16) bool) bool + getReverseIterator() shortIterable + getManyIterator() manyIterable + contains(i uint16) bool + maximum() uint16 + minimum() uint16 + + // equals is now logical equals; it does not require the + // same underlying container types, but compares across + // any of the implementations. + equals(r container) bool + + fillLeastSignificant16bits(array []uint32, i int, mask uint32) int + or(r container) container + orCardinality(r container) int + isFull() bool + ior(r container) container // i stands for inplace + intersects(r container) bool // whether the two containers intersect + lazyOR(r container) container + lazyIOR(r container) container + getSizeInBytes() int + //removeRange(start, final int) container // range is [firstOfRange,lastOfRange) (unused) + iremoveRange(start, final int) container // i stands for inplace, range is [firstOfRange,lastOfRange) + selectInt(x uint16) int // selectInt returns the xth integer in the container + serializedSizeInBytes() int + writeTo(io.Writer) (int, error) + + numberOfRuns() int + toEfficientContainer() container + String() string + containerType() contype +} + +type contype uint8 + +const ( + bitmapContype contype = iota + arrayContype + run16Contype + run32Contype +) + +// careful: range is [firstOfRange,lastOfRange] +func rangeOfOnes(start, last int) container { + if start > MaxUint16 { + panic("rangeOfOnes called with start > MaxUint16") + } + if last > MaxUint16 { + panic("rangeOfOnes called with last > MaxUint16") + } + if start < 0 { + panic("rangeOfOnes called with start < 0") + } + if last < 0 { + panic("rangeOfOnes called with last < 0") + } + return newRunContainer16Range(uint16(start), uint16(last)) +} + +type roaringArray struct { + keys []uint16 + containers []container `msg:"-"` // don't try to serialize directly. + needCopyOnWrite []bool + copyOnWrite bool +} + +func newRoaringArray() *roaringArray { + return &roaringArray{} +} + +// runOptimize compresses the element containers to minimize space consumed. +// Q: how does this interact with copyOnWrite and needCopyOnWrite? +// A: since we aren't changing the logical content, just the representation, +// we don't bother to check the needCopyOnWrite bits. We replace +// (possibly all) elements of ra.containers in-place with space +// optimized versions. +func (ra *roaringArray) runOptimize() { + for i := range ra.containers { + ra.containers[i] = ra.containers[i].toEfficientContainer() + } +} + +func (ra *roaringArray) appendContainer(key uint16, value container, mustCopyOnWrite bool) { + ra.keys = append(ra.keys, key) + ra.containers = append(ra.containers, value) + ra.needCopyOnWrite = append(ra.needCopyOnWrite, mustCopyOnWrite) +} + +func (ra *roaringArray) appendWithoutCopy(sa roaringArray, startingindex int) { + mustCopyOnWrite := sa.needCopyOnWrite[startingindex] + ra.appendContainer(sa.keys[startingindex], sa.containers[startingindex], mustCopyOnWrite) +} + +func (ra *roaringArray) appendCopy(sa roaringArray, startingindex int) { + // cow only if the two request it, or if we already have a lightweight copy + copyonwrite := (ra.copyOnWrite && sa.copyOnWrite) || sa.needsCopyOnWrite(startingindex) + if !copyonwrite { + // since there is no copy-on-write, we need to clone the container (this is important) + ra.appendContainer(sa.keys[startingindex], sa.containers[startingindex].clone(), copyonwrite) + } else { + ra.appendContainer(sa.keys[startingindex], sa.containers[startingindex], copyonwrite) + if !sa.needsCopyOnWrite(startingindex) { + sa.setNeedsCopyOnWrite(startingindex) + } + } +} + +func (ra *roaringArray) appendWithoutCopyMany(sa roaringArray, startingindex, end int) { + for i := startingindex; i < end; i++ { + ra.appendWithoutCopy(sa, i) + } +} + +func (ra *roaringArray) appendCopyMany(sa roaringArray, startingindex, end int) { + for i := startingindex; i < end; i++ { + ra.appendCopy(sa, i) + } +} + +func (ra *roaringArray) appendCopiesUntil(sa roaringArray, stoppingKey uint16) { + // cow only if the two request it, or if we already have a lightweight copy + copyonwrite := ra.copyOnWrite && sa.copyOnWrite + + for i := 0; i < sa.size(); i++ { + if sa.keys[i] >= stoppingKey { + break + } + thiscopyonewrite := copyonwrite || sa.needsCopyOnWrite(i) + if thiscopyonewrite { + ra.appendContainer(sa.keys[i], sa.containers[i], thiscopyonewrite) + if !sa.needsCopyOnWrite(i) { + sa.setNeedsCopyOnWrite(i) + } + + } else { + // since there is no copy-on-write, we need to clone the container (this is important) + ra.appendContainer(sa.keys[i], sa.containers[i].clone(), thiscopyonewrite) + + } + } +} + +func (ra *roaringArray) appendCopiesAfter(sa roaringArray, beforeStart uint16) { + // cow only if the two request it, or if we already have a lightweight copy + copyonwrite := ra.copyOnWrite && sa.copyOnWrite + + startLocation := sa.getIndex(beforeStart) + if startLocation >= 0 { + startLocation++ + } else { + startLocation = -startLocation - 1 + } + + for i := startLocation; i < sa.size(); i++ { + thiscopyonewrite := copyonwrite || sa.needsCopyOnWrite(i) + if thiscopyonewrite { + ra.appendContainer(sa.keys[i], sa.containers[i], thiscopyonewrite) + if !sa.needsCopyOnWrite(i) { + sa.setNeedsCopyOnWrite(i) + } + } else { + // since there is no copy-on-write, we need to clone the container (this is important) + ra.appendContainer(sa.keys[i], sa.containers[i].clone(), thiscopyonewrite) + + } + } +} + +func (ra *roaringArray) removeIndexRange(begin, end int) { + if end <= begin { + return + } + + r := end - begin + + copy(ra.keys[begin:], ra.keys[end:]) + copy(ra.containers[begin:], ra.containers[end:]) + copy(ra.needCopyOnWrite[begin:], ra.needCopyOnWrite[end:]) + + ra.resize(len(ra.keys) - r) +} + +func (ra *roaringArray) resize(newsize int) { + for k := newsize; k < len(ra.containers); k++ { + ra.containers[k] = nil + } + + ra.keys = ra.keys[:newsize] + ra.containers = ra.containers[:newsize] + ra.needCopyOnWrite = ra.needCopyOnWrite[:newsize] +} + +func (ra *roaringArray) clear() { + ra.resize(0) + ra.copyOnWrite = false +} + +func (ra *roaringArray) clone() *roaringArray { + + sa := roaringArray{} + sa.copyOnWrite = ra.copyOnWrite + + // this is where copyOnWrite is used. + if ra.copyOnWrite { + sa.keys = make([]uint16, len(ra.keys)) + copy(sa.keys, ra.keys) + sa.containers = make([]container, len(ra.containers)) + copy(sa.containers, ra.containers) + sa.needCopyOnWrite = make([]bool, len(ra.needCopyOnWrite)) + + ra.markAllAsNeedingCopyOnWrite() + sa.markAllAsNeedingCopyOnWrite() + + // sa.needCopyOnWrite is shared + } else { + // make a full copy + + sa.keys = make([]uint16, len(ra.keys)) + copy(sa.keys, ra.keys) + + sa.containers = make([]container, len(ra.containers)) + for i := range sa.containers { + sa.containers[i] = ra.containers[i].clone() + } + + sa.needCopyOnWrite = make([]bool, len(ra.needCopyOnWrite)) + } + return &sa +} + +// clone all containers which have needCopyOnWrite set to true +// This can be used to make sure it is safe to munmap a []byte +// that the roaring array may still have a reference to. +func (ra *roaringArray) cloneCopyOnWriteContainers() { + for i, needCopyOnWrite := range ra.needCopyOnWrite { + if needCopyOnWrite { + ra.containers[i] = ra.containers[i].clone() + ra.needCopyOnWrite[i] = false + } + } +} + +// unused function: +//func (ra *roaringArray) containsKey(x uint16) bool { +// return (ra.binarySearch(0, int64(len(ra.keys)), x) >= 0) +//} + +func (ra *roaringArray) getContainer(x uint16) container { + i := ra.binarySearch(0, int64(len(ra.keys)), x) + if i < 0 { + return nil + } + return ra.containers[i] +} + +func (ra *roaringArray) getContainerAtIndex(i int) container { + return ra.containers[i] +} + +func (ra *roaringArray) getFastContainerAtIndex(i int, needsWriteable bool) container { + c := ra.getContainerAtIndex(i) + switch t := c.(type) { + case *arrayContainer: + c = t.toBitmapContainer() + case *runContainer16: + if !t.isFull() { + c = t.toBitmapContainer() + } + case *bitmapContainer: + if needsWriteable && ra.needCopyOnWrite[i] { + c = ra.containers[i].clone() + } + } + return c +} + +// getUnionedWritableContainer switches behavior for in-place Or +// depending on whether the container requires a copy on write. +// If it does using the non-inplace or() method leads to fewer allocations. +func (ra *roaringArray) getUnionedWritableContainer(pos int, other container) container { + if ra.needCopyOnWrite[pos] { + return ra.getContainerAtIndex(pos).or(other) + } + return ra.getContainerAtIndex(pos).ior(other) + +} + +func (ra *roaringArray) getWritableContainerAtIndex(i int) container { + if ra.needCopyOnWrite[i] { + ra.containers[i] = ra.containers[i].clone() + ra.needCopyOnWrite[i] = false + } + return ra.containers[i] +} + +func (ra *roaringArray) getIndex(x uint16) int { + // before the binary search, we optimize for frequent cases + size := len(ra.keys) + if (size == 0) || (ra.keys[size-1] == x) { + return size - 1 + } + return ra.binarySearch(0, int64(size), x) +} + +func (ra *roaringArray) getKeyAtIndex(i int) uint16 { + return ra.keys[i] +} + +func (ra *roaringArray) insertNewKeyValueAt(i int, key uint16, value container) { + ra.keys = append(ra.keys, 0) + ra.containers = append(ra.containers, nil) + + copy(ra.keys[i+1:], ra.keys[i:]) + copy(ra.containers[i+1:], ra.containers[i:]) + + ra.keys[i] = key + ra.containers[i] = value + + ra.needCopyOnWrite = append(ra.needCopyOnWrite, false) + copy(ra.needCopyOnWrite[i+1:], ra.needCopyOnWrite[i:]) + ra.needCopyOnWrite[i] = false +} + +func (ra *roaringArray) remove(key uint16) bool { + i := ra.binarySearch(0, int64(len(ra.keys)), key) + if i >= 0 { // if a new key + ra.removeAtIndex(i) + return true + } + return false +} + +func (ra *roaringArray) removeAtIndex(i int) { + copy(ra.keys[i:], ra.keys[i+1:]) + copy(ra.containers[i:], ra.containers[i+1:]) + + copy(ra.needCopyOnWrite[i:], ra.needCopyOnWrite[i+1:]) + + ra.resize(len(ra.keys) - 1) +} + +func (ra *roaringArray) setContainerAtIndex(i int, c container) { + ra.containers[i] = c +} + +func (ra *roaringArray) replaceKeyAndContainerAtIndex(i int, key uint16, c container, mustCopyOnWrite bool) { + ra.keys[i] = key + ra.containers[i] = c + ra.needCopyOnWrite[i] = mustCopyOnWrite +} + +func (ra *roaringArray) size() int { + return len(ra.keys) +} + +func (ra *roaringArray) binarySearch(begin, end int64, ikey uint16) int { + low := begin + high := end - 1 + for low+16 <= high { + middleIndex := low + (high-low)/2 // avoid overflow + middleValue := ra.keys[middleIndex] + + if middleValue < ikey { + low = middleIndex + 1 + } else if middleValue > ikey { + high = middleIndex - 1 + } else { + return int(middleIndex) + } + } + for ; low <= high; low++ { + val := ra.keys[low] + if val >= ikey { + if val == ikey { + return int(low) + } + break + } + } + return -int(low + 1) +} + +func (ra *roaringArray) equals(o interface{}) bool { + srb, ok := o.(roaringArray) + if ok { + + if srb.size() != ra.size() { + return false + } + for i, k := range ra.keys { + if k != srb.keys[i] { + return false + } + } + + for i, c := range ra.containers { + if !c.equals(srb.containers[i]) { + return false + } + } + return true + } + return false +} + +func (ra *roaringArray) headerSize() uint64 { + size := uint64(len(ra.keys)) + if ra.hasRunCompression() { + if size < noOffsetThreshold { // for small bitmaps, we omit the offsets + return 4 + (size+7)/8 + 4*size + } + return 4 + (size+7)/8 + 8*size // - 4 because we pack the size with the cookie + } + return 4 + 4 + 8*size + +} + +// should be dirt cheap +func (ra *roaringArray) serializedSizeInBytes() uint64 { + answer := ra.headerSize() + for _, c := range ra.containers { + answer += uint64(c.serializedSizeInBytes()) + } + return answer +} + +// +// spec: https://github.com/RoaringBitmap/RoaringFormatSpec +// +func (ra *roaringArray) writeTo(w io.Writer) (n int64, err error) { + hasRun := ra.hasRunCompression() + isRunSizeInBytes := 0 + cookieSize := 8 + if hasRun { + cookieSize = 4 + isRunSizeInBytes = (len(ra.keys) + 7) / 8 + } + descriptiveHeaderSize := 4 * len(ra.keys) + preambleSize := cookieSize + isRunSizeInBytes + descriptiveHeaderSize + + buf := make([]byte, preambleSize+4*len(ra.keys)) + + nw := 0 + + if hasRun { + binary.LittleEndian.PutUint16(buf[0:], uint16(serialCookie)) + nw += 2 + binary.LittleEndian.PutUint16(buf[2:], uint16(len(ra.keys)-1)) + nw += 2 + // compute isRun bitmap without temporary allocation + var runbitmapslice = buf[nw : nw+isRunSizeInBytes] + for i, c := range ra.containers { + switch c.(type) { + case *runContainer16: + runbitmapslice[i/8] |= 1 << (uint(i) % 8) + } + } + nw += isRunSizeInBytes + } else { + binary.LittleEndian.PutUint32(buf[0:], uint32(serialCookieNoRunContainer)) + nw += 4 + binary.LittleEndian.PutUint32(buf[4:], uint32(len(ra.keys))) + nw += 4 + } + + // descriptive header + for i, key := range ra.keys { + binary.LittleEndian.PutUint16(buf[nw:], key) + nw += 2 + c := ra.containers[i] + binary.LittleEndian.PutUint16(buf[nw:], uint16(c.getCardinality()-1)) + nw += 2 + } + + startOffset := int64(preambleSize + 4*len(ra.keys)) + if !hasRun || (len(ra.keys) >= noOffsetThreshold) { + // offset header + for _, c := range ra.containers { + binary.LittleEndian.PutUint32(buf[nw:], uint32(startOffset)) + nw += 4 + switch rc := c.(type) { + case *runContainer16: + startOffset += 2 + int64(len(rc.iv))*4 + default: + startOffset += int64(getSizeInBytesFromCardinality(c.getCardinality())) + } + } + } + + written, err := w.Write(buf[:nw]) + if err != nil { + return n, err + } + n += int64(written) + + for _, c := range ra.containers { + written, err := c.writeTo(w) + if err != nil { + return n, err + } + n += int64(written) + } + return n, nil +} + +// +// spec: https://github.com/RoaringBitmap/RoaringFormatSpec +// +func (ra *roaringArray) toBytes() ([]byte, error) { + var buf bytes.Buffer + _, err := ra.writeTo(&buf) + return buf.Bytes(), err +} + +func (ra *roaringArray) readFrom(stream internal.ByteInput, cookieHeader ...byte) (int64, error) { + var cookie uint32 + var err error + if len(cookieHeader) > 0 && len(cookieHeader) != 4 { + return int64(len(cookieHeader)), fmt.Errorf("error in roaringArray.readFrom: could not read initial cookie: incorrect size of cookie header") + } + if len(cookieHeader) == 4 { + cookie = binary.LittleEndian.Uint32(cookieHeader) + } else { + cookie, err = stream.ReadUInt32() + if err != nil { + return stream.GetReadBytes(), fmt.Errorf("error in roaringArray.readFrom: could not read initial cookie: %s", err) + } + } + + var size uint32 + var isRunBitmap []byte + + if cookie&0x0000FFFF == serialCookie { + size = uint32(cookie>>16 + 1) + // create is-run-container bitmap + isRunBitmapSize := (int(size) + 7) / 8 + isRunBitmap, err = stream.Next(isRunBitmapSize) + + if err != nil { + return stream.GetReadBytes(), fmt.Errorf("malformed bitmap, failed to read is-run bitmap, got: %s", err) + } + } else if cookie == serialCookieNoRunContainer { + size, err = stream.ReadUInt32() + if err != nil { + return stream.GetReadBytes(), fmt.Errorf("malformed bitmap, failed to read a bitmap size: %s", err) + } + } else { + return stream.GetReadBytes(), fmt.Errorf("error in roaringArray.readFrom: did not find expected serialCookie in header") + } + + if size > (1 << 16) { + return stream.GetReadBytes(), fmt.Errorf("it is logically impossible to have more than (1<<16) containers") + } + + // descriptive header + buf, err := stream.Next(2 * 2 * int(size)) + + if err != nil { + return stream.GetReadBytes(), fmt.Errorf("failed to read descriptive header: %s", err) + } + + keycard := byteSliceAsUint16Slice(buf) + + if isRunBitmap == nil || size >= noOffsetThreshold { + if err := stream.SkipBytes(int(size) * 4); err != nil { + return stream.GetReadBytes(), fmt.Errorf("failed to skip bytes: %s", err) + } + } + + // Allocate slices upfront as number of containers is known + if cap(ra.containers) >= int(size) { + ra.containers = ra.containers[:size] + } else { + ra.containers = make([]container, size) + } + + if cap(ra.keys) >= int(size) { + ra.keys = ra.keys[:size] + } else { + ra.keys = make([]uint16, size) + } + + if cap(ra.needCopyOnWrite) >= int(size) { + ra.needCopyOnWrite = ra.needCopyOnWrite[:size] + } else { + ra.needCopyOnWrite = make([]bool, size) + } + + for i := uint32(0); i < size; i++ { + key := keycard[2*i] + card := int(keycard[2*i+1]) + 1 + ra.keys[i] = key + ra.needCopyOnWrite[i] = true + + if isRunBitmap != nil && isRunBitmap[i/8]&(1<<(i%8)) != 0 { + // run container + nr, err := stream.ReadUInt16() + + if err != nil { + return 0, fmt.Errorf("failed to read runtime container size: %s", err) + } + + buf, err := stream.Next(int(nr) * 4) + + if err != nil { + return stream.GetReadBytes(), fmt.Errorf("failed to read runtime container content: %s", err) + } + + nb := runContainer16{ + iv: byteSliceAsInterval16Slice(buf), + } + + ra.containers[i] = &nb + } else if card > arrayDefaultMaxSize { + // bitmap container + buf, err := stream.Next(arrayDefaultMaxSize * 2) + + if err != nil { + return stream.GetReadBytes(), fmt.Errorf("failed to read bitmap container: %s", err) + } + + nb := bitmapContainer{ + cardinality: card, + bitmap: byteSliceAsUint64Slice(buf), + } + + ra.containers[i] = &nb + } else { + // array container + buf, err := stream.Next(card * 2) + + if err != nil { + return stream.GetReadBytes(), fmt.Errorf("failed to read array container: %s", err) + } + + nb := arrayContainer{ + byteSliceAsUint16Slice(buf), + } + + ra.containers[i] = &nb + } + } + + return stream.GetReadBytes(), nil +} + +func (ra *roaringArray) hasRunCompression() bool { + for _, c := range ra.containers { + switch c.(type) { + case *runContainer16: + return true + } + } + return false +} + +func (ra *roaringArray) advanceUntil(min uint16, pos int) int { + lower := pos + 1 + + if lower >= len(ra.keys) || ra.keys[lower] >= min { + return lower + } + + spansize := 1 + + for lower+spansize < len(ra.keys) && ra.keys[lower+spansize] < min { + spansize *= 2 + } + var upper int + if lower+spansize < len(ra.keys) { + upper = lower + spansize + } else { + upper = len(ra.keys) - 1 + } + + if ra.keys[upper] == min { + return upper + } + + if ra.keys[upper] < min { + // means + // array + // has no + // item + // >= min + // pos = array.length; + return len(ra.keys) + } + + // we know that the next-smallest span was too small + lower += (spansize >> 1) + + mid := 0 + for lower+1 != upper { + mid = (lower + upper) >> 1 + if ra.keys[mid] == min { + return mid + } else if ra.keys[mid] < min { + lower = mid + } else { + upper = mid + } + } + return upper +} + +func (ra *roaringArray) markAllAsNeedingCopyOnWrite() { + for i := range ra.needCopyOnWrite { + ra.needCopyOnWrite[i] = true + } +} + +func (ra *roaringArray) needsCopyOnWrite(i int) bool { + return ra.needCopyOnWrite[i] +} + +func (ra *roaringArray) setNeedsCopyOnWrite(i int) { + ra.needCopyOnWrite[i] = true +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/runcontainer.go b/backend/vendor/github.com/RoaringBitmap/roaring/runcontainer.go new file mode 100644 index 0000000000..a722760b48 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/runcontainer.go @@ -0,0 +1,2604 @@ +package roaring + +// +// Copyright (c) 2016 by the roaring authors. +// Licensed under the Apache License, Version 2.0. +// +// We derive a few lines of code from the sort.Search +// function in the golang standard library. That function +// is Copyright 2009 The Go Authors, and licensed +// under the following BSD-style license. +/* +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import ( + "fmt" + "sort" + "unsafe" +) + +// runContainer16 does run-length encoding of sets of +// uint16 integers. +type runContainer16 struct { + iv []interval16 +} + +// interval16 is the internal to runContainer16 +// structure that maintains the individual [start, last] +// closed intervals. +type interval16 struct { + start uint16 + length uint16 // length minus 1 +} + +func newInterval16Range(start, last uint16) interval16 { + if last < start { + panic(fmt.Sprintf("last (%d) cannot be smaller than start (%d)", last, start)) + } + + return interval16{ + start, + last - start, + } +} + +// runlen returns the count of integers in the interval. +func (iv interval16) runlen() int { + return int(iv.length) + 1 +} + +func (iv interval16) last() uint16 { + return iv.start + iv.length +} + +// String produces a human viewable string of the contents. +func (iv interval16) String() string { + return fmt.Sprintf("[%d, %d]", iv.start, iv.length) +} + +func ivalString16(iv []interval16) string { + var s string + var j int + var p interval16 + for j, p = range iv { + s += fmt.Sprintf("%v:[%d, %d], ", j, p.start, p.last()) + } + return s +} + +// String produces a human viewable string of the contents. +func (rc *runContainer16) String() string { + if len(rc.iv) == 0 { + return "runContainer16{}" + } + is := ivalString16(rc.iv) + return `runContainer16{` + is + `}` +} + +// uint16Slice is a sort.Sort convenience method +type uint16Slice []uint16 + +// Len returns the length of p. +func (p uint16Slice) Len() int { return len(p) } + +// Less returns p[i] < p[j] +func (p uint16Slice) Less(i, j int) bool { return p[i] < p[j] } + +// Swap swaps elements i and j. +func (p uint16Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +// addHelper helps build a runContainer16. +type addHelper16 struct { + runstart uint16 + runlen uint16 + actuallyAdded uint16 + m []interval16 + rc *runContainer16 +} + +func (ah *addHelper16) storeIval(runstart, runlen uint16) { + mi := interval16{start: runstart, length: runlen} + ah.m = append(ah.m, mi) +} + +func (ah *addHelper16) add(cur, prev uint16, i int) { + if cur == prev+1 { + ah.runlen++ + ah.actuallyAdded++ + } else { + if cur < prev { + panic(fmt.Sprintf("newRunContainer16FromVals sees "+ + "unsorted vals; vals[%v]=cur=%v < prev=%v. Sort your vals"+ + " before calling us with alreadySorted == true.", i, cur, prev)) + } + if cur == prev { + // ignore duplicates + } else { + ah.actuallyAdded++ + ah.storeIval(ah.runstart, ah.runlen) + ah.runstart = cur + ah.runlen = 0 + } + } +} + +// newRunContainerRange makes a new container made of just the specified closed interval [rangestart,rangelast] +func newRunContainer16Range(rangestart uint16, rangelast uint16) *runContainer16 { + rc := &runContainer16{} + rc.iv = append(rc.iv, newInterval16Range(rangestart, rangelast)) + return rc +} + +// newRunContainer16FromVals makes a new container from vals. +// +// For efficiency, vals should be sorted in ascending order. +// Ideally vals should not contain duplicates, but we detect and +// ignore them. If vals is already sorted in ascending order, then +// pass alreadySorted = true. Otherwise, for !alreadySorted, +// we will sort vals before creating a runContainer16 of them. +// We sort the original vals, so this will change what the +// caller sees in vals as a side effect. +func newRunContainer16FromVals(alreadySorted bool, vals ...uint16) *runContainer16 { + // keep this in sync with newRunContainer16FromArray below + + rc := &runContainer16{} + ah := addHelper16{rc: rc} + + if !alreadySorted { + sort.Sort(uint16Slice(vals)) + } + n := len(vals) + var cur, prev uint16 + switch { + case n == 0: + // nothing more + case n == 1: + ah.m = append(ah.m, newInterval16Range(vals[0], vals[0])) + ah.actuallyAdded++ + default: + ah.runstart = vals[0] + ah.actuallyAdded++ + for i := 1; i < n; i++ { + prev = vals[i-1] + cur = vals[i] + ah.add(cur, prev, i) + } + ah.storeIval(ah.runstart, ah.runlen) + } + rc.iv = ah.m + return rc +} + +// newRunContainer16FromBitmapContainer makes a new run container from bc, +// somewhat efficiently. For reference, see the Java +// https://github.com/RoaringBitmap/RoaringBitmap/blob/master/src/main/java/org/roaringbitmap/RunContainer.java#L145-L192 +func newRunContainer16FromBitmapContainer(bc *bitmapContainer) *runContainer16 { + + rc := &runContainer16{} + nbrRuns := bc.numberOfRuns() + if nbrRuns == 0 { + return rc + } + rc.iv = make([]interval16, nbrRuns) + + longCtr := 0 // index of current long in bitmap + curWord := bc.bitmap[0] // its value + runCount := 0 + for { + // potentially multiword advance to first 1 bit + for curWord == 0 && longCtr < len(bc.bitmap)-1 { + longCtr++ + curWord = bc.bitmap[longCtr] + } + + if curWord == 0 { + // wrap up, no more runs + return rc + } + localRunStart := countTrailingZeros(curWord) + runStart := localRunStart + 64*longCtr + // stuff 1s into number's LSBs + curWordWith1s := curWord | (curWord - 1) + + // find the next 0, potentially in a later word + runEnd := 0 + for curWordWith1s == maxWord && longCtr < len(bc.bitmap)-1 { + longCtr++ + curWordWith1s = bc.bitmap[longCtr] + } + + if curWordWith1s == maxWord { + // a final unterminated run of 1s + runEnd = wordSizeInBits + longCtr*64 + rc.iv[runCount].start = uint16(runStart) + rc.iv[runCount].length = uint16(runEnd) - uint16(runStart) - 1 + return rc + } + localRunEnd := countTrailingZeros(^curWordWith1s) + runEnd = localRunEnd + longCtr*64 + rc.iv[runCount].start = uint16(runStart) + rc.iv[runCount].length = uint16(runEnd) - 1 - uint16(runStart) + runCount++ + // now, zero out everything right of runEnd. + curWord = curWordWith1s & (curWordWith1s + 1) + // We've lathered and rinsed, so repeat... + } + +} + +// +// newRunContainer16FromArray populates a new +// runContainer16 from the contents of arr. +// +func newRunContainer16FromArray(arr *arrayContainer) *runContainer16 { + // keep this in sync with newRunContainer16FromVals above + + rc := &runContainer16{} + ah := addHelper16{rc: rc} + + n := arr.getCardinality() + var cur, prev uint16 + switch { + case n == 0: + // nothing more + case n == 1: + ah.m = append(ah.m, newInterval16Range(arr.content[0], arr.content[0])) + ah.actuallyAdded++ + default: + ah.runstart = arr.content[0] + ah.actuallyAdded++ + for i := 1; i < n; i++ { + prev = arr.content[i-1] + cur = arr.content[i] + ah.add(cur, prev, i) + } + ah.storeIval(ah.runstart, ah.runlen) + } + rc.iv = ah.m + return rc +} + +// set adds the integers in vals to the set. Vals +// must be sorted in increasing order; if not, you should set +// alreadySorted to false, and we will sort them in place for you. +// (Be aware of this side effect -- it will affect the callers +// view of vals). +// +// If you have a small number of additions to an already +// big runContainer16, calling Add() may be faster. +func (rc *runContainer16) set(alreadySorted bool, vals ...uint16) { + + rc2 := newRunContainer16FromVals(alreadySorted, vals...) + un := rc.union(rc2) + rc.iv = un.iv +} + +// canMerge returns true iff the intervals +// a and b either overlap or they are +// contiguous and so can be merged into +// a single interval. +func canMerge16(a, b interval16) bool { + if int(a.last())+1 < int(b.start) { + return false + } + return int(b.last())+1 >= int(a.start) +} + +// haveOverlap differs from canMerge in that +// it tells you if the intersection of a +// and b would contain an element (otherwise +// it would be the empty set, and we return +// false). +func haveOverlap16(a, b interval16) bool { + if int(a.last())+1 <= int(b.start) { + return false + } + return int(b.last())+1 > int(a.start) +} + +// mergeInterval16s joins a and b into a +// new interval, and panics if it cannot. +func mergeInterval16s(a, b interval16) (res interval16) { + if !canMerge16(a, b) { + panic(fmt.Sprintf("cannot merge %#v and %#v", a, b)) + } + + if b.start < a.start { + res.start = b.start + } else { + res.start = a.start + } + + if b.last() > a.last() { + res.length = b.last() - res.start + } else { + res.length = a.last() - res.start + } + + return +} + +// intersectInterval16s returns the intersection +// of a and b. The isEmpty flag will be true if +// a and b were disjoint. +func intersectInterval16s(a, b interval16) (res interval16, isEmpty bool) { + if !haveOverlap16(a, b) { + isEmpty = true + return + } + if b.start > a.start { + res.start = b.start + } else { + res.start = a.start + } + + bEnd := b.last() + aEnd := a.last() + var resEnd uint16 + + if bEnd < aEnd { + resEnd = bEnd + } else { + resEnd = aEnd + } + res.length = resEnd - res.start + return +} + +// union merges two runContainer16s, producing +// a new runContainer16 with the union of rc and b. +func (rc *runContainer16) union(b *runContainer16) *runContainer16 { + + // rc is also known as 'a' here, but golint insisted we + // call it rc for consistency with the rest of the methods. + + var m []interval16 + + alim := int(len(rc.iv)) + blim := int(len(b.iv)) + + var na int // next from a + var nb int // next from b + + // merged holds the current merge output, which might + // get additional merges before being appended to m. + var merged interval16 + var mergedUsed bool // is merged being used at the moment? + + var cura interval16 // currently considering this interval16 from a + var curb interval16 // currently considering this interval16 from b + + pass := 0 + for na < alim && nb < blim { + pass++ + cura = rc.iv[na] + curb = b.iv[nb] + + if mergedUsed { + mergedUpdated := false + if canMerge16(cura, merged) { + merged = mergeInterval16s(cura, merged) + na = rc.indexOfIntervalAtOrAfter(int(merged.last())+1, na+1) + mergedUpdated = true + } + if canMerge16(curb, merged) { + merged = mergeInterval16s(curb, merged) + nb = b.indexOfIntervalAtOrAfter(int(merged.last())+1, nb+1) + mergedUpdated = true + } + if !mergedUpdated { + // we know that merged is disjoint from cura and curb + m = append(m, merged) + mergedUsed = false + } + continue + + } else { + // !mergedUsed + if !canMerge16(cura, curb) { + if cura.start < curb.start { + m = append(m, cura) + na++ + } else { + m = append(m, curb) + nb++ + } + } else { + merged = mergeInterval16s(cura, curb) + mergedUsed = true + na = rc.indexOfIntervalAtOrAfter(int(merged.last())+1, na+1) + nb = b.indexOfIntervalAtOrAfter(int(merged.last())+1, nb+1) + } + } + } + var aDone, bDone bool + if na >= alim { + aDone = true + } + if nb >= blim { + bDone = true + } + // finish by merging anything remaining into merged we can: + if mergedUsed { + if !aDone { + aAdds: + for na < alim { + cura = rc.iv[na] + if canMerge16(cura, merged) { + merged = mergeInterval16s(cura, merged) + na = rc.indexOfIntervalAtOrAfter(int(merged.last())+1, na+1) + } else { + break aAdds + } + } + + } + + if !bDone { + bAdds: + for nb < blim { + curb = b.iv[nb] + if canMerge16(curb, merged) { + merged = mergeInterval16s(curb, merged) + nb = b.indexOfIntervalAtOrAfter(int(merged.last())+1, nb+1) + } else { + break bAdds + } + } + + } + + m = append(m, merged) + } + if na < alim { + m = append(m, rc.iv[na:]...) + } + if nb < blim { + m = append(m, b.iv[nb:]...) + } + + res := &runContainer16{iv: m} + return res +} + +// unionCardinality returns the cardinality of the merger of two runContainer16s, the union of rc and b. +func (rc *runContainer16) unionCardinality(b *runContainer16) uint { + + // rc is also known as 'a' here, but golint insisted we + // call it rc for consistency with the rest of the methods. + answer := uint(0) + + alim := int(len(rc.iv)) + blim := int(len(b.iv)) + + var na int // next from a + var nb int // next from b + + // merged holds the current merge output, which might + // get additional merges before being appended to m. + var merged interval16 + var mergedUsed bool // is merged being used at the moment? + + var cura interval16 // currently considering this interval16 from a + var curb interval16 // currently considering this interval16 from b + + pass := 0 + for na < alim && nb < blim { + pass++ + cura = rc.iv[na] + curb = b.iv[nb] + + if mergedUsed { + mergedUpdated := false + if canMerge16(cura, merged) { + merged = mergeInterval16s(cura, merged) + na = rc.indexOfIntervalAtOrAfter(int(merged.last())+1, na+1) + mergedUpdated = true + } + if canMerge16(curb, merged) { + merged = mergeInterval16s(curb, merged) + nb = b.indexOfIntervalAtOrAfter(int(merged.last())+1, nb+1) + mergedUpdated = true + } + if !mergedUpdated { + // we know that merged is disjoint from cura and curb + //m = append(m, merged) + answer += uint(merged.last()) - uint(merged.start) + 1 + mergedUsed = false + } + continue + + } else { + // !mergedUsed + if !canMerge16(cura, curb) { + if cura.start < curb.start { + answer += uint(cura.last()) - uint(cura.start) + 1 + //m = append(m, cura) + na++ + } else { + answer += uint(curb.last()) - uint(curb.start) + 1 + //m = append(m, curb) + nb++ + } + } else { + merged = mergeInterval16s(cura, curb) + mergedUsed = true + na = rc.indexOfIntervalAtOrAfter(int(merged.last())+1, na+1) + nb = b.indexOfIntervalAtOrAfter(int(merged.last())+1, nb+1) + } + } + } + var aDone, bDone bool + if na >= alim { + aDone = true + } + if nb >= blim { + bDone = true + } + // finish by merging anything remaining into merged we can: + if mergedUsed { + if !aDone { + aAdds: + for na < alim { + cura = rc.iv[na] + if canMerge16(cura, merged) { + merged = mergeInterval16s(cura, merged) + na = rc.indexOfIntervalAtOrAfter(int(merged.last())+1, na+1) + } else { + break aAdds + } + } + + } + + if !bDone { + bAdds: + for nb < blim { + curb = b.iv[nb] + if canMerge16(curb, merged) { + merged = mergeInterval16s(curb, merged) + nb = b.indexOfIntervalAtOrAfter(int(merged.last())+1, nb+1) + } else { + break bAdds + } + } + + } + + //m = append(m, merged) + answer += uint(merged.last()) - uint(merged.start) + 1 + } + for _, r := range rc.iv[na:] { + answer += uint(r.last()) - uint(r.start) + 1 + } + for _, r := range b.iv[nb:] { + answer += uint(r.last()) - uint(r.start) + 1 + } + return answer +} + +// indexOfIntervalAtOrAfter is a helper for union. +func (rc *runContainer16) indexOfIntervalAtOrAfter(key int, startIndex int) int { + w, already, _ := rc.searchRange(key, startIndex, 0) + if already { + return w + } + return w + 1 +} + +// intersect returns a new runContainer16 holding the +// intersection of rc (also known as 'a') and b. +func (rc *runContainer16) intersect(b *runContainer16) *runContainer16 { + + a := rc + numa := int(len(a.iv)) + numb := int(len(b.iv)) + res := &runContainer16{} + if numa == 0 || numb == 0 { + return res + } + + if numa == 1 && numb == 1 { + if !haveOverlap16(a.iv[0], b.iv[0]) { + return res + } + } + + var output []interval16 + + var acuri int + var bcuri int + + astart := int(a.iv[acuri].start) + bstart := int(b.iv[bcuri].start) + + var intersection interval16 + var leftoverstart int + var isOverlap, isLeftoverA, isLeftoverB bool + var done bool +toploop: + for acuri < numa && bcuri < numb { + + isOverlap, isLeftoverA, isLeftoverB, leftoverstart, intersection = + intersectWithLeftover16(astart, int(a.iv[acuri].last()), bstart, int(b.iv[bcuri].last())) + + if !isOverlap { + switch { + case astart < bstart: + acuri, done = a.findNextIntervalThatIntersectsStartingFrom(acuri+1, bstart) + if done { + break toploop + } + astart = int(a.iv[acuri].start) + + case astart > bstart: + bcuri, done = b.findNextIntervalThatIntersectsStartingFrom(bcuri+1, astart) + if done { + break toploop + } + bstart = int(b.iv[bcuri].start) + } + + } else { + // isOverlap + output = append(output, intersection) + switch { + case isLeftoverA: + // note that we change astart without advancing acuri, + // since we need to capture any 2ndary intersections with a.iv[acuri] + astart = leftoverstart + bcuri++ + if bcuri >= numb { + break toploop + } + bstart = int(b.iv[bcuri].start) + case isLeftoverB: + // note that we change bstart without advancing bcuri, + // since we need to capture any 2ndary intersections with b.iv[bcuri] + bstart = leftoverstart + acuri++ + if acuri >= numa { + break toploop + } + astart = int(a.iv[acuri].start) + default: + // neither had leftover, both completely consumed + + // advance to next a interval + acuri++ + if acuri >= numa { + break toploop + } + astart = int(a.iv[acuri].start) + + // advance to next b interval + bcuri++ + if bcuri >= numb { + break toploop + } + bstart = int(b.iv[bcuri].start) + } + } + } // end for toploop + + if len(output) == 0 { + return res + } + + res.iv = output + return res +} + +// intersectCardinality returns the cardinality of the +// intersection of rc (also known as 'a') and b. +func (rc *runContainer16) intersectCardinality(b *runContainer16) int { + answer := int(0) + + a := rc + numa := int(len(a.iv)) + numb := int(len(b.iv)) + if numa == 0 || numb == 0 { + return 0 + } + + if numa == 1 && numb == 1 { + if !haveOverlap16(a.iv[0], b.iv[0]) { + return 0 + } + } + + var acuri int + var bcuri int + + astart := int(a.iv[acuri].start) + bstart := int(b.iv[bcuri].start) + + var intersection interval16 + var leftoverstart int + var isOverlap, isLeftoverA, isLeftoverB bool + var done bool + pass := 0 +toploop: + for acuri < numa && bcuri < numb { + pass++ + + isOverlap, isLeftoverA, isLeftoverB, leftoverstart, intersection = + intersectWithLeftover16(astart, int(a.iv[acuri].last()), bstart, int(b.iv[bcuri].last())) + + if !isOverlap { + switch { + case astart < bstart: + acuri, done = a.findNextIntervalThatIntersectsStartingFrom(acuri+1, bstart) + if done { + break toploop + } + astart = int(a.iv[acuri].start) + + case astart > bstart: + bcuri, done = b.findNextIntervalThatIntersectsStartingFrom(bcuri+1, astart) + if done { + break toploop + } + bstart = int(b.iv[bcuri].start) + } + + } else { + // isOverlap + answer += int(intersection.last()) - int(intersection.start) + 1 + switch { + case isLeftoverA: + // note that we change astart without advancing acuri, + // since we need to capture any 2ndary intersections with a.iv[acuri] + astart = leftoverstart + bcuri++ + if bcuri >= numb { + break toploop + } + bstart = int(b.iv[bcuri].start) + case isLeftoverB: + // note that we change bstart without advancing bcuri, + // since we need to capture any 2ndary intersections with b.iv[bcuri] + bstart = leftoverstart + acuri++ + if acuri >= numa { + break toploop + } + astart = int(a.iv[acuri].start) + default: + // neither had leftover, both completely consumed + + // advance to next a interval + acuri++ + if acuri >= numa { + break toploop + } + astart = int(a.iv[acuri].start) + + // advance to next b interval + bcuri++ + if bcuri >= numb { + break toploop + } + bstart = int(b.iv[bcuri].start) + } + } + } // end for toploop + + return answer +} + +// get returns true iff key is in the container. +func (rc *runContainer16) contains(key uint16) bool { + _, in, _ := rc.search(int(key)) + return in +} + +// numIntervals returns the count of intervals in the container. +func (rc *runContainer16) numIntervals() int { + return len(rc.iv) +} + +// searchRange returns alreadyPresent to indicate if the +// key is already in one of our interval16s. +// +// If key is alreadyPresent, then whichInterval16 tells +// you where. +// +// If key is not already present, then whichInterval16 is +// set as follows: +// +// a) whichInterval16 == len(rc.iv)-1 if key is beyond our +// last interval16 in rc.iv; +// +// b) whichInterval16 == -1 if key is before our first +// interval16 in rc.iv; +// +// c) whichInterval16 is set to the minimum index of rc.iv +// which comes strictly before the key; +// so rc.iv[whichInterval16].last < key, +// and if whichInterval16+1 exists, then key < rc.iv[whichInterval16+1].start +// (Note that whichInterval16+1 won't exist when +// whichInterval16 is the last interval.) +// +// runContainer16.search always returns whichInterval16 < len(rc.iv). +// +// The search space is from startIndex to endxIndex. If endxIndex is set to zero, then there +// no upper bound. +// +func (rc *runContainer16) searchRange(key int, startIndex int, endxIndex int) (whichInterval16 int, alreadyPresent bool, numCompares int) { + n := int(len(rc.iv)) + if n == 0 { + return -1, false, 0 + } + if endxIndex == 0 { + endxIndex = n + } + + // sort.Search returns the smallest index i + // in [0, n) at which f(i) is true, assuming that on the range [0, n), + // f(i) == true implies f(i+1) == true. + // If there is no such index, Search returns n. + + // For correctness, this began as verbatim snippet from + // sort.Search in the Go standard lib. + // We inline our comparison function for speed, and + // annotate with numCompares + // to observe and test that extra bounds are utilized. + i, j := startIndex, endxIndex + for i < j { + h := i + (j-i)/2 // avoid overflow when computing h as the bisector + // i <= h < j + numCompares++ + if !(key < int(rc.iv[h].start)) { + i = h + 1 + } else { + j = h + } + } + below := i + // end std lib snippet. + + // The above is a simple in-lining and annotation of: + /* below := sort.Search(n, + func(i int) bool { + return key < rc.iv[i].start + }) + */ + whichInterval16 = below - 1 + + if below == n { + // all falses => key is >= start of all interval16s + // ... so does it belong to the last interval16? + if key < int(rc.iv[n-1].last())+1 { + // yes, it belongs to the last interval16 + alreadyPresent = true + return + } + // no, it is beyond the last interval16. + // leave alreadyPreset = false + return + } + + // INVAR: key is below rc.iv[below] + if below == 0 { + // key is before the first first interval16. + // leave alreadyPresent = false + return + } + + // INVAR: key is >= rc.iv[below-1].start and + // key is < rc.iv[below].start + + // is key in below-1 interval16? + if key >= int(rc.iv[below-1].start) && key < int(rc.iv[below-1].last())+1 { + // yes, it is. key is in below-1 interval16. + alreadyPresent = true + return + } + + // INVAR: key >= rc.iv[below-1].endx && key < rc.iv[below].start + // leave alreadyPresent = false + return +} + +// search returns alreadyPresent to indicate if the +// key is already in one of our interval16s. +// +// If key is alreadyPresent, then whichInterval16 tells +// you where. +// +// If key is not already present, then whichInterval16 is +// set as follows: +// +// a) whichInterval16 == len(rc.iv)-1 if key is beyond our +// last interval16 in rc.iv; +// +// b) whichInterval16 == -1 if key is before our first +// interval16 in rc.iv; +// +// c) whichInterval16 is set to the minimum index of rc.iv +// which comes strictly before the key; +// so rc.iv[whichInterval16].last < key, +// and if whichInterval16+1 exists, then key < rc.iv[whichInterval16+1].start +// (Note that whichInterval16+1 won't exist when +// whichInterval16 is the last interval.) +// +// runContainer16.search always returns whichInterval16 < len(rc.iv). +// +func (rc *runContainer16) search(key int) (whichInterval16 int, alreadyPresent bool, numCompares int) { + return rc.searchRange(key, 0, 0) +} + +// getCardinality returns the count of the integers stored in the +// runContainer16. The running complexity depends on the size +// of the container. +func (rc *runContainer16) getCardinality() int { + // have to compute it + n := 0 + for _, p := range rc.iv { + n += p.runlen() + } + return n +} + +// isEmpty returns true if the container is empty. +// It runs in constant time. +func (rc *runContainer16) isEmpty() bool { + return len(rc.iv) == 0 +} + +// AsSlice decompresses the contents into a []uint16 slice. +func (rc *runContainer16) AsSlice() []uint16 { + s := make([]uint16, rc.getCardinality()) + j := 0 + for _, p := range rc.iv { + for i := p.start; i <= p.last(); i++ { + s[j] = i + j++ + } + } + return s +} + +// newRunContainer16 creates an empty run container. +func newRunContainer16() *runContainer16 { + return &runContainer16{} +} + +// newRunContainer16CopyIv creates a run container, initializing +// with a copy of the supplied iv slice. +// +func newRunContainer16CopyIv(iv []interval16) *runContainer16 { + rc := &runContainer16{ + iv: make([]interval16, len(iv)), + } + copy(rc.iv, iv) + return rc +} + +func (rc *runContainer16) Clone() *runContainer16 { + rc2 := newRunContainer16CopyIv(rc.iv) + return rc2 +} + +// newRunContainer16TakeOwnership returns a new runContainer16 +// backed by the provided iv slice, which we will +// assume exclusive control over from now on. +// +func newRunContainer16TakeOwnership(iv []interval16) *runContainer16 { + rc := &runContainer16{ + iv: iv, + } + return rc +} + +const baseRc16Size = int(unsafe.Sizeof(runContainer16{})) +const perIntervalRc16Size = int(unsafe.Sizeof(interval16{})) + +const baseDiskRc16Size = int(unsafe.Sizeof(uint16(0))) + +// see also runContainer16SerializedSizeInBytes(numRuns int) int + +// getSizeInBytes returns the number of bytes of memory +// required by this runContainer16. +func (rc *runContainer16) getSizeInBytes() int { + return perIntervalRc16Size*len(rc.iv) + baseRc16Size +} + +// runContainer16SerializedSizeInBytes returns the number of bytes of disk +// required to hold numRuns in a runContainer16. +func runContainer16SerializedSizeInBytes(numRuns int) int { + return perIntervalRc16Size*numRuns + baseDiskRc16Size +} + +// Add adds a single value k to the set. +func (rc *runContainer16) Add(k uint16) (wasNew bool) { + // TODO comment from runContainer16.java: + // it might be better and simpler to do return + // toBitmapOrArrayContainer(getCardinality()).add(k) + // but note that some unit tests use this method to build up test + // runcontainers without calling runOptimize + + k64 := int(k) + + index, present, _ := rc.search(k64) + if present { + return // already there + } + wasNew = true + + n := int(len(rc.iv)) + if index == -1 { + // we may need to extend the first run + if n > 0 { + if rc.iv[0].start == k+1 { + rc.iv[0].start = k + rc.iv[0].length++ + return + } + } + // nope, k stands alone, starting the new first interval16. + rc.iv = append([]interval16{newInterval16Range(k, k)}, rc.iv...) + return + } + + // are we off the end? handle both index == n and index == n-1: + if index >= n-1 { + if int(rc.iv[n-1].last())+1 == k64 { + rc.iv[n-1].length++ + return + } + rc.iv = append(rc.iv, newInterval16Range(k, k)) + return + } + + // INVAR: index and index+1 both exist, and k goes between them. + // + // Now: add k into the middle, + // possibly fusing with index or index+1 interval16 + // and possibly resulting in fusing of two interval16s + // that had a one integer gap. + + left := index + right := index + 1 + + // are we fusing left and right by adding k? + if int(rc.iv[left].last())+1 == k64 && int(rc.iv[right].start) == k64+1 { + // fuse into left + rc.iv[left].length = rc.iv[right].last() - rc.iv[left].start + // remove redundant right + rc.iv = append(rc.iv[:left+1], rc.iv[right+1:]...) + return + } + + // are we an addition to left? + if int(rc.iv[left].last())+1 == k64 { + // yes + rc.iv[left].length++ + return + } + + // are we an addition to right? + if int(rc.iv[right].start) == k64+1 { + // yes + rc.iv[right].start = k + rc.iv[right].length++ + return + } + + // k makes a standalone new interval16, inserted in the middle + tail := append([]interval16{newInterval16Range(k, k)}, rc.iv[right:]...) + rc.iv = append(rc.iv[:left+1], tail...) + return +} + +// runIterator16 advice: you must call hasNext() +// before calling next()/peekNext() to insure there are contents. +type runIterator16 struct { + rc *runContainer16 + curIndex int + curPosInIndex uint16 +} + +// newRunIterator16 returns a new empty run container. +func (rc *runContainer16) newRunIterator16() *runIterator16 { + return &runIterator16{rc: rc, curIndex: 0, curPosInIndex: 0} +} + +func (rc *runContainer16) iterate(cb func(x uint16) bool) bool { + iterator := runIterator16{rc, 0, 0} + + for iterator.hasNext() { + if !cb(iterator.next()) { + return false + } + } + + return true +} + +// hasNext returns false if calling next will panic. It +// returns true when there is at least one more value +// available in the iteration sequence. +func (ri *runIterator16) hasNext() bool { + return int(len(ri.rc.iv)) > ri.curIndex+1 || + (int(len(ri.rc.iv)) == ri.curIndex+1 && ri.rc.iv[ri.curIndex].length >= ri.curPosInIndex) +} + +// next returns the next value in the iteration sequence. +func (ri *runIterator16) next() uint16 { + next := ri.rc.iv[ri.curIndex].start + ri.curPosInIndex + + if ri.curPosInIndex == ri.rc.iv[ri.curIndex].length { + ri.curPosInIndex = 0 + ri.curIndex++ + } else { + ri.curPosInIndex++ + } + + return next +} + +// peekNext returns the next value in the iteration sequence without advancing the iterator +func (ri *runIterator16) peekNext() uint16 { + return ri.rc.iv[ri.curIndex].start + ri.curPosInIndex +} + +// advanceIfNeeded advances as long as the next value is smaller than minval +func (ri *runIterator16) advanceIfNeeded(minval uint16) { + if !ri.hasNext() || ri.peekNext() >= minval { + return + } + + // interval cannot be -1 because of minval > peekNext + interval, isPresent, _ := ri.rc.searchRange(int(minval), ri.curIndex, int(len(ri.rc.iv))) + + // if the minval is present, set the curPosIndex at the right position + if isPresent { + ri.curIndex = interval + ri.curPosInIndex = minval - ri.rc.iv[ri.curIndex].start + } else { + // otherwise interval is set to to the minimum index of rc.iv + // which comes strictly before the key, that's why we set the next interval + ri.curIndex = interval + 1 + ri.curPosInIndex = 0 + } +} + +// runReverseIterator16 advice: you must call hasNext() +// before calling next() to insure there are contents. +type runReverseIterator16 struct { + rc *runContainer16 + curIndex int // index into rc.iv + curPosInIndex uint16 // offset in rc.iv[curIndex] +} + +// newRunReverseIterator16 returns a new empty run iterator. +func (rc *runContainer16) newRunReverseIterator16() *runReverseIterator16 { + index := int(len(rc.iv)) - 1 + pos := uint16(0) + + if index >= 0 { + pos = rc.iv[index].length + } + + return &runReverseIterator16{ + rc: rc, + curIndex: index, + curPosInIndex: pos, + } +} + +// hasNext returns false if calling next will panic. It +// returns true when there is at least one more value +// available in the iteration sequence. +func (ri *runReverseIterator16) hasNext() bool { + return ri.curIndex > 0 || ri.curIndex == 0 && ri.curPosInIndex >= 0 +} + +// next returns the next value in the iteration sequence. +func (ri *runReverseIterator16) next() uint16 { + next := ri.rc.iv[ri.curIndex].start + ri.curPosInIndex + + if ri.curPosInIndex > 0 { + ri.curPosInIndex-- + } else { + ri.curIndex-- + + if ri.curIndex >= 0 { + ri.curPosInIndex = ri.rc.iv[ri.curIndex].length + } + } + + return next +} + +func (rc *runContainer16) newManyRunIterator16() *runIterator16 { + return rc.newRunIterator16() +} + +// hs are the high bits to include to avoid needing to reiterate over the buffer in NextMany +func (ri *runIterator16) nextMany(hs uint32, buf []uint32) int { + n := 0 + + if !ri.hasNext() { + return n + } + + // start and end are inclusive + for n < len(buf) { + moreVals := 0 + + if ri.rc.iv[ri.curIndex].length >= ri.curPosInIndex { + // add as many as you can from this seq + moreVals = minOfInt(int(ri.rc.iv[ri.curIndex].length-ri.curPosInIndex)+1, len(buf)-n) + base := uint32(ri.rc.iv[ri.curIndex].start+ri.curPosInIndex) | hs + + // allows BCE + buf2 := buf[n : n+moreVals] + for i := range buf2 { + buf2[i] = base + uint32(i) + } + + // update values + n += moreVals + } + + if moreVals+int(ri.curPosInIndex) > int(ri.rc.iv[ri.curIndex].length) { + ri.curPosInIndex = 0 + ri.curIndex++ + + if ri.curIndex == int(len(ri.rc.iv)) { + break + } + } else { + ri.curPosInIndex += uint16(moreVals) //moreVals always fits in uint16 + } + } + + return n +} + +func (ri *runIterator16) nextMany64(hs uint64, buf []uint64) int { + n := 0 + + if !ri.hasNext() { + return n + } + + // start and end are inclusive + for n < len(buf) { + moreVals := 0 + + if ri.rc.iv[ri.curIndex].length >= ri.curPosInIndex { + // add as many as you can from this seq + moreVals = minOfInt(int(ri.rc.iv[ri.curIndex].length-ri.curPosInIndex)+1, len(buf)-n) + base := uint64(ri.rc.iv[ri.curIndex].start+ri.curPosInIndex) | hs + + // allows BCE + buf2 := buf[n : n+moreVals] + for i := range buf2 { + buf2[i] = base + uint64(i) + } + + // update values + n += moreVals + } + + if moreVals+int(ri.curPosInIndex) > int(ri.rc.iv[ri.curIndex].length) { + ri.curPosInIndex = 0 + ri.curIndex++ + + if ri.curIndex == int(len(ri.rc.iv)) { + break + } + } else { + ri.curPosInIndex += uint16(moreVals) //moreVals always fits in uint16 + } + } + + return n +} + +// remove removes key from the container. +func (rc *runContainer16) removeKey(key uint16) (wasPresent bool) { + + var index int + index, wasPresent, _ = rc.search(int(key)) + if !wasPresent { + return // already removed, nothing to do. + } + pos := key - rc.iv[index].start + rc.deleteAt(&index, &pos) + return +} + +// internal helper functions + +func (rc *runContainer16) deleteAt(curIndex *int, curPosInIndex *uint16) { + ci := *curIndex + pos := *curPosInIndex + + // are we first, last, or in the middle of our interval16? + switch { + case pos == 0: + if int(rc.iv[ci].length) == 0 { + // our interval disappears + rc.iv = append(rc.iv[:ci], rc.iv[ci+1:]...) + // curIndex stays the same, since the delete did + // the advance for us. + *curPosInIndex = 0 + } else { + rc.iv[ci].start++ // no longer overflowable + rc.iv[ci].length-- + } + case pos == rc.iv[ci].length: + // length + rc.iv[ci].length-- + // our interval16 cannot disappear, else we would have been pos == 0, case first above. + *curPosInIndex-- + // if we leave *curIndex alone, then Next() will work properly even after the delete. + default: + //middle + // split into two, adding an interval16 + new0 := newInterval16Range(rc.iv[ci].start, rc.iv[ci].start+*curPosInIndex-1) + + new1start := int(rc.iv[ci].start+*curPosInIndex) + 1 + if new1start > int(MaxUint16) { + panic("overflow?!?!") + } + new1 := newInterval16Range(uint16(new1start), rc.iv[ci].last()) + tail := append([]interval16{new0, new1}, rc.iv[ci+1:]...) + rc.iv = append(rc.iv[:ci], tail...) + // update curIndex and curPosInIndex + *curIndex++ + *curPosInIndex = 0 + } + +} + +func have4Overlap16(astart, alast, bstart, blast int) bool { + if alast+1 <= bstart { + return false + } + return blast+1 > astart +} + +func intersectWithLeftover16(astart, alast, bstart, blast int) (isOverlap, isLeftoverA, isLeftoverB bool, leftoverstart int, intersection interval16) { + if !have4Overlap16(astart, alast, bstart, blast) { + return + } + isOverlap = true + + // do the intersection: + if bstart > astart { + intersection.start = uint16(bstart) + } else { + intersection.start = uint16(astart) + } + + switch { + case blast < alast: + isLeftoverA = true + leftoverstart = blast + 1 + intersection.length = uint16(blast) - intersection.start + case alast < blast: + isLeftoverB = true + leftoverstart = alast + 1 + intersection.length = uint16(alast) - intersection.start + default: + // alast == blast + intersection.length = uint16(alast) - intersection.start + } + + return +} + +func (rc *runContainer16) findNextIntervalThatIntersectsStartingFrom(startIndex int, key int) (index int, done bool) { + w, _, _ := rc.searchRange(key, startIndex, 0) + // rc.search always returns w < len(rc.iv) + if w < startIndex { + // not found and comes before lower bound startIndex, + // so just use the lower bound. + if startIndex == int(len(rc.iv)) { + // also this bump up means that we are done + return startIndex, true + } + return startIndex, false + } + + return w, false +} + +func sliceToString16(m []interval16) string { + s := "" + for i := range m { + s += fmt.Sprintf("%v: %s, ", i, m[i]) + } + return s +} + +// helper for invert +func (rc *runContainer16) invertlastInterval(origin uint16, lastIdx int) []interval16 { + cur := rc.iv[lastIdx] + if cur.last() == MaxUint16 { + if cur.start == origin { + return nil // empty container + } + return []interval16{newInterval16Range(origin, cur.start-1)} + } + if cur.start == origin { + return []interval16{newInterval16Range(cur.last()+1, MaxUint16)} + } + // invert splits + return []interval16{ + newInterval16Range(origin, cur.start-1), + newInterval16Range(cur.last()+1, MaxUint16), + } +} + +// invert returns a new container (not inplace), that is +// the inversion of rc. For each bit b in rc, the +// returned value has !b +func (rc *runContainer16) invert() *runContainer16 { + ni := len(rc.iv) + var m []interval16 + switch ni { + case 0: + return &runContainer16{iv: []interval16{newInterval16Range(0, MaxUint16)}} + case 1: + return &runContainer16{iv: rc.invertlastInterval(0, 0)} + } + var invstart int + ult := ni - 1 + for i, cur := range rc.iv { + if i == ult { + // invertlastInteval will add both intervals (b) and (c) in + // diagram below. + m = append(m, rc.invertlastInterval(uint16(invstart), i)...) + break + } + // INVAR: i and cur are not the last interval, there is a next at i+1 + // + // ........[cur.start, cur.last] ...... [next.start, next.last].... + // ^ ^ ^ + // (a) (b) (c) + // + // Now: we add interval (a); but if (a) is empty, for cur.start==0, we skip it. + if cur.start > 0 { + m = append(m, newInterval16Range(uint16(invstart), cur.start-1)) + } + invstart = int(cur.last() + 1) + } + return &runContainer16{iv: m} +} + +func (iv interval16) equal(b interval16) bool { + return iv.start == b.start && iv.length == b.length +} + +func (iv interval16) isSuperSetOf(b interval16) bool { + return iv.start <= b.start && b.last() <= iv.last() +} + +func (iv interval16) subtractInterval(del interval16) (left []interval16, delcount int) { + isect, isEmpty := intersectInterval16s(iv, del) + + if isEmpty { + return nil, 0 + } + if del.isSuperSetOf(iv) { + return nil, iv.runlen() + } + + switch { + case isect.start > iv.start && isect.last() < iv.last(): + new0 := newInterval16Range(iv.start, isect.start-1) + new1 := newInterval16Range(isect.last()+1, iv.last()) + return []interval16{new0, new1}, isect.runlen() + case isect.start == iv.start: + return []interval16{newInterval16Range(isect.last()+1, iv.last())}, isect.runlen() + default: + return []interval16{newInterval16Range(iv.start, isect.start-1)}, isect.runlen() + } +} + +func (rc *runContainer16) isubtract(del interval16) { + origiv := make([]interval16, len(rc.iv)) + copy(origiv, rc.iv) + n := int(len(rc.iv)) + if n == 0 { + return // already done. + } + + _, isEmpty := intersectInterval16s(newInterval16Range(rc.iv[0].start, rc.iv[n-1].last()), del) + if isEmpty { + return // done + } + + // INVAR there is some intersection between rc and del + istart, startAlready, _ := rc.search(int(del.start)) + ilast, lastAlready, _ := rc.search(int(del.last())) + if istart == -1 { + if ilast == n-1 && !lastAlready { + rc.iv = nil + return + } + } + // some intervals will remain + switch { + case startAlready && lastAlready: + res0, _ := rc.iv[istart].subtractInterval(del) + + // would overwrite values in iv b/c res0 can have len 2. so + // write to origiv instead. + lost := 1 + ilast - istart + changeSize := int(len(res0)) - lost + newSize := int(len(rc.iv)) + changeSize + + // rc.iv = append(pre, caboose...) + // return + + if ilast != istart { + res1, _ := rc.iv[ilast].subtractInterval(del) + res0 = append(res0, res1...) + changeSize = int(len(res0)) - lost + newSize = int(len(rc.iv)) + changeSize + } + switch { + case changeSize < 0: + // shrink + copy(rc.iv[istart+int(len(res0)):], rc.iv[ilast+1:]) + copy(rc.iv[istart:istart+int(len(res0))], res0) + rc.iv = rc.iv[:newSize] + return + case changeSize == 0: + // stay the same + copy(rc.iv[istart:istart+int(len(res0))], res0) + return + default: + // changeSize > 0 is only possible when ilast == istart. + // Hence we now know: changeSize == 1 and len(res0) == 2 + rc.iv = append(rc.iv, interval16{}) + // len(rc.iv) is correct now, no need to rc.iv = rc.iv[:newSize] + + // copy the tail into place + copy(rc.iv[ilast+2:], rc.iv[ilast+1:]) + // copy the new item(s) into place + copy(rc.iv[istart:istart+2], res0) + return + } + + case !startAlready && !lastAlready: + // we get to discard whole intervals + + // from the search() definition: + + // if del.start is not present, then istart is + // set as follows: + // + // a) istart == n-1 if del.start is beyond our + // last interval16 in rc.iv; + // + // b) istart == -1 if del.start is before our first + // interval16 in rc.iv; + // + // c) istart is set to the minimum index of rc.iv + // which comes strictly before the del.start; + // so del.start > rc.iv[istart].last, + // and if istart+1 exists, then del.start < rc.iv[istart+1].startx + + // if del.last is not present, then ilast is + // set as follows: + // + // a) ilast == n-1 if del.last is beyond our + // last interval16 in rc.iv; + // + // b) ilast == -1 if del.last is before our first + // interval16 in rc.iv; + // + // c) ilast is set to the minimum index of rc.iv + // which comes strictly before the del.last; + // so del.last > rc.iv[ilast].last, + // and if ilast+1 exists, then del.last < rc.iv[ilast+1].start + + // INVAR: istart >= 0 + pre := rc.iv[:istart+1] + if ilast == n-1 { + rc.iv = pre + return + } + // INVAR: ilast < n-1 + lost := ilast - istart + changeSize := -lost + newSize := int(len(rc.iv)) + changeSize + if changeSize != 0 { + copy(rc.iv[ilast+1+changeSize:], rc.iv[ilast+1:]) + } + rc.iv = rc.iv[:newSize] + return + + case startAlready && !lastAlready: + // we can only shrink or stay the same size + // i.e. we either eliminate the whole interval, + // or just cut off the right side. + res0, _ := rc.iv[istart].subtractInterval(del) + if len(res0) > 0 { + // len(res) must be 1 + rc.iv[istart] = res0[0] + } + lost := 1 + (ilast - istart) + changeSize := int(len(res0)) - lost + newSize := int(len(rc.iv)) + changeSize + if changeSize != 0 { + copy(rc.iv[ilast+1+changeSize:], rc.iv[ilast+1:]) + } + rc.iv = rc.iv[:newSize] + return + + case !startAlready && lastAlready: + // we can only shrink or stay the same size + res1, _ := rc.iv[ilast].subtractInterval(del) + lost := ilast - istart + changeSize := int(len(res1)) - lost + newSize := int(len(rc.iv)) + changeSize + if changeSize != 0 { + // move the tail first to make room for res1 + copy(rc.iv[ilast+1+changeSize:], rc.iv[ilast+1:]) + } + copy(rc.iv[istart+1:], res1) + rc.iv = rc.iv[:newSize] + return + } +} + +// compute rc minus b, and return the result as a new value (not inplace). +// port of run_container_andnot from CRoaring... +// https://github.com/RoaringBitmap/CRoaring/blob/master/src/containers/run.c#L435-L496 +func (rc *runContainer16) AndNotRunContainer16(b *runContainer16) *runContainer16 { + + if len(b.iv) == 0 || len(rc.iv) == 0 { + return rc + } + + dst := newRunContainer16() + apos := 0 + bpos := 0 + + a := rc + + astart := a.iv[apos].start + alast := a.iv[apos].last() + bstart := b.iv[bpos].start + blast := b.iv[bpos].last() + + alen := len(a.iv) + blen := len(b.iv) + + for apos < alen && bpos < blen { + switch { + case alast < bstart: + // output the first run + dst.iv = append(dst.iv, newInterval16Range(astart, alast)) + apos++ + if apos < alen { + astart = a.iv[apos].start + alast = a.iv[apos].last() + } + case blast < astart: + // exit the second run + bpos++ + if bpos < blen { + bstart = b.iv[bpos].start + blast = b.iv[bpos].last() + } + default: + // a: [ ] + // b: [ ] + // alast >= bstart + // blast >= astart + if astart < bstart { + dst.iv = append(dst.iv, newInterval16Range(astart, bstart-1)) + } + if alast > blast { + astart = blast + 1 + } else { + apos++ + if apos < alen { + astart = a.iv[apos].start + alast = a.iv[apos].last() + } + } + } + } + if apos < alen { + dst.iv = append(dst.iv, newInterval16Range(astart, alast)) + apos++ + if apos < alen { + dst.iv = append(dst.iv, a.iv[apos:]...) + } + } + + return dst +} + +func (rc *runContainer16) numberOfRuns() (nr int) { + return len(rc.iv) +} + +func (rc *runContainer16) containerType() contype { + return run16Contype +} + +func (rc *runContainer16) equals16(srb *runContainer16) bool { + // Check if the containers are the same object. + if rc == srb { + return true + } + + if len(srb.iv) != len(rc.iv) { + return false + } + + for i, v := range rc.iv { + if v != srb.iv[i] { + return false + } + } + return true +} + +// compile time verify we meet interface requirements +var _ container = &runContainer16{} + +func (rc *runContainer16) clone() container { + return newRunContainer16CopyIv(rc.iv) +} + +func (rc *runContainer16) minimum() uint16 { + return rc.iv[0].start // assume not empty +} + +func (rc *runContainer16) maximum() uint16 { + return rc.iv[len(rc.iv)-1].last() // assume not empty +} + +func (rc *runContainer16) isFull() bool { + return (len(rc.iv) == 1) && ((rc.iv[0].start == 0) && (rc.iv[0].last() == MaxUint16)) +} + +func (rc *runContainer16) and(a container) container { + if rc.isFull() { + return a.clone() + } + switch c := a.(type) { + case *runContainer16: + return rc.intersect(c) + case *arrayContainer: + return rc.andArray(c) + case *bitmapContainer: + return rc.andBitmapContainer(c) + } + panic("unsupported container type") +} + +func (rc *runContainer16) andCardinality(a container) int { + switch c := a.(type) { + case *runContainer16: + return int(rc.intersectCardinality(c)) + case *arrayContainer: + return rc.andArrayCardinality(c) + case *bitmapContainer: + return rc.andBitmapContainerCardinality(c) + } + panic("unsupported container type") +} + +// andBitmapContainer finds the intersection of rc and b. +func (rc *runContainer16) andBitmapContainer(bc *bitmapContainer) container { + bc2 := newBitmapContainerFromRun(rc) + return bc2.andBitmap(bc) +} + +func (rc *runContainer16) andArrayCardinality(ac *arrayContainer) int { + pos := 0 + answer := 0 + maxpos := ac.getCardinality() + if maxpos == 0 { + return 0 // won't happen in actual code + } + v := ac.content[pos] +mainloop: + for _, p := range rc.iv { + for v < p.start { + pos++ + if pos == maxpos { + break mainloop + } + v = ac.content[pos] + } + for v <= p.last() { + answer++ + pos++ + if pos == maxpos { + break mainloop + } + v = ac.content[pos] + } + } + return answer +} + +func (rc *runContainer16) iand(a container) container { + if rc.isFull() { + return a.clone() + } + switch c := a.(type) { + case *runContainer16: + return rc.inplaceIntersect(c) + case *arrayContainer: + return rc.andArray(c) + case *bitmapContainer: + return rc.iandBitmapContainer(c) + } + panic("unsupported container type") +} + +func (rc *runContainer16) inplaceIntersect(rc2 *runContainer16) container { + sect := rc.intersect(rc2) + *rc = *sect + return rc +} + +func (rc *runContainer16) iandBitmapContainer(bc *bitmapContainer) container { + isect := rc.andBitmapContainer(bc) + *rc = *newRunContainer16FromContainer(isect) + return rc +} + +func (rc *runContainer16) andArray(ac *arrayContainer) container { + if len(rc.iv) == 0 { + return newArrayContainer() + } + + acCardinality := ac.getCardinality() + c := newArrayContainerCapacity(acCardinality) + + for rlePos, arrayPos := 0, 0; arrayPos < acCardinality; { + iv := rc.iv[rlePos] + arrayVal := ac.content[arrayPos] + + for iv.last() < arrayVal { + rlePos++ + if rlePos == len(rc.iv) { + return c + } + iv = rc.iv[rlePos] + } + + if iv.start > arrayVal { + arrayPos = advanceUntil(ac.content, arrayPos, len(ac.content), iv.start) + } else { + c.content = append(c.content, arrayVal) + arrayPos++ + } + } + return c +} + +func (rc *runContainer16) andNot(a container) container { + switch c := a.(type) { + case *arrayContainer: + return rc.andNotArray(c) + case *bitmapContainer: + return rc.andNotBitmap(c) + case *runContainer16: + return rc.andNotRunContainer16(c) + } + panic("unsupported container type") +} + +func (rc *runContainer16) fillLeastSignificant16bits(x []uint32, i int, mask uint32) int { + k := i + var val int + for _, p := range rc.iv { + n := p.runlen() + for j := int(0); j < n; j++ { + val = int(p.start) + j + x[k] = uint32(val) | mask + k++ + } + } + return k +} + +func (rc *runContainer16) getShortIterator() shortPeekable { + return rc.newRunIterator16() +} + +func (rc *runContainer16) getReverseIterator() shortIterable { + return rc.newRunReverseIterator16() +} + +func (rc *runContainer16) getManyIterator() manyIterable { + return rc.newManyRunIterator16() +} + +// add the values in the range [firstOfRange, endx). endx +// is still abe to express 2^16 because it is an int not an uint16. +func (rc *runContainer16) iaddRange(firstOfRange, endx int) container { + + if firstOfRange > endx { + panic(fmt.Sprintf("invalid %v = endx > firstOfRange", endx)) + } + if firstOfRange == endx { + return rc + } + addme := newRunContainer16TakeOwnership([]interval16{ + { + start: uint16(firstOfRange), + length: uint16(endx - 1 - firstOfRange), + }, + }) + *rc = *rc.union(addme) + return rc +} + +// remove the values in the range [firstOfRange,endx) +func (rc *runContainer16) iremoveRange(firstOfRange, endx int) container { + if firstOfRange > endx { + panic(fmt.Sprintf("request to iremove empty set [%v, %v),"+ + " nothing to do.", firstOfRange, endx)) + } + // empty removal + if firstOfRange == endx { + return rc + } + x := newInterval16Range(uint16(firstOfRange), uint16(endx-1)) + rc.isubtract(x) + return rc +} + +// not flip the values in the range [firstOfRange,endx) +func (rc *runContainer16) not(firstOfRange, endx int) container { + if firstOfRange > endx { + panic(fmt.Sprintf("invalid %v = endx > firstOfRange = %v", endx, firstOfRange)) + } + + return rc.Not(firstOfRange, endx) +} + +// Not flips the values in the range [firstOfRange,endx). +// This is not inplace. Only the returned value has the flipped bits. +// +// Currently implemented as (!A intersect B) union (A minus B), +// where A is rc, and B is the supplied [firstOfRange, endx) interval. +// +// TODO(time optimization): convert this to a single pass +// algorithm by copying AndNotRunContainer16() and modifying it. +// Current routine is correct but +// makes 2 more passes through the arrays than should be +// strictly necessary. Measure both ways though--this may not matter. +// +func (rc *runContainer16) Not(firstOfRange, endx int) *runContainer16 { + + if firstOfRange > endx { + panic(fmt.Sprintf("invalid %v = endx > firstOfRange == %v", endx, firstOfRange)) + } + + if firstOfRange >= endx { + return rc.Clone() + } + + a := rc + // algo: + // (!A intersect B) union (A minus B) + + nota := a.invert() + + bs := []interval16{newInterval16Range(uint16(firstOfRange), uint16(endx-1))} + b := newRunContainer16TakeOwnership(bs) + + notAintersectB := nota.intersect(b) + + aMinusB := a.AndNotRunContainer16(b) + + rc2 := notAintersectB.union(aMinusB) + return rc2 +} + +// equals is now logical equals; it does not require the +// same underlying container type. +func (rc *runContainer16) equals(o container) bool { + srb, ok := o.(*runContainer16) + + if !ok { + // maybe value instead of pointer + val, valok := o.(*runContainer16) + if valok { + srb = val + ok = true + } + } + if ok { + // Check if the containers are the same object. + if rc == srb { + return true + } + + if len(srb.iv) != len(rc.iv) { + return false + } + + for i, v := range rc.iv { + if v != srb.iv[i] { + return false + } + } + return true + } + + // use generic comparison + if o.getCardinality() != rc.getCardinality() { + return false + } + rit := rc.getShortIterator() + bit := o.getShortIterator() + + //k := 0 + for rit.hasNext() { + if bit.next() != rit.next() { + return false + } + //k++ + } + return true +} + +func (rc *runContainer16) iaddReturnMinimized(x uint16) container { + rc.Add(x) + return rc +} + +func (rc *runContainer16) iadd(x uint16) (wasNew bool) { + return rc.Add(x) +} + +func (rc *runContainer16) iremoveReturnMinimized(x uint16) container { + rc.removeKey(x) + return rc +} + +func (rc *runContainer16) iremove(x uint16) bool { + return rc.removeKey(x) +} + +func (rc *runContainer16) or(a container) container { + if rc.isFull() { + return rc.clone() + } + switch c := a.(type) { + case *runContainer16: + return rc.union(c) + case *arrayContainer: + return rc.orArray(c) + case *bitmapContainer: + return rc.orBitmapContainer(c) + } + panic("unsupported container type") +} + +func (rc *runContainer16) orCardinality(a container) int { + switch c := a.(type) { + case *runContainer16: + return int(rc.unionCardinality(c)) + case *arrayContainer: + return rc.orArrayCardinality(c) + case *bitmapContainer: + return rc.orBitmapContainerCardinality(c) + } + panic("unsupported container type") +} + +// orBitmapContainer finds the union of rc and bc. +func (rc *runContainer16) orBitmapContainer(bc *bitmapContainer) container { + bc2 := newBitmapContainerFromRun(rc) + return bc2.iorBitmap(bc) +} + +func (rc *runContainer16) andBitmapContainerCardinality(bc *bitmapContainer) int { + answer := 0 + for i := range rc.iv { + answer += bc.getCardinalityInRange(uint(rc.iv[i].start), uint(rc.iv[i].last())+1) + } + //bc.computeCardinality() + return answer +} + +func (rc *runContainer16) orBitmapContainerCardinality(bc *bitmapContainer) int { + return rc.getCardinality() + bc.getCardinality() - rc.andBitmapContainerCardinality(bc) +} + +// orArray finds the union of rc and ac. +func (rc *runContainer16) orArray(ac *arrayContainer) container { + if ac.isEmpty() { + return rc.clone() + } + if rc.isEmpty() { + return ac.clone() + } + intervals, cardMinusOne := runArrayUnionToRuns(rc, ac) + result := newRunContainer16TakeOwnership(intervals) + if len(intervals) >= 2048 && cardMinusOne >= arrayDefaultMaxSize { + return newBitmapContainerFromRun(result) + } + if len(intervals)*2 > 1+int(cardMinusOne) { + return result.toArrayContainer() + } + return result +} + +// orArray finds the union of rc and ac. +func (rc *runContainer16) orArrayCardinality(ac *arrayContainer) int { + return ac.getCardinality() + rc.getCardinality() - rc.andArrayCardinality(ac) +} + +func (rc *runContainer16) ior(a container) container { + if rc.isFull() { + return rc + } + switch c := a.(type) { + case *runContainer16: + return rc.inplaceUnion(c) + case *arrayContainer: + return rc.iorArray(c) + case *bitmapContainer: + return rc.iorBitmapContainer(c) + } + panic("unsupported container type") +} + +func (rc *runContainer16) inplaceUnion(rc2 *runContainer16) container { + for _, p := range rc2.iv { + last := int(p.last()) + for i := int(p.start); i <= last; i++ { + rc.Add(uint16(i)) + } + } + return rc +} + +func (rc *runContainer16) iorBitmapContainer(bc *bitmapContainer) container { + + it := bc.getShortIterator() + for it.hasNext() { + rc.Add(it.next()) + } + return rc +} + +func (rc *runContainer16) iorArray(ac *arrayContainer) container { + if rc.isEmpty() { + return ac.clone() + } + if ac.isEmpty() { + return rc + } + var cardMinusOne uint16 + //TODO: perform the union algorithm in-place using rc.iv + // this can be done with methods like the in-place array container union + // but maybe lazily moving the remaining elements back. + rc.iv, cardMinusOne = runArrayUnionToRuns(rc, ac) + if len(rc.iv) >= 2048 && cardMinusOne >= arrayDefaultMaxSize { + return newBitmapContainerFromRun(rc) + } + if len(rc.iv)*2 > 1+int(cardMinusOne) { + return rc.toArrayContainer() + } + return rc +} + +func runArrayUnionToRuns(rc *runContainer16, ac *arrayContainer) ([]interval16, uint16) { + pos1 := 0 + pos2 := 0 + length1 := len(ac.content) + length2 := len(rc.iv) + target := make([]interval16, 0, len(rc.iv)) + // have to find the first range + // options are + // 1. from array container + // 2. from run container + var previousInterval interval16 + var cardMinusOne uint16 + if ac.content[0] < rc.iv[0].start { + previousInterval.start = ac.content[0] + previousInterval.length = 0 + pos1++ + } else { + previousInterval.start = rc.iv[0].start + previousInterval.length = rc.iv[0].length + pos2++ + } + + for pos1 < length1 || pos2 < length2 { + if pos1 < length1 { + s1 := ac.content[pos1] + if s1 <= previousInterval.start+previousInterval.length { + pos1++ + continue + } + if previousInterval.last() < MaxUint16 && previousInterval.last()+1 == s1 { + previousInterval.length++ + pos1++ + continue + } + } + if pos2 < length2 { + range2 := rc.iv[pos2] + if range2.start <= previousInterval.last() || range2.start > 0 && range2.start-1 == previousInterval.last() { + pos2++ + if previousInterval.last() < range2.last() { + previousInterval.length = range2.last() - previousInterval.start + } + continue + } + } + cardMinusOne += previousInterval.length + 1 + target = append(target, previousInterval) + if pos2 == length2 || pos1 < length1 && ac.content[pos1] < rc.iv[pos2].start { + previousInterval.start = ac.content[pos1] + previousInterval.length = 0 + pos1++ + } else { + previousInterval = rc.iv[pos2] + pos2++ + } + } + cardMinusOne += previousInterval.length + 1 + target = append(target, previousInterval) + + return target, cardMinusOne +} + +// lazyIOR is described (not yet implemented) in +// this nice note from @lemire on +// https://github.com/RoaringBitmap/roaring/pull/70#issuecomment-263613737 +// +// Description of lazyOR and lazyIOR from @lemire: +// +// Lazy functions are optional and can be simply +// wrapper around non-lazy functions. +// +// The idea of "laziness" is as follows. It is +// inspired by the concept of lazy evaluation +// you might be familiar with (functional programming +// and all that). So a roaring bitmap is +// such that all its containers are, in some +// sense, chosen to use as little memory as +// possible. This is nice. Also, all bitsets +// are "cardinality aware" so that you can do +// fast rank/select queries, or query the +// cardinality of the whole bitmap... very fast, +// without latency. +// +// However, imagine that you are aggregating 100 +// bitmaps together. So you OR the first two, then OR +// that with the third one and so forth. Clearly, +// intermediate bitmaps don't need to be as +// compressed as possible, right? They can be +// in a "dirty state". You only need the end +// result to be in a nice state... which you +// can achieve by calling repairAfterLazy at the end. +// +// The Java/C code does something special for +// the in-place lazy OR runs. The idea is that +// instead of taking two run containers and +// generating a new one, we actually try to +// do the computation in-place through a +// technique invented by @gssiyankai (pinging him!). +// What you do is you check whether the host +// run container has lots of extra capacity. +// If it does, you move its data at the end of +// the backing array, and then you write +// the answer at the beginning. What this +// trick does is minimize memory allocations. +// +func (rc *runContainer16) lazyIOR(a container) container { + // not lazy at the moment + return rc.ior(a) +} + +// lazyOR is described above in lazyIOR. +func (rc *runContainer16) lazyOR(a container) container { + // not lazy at the moment + return rc.or(a) +} + +func (rc *runContainer16) intersects(a container) bool { + // TODO: optimize by doing inplace/less allocation + isect := rc.and(a) + return !isect.isEmpty() +} + +func (rc *runContainer16) xor(a container) container { + switch c := a.(type) { + case *arrayContainer: + return rc.xorArray(c) + case *bitmapContainer: + return rc.xorBitmap(c) + case *runContainer16: + return rc.xorRunContainer16(c) + } + panic("unsupported container type") +} + +func (rc *runContainer16) iandNot(a container) container { + switch c := a.(type) { + case *arrayContainer: + return rc.iandNotArray(c) + case *bitmapContainer: + return rc.iandNotBitmap(c) + case *runContainer16: + return rc.iandNotRunContainer16(c) + } + panic("unsupported container type") +} + +// flip the values in the range [firstOfRange,endx) +func (rc *runContainer16) inot(firstOfRange, endx int) container { + if firstOfRange > endx { + panic(fmt.Sprintf("invalid %v = endx > firstOfRange = %v", endx, firstOfRange)) + } + if firstOfRange > endx { + return rc + } + // TODO: minimize copies, do it all inplace; not() makes a copy. + rc = rc.Not(firstOfRange, endx) + return rc +} + +func (rc *runContainer16) rank(x uint16) int { + n := int(len(rc.iv)) + xx := int(x) + w, already, _ := rc.search(xx) + if w < 0 { + return 0 + } + if !already && w == n-1 { + return rc.getCardinality() + } + var rnk int + if !already { + for i := int(0); i <= w; i++ { + rnk += rc.iv[i].runlen() + } + return int(rnk) + } + for i := int(0); i < w; i++ { + rnk += rc.iv[i].runlen() + } + rnk += int(x-rc.iv[w].start) + 1 + return int(rnk) +} + +func (rc *runContainer16) selectInt(x uint16) int { + var offset int + for k := range rc.iv { + nextOffset := offset + rc.iv[k].runlen() + if nextOffset > int(x) { + return int(int(rc.iv[k].start) + (int(x) - offset)) + } + offset = nextOffset + } + panic("cannot select x") +} + +func (rc *runContainer16) andNotRunContainer16(b *runContainer16) container { + return rc.AndNotRunContainer16(b) +} + +func (rc *runContainer16) andNotArray(ac *arrayContainer) container { + rcb := rc.toBitmapContainer() + acb := ac.toBitmapContainer() + return rcb.andNotBitmap(acb) +} + +func (rc *runContainer16) andNotBitmap(bc *bitmapContainer) container { + rcb := rc.toBitmapContainer() + return rcb.andNotBitmap(bc) +} + +func (rc *runContainer16) toBitmapContainer() *bitmapContainer { + bc := newBitmapContainer() + for i := range rc.iv { + bc.iaddRange(int(rc.iv[i].start), int(rc.iv[i].last())+1) + } + bc.computeCardinality() + return bc +} + +func (rc *runContainer16) iandNotRunContainer16(x2 *runContainer16) container { + rcb := rc.toBitmapContainer() + x2b := x2.toBitmapContainer() + rcb.iandNotBitmapSurely(x2b) + // TODO: check size and optimize the return value + // TODO: is inplace modification really required? If not, elide the copy. + rc2 := newRunContainer16FromBitmapContainer(rcb) + *rc = *rc2 + return rc +} + +func (rc *runContainer16) iandNotArray(ac *arrayContainer) container { + rcb := rc.toBitmapContainer() + acb := ac.toBitmapContainer() + rcb.iandNotBitmapSurely(acb) + // TODO: check size and optimize the return value + // TODO: is inplace modification really required? If not, elide the copy. + rc2 := newRunContainer16FromBitmapContainer(rcb) + *rc = *rc2 + return rc +} + +func (rc *runContainer16) iandNotBitmap(bc *bitmapContainer) container { + rcb := rc.toBitmapContainer() + rcb.iandNotBitmapSurely(bc) + // TODO: check size and optimize the return value + // TODO: is inplace modification really required? If not, elide the copy. + rc2 := newRunContainer16FromBitmapContainer(rcb) + *rc = *rc2 + return rc +} + +func (rc *runContainer16) xorRunContainer16(x2 *runContainer16) container { + rcb := rc.toBitmapContainer() + x2b := x2.toBitmapContainer() + return rcb.xorBitmap(x2b) +} + +func (rc *runContainer16) xorArray(ac *arrayContainer) container { + rcb := rc.toBitmapContainer() + acb := ac.toBitmapContainer() + return rcb.xorBitmap(acb) +} + +func (rc *runContainer16) xorBitmap(bc *bitmapContainer) container { + rcb := rc.toBitmapContainer() + return rcb.xorBitmap(bc) +} + +// convert to bitmap or array *if needed* +func (rc *runContainer16) toEfficientContainer() container { + sizeAsRunContainer := rc.getSizeInBytes() + sizeAsBitmapContainer := bitmapContainerSizeInBytes() + card := rc.getCardinality() + sizeAsArrayContainer := arrayContainerSizeInBytes(card) + if sizeAsRunContainer <= minOfInt(sizeAsBitmapContainer, sizeAsArrayContainer) { + return rc + } + if card <= arrayDefaultMaxSize { + return rc.toArrayContainer() + } + bc := newBitmapContainerFromRun(rc) + return bc +} + +func (rc *runContainer16) toArrayContainer() *arrayContainer { + ac := newArrayContainer() + for i := range rc.iv { + ac.iaddRange(int(rc.iv[i].start), int(rc.iv[i].last())+1) + } + return ac +} + +func newRunContainer16FromContainer(c container) *runContainer16 { + + switch x := c.(type) { + case *runContainer16: + return x.Clone() + case *arrayContainer: + return newRunContainer16FromArray(x) + case *bitmapContainer: + return newRunContainer16FromBitmapContainer(x) + } + panic("unsupported container type") +} + +// And finds the intersection of rc and b. +func (rc *runContainer16) And(b *Bitmap) *Bitmap { + out := NewBitmap() + for _, p := range rc.iv { + plast := p.last() + for i := p.start; i <= plast; i++ { + if b.Contains(uint32(i)) { + out.Add(uint32(i)) + } + } + } + return out +} + +// Xor returns the exclusive-or of rc and b. +func (rc *runContainer16) Xor(b *Bitmap) *Bitmap { + out := b.Clone() + for _, p := range rc.iv { + plast := p.last() + for v := p.start; v <= plast; v++ { + w := uint32(v) + if out.Contains(w) { + out.RemoveRange(uint64(w), uint64(w+1)) + } else { + out.Add(w) + } + } + } + return out +} + +// Or returns the union of rc and b. +func (rc *runContainer16) Or(b *Bitmap) *Bitmap { + out := b.Clone() + for _, p := range rc.iv { + plast := p.last() + for v := p.start; v <= plast; v++ { + out.Add(uint32(v)) + } + } + return out +} + +// serializedSizeInBytes returns the number of bytes of memory +// required by this runContainer16. This is for the +// Roaring format, as specified https://github.com/RoaringBitmap/RoaringFormatSpec/ +func (rc *runContainer16) serializedSizeInBytes() int { + // number of runs in one uint16, then each run + // needs two more uint16 + return 2 + len(rc.iv)*4 +} + +func (rc *runContainer16) addOffset(x uint16) []container { + low := newRunContainer16() + high := newRunContainer16() + + for _, iv := range rc.iv { + val := int(iv.start) + int(x) + finalVal := int(val) + int(iv.length) + if val <= 0xffff { + if finalVal <= 0xffff { + low.iv = append(low.iv, interval16{uint16(val), iv.length}) + } else { + low.iv = append(low.iv, interval16{uint16(val), uint16(0xffff - val)}) + high.iv = append(high.iv, interval16{uint16(0), uint16(finalVal & 0xffff)}) + } + } else { + high.iv = append(high.iv, interval16{uint16(val & 0xffff), iv.length}) + } + } + return []container{low, high} +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/serialization.go b/backend/vendor/github.com/RoaringBitmap/roaring/serialization.go new file mode 100644 index 0000000000..70e3bbcc57 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/serialization.go @@ -0,0 +1,19 @@ +package roaring + +import ( + "encoding/binary" + "io" +) + +// writeTo for runContainer16 follows this +// spec: https://github.com/RoaringBitmap/RoaringFormatSpec +// +func (b *runContainer16) writeTo(stream io.Writer) (int, error) { + buf := make([]byte, 2+4*len(b.iv)) + binary.LittleEndian.PutUint16(buf[0:], uint16(len(b.iv))) + for i, v := range b.iv { + binary.LittleEndian.PutUint16(buf[2+i*4:], v.start) + binary.LittleEndian.PutUint16(buf[2+2+i*4:], v.length) + } + return stream.Write(buf) +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/serialization_generic.go b/backend/vendor/github.com/RoaringBitmap/roaring/serialization_generic.go new file mode 100644 index 0000000000..90a336cdae --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/serialization_generic.go @@ -0,0 +1,133 @@ +// +build !amd64,!386,!arm,!arm64,!ppc64le,!mipsle,!mips64le,!mips64p32le,!wasm appengine + +package roaring + +import ( + "encoding/binary" + "errors" + "io" +) + +func (b *arrayContainer) writeTo(stream io.Writer) (int, error) { + buf := make([]byte, 2*len(b.content)) + for i, v := range b.content { + base := i * 2 + buf[base] = byte(v) + buf[base+1] = byte(v >> 8) + } + return stream.Write(buf) +} + +func (b *arrayContainer) readFrom(stream io.Reader) (int, error) { + err := binary.Read(stream, binary.LittleEndian, b.content) + if err != nil { + return 0, err + } + return 2 * len(b.content), nil +} + +func (b *bitmapContainer) writeTo(stream io.Writer) (int, error) { + if b.cardinality <= arrayDefaultMaxSize { + return 0, errors.New("refusing to write bitmap container with cardinality of array container") + } + + // Write set + buf := make([]byte, 8*len(b.bitmap)) + for i, v := range b.bitmap { + base := i * 8 + buf[base] = byte(v) + buf[base+1] = byte(v >> 8) + buf[base+2] = byte(v >> 16) + buf[base+3] = byte(v >> 24) + buf[base+4] = byte(v >> 32) + buf[base+5] = byte(v >> 40) + buf[base+6] = byte(v >> 48) + buf[base+7] = byte(v >> 56) + } + return stream.Write(buf) +} + +func (b *bitmapContainer) readFrom(stream io.Reader) (int, error) { + err := binary.Read(stream, binary.LittleEndian, b.bitmap) + if err != nil { + return 0, err + } + b.computeCardinality() + return 8 * len(b.bitmap), nil +} + +func (bc *bitmapContainer) asLittleEndianByteSlice() []byte { + by := make([]byte, len(bc.bitmap)*8) + for i := range bc.bitmap { + binary.LittleEndian.PutUint64(by[i*8:], bc.bitmap[i]) + } + return by +} + +func uint64SliceAsByteSlice(slice []uint64) []byte { + by := make([]byte, len(slice)*8) + + for i, v := range slice { + binary.LittleEndian.PutUint64(by[i*8:], v) + } + + return by +} + +func uint16SliceAsByteSlice(slice []uint16) []byte { + by := make([]byte, len(slice)*2) + + for i, v := range slice { + binary.LittleEndian.PutUint16(by[i*2:], v) + } + + return by +} + +func byteSliceAsUint16Slice(slice []byte) []uint16 { + if len(slice)%2 != 0 { + panic("Slice size should be divisible by 2") + } + + b := make([]uint16, len(slice)/2) + + for i := range b { + b[i] = binary.LittleEndian.Uint16(slice[2*i:]) + } + + return b +} + +func byteSliceAsUint64Slice(slice []byte) []uint64 { + if len(slice)%8 != 0 { + panic("Slice size should be divisible by 8") + } + + b := make([]uint64, len(slice)/8) + + for i := range b { + b[i] = binary.LittleEndian.Uint64(slice[8*i:]) + } + + return b +} + +// Converts a byte slice to a interval16 slice. +// The function assumes that the slice byte buffer is run container data +// encoded according to Roaring Format Spec +func byteSliceAsInterval16Slice(byteSlice []byte) []interval16 { + if len(byteSlice)%4 != 0 { + panic("Slice size should be divisible by 4") + } + + intervalSlice := make([]interval16, len(byteSlice)/4) + + for i := range intervalSlice { + intervalSlice[i] = interval16{ + start: binary.LittleEndian.Uint16(byteSlice[i*4:]), + length: binary.LittleEndian.Uint16(byteSlice[i*4+2:]), + } + } + + return intervalSlice +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/serialization_littleendian.go b/backend/vendor/github.com/RoaringBitmap/roaring/serialization_littleendian.go new file mode 100644 index 0000000000..221e173fe4 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/serialization_littleendian.go @@ -0,0 +1,417 @@ +// +build 386,!appengine amd64,!appengine arm,!appengine arm64,!appengine ppc64le,!appengine mipsle,!appengine mips64le,!appengine mips64p32le,!appengine wasm,!appengine + +package roaring + +import ( + "encoding/binary" + "errors" + "io" + "reflect" + "runtime" + "unsafe" +) + +func (ac *arrayContainer) writeTo(stream io.Writer) (int, error) { + buf := uint16SliceAsByteSlice(ac.content) + return stream.Write(buf) +} + +func (bc *bitmapContainer) writeTo(stream io.Writer) (int, error) { + if bc.cardinality <= arrayDefaultMaxSize { + return 0, errors.New("refusing to write bitmap container with cardinality of array container") + } + buf := uint64SliceAsByteSlice(bc.bitmap) + return stream.Write(buf) +} + +func uint64SliceAsByteSlice(slice []uint64) []byte { + // make a new slice header + header := *(*reflect.SliceHeader)(unsafe.Pointer(&slice)) + + // update its capacity and length + header.Len *= 8 + header.Cap *= 8 + + // instantiate result and use KeepAlive so data isn't unmapped. + result := *(*[]byte)(unsafe.Pointer(&header)) + runtime.KeepAlive(&slice) + + // return it + return result +} + +func uint16SliceAsByteSlice(slice []uint16) []byte { + // make a new slice header + header := *(*reflect.SliceHeader)(unsafe.Pointer(&slice)) + + // update its capacity and length + header.Len *= 2 + header.Cap *= 2 + + // instantiate result and use KeepAlive so data isn't unmapped. + result := *(*[]byte)(unsafe.Pointer(&header)) + runtime.KeepAlive(&slice) + + // return it + return result +} + +func (bc *bitmapContainer) asLittleEndianByteSlice() []byte { + return uint64SliceAsByteSlice(bc.bitmap) +} + +// Deserialization code follows + +//// +// These methods (byteSliceAsUint16Slice,...) do not make copies, +// they are pointer-based (unsafe). The caller is responsible to +// ensure that the input slice does not get garbage collected, deleted +// or modified while you hold the returned slince. +//// +func byteSliceAsUint16Slice(slice []byte) (result []uint16) { // here we create a new slice holder + if len(slice)%2 != 0 { + panic("Slice size should be divisible by 2") + } + // reference: https://go101.org/article/unsafe.html + + // make a new slice header + bHeader := (*reflect.SliceHeader)(unsafe.Pointer(&slice)) + rHeader := (*reflect.SliceHeader)(unsafe.Pointer(&result)) + + // transfer the data from the given slice to a new variable (our result) + rHeader.Data = bHeader.Data + rHeader.Len = bHeader.Len / 2 + rHeader.Cap = bHeader.Cap / 2 + + // instantiate result and use KeepAlive so data isn't unmapped. + runtime.KeepAlive(&slice) // it is still crucial, GC can free it) + + // return result + return +} + +func byteSliceAsUint64Slice(slice []byte) (result []uint64) { + if len(slice)%8 != 0 { + panic("Slice size should be divisible by 8") + } + // reference: https://go101.org/article/unsafe.html + + // make a new slice header + bHeader := (*reflect.SliceHeader)(unsafe.Pointer(&slice)) + rHeader := (*reflect.SliceHeader)(unsafe.Pointer(&result)) + + // transfer the data from the given slice to a new variable (our result) + rHeader.Data = bHeader.Data + rHeader.Len = bHeader.Len / 8 + rHeader.Cap = bHeader.Cap / 8 + + // instantiate result and use KeepAlive so data isn't unmapped. + runtime.KeepAlive(&slice) // it is still crucial, GC can free it) + + // return result + return +} + +func byteSliceAsInterval16Slice(slice []byte) (result []interval16) { + if len(slice)%4 != 0 { + panic("Slice size should be divisible by 4") + } + // reference: https://go101.org/article/unsafe.html + + // make a new slice header + bHeader := (*reflect.SliceHeader)(unsafe.Pointer(&slice)) + rHeader := (*reflect.SliceHeader)(unsafe.Pointer(&result)) + + // transfer the data from the given slice to a new variable (our result) + rHeader.Data = bHeader.Data + rHeader.Len = bHeader.Len / 4 + rHeader.Cap = bHeader.Cap / 4 + + // instantiate result and use KeepAlive so data isn't unmapped. + runtime.KeepAlive(&slice) // it is still crucial, GC can free it) + + // return result + return +} + +// FromBuffer creates a bitmap from its serialized version stored in buffer. +// It uses CRoaring's frozen bitmap format. +// +// The format specification is available here: +// https://github.com/RoaringBitmap/CRoaring/blob/2c867e9f9c9e2a3a7032791f94c4c7ae3013f6e0/src/roaring.c#L2756-L2783 +// +// The provided byte array (buf) is expected to be a constant. +// The function makes the best effort attempt not to copy data. +// Only little endian is supported. The function will err if it detects a big +// endian serialized file. +// You should take care not to modify buff as it will likely result in +// unexpected program behavior. +// If said buffer comes from a memory map, it's advisable to give it read +// only permissions, either at creation or by calling Mprotect from the +// golang.org/x/sys/unix package. +// +// Resulting bitmaps are effectively immutable in the following sense: +// a copy-on-write marker is used so that when you modify the resulting +// bitmap, copies of selected data (containers) are made. +// You should *not* change the copy-on-write status of the resulting +// bitmaps (SetCopyOnWrite). +// +// If buf becomes unavailable, then a bitmap created with +// FromBuffer would be effectively broken. Furthermore, any +// bitmap derived from this bitmap (e.g., via Or, And) might +// also be broken. Thus, before making buf unavailable, you should +// call CloneCopyOnWriteContainers on all such bitmaps. +// +func (rb *Bitmap) FrozenView(buf []byte) error { + return rb.highlowcontainer.frozenView(buf) +} + +/* Verbatim specification from CRoaring. + * + * FROZEN SERIALIZATION FORMAT DESCRIPTION + * + * -- (beginning must be aligned by 32 bytes) -- + * uint64_t[BITSET_CONTAINER_SIZE_IN_WORDS * num_bitset_containers] + * rle16_t[total number of rle elements in all run containers] + * uint16_t[total number of array elements in all array containers] + * uint16_t[num_containers] + * uint16_t[num_containers] + * uint8_t[num_containers] + *
uint32_t + * + *
is a 4-byte value which is a bit union of FROZEN_COOKIE (15 bits) + * and the number of containers (17 bits). + * + * stores number of elements for every container. + * Its meaning depends on container type. + * For array and bitset containers, this value is the container cardinality minus one. + * For run container, it is the number of rle_t elements (n_runs). + * + * ,, are flat arrays of elements of + * all containers of respective type. + * + * <*_data> and are kept close together because they are not accessed + * during deserilization. This may reduce IO in case of large mmaped bitmaps. + * All members have their native alignments during deserilization except
, + * which is not guaranteed to be aligned by 4 bytes. + */ +const FROZEN_COOKIE = 13766 + +var ( + FrozenBitmapInvalidCookie = errors.New("header does not contain the FROZEN_COOKIE") + FrozenBitmapBigEndian = errors.New("loading big endian frozen bitmaps is not supported") + FrozenBitmapIncomplete = errors.New("input buffer too small to contain a frozen bitmap") + FrozenBitmapOverpopulated = errors.New("too many containers") + FrozenBitmapUnexpectedData = errors.New("spurious data in input") + FrozenBitmapInvalidTypecode = errors.New("unrecognized typecode") + FrozenBitmapBufferTooSmall = errors.New("buffer too small") +) + +func (ra *roaringArray) frozenView(buf []byte) error { + if len(buf) < 4 { + return FrozenBitmapIncomplete + } + + headerBE := binary.BigEndian.Uint32(buf[len(buf)-4:]) + if headerBE & 0x7fff == FROZEN_COOKIE { + return FrozenBitmapBigEndian + } + + header := binary.LittleEndian.Uint32(buf[len(buf)-4:]) + buf = buf[:len(buf)-4] + + if header & 0x7fff != FROZEN_COOKIE { + return FrozenBitmapInvalidCookie + } + + nCont := int(header >> 15) + if nCont > (1 << 16) { + return FrozenBitmapOverpopulated + } + + // 1 byte per type, 2 bytes per key, 2 bytes per count. + if len(buf) < 5*nCont { + return FrozenBitmapIncomplete + } + + types := buf[len(buf)-nCont:] + buf = buf[:len(buf)-nCont] + + counts := byteSliceAsUint16Slice(buf[len(buf)-2*nCont:]) + buf = buf[:len(buf)-2*nCont] + + keys := byteSliceAsUint16Slice(buf[len(buf)-2*nCont:]) + buf = buf[:len(buf)-2*nCont] + + nBitmap, nArray, nRun := uint64(0), uint64(0), uint64(0) + nArrayEl, nRunEl := uint64(0), uint64(0) + for i, t := range types { + switch (t) { + case 1: + nBitmap++ + case 2: + nArray++ + nArrayEl += uint64(counts[i])+1 + case 3: + nRun++ + nRunEl += uint64(counts[i]) + default: + return FrozenBitmapInvalidTypecode + } + } + + if uint64(len(buf)) < (1 << 13)*nBitmap + 4*nRunEl + 2*nArrayEl { + return FrozenBitmapIncomplete + } + + bitsetsArena := byteSliceAsUint64Slice(buf[:(1 << 13)*nBitmap]) + buf = buf[(1 << 13)*nBitmap:] + + runsArena := byteSliceAsInterval16Slice(buf[:4*nRunEl]) + buf = buf[4*nRunEl:] + + arraysArena := byteSliceAsUint16Slice(buf[:2*nArrayEl]) + buf = buf[2*nArrayEl:] + + if len(buf) != 0 { + return FrozenBitmapUnexpectedData + } + + // TODO: maybe arena_alloc all this. + containers := make([]container, nCont) + bitsets := make([]bitmapContainer, nBitmap) + arrays := make([]arrayContainer, nArray) + runs := make([]runContainer16, nRun) + needCOW := make([]bool, nCont) + + iBitset, iArray, iRun := uint64(0), uint64(0), uint64(0) + for i, t := range types { + needCOW[i] = true + + switch (t) { + case 1: + containers[i] = &bitsets[iBitset] + bitsets[iBitset].cardinality = int(counts[i])+1 + bitsets[iBitset].bitmap = bitsetsArena[:1024] + bitsetsArena = bitsetsArena[1024:] + iBitset++ + case 2: + containers[i] = &arrays[iArray] + sz := int(counts[i])+1 + arrays[iArray].content = arraysArena[:sz] + arraysArena = arraysArena[sz:] + iArray++ + case 3: + containers[i] = &runs[iRun] + runs[iRun].iv = runsArena[:counts[i]] + runsArena = runsArena[counts[i]:] + iRun++ + } + } + + // Not consuming the full input is a bug. + if iBitset != nBitmap || len(bitsetsArena) != 0 || + iArray != nArray || len(arraysArena) != 0 || + iRun != nRun || len(runsArena) != 0 { + panic("we missed something") + } + + ra.keys = keys + ra.containers = containers + ra.needCopyOnWrite = needCOW + ra.copyOnWrite = true + + return nil +} + +func (bm *Bitmap) GetFrozenSizeInBytes() uint64 { + nBits, nArrayEl, nRunEl := uint64(0), uint64(0), uint64(0) + for _, c := range bm.highlowcontainer.containers { + switch v := c.(type) { + case *bitmapContainer: + nBits++ + case *arrayContainer: + nArrayEl += uint64(len(v.content)) + case *runContainer16: + nRunEl += uint64(len(v.iv)) + } + } + return 4 + 5*uint64(len(bm.highlowcontainer.containers)) + + (nBits << 13) + 2*nArrayEl + 4*nRunEl +} + +func (bm *Bitmap) Freeze() ([]byte, error) { + sz := bm.GetFrozenSizeInBytes() + buf := make([]byte, sz) + _, err := bm.FreezeTo(buf) + return buf, err +} + +func (bm *Bitmap) FreezeTo(buf []byte) (int, error) { + containers := bm.highlowcontainer.containers + nCont := len(containers) + + nBits, nArrayEl, nRunEl := 0, 0, 0 + for _, c := range containers { + switch v := c.(type) { + case *bitmapContainer: + nBits++ + case *arrayContainer: + nArrayEl += len(v.content) + case *runContainer16: + nRunEl += len(v.iv) + } + } + + serialSize := 4 + 5*nCont + (1 << 13)*nBits + 4*nRunEl + 2*nArrayEl + if len(buf) < serialSize { + return 0, FrozenBitmapBufferTooSmall + } + + bitsArena := byteSliceAsUint64Slice(buf[:(1 << 13)*nBits]) + buf = buf[(1 << 13)*nBits:] + + runsArena := byteSliceAsInterval16Slice(buf[:4*nRunEl]) + buf = buf[4*nRunEl:] + + arraysArena := byteSliceAsUint16Slice(buf[:2*nArrayEl]) + buf = buf[2*nArrayEl:] + + keys := byteSliceAsUint16Slice(buf[:2*nCont]) + buf = buf[2*nCont:] + + counts := byteSliceAsUint16Slice(buf[:2*nCont]) + buf = buf[2*nCont:] + + types := buf[:nCont] + buf = buf[nCont:] + + header := uint32(FROZEN_COOKIE|(nCont << 15)) + binary.LittleEndian.PutUint32(buf[:4], header) + + copy(keys, bm.highlowcontainer.keys[:]) + + for i, c := range containers { + switch v := c.(type) { + case *bitmapContainer: + copy(bitsArena, v.bitmap) + bitsArena = bitsArena[1024:] + counts[i] = uint16(v.cardinality-1) + types[i] = 1 + case *arrayContainer: + copy(arraysArena, v.content) + arraysArena = arraysArena[len(v.content):] + elems := len(v.content) + counts[i] = uint16(elems-1) + types[i] = 2 + case *runContainer16: + copy(runsArena, v.iv) + runs := len(v.iv) + runsArena = runsArena[runs:] + counts[i] = uint16(runs) + types[i] = 3 + } + } + + return serialSize, nil +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/serializationfuzz.go b/backend/vendor/github.com/RoaringBitmap/roaring/serializationfuzz.go new file mode 100644 index 0000000000..5eaa22202c --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/serializationfuzz.go @@ -0,0 +1,21 @@ +// +build gofuzz + +package roaring + +import "bytes" + +func FuzzSerializationStream(data []byte) int { + newrb := NewBitmap() + if _, err := newrb.ReadFrom(bytes.NewReader(data)); err != nil { + return 0 + } + return 1 +} + +func FuzzSerializationBuffer(data []byte) int { + newrb := NewBitmap() + if _, err := newrb.FromBuffer(data); err != nil { + return 0 + } + return 1 +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/setutil.go b/backend/vendor/github.com/RoaringBitmap/roaring/setutil.go new file mode 100644 index 0000000000..663c4fa37e --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/setutil.go @@ -0,0 +1,550 @@ +package roaring + +func equal(a, b []uint16) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if a[i] != b[i] { + return false + } + } + return true +} + +func difference(set1 []uint16, set2 []uint16, buffer []uint16) int { + if 0 == len(set2) { + buffer = buffer[:len(set1)] + for k := 0; k < len(set1); k++ { + buffer[k] = set1[k] + } + return len(set1) + } + if 0 == len(set1) { + return 0 + } + pos := 0 + k1 := 0 + k2 := 0 + buffer = buffer[:cap(buffer)] + s1 := set1[k1] + s2 := set2[k2] + for { + if s1 < s2 { + buffer[pos] = s1 + pos++ + k1++ + if k1 >= len(set1) { + break + } + s1 = set1[k1] + } else if s1 == s2 { + k1++ + k2++ + if k1 >= len(set1) { + break + } + s1 = set1[k1] + if k2 >= len(set2) { + for ; k1 < len(set1); k1++ { + buffer[pos] = set1[k1] + pos++ + } + break + } + s2 = set2[k2] + } else { // if (val1>val2) + k2++ + if k2 >= len(set2) { + for ; k1 < len(set1); k1++ { + buffer[pos] = set1[k1] + pos++ + } + break + } + s2 = set2[k2] + } + } + return pos + +} + +func exclusiveUnion2by2(set1 []uint16, set2 []uint16, buffer []uint16) int { + if 0 == len(set2) { + buffer = buffer[:len(set1)] + copy(buffer, set1[:]) + return len(set1) + } + if 0 == len(set1) { + buffer = buffer[:len(set2)] + copy(buffer, set2[:]) + return len(set2) + } + pos := 0 + k1 := 0 + k2 := 0 + s1 := set1[k1] + s2 := set2[k2] + buffer = buffer[:cap(buffer)] + for { + if s1 < s2 { + buffer[pos] = s1 + pos++ + k1++ + if k1 >= len(set1) { + for ; k2 < len(set2); k2++ { + buffer[pos] = set2[k2] + pos++ + } + break + } + s1 = set1[k1] + } else if s1 == s2 { + k1++ + k2++ + if k1 >= len(set1) { + for ; k2 < len(set2); k2++ { + buffer[pos] = set2[k2] + pos++ + } + break + } + if k2 >= len(set2) { + for ; k1 < len(set1); k1++ { + buffer[pos] = set1[k1] + pos++ + } + break + } + s1 = set1[k1] + s2 = set2[k2] + } else { // if (val1>val2) + buffer[pos] = s2 + pos++ + k2++ + if k2 >= len(set2) { + for ; k1 < len(set1); k1++ { + buffer[pos] = set1[k1] + pos++ + } + break + } + s2 = set2[k2] + } + } + return pos +} + +func union2by2Cardinality(set1 []uint16, set2 []uint16) int { + pos := 0 + k1 := 0 + k2 := 0 + if 0 == len(set2) { + return len(set1) + } + if 0 == len(set1) { + return len(set2) + } + s1 := set1[k1] + s2 := set2[k2] + for { + if s1 < s2 { + pos++ + k1++ + if k1 >= len(set1) { + pos += len(set2) - k2 + break + } + s1 = set1[k1] + } else if s1 == s2 { + pos++ + k1++ + k2++ + if k1 >= len(set1) { + pos += len(set2) - k2 + break + } + if k2 >= len(set2) { + pos += len(set1) - k1 + break + } + s1 = set1[k1] + s2 = set2[k2] + } else { // if (set1[k1]>set2[k2]) + pos++ + k2++ + if k2 >= len(set2) { + pos += len(set1) - k1 + break + } + s2 = set2[k2] + } + } + return pos +} + +func intersection2by2( + set1 []uint16, + set2 []uint16, + buffer []uint16) int { + + if len(set1)*64 < len(set2) { + return onesidedgallopingintersect2by2(set1, set2, buffer) + } else if len(set2)*64 < len(set1) { + return onesidedgallopingintersect2by2(set2, set1, buffer) + } else { + return localintersect2by2(set1, set2, buffer) + } +} + +func intersection2by2Cardinality( + set1 []uint16, + set2 []uint16) int { + + if len(set1)*64 < len(set2) { + return onesidedgallopingintersect2by2Cardinality(set1, set2) + } else if len(set2)*64 < len(set1) { + return onesidedgallopingintersect2by2Cardinality(set2, set1) + } else { + return localintersect2by2Cardinality(set1, set2) + } +} + +func intersects2by2( + set1 []uint16, + set2 []uint16) bool { + // could be optimized if one set is much larger than the other one + if (0 == len(set1)) || (0 == len(set2)) { + return false + } + k1 := 0 + k2 := 0 + s1 := set1[k1] + s2 := set2[k2] +mainwhile: + for { + + if s2 < s1 { + for { + k2++ + if k2 == len(set2) { + break mainwhile + } + s2 = set2[k2] + if s2 >= s1 { + break + } + } + } + if s1 < s2 { + for { + k1++ + if k1 == len(set1) { + break mainwhile + } + s1 = set1[k1] + if s1 >= s2 { + break + } + } + + } else { + // (set2[k2] == set1[k1]) + return true + } + } + return false +} + +func localintersect2by2( + set1 []uint16, + set2 []uint16, + buffer []uint16) int { + + if (0 == len(set1)) || (0 == len(set2)) { + return 0 + } + k1 := 0 + k2 := 0 + pos := 0 + buffer = buffer[:cap(buffer)] + s1 := set1[k1] + s2 := set2[k2] +mainwhile: + for { + if s2 < s1 { + for { + k2++ + if k2 == len(set2) { + break mainwhile + } + s2 = set2[k2] + if s2 >= s1 { + break + } + } + } + if s1 < s2 { + for { + k1++ + if k1 == len(set1) { + break mainwhile + } + s1 = set1[k1] + if s1 >= s2 { + break + } + } + + } else { + // (set2[k2] == set1[k1]) + buffer[pos] = s1 + pos++ + k1++ + if k1 == len(set1) { + break + } + s1 = set1[k1] + k2++ + if k2 == len(set2) { + break + } + s2 = set2[k2] + } + } + return pos +} + +func localintersect2by2Cardinality( + set1 []uint16, + set2 []uint16) int { + + if (0 == len(set1)) || (0 == len(set2)) { + return 0 + } + k1 := 0 + k2 := 0 + pos := 0 + s1 := set1[k1] + s2 := set2[k2] +mainwhile: + for { + if s2 < s1 { + for { + k2++ + if k2 == len(set2) { + break mainwhile + } + s2 = set2[k2] + if s2 >= s1 { + break + } + } + } + if s1 < s2 { + for { + k1++ + if k1 == len(set1) { + break mainwhile + } + s1 = set1[k1] + if s1 >= s2 { + break + } + } + + } else { + // (set2[k2] == set1[k1]) + pos++ + k1++ + if k1 == len(set1) { + break + } + s1 = set1[k1] + k2++ + if k2 == len(set2) { + break + } + s2 = set2[k2] + } + } + return pos +} + +func advanceUntil( + array []uint16, + pos int, + length int, + min uint16) int { + lower := pos + 1 + + if lower >= length || array[lower] >= min { + return lower + } + + spansize := 1 + + for lower+spansize < length && array[lower+spansize] < min { + spansize *= 2 + } + var upper int + if lower+spansize < length { + upper = lower + spansize + } else { + upper = length - 1 + } + + if array[upper] == min { + return upper + } + + if array[upper] < min { + // means + // array + // has no + // item + // >= min + // pos = array.length; + return length + } + + // we know that the next-smallest span was too small + lower += (spansize >> 1) + + mid := 0 + for lower+1 != upper { + mid = (lower + upper) >> 1 + if array[mid] == min { + return mid + } else if array[mid] < min { + lower = mid + } else { + upper = mid + } + } + return upper + +} + +func onesidedgallopingintersect2by2( + smallset []uint16, + largeset []uint16, + buffer []uint16) int { + + if 0 == len(smallset) { + return 0 + } + buffer = buffer[:cap(buffer)] + k1 := 0 + k2 := 0 + pos := 0 + s1 := largeset[k1] + s2 := smallset[k2] +mainwhile: + + for { + if s1 < s2 { + k1 = advanceUntil(largeset, k1, len(largeset), s2) + if k1 == len(largeset) { + break mainwhile + } + s1 = largeset[k1] + } + if s2 < s1 { + k2++ + if k2 == len(smallset) { + break mainwhile + } + s2 = smallset[k2] + } else { + + buffer[pos] = s2 + pos++ + k2++ + if k2 == len(smallset) { + break + } + s2 = smallset[k2] + k1 = advanceUntil(largeset, k1, len(largeset), s2) + if k1 == len(largeset) { + break mainwhile + } + s1 = largeset[k1] + } + + } + return pos +} + +func onesidedgallopingintersect2by2Cardinality( + smallset []uint16, + largeset []uint16) int { + + if 0 == len(smallset) { + return 0 + } + k1 := 0 + k2 := 0 + pos := 0 + s1 := largeset[k1] + s2 := smallset[k2] +mainwhile: + + for { + if s1 < s2 { + k1 = advanceUntil(largeset, k1, len(largeset), s2) + if k1 == len(largeset) { + break mainwhile + } + s1 = largeset[k1] + } + if s2 < s1 { + k2++ + if k2 == len(smallset) { + break mainwhile + } + s2 = smallset[k2] + } else { + + pos++ + k2++ + if k2 == len(smallset) { + break + } + s2 = smallset[k2] + k1 = advanceUntil(largeset, k1, len(largeset), s2) + if k1 == len(largeset) { + break mainwhile + } + s1 = largeset[k1] + } + + } + return pos +} + +func binarySearch(array []uint16, ikey uint16) int { + low := 0 + high := len(array) - 1 + for low+16 <= high { + middleIndex := int(uint32(low+high) >> 1) + middleValue := array[middleIndex] + if middleValue < ikey { + low = middleIndex + 1 + } else if middleValue > ikey { + high = middleIndex - 1 + } else { + return middleIndex + } + } + for ; low <= high; low++ { + val := array[low] + if val >= ikey { + if val == ikey { + return low + } + break + } + } + return -(low + 1) +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/setutil_arm64.go b/backend/vendor/github.com/RoaringBitmap/roaring/setutil_arm64.go new file mode 100644 index 0000000000..debca813c4 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/setutil_arm64.go @@ -0,0 +1,6 @@ +// +build arm64,!gccgo,!appengine + +package roaring + +//go:noescape +func union2by2(set1 []uint16, set2 []uint16, buffer []uint16) (size int) diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/setutil_arm64.s b/backend/vendor/github.com/RoaringBitmap/roaring/setutil_arm64.s new file mode 100644 index 0000000000..e4f0f20473 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/setutil_arm64.s @@ -0,0 +1,132 @@ +// +build arm64,!gccgo,!appengine + +#include "textflag.h" + + +// This implements union2by2 using golang's version of arm64 assembly +// The algorithm is very similar to the generic one, +// but makes better use of arm64 features so is notably faster. +// The basic algorithm structure is as follows: +// 1. If either set is empty, copy the other set into the buffer and return the length +// 2. Otherwise, load the first element of each set into a variable (s1 and s2). +// 3. a. Compare the values of s1 and s2. + // b. add the smaller one to the buffer. + // c. perform a bounds check before incrementing. + // If one set is finished, copy the rest of the other set over. + // d. update s1 and or s2 to the next value, continue loop. + // + // Past the fact of the algorithm, this code makes use of several arm64 features + // Condition Codes: + // arm64's CMP operation sets 4 bits that can be used for branching, + // rather than just true or false. + // As a consequence, a single comparison gives enough information to distinguish the three cases + // + // Post-increment pointers after load/store: + // Instructions like `MOVHU.P 2(R0), R6` + // increment the register by a specified amount, in this example 2. + // Because uint16's are exactly 2 bytes and the length of the slices + // is part of the slice header, + // there is no need to separately track the index into the slice. + // Instead, the code can calculate the final read value and compare against that, + // using the post-increment reads to move the pointers along. + // + // TODO: CALL out to memmove once the list is exhausted. + // Right now it moves the necessary shorts so that the remaining count + // is a multiple of 4 and then copies 64 bits at a time. + +TEXT ·union2by2(SB), NOSPLIT, $0-80 + // R0, R1, and R2 for the pointers to the three slices + MOVD set1+0(FP), R0 + MOVD set2+24(FP), R1 + MOVD buffer+48(FP), R2 + + //R3 and R4 will be the values at which we will have finished reading set1 and set2. + // R3 should be R0 + 2 * set1_len+8(FP) + MOVD set1_len+8(FP), R3 + MOVD set2_len+32(FP), R4 + + ADD R3<<1, R0, R3 + ADD R4<<1, R1, R4 + + + //Rather than counting the number of elements added separately + //Save the starting register of buffer. + MOVD buffer+48(FP), R5 + + // set1 is empty, just flush set2 + CMP R0, R3 + BEQ flush_right + + // set2 is empty, just flush set1 + CMP R1, R4 + BEQ flush_left + + // R6, R7 are the working space for s1 and s2 + MOVD ZR, R6 + MOVD ZR, R7 + + MOVHU.P 2(R0), R6 + MOVHU.P 2(R1), R7 +loop: + + CMP R6, R7 + BEQ pop_both // R6 == R7 + BLS pop_right // R6 > R7 +//pop_left: // R6 < R7 + MOVHU.P R6, 2(R2) + CMP R0, R3 + BEQ pop_then_flush_right + MOVHU.P 2(R0), R6 + JMP loop +pop_both: + MOVHU.P R6, 2(R2) //could also use R7, since they are equal + CMP R0, R3 + BEQ flush_right + CMP R1, R4 + BEQ flush_left + MOVHU.P 2(R0), R6 + MOVHU.P 2(R1), R7 + JMP loop +pop_right: + MOVHU.P R7, 2(R2) + CMP R1, R4 + BEQ pop_then_flush_left + MOVHU.P 2(R1), R7 + JMP loop + +pop_then_flush_right: + MOVHU.P R7, 2(R2) +flush_right: + MOVD R1, R0 + MOVD R4, R3 + JMP flush_left +pop_then_flush_left: + MOVHU.P R6, 2(R2) +flush_left: + CMP R0, R3 + BEQ return + //figure out how many bytes to slough off. Must be a multiple of two + SUB R0, R3, R4 + ANDS $6, R4 + BEQ long_flush //handles the 0 mod 8 case + SUBS $4, R4, R4 // since possible values are 2, 4, 6, this splits evenly + BLT pop_single // exactly the 2 case + MOVW.P 4(R0), R6 + MOVW.P R6, 4(R2) + BEQ long_flush // we're now aligned by 64 bits, as R4==4, otherwise 2 more +pop_single: + MOVHU.P 2(R0), R6 + MOVHU.P R6, 2(R2) +long_flush: + // at this point we know R3 - R0 is a multiple of 8. + CMP R0, R3 + BEQ return + MOVD.P 8(R0), R6 + MOVD.P R6, 8(R2) + JMP long_flush +return: + // number of shorts written is (R5 - R2) >> 1 + SUB R5, R2 + LSR $1, R2, R2 + MOVD R2, size+72(FP) + RET diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/setutil_generic.go b/backend/vendor/github.com/RoaringBitmap/roaring/setutil_generic.go new file mode 100644 index 0000000000..9edcc9025e --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/setutil_generic.go @@ -0,0 +1,63 @@ +// +build !arm64 gccgo appengine + +package roaring + +func union2by2(set1 []uint16, set2 []uint16, buffer []uint16) int { + pos := 0 + k1 := 0 + k2 := 0 + if 0 == len(set2) { + buffer = buffer[:len(set1)] + copy(buffer, set1[:]) + return len(set1) + } + if 0 == len(set1) { + buffer = buffer[:len(set2)] + copy(buffer, set2[:]) + return len(set2) + } + s1 := set1[k1] + s2 := set2[k2] + buffer = buffer[:cap(buffer)] + for { + if s1 < s2 { + buffer[pos] = s1 + pos++ + k1++ + if k1 >= len(set1) { + copy(buffer[pos:], set2[k2:]) + pos += len(set2) - k2 + break + } + s1 = set1[k1] + } else if s1 == s2 { + buffer[pos] = s1 + pos++ + k1++ + k2++ + if k1 >= len(set1) { + copy(buffer[pos:], set2[k2:]) + pos += len(set2) - k2 + break + } + if k2 >= len(set2) { + copy(buffer[pos:], set1[k1:]) + pos += len(set1) - k1 + break + } + s1 = set1[k1] + s2 = set2[k2] + } else { // if (set1[k1]>set2[k2]) + buffer[pos] = s2 + pos++ + k2++ + if k2 >= len(set2) { + copy(buffer[pos:], set1[k1:]) + pos += len(set1) - k1 + break + } + s2 = set2[k2] + } + } + return pos +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/shortiterator.go b/backend/vendor/github.com/RoaringBitmap/roaring/shortiterator.go new file mode 100644 index 0000000000..15b78bd0c1 --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/shortiterator.go @@ -0,0 +1,52 @@ +package roaring + +type shortIterable interface { + hasNext() bool + next() uint16 +} + +type shortPeekable interface { + shortIterable + peekNext() uint16 + advanceIfNeeded(minval uint16) +} + +type shortIterator struct { + slice []uint16 + loc int +} + +func (si *shortIterator) hasNext() bool { + return si.loc < len(si.slice) +} + +func (si *shortIterator) next() uint16 { + a := si.slice[si.loc] + si.loc++ + return a +} + +func (si *shortIterator) peekNext() uint16 { + return si.slice[si.loc] +} + +func (si *shortIterator) advanceIfNeeded(minval uint16) { + if si.hasNext() && si.peekNext() < minval { + si.loc = advanceUntil(si.slice, si.loc, len(si.slice), minval) + } +} + +type reverseIterator struct { + slice []uint16 + loc int +} + +func (si *reverseIterator) hasNext() bool { + return si.loc >= 0 +} + +func (si *reverseIterator) next() uint16 { + a := si.slice[si.loc] + si.loc-- + return a +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/smat.go b/backend/vendor/github.com/RoaringBitmap/roaring/smat.go new file mode 100644 index 0000000000..972cd244da --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/smat.go @@ -0,0 +1,383 @@ +// +build gofuzz + +/* +# Instructions for smat testing for roaring + +[smat](https://github.com/mschoch/smat) is a framework that provides +state machine assisted fuzz testing. + +To run the smat tests for roaring... + +## Prerequisites + + $ go get github.com/dvyukov/go-fuzz/go-fuzz + $ go get github.com/dvyukov/go-fuzz/go-fuzz-build + +## Steps + +1. Generate initial smat corpus: +``` + go test -tags=gofuzz -run=TestGenerateSmatCorpus +``` + +2. Build go-fuzz test program with instrumentation: +``` + go-fuzz-build -func FuzzSmat github.com/RoaringBitmap/roaring +``` + +3. Run go-fuzz: +``` + go-fuzz -bin=./roaring-fuzz.zip -workdir=workdir/ -timeout=200 +``` + +You should see output like... +``` +2016/09/16 13:58:35 slaves: 8, corpus: 1 (3s ago), crashers: 0, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 3s +2016/09/16 13:58:38 slaves: 8, corpus: 1 (6s ago), crashers: 0, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 6s +2016/09/16 13:58:41 slaves: 8, corpus: 1 (9s ago), crashers: 0, restarts: 1/44, execs: 44 (5/sec), cover: 0, uptime: 9s +2016/09/16 13:58:44 slaves: 8, corpus: 1 (12s ago), crashers: 0, restarts: 1/45, execs: 45 (4/sec), cover: 0, uptime: 12s +2016/09/16 13:58:47 slaves: 8, corpus: 1 (15s ago), crashers: 0, restarts: 1/46, execs: 46 (3/sec), cover: 0, uptime: 15s +2016/09/16 13:58:50 slaves: 8, corpus: 1 (18s ago), crashers: 0, restarts: 1/47, execs: 47 (3/sec), cover: 0, uptime: 18s +2016/09/16 13:58:53 slaves: 8, corpus: 1 (21s ago), crashers: 0, restarts: 1/63, execs: 63 (3/sec), cover: 0, uptime: 21s +2016/09/16 13:58:56 slaves: 8, corpus: 1 (24s ago), crashers: 0, restarts: 1/65, execs: 65 (3/sec), cover: 0, uptime: 24s +2016/09/16 13:58:59 slaves: 8, corpus: 1 (27s ago), crashers: 0, restarts: 1/66, execs: 66 (2/sec), cover: 0, uptime: 27s +2016/09/16 13:59:02 slaves: 8, corpus: 1 (30s ago), crashers: 0, restarts: 1/67, execs: 67 (2/sec), cover: 0, uptime: 30s +2016/09/16 13:59:05 slaves: 8, corpus: 1 (33s ago), crashers: 0, restarts: 1/83, execs: 83 (3/sec), cover: 0, uptime: 33s +2016/09/16 13:59:08 slaves: 8, corpus: 1 (36s ago), crashers: 0, restarts: 1/84, execs: 84 (2/sec), cover: 0, uptime: 36s +2016/09/16 13:59:11 slaves: 8, corpus: 2 (0s ago), crashers: 0, restarts: 1/85, execs: 85 (2/sec), cover: 0, uptime: 39s +2016/09/16 13:59:14 slaves: 8, corpus: 17 (2s ago), crashers: 0, restarts: 1/86, execs: 86 (2/sec), cover: 480, uptime: 42s +2016/09/16 13:59:17 slaves: 8, corpus: 17 (5s ago), crashers: 0, restarts: 1/66, execs: 132 (3/sec), cover: 487, uptime: 45s +2016/09/16 13:59:20 slaves: 8, corpus: 17 (8s ago), crashers: 0, restarts: 1/440, execs: 2645 (55/sec), cover: 487, uptime: 48s + +``` + +Let it run, and if the # of crashers is > 0, check out the reports in +the workdir where you should be able to find the panic goroutine stack +traces. +*/ + +package roaring + +import ( + "fmt" + "sort" + + "github.com/mschoch/smat" + "github.com/bits-and-blooms/bitset" +) + +// fuzz test using state machine driven by byte stream. +func FuzzSmat(data []byte) int { + return smat.Fuzz(&smatContext{}, smat.ActionID('S'), smat.ActionID('T'), + smatActionMap, data) +} + +var smatDebug = false + +func smatLog(prefix, format string, args ...interface{}) { + if smatDebug { + fmt.Print(prefix) + fmt.Printf(format, args...) + } +} + +type smatContext struct { + pairs []*smatPair + + // Two registers, x & y. + x int + y int + + actions int +} + +type smatPair struct { + bm *Bitmap + bs *bitset.BitSet +} + +// ------------------------------------------------------------------ + +var smatActionMap = smat.ActionMap{ + smat.ActionID('X'): smatAction("x++", smatWrap(func(c *smatContext) { c.x++ })), + smat.ActionID('x'): smatAction("x--", smatWrap(func(c *smatContext) { c.x-- })), + smat.ActionID('Y'): smatAction("y++", smatWrap(func(c *smatContext) { c.y++ })), + smat.ActionID('y'): smatAction("y--", smatWrap(func(c *smatContext) { c.y-- })), + smat.ActionID('*'): smatAction("x*y", smatWrap(func(c *smatContext) { c.x = c.x * c.y })), + smat.ActionID('<'): smatAction("x<<", smatWrap(func(c *smatContext) { c.x = c.x << 1 })), + + smat.ActionID('^'): smatAction("swap", smatWrap(func(c *smatContext) { c.x, c.y = c.y, c.x })), + + smat.ActionID('['): smatAction(" pushPair", smatWrap(smatPushPair)), + smat.ActionID(']'): smatAction(" popPair", smatWrap(smatPopPair)), + + smat.ActionID('B'): smatAction(" setBit", smatWrap(smatSetBit)), + smat.ActionID('b'): smatAction(" removeBit", smatWrap(smatRemoveBit)), + + smat.ActionID('o'): smatAction(" or", smatWrap(smatOr)), + smat.ActionID('a'): smatAction(" and", smatWrap(smatAnd)), + + smat.ActionID('#'): smatAction(" cardinality", smatWrap(smatCardinality)), + + smat.ActionID('O'): smatAction(" orCardinality", smatWrap(smatOrCardinality)), + smat.ActionID('A'): smatAction(" andCardinality", smatWrap(smatAndCardinality)), + + smat.ActionID('c'): smatAction(" clear", smatWrap(smatClear)), + smat.ActionID('r'): smatAction(" runOptimize", smatWrap(smatRunOptimize)), + + smat.ActionID('e'): smatAction(" isEmpty", smatWrap(smatIsEmpty)), + + smat.ActionID('i'): smatAction(" intersects", smatWrap(smatIntersects)), + + smat.ActionID('f'): smatAction(" flip", smatWrap(smatFlip)), + + smat.ActionID('-'): smatAction(" difference", smatWrap(smatDifference)), +} + +var smatRunningPercentActions []smat.PercentAction + +func init() { + var ids []int + for actionId := range smatActionMap { + ids = append(ids, int(actionId)) + } + sort.Ints(ids) + + pct := 100 / len(smatActionMap) + for _, actionId := range ids { + smatRunningPercentActions = append(smatRunningPercentActions, + smat.PercentAction{pct, smat.ActionID(actionId)}) + } + + smatActionMap[smat.ActionID('S')] = smatAction("SETUP", smatSetupFunc) + smatActionMap[smat.ActionID('T')] = smatAction("TEARDOWN", smatTeardownFunc) +} + +// We only have one smat state: running. +func smatRunning(next byte) smat.ActionID { + return smat.PercentExecute(next, smatRunningPercentActions...) +} + +func smatAction(name string, f func(ctx smat.Context) (smat.State, error)) func(smat.Context) (smat.State, error) { + return func(ctx smat.Context) (smat.State, error) { + c := ctx.(*smatContext) + c.actions++ + + smatLog(" ", "%s\n", name) + + return f(ctx) + } +} + +// Creates an smat action func based on a simple callback. +func smatWrap(cb func(c *smatContext)) func(smat.Context) (next smat.State, err error) { + return func(ctx smat.Context) (next smat.State, err error) { + c := ctx.(*smatContext) + cb(c) + return smatRunning, nil + } +} + +// Invokes a callback function with the input v bounded to len(c.pairs). +func (c *smatContext) withPair(v int, cb func(*smatPair)) { + if len(c.pairs) > 0 { + if v < 0 { + v = -v + } + v = v % len(c.pairs) + cb(c.pairs[v]) + } +} + +// ------------------------------------------------------------------ + +func smatSetupFunc(ctx smat.Context) (next smat.State, err error) { + return smatRunning, nil +} + +func smatTeardownFunc(ctx smat.Context) (next smat.State, err error) { + return nil, err +} + +// ------------------------------------------------------------------ + +func smatPushPair(c *smatContext) { + c.pairs = append(c.pairs, &smatPair{ + bm: NewBitmap(), + bs: bitset.New(100), + }) +} + +func smatPopPair(c *smatContext) { + if len(c.pairs) > 0 { + c.pairs = c.pairs[0 : len(c.pairs)-1] + } +} + +func smatSetBit(c *smatContext) { + c.withPair(c.x, func(p *smatPair) { + y := uint32(c.y) + p.bm.AddInt(int(y)) + p.bs.Set(uint(y)) + p.checkEquals() + }) +} + +func smatRemoveBit(c *smatContext) { + c.withPair(c.x, func(p *smatPair) { + y := uint32(c.y) + p.bm.Remove(y) + p.bs.Clear(uint(y)) + p.checkEquals() + }) +} + +func smatAnd(c *smatContext) { + c.withPair(c.x, func(px *smatPair) { + c.withPair(c.y, func(py *smatPair) { + px.bm.And(py.bm) + px.bs = px.bs.Intersection(py.bs) + px.checkEquals() + py.checkEquals() + }) + }) +} + +func smatOr(c *smatContext) { + c.withPair(c.x, func(px *smatPair) { + c.withPair(c.y, func(py *smatPair) { + px.bm.Or(py.bm) + px.bs = px.bs.Union(py.bs) + px.checkEquals() + py.checkEquals() + }) + }) +} + +func smatAndCardinality(c *smatContext) { + c.withPair(c.x, func(px *smatPair) { + c.withPair(c.y, func(py *smatPair) { + c0 := px.bm.AndCardinality(py.bm) + c1 := px.bs.IntersectionCardinality(py.bs) + if c0 != uint64(c1) { + panic("expected same add cardinality") + } + px.checkEquals() + py.checkEquals() + }) + }) +} + +func smatOrCardinality(c *smatContext) { + c.withPair(c.x, func(px *smatPair) { + c.withPair(c.y, func(py *smatPair) { + c0 := px.bm.OrCardinality(py.bm) + c1 := px.bs.UnionCardinality(py.bs) + if c0 != uint64(c1) { + panic("expected same or cardinality") + } + px.checkEquals() + py.checkEquals() + }) + }) +} + +func smatRunOptimize(c *smatContext) { + c.withPair(c.x, func(px *smatPair) { + px.bm.RunOptimize() + px.checkEquals() + }) +} + +func smatClear(c *smatContext) { + c.withPair(c.x, func(px *smatPair) { + px.bm.Clear() + px.bs = px.bs.ClearAll() + px.checkEquals() + }) +} + +func smatCardinality(c *smatContext) { + c.withPair(c.x, func(px *smatPair) { + c0 := px.bm.GetCardinality() + c1 := px.bs.Count() + if c0 != uint64(c1) { + panic("expected same cardinality") + } + }) +} + +func smatIsEmpty(c *smatContext) { + c.withPair(c.x, func(px *smatPair) { + c0 := px.bm.IsEmpty() + c1 := px.bs.None() + if c0 != c1 { + panic("expected same is empty") + } + }) +} + +func smatIntersects(c *smatContext) { + c.withPair(c.x, func(px *smatPair) { + c.withPair(c.y, func(py *smatPair) { + v0 := px.bm.Intersects(py.bm) + v1 := px.bs.IntersectionCardinality(py.bs) > 0 + if v0 != v1 { + panic("intersects not equal") + } + + px.checkEquals() + py.checkEquals() + }) + }) +} + +func smatFlip(c *smatContext) { + c.withPair(c.x, func(p *smatPair) { + y := uint32(c.y) + p.bm.Flip(uint64(y), uint64(y)+1) + p.bs = p.bs.Flip(uint(y)) + p.checkEquals() + }) +} + +func smatDifference(c *smatContext) { + c.withPair(c.x, func(px *smatPair) { + c.withPair(c.y, func(py *smatPair) { + px.bm.AndNot(py.bm) + px.bs = px.bs.Difference(py.bs) + px.checkEquals() + py.checkEquals() + }) + }) +} + +func (p *smatPair) checkEquals() { + if !p.equalsBitSet(p.bs, p.bm) { + panic("bitset mismatch") + } +} + +func (p *smatPair) equalsBitSet(a *bitset.BitSet, b *Bitmap) bool { + for i, e := a.NextSet(0); e; i, e = a.NextSet(i + 1) { + if !b.ContainsInt(int(i)) { + fmt.Printf("in a bitset, not b bitmap, i: %d\n", i) + fmt.Printf(" a bitset: %s\n b bitmap: %s\n", + a.String(), b.String()) + return false + } + } + + i := b.Iterator() + for i.HasNext() { + v := i.Next() + if !a.Test(uint(v)) { + fmt.Printf("in b bitmap, not a bitset, v: %d\n", v) + fmt.Printf(" a bitset: %s\n b bitmap: %s\n", + a.String(), b.String()) + return false + } + } + + return true +} diff --git a/backend/vendor/github.com/RoaringBitmap/roaring/util.go b/backend/vendor/github.com/RoaringBitmap/roaring/util.go new file mode 100644 index 0000000000..48b9d5a10e --- /dev/null +++ b/backend/vendor/github.com/RoaringBitmap/roaring/util.go @@ -0,0 +1,305 @@ +package roaring + +import ( + "math" + "math/rand" + "sort" +) + +const ( + arrayDefaultMaxSize = 4096 // containers with 4096 or fewer integers should be array containers. + arrayLazyLowerBound = 1024 + maxCapacity = 1 << 16 + serialCookieNoRunContainer = 12346 // only arrays and bitmaps + invalidCardinality = -1 + serialCookie = 12347 // runs, arrays, and bitmaps + noOffsetThreshold = 4 + + // MaxUint32 is the largest uint32 value. + MaxUint32 = math.MaxUint32 + + // MaxRange is One more than the maximum allowed bitmap bit index. For use as an upper + // bound for ranges. + MaxRange uint64 = MaxUint32 + 1 + + // MaxUint16 is the largest 16 bit unsigned int. + // This is the largest value an interval16 can store. + MaxUint16 = math.MaxUint16 + + // Compute wordSizeInBytes, the size of a word in bytes. + _m = ^uint64(0) + _logS = _m>>8&1 + _m>>16&1 + _m>>32&1 + wordSizeInBytes = 1 << _logS + + // other constants used in ctz_generic.go + wordSizeInBits = wordSizeInBytes << 3 // word size in bits +) + +const maxWord = 1< arrayDefaultMaxSize { + // bitmapContainer + return maxCapacity / 8 + } + // arrayContainer + return 2 * card +} + +func fill(arr []uint64, val uint64) { + for i := range arr { + arr[i] = val + } +} +func fillRange(arr []uint64, start, end int, val uint64) { + for i := start; i < end; i++ { + arr[i] = val + } +} + +func fillArrayAND(container []uint16, bitmap1, bitmap2 []uint64) { + if len(bitmap1) != len(bitmap2) { + panic("array lengths don't match") + } + // TODO: rewrite in assembly + pos := 0 + for k := range bitmap1 { + bitset := bitmap1[k] & bitmap2[k] + for bitset != 0 { + t := bitset & -bitset + container[pos] = uint16((k*64 + int(popcount(t-1)))) + pos = pos + 1 + bitset ^= t + } + } +} + +func fillArrayANDNOT(container []uint16, bitmap1, bitmap2 []uint64) { + if len(bitmap1) != len(bitmap2) { + panic("array lengths don't match") + } + // TODO: rewrite in assembly + pos := 0 + for k := range bitmap1 { + bitset := bitmap1[k] &^ bitmap2[k] + for bitset != 0 { + t := bitset & -bitset + container[pos] = uint16((k*64 + int(popcount(t-1)))) + pos = pos + 1 + bitset ^= t + } + } +} + +func fillArrayXOR(container []uint16, bitmap1, bitmap2 []uint64) { + if len(bitmap1) != len(bitmap2) { + panic("array lengths don't match") + } + // TODO: rewrite in assembly + pos := 0 + for k := 0; k < len(bitmap1); k++ { + bitset := bitmap1[k] ^ bitmap2[k] + for bitset != 0 { + t := bitset & -bitset + container[pos] = uint16((k*64 + int(popcount(t-1)))) + pos = pos + 1 + bitset ^= t + } + } +} + +func highbits(x uint32) uint16 { + return uint16(x >> 16) +} +func lowbits(x uint32) uint16 { + return uint16(x & maxLowBit) +} + +const maxLowBit = 0xFFFF + +func flipBitmapRange(bitmap []uint64, start int, end int) { + if start >= end { + return + } + firstword := start / 64 + endword := (end - 1) / 64 + bitmap[firstword] ^= ^(^uint64(0) << uint(start%64)) + for i := firstword; i < endword; i++ { + bitmap[i] = ^bitmap[i] + } + bitmap[endword] ^= ^uint64(0) >> (uint(-end) % 64) +} + +func resetBitmapRange(bitmap []uint64, start int, end int) { + if start >= end { + return + } + firstword := start / 64 + endword := (end - 1) / 64 + if firstword == endword { + bitmap[firstword] &= ^((^uint64(0) << uint(start%64)) & (^uint64(0) >> (uint(-end) % 64))) + return + } + bitmap[firstword] &= ^(^uint64(0) << uint(start%64)) + for i := firstword + 1; i < endword; i++ { + bitmap[i] = 0 + } + bitmap[endword] &= ^(^uint64(0) >> (uint(-end) % 64)) + +} + +func setBitmapRange(bitmap []uint64, start int, end int) { + if start >= end { + return + } + firstword := start / 64 + endword := (end - 1) / 64 + if firstword == endword { + bitmap[firstword] |= (^uint64(0) << uint(start%64)) & (^uint64(0) >> (uint(-end) % 64)) + return + } + bitmap[firstword] |= ^uint64(0) << uint(start%64) + for i := firstword + 1; i < endword; i++ { + bitmap[i] = ^uint64(0) + } + bitmap[endword] |= ^uint64(0) >> (uint(-end) % 64) +} + +func flipBitmapRangeAndCardinalityChange(bitmap []uint64, start int, end int) int { + before := wordCardinalityForBitmapRange(bitmap, start, end) + flipBitmapRange(bitmap, start, end) + after := wordCardinalityForBitmapRange(bitmap, start, end) + return int(after - before) +} + +func resetBitmapRangeAndCardinalityChange(bitmap []uint64, start int, end int) int { + before := wordCardinalityForBitmapRange(bitmap, start, end) + resetBitmapRange(bitmap, start, end) + after := wordCardinalityForBitmapRange(bitmap, start, end) + return int(after - before) +} + +func setBitmapRangeAndCardinalityChange(bitmap []uint64, start int, end int) int { + before := wordCardinalityForBitmapRange(bitmap, start, end) + setBitmapRange(bitmap, start, end) + after := wordCardinalityForBitmapRange(bitmap, start, end) + return int(after - before) +} + +func wordCardinalityForBitmapRange(bitmap []uint64, start int, end int) uint64 { + answer := uint64(0) + if start >= end { + return answer + } + firstword := start / 64 + endword := (end - 1) / 64 + for i := firstword; i <= endword; i++ { + answer += popcount(bitmap[i]) + } + return answer +} + +func selectBitPosition(w uint64, j int) int { + seen := 0 + + // Divide 64bit + part := w & 0xFFFFFFFF + n := popcount(part) + if n <= uint64(j) { + part = w >> 32 + seen += 32 + j -= int(n) + } + w = part + + // Divide 32bit + part = w & 0xFFFF + n = popcount(part) + if n <= uint64(j) { + part = w >> 16 + seen += 16 + j -= int(n) + } + w = part + + // Divide 16bit + part = w & 0xFF + n = popcount(part) + if n <= uint64(j) { + part = w >> 8 + seen += 8 + j -= int(n) + } + w = part + + // Lookup in final byte + var counter uint + for counter = 0; counter < 8; counter++ { + j -= int((w >> counter) & 1) + if j < 0 { + break + } + } + return seen + int(counter) + +} + +func panicOn(err error) { + if err != nil { + panic(err) + } +} + +type ph struct { + orig int + rand int +} + +type pha []ph + +func (p pha) Len() int { return len(p) } +func (p pha) Less(i, j int) bool { return p[i].rand < p[j].rand } +func (p pha) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +func getRandomPermutation(n int) []int { + r := make([]ph, n) + for i := 0; i < n; i++ { + r[i].orig = i + r[i].rand = rand.Intn(1 << 29) + } + sort.Sort(pha(r)) + m := make([]int, n) + for i := range m { + m[i] = r[i].orig + } + return m +} + +func minOfInt(a, b int) int { + if a < b { + return a + } + return b +} + +func maxOfInt(a, b int) int { + if a > b { + return a + } + return b +} + +func maxOfUint16(a, b uint16) uint16 { + if a > b { + return a + } + return b +} + +func minOfUint16(a, b uint16) uint16 { + if a < b { + return a + } + return b +} diff --git a/backend/vendor/github.com/bits-and-blooms/bitset/.gitignore b/backend/vendor/github.com/bits-and-blooms/bitset/.gitignore new file mode 100644 index 0000000000..5c204d28b0 --- /dev/null +++ b/backend/vendor/github.com/bits-and-blooms/bitset/.gitignore @@ -0,0 +1,26 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof + +target diff --git a/backend/vendor/github.com/bits-and-blooms/bitset/.travis.yml b/backend/vendor/github.com/bits-and-blooms/bitset/.travis.yml new file mode 100644 index 0000000000..094aa5ce07 --- /dev/null +++ b/backend/vendor/github.com/bits-and-blooms/bitset/.travis.yml @@ -0,0 +1,37 @@ +language: go + +sudo: false + +branches: + except: + - release + +branches: + only: + - master + - travis + +go: + - "1.11.x" + - tip + +matrix: + allow_failures: + - go: tip + +before_install: + - if [ -n "$GH_USER" ]; then git config --global github.user ${GH_USER}; fi; + - if [ -n "$GH_TOKEN" ]; then git config --global github.token ${GH_TOKEN}; fi; + - go get github.com/mattn/goveralls + +before_script: + - make deps + +script: + - make qa + +after_failure: + - cat ./target/test/report.xml + +after_success: + - if [ "$TRAVIS_GO_VERSION" = "1.11.1" ]; then $HOME/gopath/bin/goveralls -covermode=count -coverprofile=target/report/coverage.out -service=travis-ci; fi; diff --git a/backend/vendor/github.com/bits-and-blooms/bitset/LICENSE b/backend/vendor/github.com/bits-and-blooms/bitset/LICENSE new file mode 100644 index 0000000000..59cab8a939 --- /dev/null +++ b/backend/vendor/github.com/bits-and-blooms/bitset/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2014 Will Fitzgerald. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/backend/vendor/github.com/bits-and-blooms/bitset/README.md b/backend/vendor/github.com/bits-and-blooms/bitset/README.md new file mode 100644 index 0000000000..97e83071e4 --- /dev/null +++ b/backend/vendor/github.com/bits-and-blooms/bitset/README.md @@ -0,0 +1,93 @@ +# bitset + +*Go language library to map between non-negative integers and boolean values* + +[![Test](https://github.com/bits-and-blooms/bitset/workflows/Test/badge.svg)](https://github.com/willf/bitset/actions?query=workflow%3ATest) +[![Go Report Card](https://goreportcard.com/badge/github.com/willf/bitset)](https://goreportcard.com/report/github.com/willf/bitset) +[![PkgGoDev](https://pkg.go.dev/badge/github.com/bits-and-blooms/bitset?tab=doc)](https://pkg.go.dev/github.com/bits-and-blooms/bitset?tab=doc) + + +## Description + +Package bitset implements bitsets, a mapping between non-negative integers and boolean values. +It should be more efficient than map[uint] bool. + +It provides methods for setting, clearing, flipping, and testing individual integers. + +But it also provides set intersection, union, difference, complement, and symmetric operations, as well as tests to check whether any, all, or no bits are set, and querying a bitset's current length and number of positive bits. + +BitSets are expanded to the size of the largest set bit; the memory allocation is approximately Max bits, where Max is the largest set bit. BitSets are never shrunk. On creation, a hint can be given for the number of bits that will be used. + +Many of the methods, including Set, Clear, and Flip, return a BitSet pointer, which allows for chaining. + +### Example use: + +```go +package main + +import ( + "fmt" + "math/rand" + + "github.com/bits-and-blooms/bitset" +) + +func main() { + fmt.Printf("Hello from BitSet!\n") + var b bitset.BitSet + // play some Go Fish + for i := 0; i < 100; i++ { + card1 := uint(rand.Intn(52)) + card2 := uint(rand.Intn(52)) + b.Set(card1) + if b.Test(card2) { + fmt.Println("Go Fish!") + } + b.Clear(card1) + } + + // Chaining + b.Set(10).Set(11) + + for i, e := b.NextSet(0); e; i, e = b.NextSet(i + 1) { + fmt.Println("The following bit is set:", i) + } + if b.Intersection(bitset.New(100).Set(10)).Count() == 1 { + fmt.Println("Intersection works.") + } else { + fmt.Println("Intersection doesn't work???") + } +} +``` + +As an alternative to BitSets, one should check out the 'big' package, which provides a (less set-theoretical) view of bitsets. + +Package documentation is at: https://pkg.go.dev/github.com/bits-and-blooms/bitset?tab=doc + +## Memory Usage + +The memory usage of a bitset using N bits is at least N/8 bytes. The number of bits in a bitset is at least as large as one plus the greatest bit index you have accessed. Thus it is possible to run out of memory while using a bitset. If you have lots of bits, you might prefer compressed bitsets, like the [Roaring bitmaps](http://roaringbitmap.org) and its [Go implementation](https://github.com/RoaringBitmap/roaring). + +## Implementation Note + +Go 1.9 introduced a native `math/bits` library. We provide backward compatibility to Go 1.7, which might be removed. + +It is possible that a later version will match the `math/bits` return signature for counts (which is `int`, rather than our library's `unit64`). If so, the version will be bumped. + +## Installation + +```bash +go get github.com/bits-and-blooms/bitset +``` + +## Contributing + +If you wish to contribute to this project, please branch and issue a pull request against master ("[GitHub Flow](https://guides.github.com/introduction/flow/)") + +## Running all tests + +Before committing the code, please check if it passes tests, has adequate coverage, etc. +```bash +go test +go test -cover +``` diff --git a/backend/vendor/github.com/bits-and-blooms/bitset/azure-pipelines.yml b/backend/vendor/github.com/bits-and-blooms/bitset/azure-pipelines.yml new file mode 100644 index 0000000000..f9b2959184 --- /dev/null +++ b/backend/vendor/github.com/bits-and-blooms/bitset/azure-pipelines.yml @@ -0,0 +1,39 @@ +# Go +# Build your Go project. +# Add steps that test, save build artifacts, deploy, and more: +# https://docs.microsoft.com/azure/devops/pipelines/languages/go + +trigger: +- master + +pool: + vmImage: 'Ubuntu-16.04' + +variables: + GOBIN: '$(GOPATH)/bin' # Go binaries path + GOROOT: '/usr/local/go1.11' # Go installation path + GOPATH: '$(system.defaultWorkingDirectory)/gopath' # Go workspace path + modulePath: '$(GOPATH)/src/github.com/$(build.repository.name)' # Path to the module's code + +steps: +- script: | + mkdir -p '$(GOBIN)' + mkdir -p '$(GOPATH)/pkg' + mkdir -p '$(modulePath)' + shopt -s extglob + shopt -s dotglob + mv !(gopath) '$(modulePath)' + echo '##vso[task.prependpath]$(GOBIN)' + echo '##vso[task.prependpath]$(GOROOT)/bin' + displayName: 'Set up the Go workspace' + +- script: | + go version + go get -v -t -d ./... + if [ -f Gopkg.toml ]; then + curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh + dep ensure + fi + go build -v . + workingDirectory: '$(modulePath)' + displayName: 'Get dependencies, then build' diff --git a/backend/vendor/github.com/bits-and-blooms/bitset/bitset.go b/backend/vendor/github.com/bits-and-blooms/bitset/bitset.go new file mode 100644 index 0000000000..d688806a54 --- /dev/null +++ b/backend/vendor/github.com/bits-and-blooms/bitset/bitset.go @@ -0,0 +1,952 @@ +/* +Package bitset implements bitsets, a mapping +between non-negative integers and boolean values. It should be more +efficient than map[uint] bool. + +It provides methods for setting, clearing, flipping, and testing +individual integers. + +But it also provides set intersection, union, difference, +complement, and symmetric operations, as well as tests to +check whether any, all, or no bits are set, and querying a +bitset's current length and number of positive bits. + +BitSets are expanded to the size of the largest set bit; the +memory allocation is approximately Max bits, where Max is +the largest set bit. BitSets are never shrunk. On creation, +a hint can be given for the number of bits that will be used. + +Many of the methods, including Set,Clear, and Flip, return +a BitSet pointer, which allows for chaining. + +Example use: + + import "bitset" + var b BitSet + b.Set(10).Set(11) + if b.Test(1000) { + b.Clear(1000) + } + if B.Intersection(bitset.New(100).Set(10)).Count() > 1 { + fmt.Println("Intersection works.") + } + +As an alternative to BitSets, one should check out the 'big' package, +which provides a (less set-theoretical) view of bitsets. + +*/ +package bitset + +import ( + "bufio" + "bytes" + "encoding/base64" + "encoding/binary" + "encoding/json" + "errors" + "fmt" + "io" + "strconv" +) + +// the wordSize of a bit set +const wordSize = uint(64) + +// log2WordSize is lg(wordSize) +const log2WordSize = uint(6) + +// allBits has every bit set +const allBits uint64 = 0xffffffffffffffff + +// default binary BigEndian +var binaryOrder binary.ByteOrder = binary.BigEndian + +// default json encoding base64.URLEncoding +var base64Encoding = base64.URLEncoding + +// Base64StdEncoding Marshal/Unmarshal BitSet with base64.StdEncoding(Default: base64.URLEncoding) +func Base64StdEncoding() { base64Encoding = base64.StdEncoding } + +// LittleEndian Marshal/Unmarshal Binary as Little Endian(Default: binary.BigEndian) +func LittleEndian() { binaryOrder = binary.LittleEndian } + +// A BitSet is a set of bits. The zero value of a BitSet is an empty set of length 0. +type BitSet struct { + length uint + set []uint64 +} + +// Error is used to distinguish errors (panics) generated in this package. +type Error string + +// safeSet will fixup b.set to be non-nil and return the field value +func (b *BitSet) safeSet() []uint64 { + if b.set == nil { + b.set = make([]uint64, wordsNeeded(0)) + } + return b.set +} + +// From is a constructor used to create a BitSet from an array of integers +func From(buf []uint64) *BitSet { + return &BitSet{uint(len(buf)) * 64, buf} +} + +// Bytes returns the bitset as array of integers +func (b *BitSet) Bytes() []uint64 { + return b.set +} + +// wordsNeeded calculates the number of words needed for i bits +func wordsNeeded(i uint) int { + if i > (Cap() - wordSize + 1) { + return int(Cap() >> log2WordSize) + } + return int((i + (wordSize - 1)) >> log2WordSize) +} + +// New creates a new BitSet with a hint that length bits will be required +func New(length uint) (bset *BitSet) { + defer func() { + if r := recover(); r != nil { + bset = &BitSet{ + 0, + make([]uint64, 0), + } + } + }() + + bset = &BitSet{ + length, + make([]uint64, wordsNeeded(length)), + } + + return bset +} + +// Cap returns the total possible capacity, or number of bits +func Cap() uint { + return ^uint(0) +} + +// Len returns the number of bits in the BitSet. +// Note the difference to method Count, see example. +func (b *BitSet) Len() uint { + return b.length +} + +// extendSetMaybe adds additional words to incorporate new bits if needed +func (b *BitSet) extendSetMaybe(i uint) { + if i >= b.length { // if we need more bits, make 'em + if i >= Cap() { + panic("You are exceeding the capacity") + } + nsize := wordsNeeded(i + 1) + if b.set == nil { + b.set = make([]uint64, nsize) + } else if cap(b.set) >= nsize { + b.set = b.set[:nsize] // fast resize + } else if len(b.set) < nsize { + newset := make([]uint64, nsize, 2*nsize) // increase capacity 2x + copy(newset, b.set) + b.set = newset + } + b.length = i + 1 + } +} + +// Test whether bit i is set. +func (b *BitSet) Test(i uint) bool { + if i >= b.length { + return false + } + return b.set[i>>log2WordSize]&(1<<(i&(wordSize-1))) != 0 +} + +// Set bit i to 1, the capacity of the bitset is automatically +// increased accordingly. +// If i>= Cap(), this function will panic. +// Warning: using a very large value for 'i' +// may lead to a memory shortage and a panic: the caller is responsible +// for providing sensible parameters in line with their memory capacity. +func (b *BitSet) Set(i uint) *BitSet { + b.extendSetMaybe(i) + b.set[i>>log2WordSize] |= 1 << (i & (wordSize - 1)) + return b +} + +// Clear bit i to 0 +func (b *BitSet) Clear(i uint) *BitSet { + if i >= b.length { + return b + } + b.set[i>>log2WordSize] &^= 1 << (i & (wordSize - 1)) + return b +} + +// SetTo sets bit i to value. +// If i>= Cap(), this function will panic. +// Warning: using a very large value for 'i' +// may lead to a memory shortage and a panic: the caller is responsible +// for providing sensible parameters in line with their memory capacity. +func (b *BitSet) SetTo(i uint, value bool) *BitSet { + if value { + return b.Set(i) + } + return b.Clear(i) +} + +// Flip bit at i. +// If i>= Cap(), this function will panic. +// Warning: using a very large value for 'i' +// may lead to a memory shortage and a panic: the caller is responsible +// for providing sensible parameters in line with their memory capacity. +func (b *BitSet) Flip(i uint) *BitSet { + if i >= b.length { + return b.Set(i) + } + b.set[i>>log2WordSize] ^= 1 << (i & (wordSize - 1)) + return b +} + +// FlipRange bit in [start, end). +// If end>= Cap(), this function will panic. +// Warning: using a very large value for 'end' +// may lead to a memory shortage and a panic: the caller is responsible +// for providing sensible parameters in line with their memory capacity. +func (b *BitSet) FlipRange(start, end uint) *BitSet { + if start >= end { + return b + } + + b.extendSetMaybe(end - 1) + var startWord uint = start >> log2WordSize + var endWord uint = end >> log2WordSize + b.set[startWord] ^= ^(^uint64(0) << (start & (wordSize - 1))) + for i := startWord; i < endWord; i++ { + b.set[i] = ^b.set[i] + } + b.set[endWord] ^= ^uint64(0) >> (-end & (wordSize - 1)) + return b +} + +// Shrink shrinks BitSet so that the provided value is the last possible +// set value. It clears all bits > the provided index and reduces the size +// and length of the set. +// +// Note that the parameter value is not the new length in bits: it is the +// maximal value that can be stored in the bitset after the function call. +// The new length in bits is the parameter value + 1. Thus it is not possible +// to use this function to set the length to 0, the minimal value of the length +// after this function call is 1. +// +// A new slice is allocated to store the new bits, so you may see an increase in +// memory usage until the GC runs. Normally this should not be a problem, but if you +// have an extremely large BitSet its important to understand that the old BitSet will +// remain in memory until the GC frees it. +func (b *BitSet) Shrink(lastbitindex uint) *BitSet { + length := lastbitindex + 1 + idx := wordsNeeded(length) + if idx > len(b.set) { + return b + } + shrunk := make([]uint64, idx) + copy(shrunk, b.set[:idx]) + b.set = shrunk + b.length = length + b.set[idx-1] &= (allBits >> (uint64(64) - uint64(length&(wordSize-1)))) + return b +} + +// Compact shrinks BitSet to so that we preserve all set bits, while minimizing +// memory usage. Compact calls Shrink. +func (b *BitSet) Compact() *BitSet { + idx := len(b.set) - 1 + for ; idx >= 0 && b.set[idx] == 0; idx-- { + } + newlength := uint((idx + 1) << log2WordSize) + if newlength >= b.length { + return b // nothing to do + } + if newlength > 0 { + return b.Shrink(newlength - 1) + } + // We preserve one word + return b.Shrink(63) +} + +// InsertAt takes an index which indicates where a bit should be +// inserted. Then it shifts all the bits in the set to the left by 1, starting +// from the given index position, and sets the index position to 0. +// +// Depending on the size of your BitSet, and where you are inserting the new entry, +// this method could be extremely slow and in some cases might cause the entire BitSet +// to be recopied. +func (b *BitSet) InsertAt(idx uint) *BitSet { + insertAtElement := (idx >> log2WordSize) + + // if length of set is a multiple of wordSize we need to allocate more space first + if b.isLenExactMultiple() { + b.set = append(b.set, uint64(0)) + } + + var i uint + for i = uint(len(b.set) - 1); i > insertAtElement; i-- { + // all elements above the position where we want to insert can simply by shifted + b.set[i] <<= 1 + + // we take the most significant bit of the previous element and set it as + // the least significant bit of the current element + b.set[i] |= (b.set[i-1] & 0x8000000000000000) >> 63 + } + + // generate a mask to extract the data that we need to shift left + // within the element where we insert a bit + dataMask := ^(uint64(1)< 0x40000 { + buffer.WriteString("...") + break + } + buffer.WriteString(strconv.FormatInt(int64(i), 10)) + i, e = b.NextSet(i + 1) + if e { + buffer.WriteString(",") + } + } + buffer.WriteString("}") + return buffer.String() +} + +// DeleteAt deletes the bit at the given index position from +// within the bitset +// All the bits residing on the left of the deleted bit get +// shifted right by 1 +// The running time of this operation may potentially be +// relatively slow, O(length) +func (b *BitSet) DeleteAt(i uint) *BitSet { + // the index of the slice element where we'll delete a bit + deleteAtElement := i >> log2WordSize + + // generate a mask for the data that needs to be shifted right + // within that slice element that gets modified + dataMask := ^((uint64(1) << (i & (wordSize - 1))) - 1) + + // extract the data that we'll shift right from the slice element + data := b.set[deleteAtElement] & dataMask + + // set the masked area to 0 while leaving the rest as it is + b.set[deleteAtElement] &= ^dataMask + + // shift the previously extracted data to the right and then + // set it in the previously masked area + b.set[deleteAtElement] |= (data >> 1) & dataMask + + // loop over all the consecutive slice elements to copy each + // lowest bit into the highest position of the previous element, + // then shift the entire content to the right by 1 + for i := int(deleteAtElement) + 1; i < len(b.set); i++ { + b.set[i-1] |= (b.set[i] & 1) << 63 + b.set[i] >>= 1 + } + + b.length = b.length - 1 + + return b +} + +// NextSet returns the next bit set from the specified index, +// including possibly the current index +// along with an error code (true = valid, false = no set bit found) +// for i,e := v.NextSet(0); e; i,e = v.NextSet(i + 1) {...} +// +// Users concerned with performance may want to use NextSetMany to +// retrieve several values at once. +func (b *BitSet) NextSet(i uint) (uint, bool) { + x := int(i >> log2WordSize) + if x >= len(b.set) { + return 0, false + } + w := b.set[x] + w = w >> (i & (wordSize - 1)) + if w != 0 { + return i + trailingZeroes64(w), true + } + x = x + 1 + for x < len(b.set) { + if b.set[x] != 0 { + return uint(x)*wordSize + trailingZeroes64(b.set[x]), true + } + x = x + 1 + + } + return 0, false +} + +// NextSetMany returns many next bit sets from the specified index, +// including possibly the current index and up to cap(buffer). +// If the returned slice has len zero, then no more set bits were found +// +// buffer := make([]uint, 256) // this should be reused +// j := uint(0) +// j, buffer = bitmap.NextSetMany(j, buffer) +// for ; len(buffer) > 0; j, buffer = bitmap.NextSetMany(j,buffer) { +// for k := range buffer { +// do something with buffer[k] +// } +// j += 1 +// } +// +// +// It is possible to retrieve all set bits as follow: +// +// indices := make([]uint, bitmap.Count()) +// bitmap.NextSetMany(0, indices) +// +// However if bitmap.Count() is large, it might be preferable to +// use several calls to NextSetMany, for performance reasons. +func (b *BitSet) NextSetMany(i uint, buffer []uint) (uint, []uint) { + myanswer := buffer + capacity := cap(buffer) + x := int(i >> log2WordSize) + if x >= len(b.set) || capacity == 0 { + return 0, myanswer[:0] + } + skip := i & (wordSize - 1) + word := b.set[x] >> skip + myanswer = myanswer[:capacity] + size := int(0) + for word != 0 { + r := trailingZeroes64(word) + t := word & ((^word) + 1) + myanswer[size] = r + i + size++ + if size == capacity { + goto End + } + word = word ^ t + } + x++ + for idx, word := range b.set[x:] { + for word != 0 { + r := trailingZeroes64(word) + t := word & ((^word) + 1) + myanswer[size] = r + (uint(x+idx) << 6) + size++ + if size == capacity { + goto End + } + word = word ^ t + } + } +End: + if size > 0 { + return myanswer[size-1], myanswer[:size] + } + return 0, myanswer[:0] +} + +// NextClear returns the next clear bit from the specified index, +// including possibly the current index +// along with an error code (true = valid, false = no bit found i.e. all bits are set) +func (b *BitSet) NextClear(i uint) (uint, bool) { + x := int(i >> log2WordSize) + if x >= len(b.set) { + return 0, false + } + w := b.set[x] + w = w >> (i & (wordSize - 1)) + wA := allBits >> (i & (wordSize - 1)) + index := i + trailingZeroes64(^w) + if w != wA && index < b.length { + return index, true + } + x++ + for x < len(b.set) { + index = uint(x)*wordSize + trailingZeroes64(^b.set[x]) + if b.set[x] != allBits && index < b.length { + return index, true + } + x++ + } + return 0, false +} + +// ClearAll clears the entire BitSet +func (b *BitSet) ClearAll() *BitSet { + if b != nil && b.set != nil { + for i := range b.set { + b.set[i] = 0 + } + } + return b +} + +// wordCount returns the number of words used in a bit set +func (b *BitSet) wordCount() int { + return len(b.set) +} + +// Clone this BitSet +func (b *BitSet) Clone() *BitSet { + c := New(b.length) + if b.set != nil { // Clone should not modify current object + copy(c.set, b.set) + } + return c +} + +// Copy into a destination BitSet +// Returning the size of the destination BitSet +// like array copy +func (b *BitSet) Copy(c *BitSet) (count uint) { + if c == nil { + return + } + if b.set != nil { // Copy should not modify current object + copy(c.set, b.set) + } + count = c.length + if b.length < c.length { + count = b.length + } + return +} + +// Count (number of set bits). +// Also known as "popcount" or "population count". +func (b *BitSet) Count() uint { + if b != nil && b.set != nil { + return uint(popcntSlice(b.set)) + } + return 0 +} + +// Equal tests the equivalence of two BitSets. +// False if they are of different sizes, otherwise true +// only if all the same bits are set +func (b *BitSet) Equal(c *BitSet) bool { + if c == nil || b == nil { + return c == b + } + if b.length != c.length { + return false + } + if b.length == 0 { // if they have both length == 0, then could have nil set + return true + } + // testing for equality shoud not transform the bitset (no call to safeSet) + + for p, v := range b.set { + if c.set[p] != v { + return false + } + } + return true +} + +func panicIfNull(b *BitSet) { + if b == nil { + panic(Error("BitSet must not be null")) + } +} + +// Difference of base set and other set +// This is the BitSet equivalent of &^ (and not) +func (b *BitSet) Difference(compare *BitSet) (result *BitSet) { + panicIfNull(b) + panicIfNull(compare) + result = b.Clone() // clone b (in case b is bigger than compare) + l := int(compare.wordCount()) + if l > int(b.wordCount()) { + l = int(b.wordCount()) + } + for i := 0; i < l; i++ { + result.set[i] = b.set[i] &^ compare.set[i] + } + return +} + +// DifferenceCardinality computes the cardinality of the differnce +func (b *BitSet) DifferenceCardinality(compare *BitSet) uint { + panicIfNull(b) + panicIfNull(compare) + l := int(compare.wordCount()) + if l > int(b.wordCount()) { + l = int(b.wordCount()) + } + cnt := uint64(0) + cnt += popcntMaskSlice(b.set[:l], compare.set[:l]) + cnt += popcntSlice(b.set[l:]) + return uint(cnt) +} + +// InPlaceDifference computes the difference of base set and other set +// This is the BitSet equivalent of &^ (and not) +func (b *BitSet) InPlaceDifference(compare *BitSet) { + panicIfNull(b) + panicIfNull(compare) + l := int(compare.wordCount()) + if l > int(b.wordCount()) { + l = int(b.wordCount()) + } + for i := 0; i < l; i++ { + b.set[i] &^= compare.set[i] + } +} + +// Convenience function: return two bitsets ordered by +// increasing length. Note: neither can be nil +func sortByLength(a *BitSet, b *BitSet) (ap *BitSet, bp *BitSet) { + if a.length <= b.length { + ap, bp = a, b + } else { + ap, bp = b, a + } + return +} + +// Intersection of base set and other set +// This is the BitSet equivalent of & (and) +func (b *BitSet) Intersection(compare *BitSet) (result *BitSet) { + panicIfNull(b) + panicIfNull(compare) + b, compare = sortByLength(b, compare) + result = New(b.length) + for i, word := range b.set { + result.set[i] = word & compare.set[i] + } + return +} + +// IntersectionCardinality computes the cardinality of the union +func (b *BitSet) IntersectionCardinality(compare *BitSet) uint { + panicIfNull(b) + panicIfNull(compare) + b, compare = sortByLength(b, compare) + cnt := popcntAndSlice(b.set, compare.set) + return uint(cnt) +} + +// InPlaceIntersection destructively computes the intersection of +// base set and the compare set. +// This is the BitSet equivalent of & (and) +func (b *BitSet) InPlaceIntersection(compare *BitSet) { + panicIfNull(b) + panicIfNull(compare) + l := int(compare.wordCount()) + if l > int(b.wordCount()) { + l = int(b.wordCount()) + } + for i := 0; i < l; i++ { + b.set[i] &= compare.set[i] + } + for i := l; i < len(b.set); i++ { + b.set[i] = 0 + } + if compare.length > 0 { + b.extendSetMaybe(compare.length - 1) + } +} + +// Union of base set and other set +// This is the BitSet equivalent of | (or) +func (b *BitSet) Union(compare *BitSet) (result *BitSet) { + panicIfNull(b) + panicIfNull(compare) + b, compare = sortByLength(b, compare) + result = compare.Clone() + for i, word := range b.set { + result.set[i] = word | compare.set[i] + } + return +} + +// UnionCardinality computes the cardinality of the uniton of the base set +// and the compare set. +func (b *BitSet) UnionCardinality(compare *BitSet) uint { + panicIfNull(b) + panicIfNull(compare) + b, compare = sortByLength(b, compare) + cnt := popcntOrSlice(b.set, compare.set) + if len(compare.set) > len(b.set) { + cnt += popcntSlice(compare.set[len(b.set):]) + } + return uint(cnt) +} + +// InPlaceUnion creates the destructive union of base set and compare set. +// This is the BitSet equivalent of | (or). +func (b *BitSet) InPlaceUnion(compare *BitSet) { + panicIfNull(b) + panicIfNull(compare) + l := int(compare.wordCount()) + if l > int(b.wordCount()) { + l = int(b.wordCount()) + } + if compare.length > 0 { + b.extendSetMaybe(compare.length - 1) + } + for i := 0; i < l; i++ { + b.set[i] |= compare.set[i] + } + if len(compare.set) > l { + for i := l; i < len(compare.set); i++ { + b.set[i] = compare.set[i] + } + } +} + +// SymmetricDifference of base set and other set +// This is the BitSet equivalent of ^ (xor) +func (b *BitSet) SymmetricDifference(compare *BitSet) (result *BitSet) { + panicIfNull(b) + panicIfNull(compare) + b, compare = sortByLength(b, compare) + // compare is bigger, so clone it + result = compare.Clone() + for i, word := range b.set { + result.set[i] = word ^ compare.set[i] + } + return +} + +// SymmetricDifferenceCardinality computes the cardinality of the symmetric difference +func (b *BitSet) SymmetricDifferenceCardinality(compare *BitSet) uint { + panicIfNull(b) + panicIfNull(compare) + b, compare = sortByLength(b, compare) + cnt := popcntXorSlice(b.set, compare.set) + if len(compare.set) > len(b.set) { + cnt += popcntSlice(compare.set[len(b.set):]) + } + return uint(cnt) +} + +// InPlaceSymmetricDifference creates the destructive SymmetricDifference of base set and other set +// This is the BitSet equivalent of ^ (xor) +func (b *BitSet) InPlaceSymmetricDifference(compare *BitSet) { + panicIfNull(b) + panicIfNull(compare) + l := int(compare.wordCount()) + if l > int(b.wordCount()) { + l = int(b.wordCount()) + } + if compare.length > 0 { + b.extendSetMaybe(compare.length - 1) + } + for i := 0; i < l; i++ { + b.set[i] ^= compare.set[i] + } + if len(compare.set) > l { + for i := l; i < len(compare.set); i++ { + b.set[i] = compare.set[i] + } + } +} + +// Is the length an exact multiple of word sizes? +func (b *BitSet) isLenExactMultiple() bool { + return b.length%wordSize == 0 +} + +// Clean last word by setting unused bits to 0 +func (b *BitSet) cleanLastWord() { + if !b.isLenExactMultiple() { + b.set[len(b.set)-1] &= allBits >> (wordSize - b.length%wordSize) + } +} + +// Complement computes the (local) complement of a biset (up to length bits) +func (b *BitSet) Complement() (result *BitSet) { + panicIfNull(b) + result = New(b.length) + for i, word := range b.set { + result.set[i] = ^word + } + result.cleanLastWord() + return +} + +// All returns true if all bits are set, false otherwise. Returns true for +// empty sets. +func (b *BitSet) All() bool { + panicIfNull(b) + return b.Count() == b.length +} + +// None returns true if no bit is set, false otherwise. Returns true for +// empty sets. +func (b *BitSet) None() bool { + panicIfNull(b) + if b != nil && b.set != nil { + for _, word := range b.set { + if word > 0 { + return false + } + } + return true + } + return true +} + +// Any returns true if any bit is set, false otherwise +func (b *BitSet) Any() bool { + panicIfNull(b) + return !b.None() +} + +// IsSuperSet returns true if this is a superset of the other set +func (b *BitSet) IsSuperSet(other *BitSet) bool { + for i, e := other.NextSet(0); e; i, e = other.NextSet(i + 1) { + if !b.Test(i) { + return false + } + } + return true +} + +// IsStrictSuperSet returns true if this is a strict superset of the other set +func (b *BitSet) IsStrictSuperSet(other *BitSet) bool { + return b.Count() > other.Count() && b.IsSuperSet(other) +} + +// DumpAsBits dumps a bit set as a string of bits +func (b *BitSet) DumpAsBits() string { + if b.set == nil { + return "." + } + buffer := bytes.NewBufferString("") + i := len(b.set) - 1 + for ; i >= 0; i-- { + fmt.Fprintf(buffer, "%064b.", b.set[i]) + } + return buffer.String() +} + +// BinaryStorageSize returns the binary storage requirements +func (b *BitSet) BinaryStorageSize() int { + return binary.Size(uint64(0)) + binary.Size(b.set) +} + +// WriteTo writes a BitSet to a stream +func (b *BitSet) WriteTo(stream io.Writer) (int64, error) { + length := uint64(b.length) + + // Write length + err := binary.Write(stream, binaryOrder, length) + if err != nil { + return 0, err + } + + // Write set + err = binary.Write(stream, binaryOrder, b.set) + return int64(b.BinaryStorageSize()), err +} + +// ReadFrom reads a BitSet from a stream written using WriteTo +func (b *BitSet) ReadFrom(stream io.Reader) (int64, error) { + var length uint64 + + // Read length first + err := binary.Read(stream, binaryOrder, &length) + if err != nil { + return 0, err + } + newset := New(uint(length)) + + if uint64(newset.length) != length { + return 0, errors.New("unmarshalling error: type mismatch") + } + + // Read remaining bytes as set + err = binary.Read(stream, binaryOrder, newset.set) + if err != nil { + return 0, err + } + + *b = *newset + return int64(b.BinaryStorageSize()), nil +} + +// MarshalBinary encodes a BitSet into a binary form and returns the result. +func (b *BitSet) MarshalBinary() ([]byte, error) { + var buf bytes.Buffer + writer := bufio.NewWriter(&buf) + + _, err := b.WriteTo(writer) + if err != nil { + return []byte{}, err + } + + err = writer.Flush() + + return buf.Bytes(), err +} + +// UnmarshalBinary decodes the binary form generated by MarshalBinary. +func (b *BitSet) UnmarshalBinary(data []byte) error { + buf := bytes.NewReader(data) + reader := bufio.NewReader(buf) + + _, err := b.ReadFrom(reader) + + return err +} + +// MarshalJSON marshals a BitSet as a JSON structure +func (b *BitSet) MarshalJSON() ([]byte, error) { + buffer := bytes.NewBuffer(make([]byte, 0, b.BinaryStorageSize())) + _, err := b.WriteTo(buffer) + if err != nil { + return nil, err + } + + // URLEncode all bytes + return json.Marshal(base64Encoding.EncodeToString(buffer.Bytes())) +} + +// UnmarshalJSON unmarshals a BitSet from JSON created using MarshalJSON +func (b *BitSet) UnmarshalJSON(data []byte) error { + // Unmarshal as string + var s string + err := json.Unmarshal(data, &s) + if err != nil { + return err + } + + // URLDecode string + buf, err := base64Encoding.DecodeString(s) + if err != nil { + return err + } + + _, err = b.ReadFrom(bytes.NewReader(buf)) + return err +} diff --git a/backend/vendor/github.com/bits-and-blooms/bitset/popcnt.go b/backend/vendor/github.com/bits-and-blooms/bitset/popcnt.go new file mode 100644 index 0000000000..76577a8382 --- /dev/null +++ b/backend/vendor/github.com/bits-and-blooms/bitset/popcnt.go @@ -0,0 +1,53 @@ +package bitset + +// bit population count, take from +// https://code.google.com/p/go/issues/detail?id=4988#c11 +// credit: https://code.google.com/u/arnehormann/ +func popcount(x uint64) (n uint64) { + x -= (x >> 1) & 0x5555555555555555 + x = (x>>2)&0x3333333333333333 + x&0x3333333333333333 + x += x >> 4 + x &= 0x0f0f0f0f0f0f0f0f + x *= 0x0101010101010101 + return x >> 56 +} + +func popcntSliceGo(s []uint64) uint64 { + cnt := uint64(0) + for _, x := range s { + cnt += popcount(x) + } + return cnt +} + +func popcntMaskSliceGo(s, m []uint64) uint64 { + cnt := uint64(0) + for i := range s { + cnt += popcount(s[i] &^ m[i]) + } + return cnt +} + +func popcntAndSliceGo(s, m []uint64) uint64 { + cnt := uint64(0) + for i := range s { + cnt += popcount(s[i] & m[i]) + } + return cnt +} + +func popcntOrSliceGo(s, m []uint64) uint64 { + cnt := uint64(0) + for i := range s { + cnt += popcount(s[i] | m[i]) + } + return cnt +} + +func popcntXorSliceGo(s, m []uint64) uint64 { + cnt := uint64(0) + for i := range s { + cnt += popcount(s[i] ^ m[i]) + } + return cnt +} diff --git a/backend/vendor/github.com/bits-and-blooms/bitset/popcnt_19.go b/backend/vendor/github.com/bits-and-blooms/bitset/popcnt_19.go new file mode 100644 index 0000000000..fc8ff4f367 --- /dev/null +++ b/backend/vendor/github.com/bits-and-blooms/bitset/popcnt_19.go @@ -0,0 +1,45 @@ +// +build go1.9 + +package bitset + +import "math/bits" + +func popcntSlice(s []uint64) uint64 { + var cnt int + for _, x := range s { + cnt += bits.OnesCount64(x) + } + return uint64(cnt) +} + +func popcntMaskSlice(s, m []uint64) uint64 { + var cnt int + for i := range s { + cnt += bits.OnesCount64(s[i] &^ m[i]) + } + return uint64(cnt) +} + +func popcntAndSlice(s, m []uint64) uint64 { + var cnt int + for i := range s { + cnt += bits.OnesCount64(s[i] & m[i]) + } + return uint64(cnt) +} + +func popcntOrSlice(s, m []uint64) uint64 { + var cnt int + for i := range s { + cnt += bits.OnesCount64(s[i] | m[i]) + } + return uint64(cnt) +} + +func popcntXorSlice(s, m []uint64) uint64 { + var cnt int + for i := range s { + cnt += bits.OnesCount64(s[i] ^ m[i]) + } + return uint64(cnt) +} diff --git a/backend/vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.go b/backend/vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.go new file mode 100644 index 0000000000..4cf64f24ad --- /dev/null +++ b/backend/vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.go @@ -0,0 +1,68 @@ +// +build !go1.9 +// +build amd64,!appengine + +package bitset + +// *** the following functions are defined in popcnt_amd64.s + +//go:noescape + +func hasAsm() bool + +// useAsm is a flag used to select the GO or ASM implementation of the popcnt function +var useAsm = hasAsm() + +//go:noescape + +func popcntSliceAsm(s []uint64) uint64 + +//go:noescape + +func popcntMaskSliceAsm(s, m []uint64) uint64 + +//go:noescape + +func popcntAndSliceAsm(s, m []uint64) uint64 + +//go:noescape + +func popcntOrSliceAsm(s, m []uint64) uint64 + +//go:noescape + +func popcntXorSliceAsm(s, m []uint64) uint64 + +func popcntSlice(s []uint64) uint64 { + if useAsm { + return popcntSliceAsm(s) + } + return popcntSliceGo(s) +} + +func popcntMaskSlice(s, m []uint64) uint64 { + if useAsm { + return popcntMaskSliceAsm(s, m) + } + return popcntMaskSliceGo(s, m) +} + +func popcntAndSlice(s, m []uint64) uint64 { + if useAsm { + return popcntAndSliceAsm(s, m) + } + return popcntAndSliceGo(s, m) +} + +func popcntOrSlice(s, m []uint64) uint64 { + if useAsm { + return popcntOrSliceAsm(s, m) + } + return popcntOrSliceGo(s, m) +} + +func popcntXorSlice(s, m []uint64) uint64 { + if useAsm { + return popcntXorSliceAsm(s, m) + } + return popcntXorSliceGo(s, m) +} diff --git a/backend/vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.s b/backend/vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.s new file mode 100644 index 0000000000..666c0dcc17 --- /dev/null +++ b/backend/vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.s @@ -0,0 +1,104 @@ +// +build !go1.9 +// +build amd64,!appengine + +TEXT ·hasAsm(SB),4,$0-1 +MOVQ $1, AX +CPUID +SHRQ $23, CX +ANDQ $1, CX +MOVB CX, ret+0(FP) +RET + +#define POPCNTQ_DX_DX BYTE $0xf3; BYTE $0x48; BYTE $0x0f; BYTE $0xb8; BYTE $0xd2 + +TEXT ·popcntSliceAsm(SB),4,$0-32 +XORQ AX, AX +MOVQ s+0(FP), SI +MOVQ s_len+8(FP), CX +TESTQ CX, CX +JZ popcntSliceEnd +popcntSliceLoop: +BYTE $0xf3; BYTE $0x48; BYTE $0x0f; BYTE $0xb8; BYTE $0x16 // POPCNTQ (SI), DX +ADDQ DX, AX +ADDQ $8, SI +LOOP popcntSliceLoop +popcntSliceEnd: +MOVQ AX, ret+24(FP) +RET + +TEXT ·popcntMaskSliceAsm(SB),4,$0-56 +XORQ AX, AX +MOVQ s+0(FP), SI +MOVQ s_len+8(FP), CX +TESTQ CX, CX +JZ popcntMaskSliceEnd +MOVQ m+24(FP), DI +popcntMaskSliceLoop: +MOVQ (DI), DX +NOTQ DX +ANDQ (SI), DX +POPCNTQ_DX_DX +ADDQ DX, AX +ADDQ $8, SI +ADDQ $8, DI +LOOP popcntMaskSliceLoop +popcntMaskSliceEnd: +MOVQ AX, ret+48(FP) +RET + +TEXT ·popcntAndSliceAsm(SB),4,$0-56 +XORQ AX, AX +MOVQ s+0(FP), SI +MOVQ s_len+8(FP), CX +TESTQ CX, CX +JZ popcntAndSliceEnd +MOVQ m+24(FP), DI +popcntAndSliceLoop: +MOVQ (DI), DX +ANDQ (SI), DX +POPCNTQ_DX_DX +ADDQ DX, AX +ADDQ $8, SI +ADDQ $8, DI +LOOP popcntAndSliceLoop +popcntAndSliceEnd: +MOVQ AX, ret+48(FP) +RET + +TEXT ·popcntOrSliceAsm(SB),4,$0-56 +XORQ AX, AX +MOVQ s+0(FP), SI +MOVQ s_len+8(FP), CX +TESTQ CX, CX +JZ popcntOrSliceEnd +MOVQ m+24(FP), DI +popcntOrSliceLoop: +MOVQ (DI), DX +ORQ (SI), DX +POPCNTQ_DX_DX +ADDQ DX, AX +ADDQ $8, SI +ADDQ $8, DI +LOOP popcntOrSliceLoop +popcntOrSliceEnd: +MOVQ AX, ret+48(FP) +RET + +TEXT ·popcntXorSliceAsm(SB),4,$0-56 +XORQ AX, AX +MOVQ s+0(FP), SI +MOVQ s_len+8(FP), CX +TESTQ CX, CX +JZ popcntXorSliceEnd +MOVQ m+24(FP), DI +popcntXorSliceLoop: +MOVQ (DI), DX +XORQ (SI), DX +POPCNTQ_DX_DX +ADDQ DX, AX +ADDQ $8, SI +ADDQ $8, DI +LOOP popcntXorSliceLoop +popcntXorSliceEnd: +MOVQ AX, ret+48(FP) +RET diff --git a/backend/vendor/github.com/bits-and-blooms/bitset/popcnt_generic.go b/backend/vendor/github.com/bits-and-blooms/bitset/popcnt_generic.go new file mode 100644 index 0000000000..21e0ff7b4f --- /dev/null +++ b/backend/vendor/github.com/bits-and-blooms/bitset/popcnt_generic.go @@ -0,0 +1,24 @@ +// +build !go1.9 +// +build !amd64 appengine + +package bitset + +func popcntSlice(s []uint64) uint64 { + return popcntSliceGo(s) +} + +func popcntMaskSlice(s, m []uint64) uint64 { + return popcntMaskSliceGo(s, m) +} + +func popcntAndSlice(s, m []uint64) uint64 { + return popcntAndSliceGo(s, m) +} + +func popcntOrSlice(s, m []uint64) uint64 { + return popcntOrSliceGo(s, m) +} + +func popcntXorSlice(s, m []uint64) uint64 { + return popcntXorSliceGo(s, m) +} diff --git a/backend/vendor/github.com/bits-and-blooms/bitset/trailing_zeros_18.go b/backend/vendor/github.com/bits-and-blooms/bitset/trailing_zeros_18.go new file mode 100644 index 0000000000..c52b61be9f --- /dev/null +++ b/backend/vendor/github.com/bits-and-blooms/bitset/trailing_zeros_18.go @@ -0,0 +1,14 @@ +// +build !go1.9 + +package bitset + +var deBruijn = [...]byte{ + 0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4, + 62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5, + 63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11, + 54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6, +} + +func trailingZeroes64(v uint64) uint { + return uint(deBruijn[((v&-v)*0x03f79d71b4ca8b09)>>58]) +} diff --git a/backend/vendor/github.com/bits-and-blooms/bitset/trailing_zeros_19.go b/backend/vendor/github.com/bits-and-blooms/bitset/trailing_zeros_19.go new file mode 100644 index 0000000000..36a988e714 --- /dev/null +++ b/backend/vendor/github.com/bits-and-blooms/bitset/trailing_zeros_19.go @@ -0,0 +1,9 @@ +// +build go1.9 + +package bitset + +import "math/bits" + +func trailingZeroes64(v uint64) uint { + return uint(bits.TrailingZeros64(v)) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/.gitignore b/backend/vendor/github.com/blevesearch/bleve/v2/.gitignore new file mode 100644 index 0000000000..7512de770f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/.gitignore @@ -0,0 +1,20 @@ +#* +*.sublime-* +*~ +.#* +.project +.settings +**/.idea/ +**/*.iml +.DS_Store +query_string.y.go.tmp +/analysis/token_filters/cld2/cld2-read-only +/analysis/token_filters/cld2/libcld2_full.a +/cmd/bleve/bleve +vendor/** +!vendor/manifest +/y.output +/search/query/y.output +*.test +tags +go.sum diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/.travis.yml b/backend/vendor/github.com/blevesearch/bleve/v2/.travis.yml new file mode 100644 index 0000000000..7b7297afe3 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/.travis.yml @@ -0,0 +1,25 @@ +sudo: false + +language: go + +go: + - "1.12.x" + - "1.13.x" + - "1.14.x" + +script: + - go get golang.org/x/tools/cmd/cover + - go get github.com/mattn/goveralls + - go get github.com/kisielk/errcheck + - go get -u github.com/FiloSottile/gvt + - gvt restore + - go test -race -v $(go list ./... | grep -v vendor/) + - go vet $(go list ./... | grep -v vendor/) + - go test ./test -v -indexType scorch + - errcheck -ignorepkg fmt $(go list ./... | grep -v vendor/); + - docs/project-code-coverage.sh + - docs/build_children.sh + +notifications: + email: + - marty.schoch@gmail.com diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/CONTRIBUTING.md b/backend/vendor/github.com/blevesearch/bleve/v2/CONTRIBUTING.md new file mode 100644 index 0000000000..5ebf3d65bc --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/CONTRIBUTING.md @@ -0,0 +1,16 @@ +# Contributing to Bleve + +We look forward to your contributions, but ask that you first review these guidelines. + +### Sign the CLA + +As Bleve is a Couchbase project we require contributors accept the [Couchbase Contributor License Agreement](http://review.couchbase.org/static/individual_agreement.html). To sign this agreement log into the Couchbase [code review tool](http://review.couchbase.org/). The Bleve project does not use this code review tool but it is still used to track acceptance of the contributor license agreements. + +### Submitting a Pull Request + +All types of contributions are welcome, but please keep the following in mind: + +- If you're planning a large change, you should really discuss it in a github issue or on the google group first. This helps avoid duplicate effort and spending time on something that may not be merged. +- Existing tests should continue to pass, new tests for the contribution are nice to have. +- All code should have gone through `go fmt` +- All code should pass `go vet` diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/LICENSE b/backend/vendor/github.com/blevesearch/bleve/v2/LICENSE new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/README.md b/backend/vendor/github.com/blevesearch/bleve/v2/README.md new file mode 100644 index 0000000000..34f57a4e09 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/README.md @@ -0,0 +1,112 @@ +# ![bleve](docs/bleve.png) bleve + +[![Tests](https://github.com/blevesearch/bleve/workflows/Tests/badge.svg?branch=master&event=push)](https://github.com/blevesearch/bleve/actions?query=workflow%3ATests+event%3Apush+branch%3Amaster) +[![Coverage Status](https://coveralls.io/repos/github/blevesearch/bleve/badge.svg?branch=master)](https://coveralls.io/github/blevesearch/bleve?branch=master) +[![GoDoc](https://godoc.org/github.com/blevesearch/bleve?status.svg)](https://godoc.org/github.com/blevesearch/bleve) +[![Join the chat at https://gitter.im/blevesearch/bleve](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/blevesearch/bleve?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![codebeat](https://codebeat.co/badges/38a7cbc9-9cf5-41c0-a315-0746178230f4)](https://codebeat.co/projects/github-com-blevesearch-bleve) +[![Go Report Card](https://goreportcard.com/badge/blevesearch/bleve)](https://goreportcard.com/report/blevesearch/bleve) +[![Sourcegraph](https://sourcegraph.com/github.com/blevesearch/bleve/-/badge.svg)](https://sourcegraph.com/github.com/blevesearch/bleve?badge) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) + +modern text indexing in go - [blevesearch.com](http://www.blevesearch.com/) + +## Features + +* Index any go data structure (including JSON) +* Intelligent defaults backed up by powerful configuration +* Supported field types: + * Text, Numeric, Datetime, Boolean +* Supported query types: + * Term, Phrase, Match, Match Phrase, Prefix, Fuzzy + * Conjunction, Disjunction, Boolean (must/should/must_not) + * Term Range, Numeric Range, Date Range + * [Geo Spatial](https://github.com/blevesearch/bleve/blob/master/geo/README.md) + * Simple [query string syntax](http://www.blevesearch.com/docs/Query-String-Query/) for human entry +* [tf-idf](https://en.wikipedia.org/wiki/Tf-idf) Scoring +* Boosting +* Search result match highlighting +* Aggregations/faceting support: + * Terms Facet + * Numeric Range Facet + * Date Range Facet + +## Indexing + +```go +message := struct{ + Id string + From string + Body string +}{ + Id: "example", + From: "marty.schoch@gmail.com", + Body: "bleve indexing is easy", +} + +mapping := bleve.NewIndexMapping() +index, err := bleve.New("example.bleve", mapping) +if err != nil { + panic(err) +} +index.Index(message.Id, message) +``` + +## Querying + +```go +index, _ := bleve.Open("example.bleve") +query := bleve.NewQueryStringQuery("bleve") +searchRequest := bleve.NewSearchRequest(query) +searchResult, _ := index.Search(searchRequest) +``` + +## Command Line Interface + +To install the CLI for the latest release of bleve, run: + +```bash +$ go install github.com/blevesearch/bleve/v2/cmd/bleve@latest +``` + +``` +$ bleve --help +Bleve is a command-line tool to interact with a bleve index. + +Usage: + bleve [command] + +Available Commands: + bulk bulk loads from newline delimited JSON files + check checks the contents of the index + count counts the number documents in the index + create creates a new index + dictionary prints the term dictionary for the specified field in the index + dump dumps the contents of the index + fields lists the fields in this index + help Help about any command + index adds the files to the index + mapping prints the mapping used for this index + query queries the index + registry registry lists the bleve components compiled into this executable + scorch command-line tool to interact with a scorch index + +Flags: + -h, --help help for bleve + +Use "bleve [command] --help" for more information about a command. +``` + +## Text Analysis Wizard + +[bleveanalysis.couchbase.com](https://bleveanalysis.couchbase.com) + +## Discussion/Issues + +Discuss usage/development of bleve and/or report issues here: +* [Github issues](https://github.com/blevesearch/bleve/issues) +* [Google group](https://groups.google.com/forum/#!forum/bleve) + +## License + +Apache License Version 2.0 diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/SECURITY.md b/backend/vendor/github.com/blevesearch/bleve/v2/SECURITY.md new file mode 100644 index 0000000000..51c6b6bdca --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/SECURITY.md @@ -0,0 +1,15 @@ +# Security Policy + +## Supported Versions + +We support the latest release (for example, bleve v2.3.x). + +## Reporting a Vulnerability + +All security issues for this project should be reported by email to security@couchbase.com and fts-team@couchbase.com. +This mail will be delivered to the owners of this project. + +- To ensure your report is NOT marked as spam, please include the word "security/vulnerability" along with the project name (blevesearch/bleve) in the subject of the email. +- Please be as descriptive as possible while explaining the issue, and a testcase highlighting the issue is always welcome. + +Your email will be acknowledged at the soonest possible. diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/analyzer/custom/custom.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/analyzer/custom/custom.go new file mode 100644 index 0000000000..5e28c95a50 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/analyzer/custom/custom.go @@ -0,0 +1,145 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package custom + +import ( + "fmt" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const Name = "custom" + +func AnalyzerConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.Analyzer, error) { + + var err error + var charFilters []analysis.CharFilter + charFiltersValue, ok := config["char_filters"] + if ok { + switch charFiltersValue := charFiltersValue.(type) { + case []string: + charFilters, err = getCharFilters(charFiltersValue, cache) + if err != nil { + return nil, err + } + case []interface{}: + charFiltersNames, err := convertInterfaceSliceToStringSlice(charFiltersValue, "char filter") + if err != nil { + return nil, err + } + charFilters, err = getCharFilters(charFiltersNames, cache) + if err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("unsupported type for char_filters, must be slice") + } + } + + var tokenizerName string + tokenizerValue, ok := config["tokenizer"] + if ok { + tokenizerName, ok = tokenizerValue.(string) + if !ok { + return nil, fmt.Errorf("must specify tokenizer as string") + } + } else { + return nil, fmt.Errorf("must specify tokenizer") + } + + tokenizer, err := cache.TokenizerNamed(tokenizerName) + if err != nil { + return nil, err + } + + var tokenFilters []analysis.TokenFilter + tokenFiltersValue, ok := config["token_filters"] + if ok { + switch tokenFiltersValue := tokenFiltersValue.(type) { + case []string: + tokenFilters, err = getTokenFilters(tokenFiltersValue, cache) + if err != nil { + return nil, err + } + case []interface{}: + tokenFiltersNames, err := convertInterfaceSliceToStringSlice(tokenFiltersValue, "token filter") + if err != nil { + return nil, err + } + tokenFilters, err = getTokenFilters(tokenFiltersNames, cache) + if err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("unsupported type for token_filters, must be slice") + } + } + + rv := analysis.DefaultAnalyzer{ + Tokenizer: tokenizer, + } + if charFilters != nil { + rv.CharFilters = charFilters + } + if tokenFilters != nil { + rv.TokenFilters = tokenFilters + } + return &rv, nil +} + +func init() { + registry.RegisterAnalyzer(Name, AnalyzerConstructor) +} + +func getCharFilters(charFilterNames []string, cache *registry.Cache) ([]analysis.CharFilter, error) { + charFilters := make([]analysis.CharFilter, len(charFilterNames)) + for i, charFilterName := range charFilterNames { + charFilter, err := cache.CharFilterNamed(charFilterName) + if err != nil { + return nil, err + } + charFilters[i] = charFilter + } + + return charFilters, nil +} + +func getTokenFilters(tokenFilterNames []string, cache *registry.Cache) ([]analysis.TokenFilter, error) { + tokenFilters := make([]analysis.TokenFilter, len(tokenFilterNames)) + for i, tokenFilterName := range tokenFilterNames { + tokenFilter, err := cache.TokenFilterNamed(tokenFilterName) + if err != nil { + return nil, err + } + tokenFilters[i] = tokenFilter + } + + return tokenFilters, nil +} + +func convertInterfaceSliceToStringSlice(interfaceSlice []interface{}, objType string) ([]string, error) { + stringSlice := make([]string, len(interfaceSlice)) + for i, interfaceObj := range interfaceSlice { + stringObj, ok := interfaceObj.(string) + if ok { + stringSlice[i] = stringObj + } else { + return nil, fmt.Errorf(objType + " name must be a string") + } + } + + return stringSlice, nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/analyzer/keyword/keyword.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/analyzer/keyword/keyword.go new file mode 100644 index 0000000000..6bb56d6f7a --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/analyzer/keyword/keyword.go @@ -0,0 +1,38 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package keyword + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/analysis/tokenizer/single" + "github.com/blevesearch/bleve/v2/registry" +) + +const Name = "keyword" + +func AnalyzerConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.Analyzer, error) { + keywordTokenizer, err := cache.TokenizerNamed(single.Name) + if err != nil { + return nil, err + } + rv := analysis.DefaultAnalyzer{ + Tokenizer: keywordTokenizer, + } + return &rv, nil +} + +func init() { + registry.RegisterAnalyzer(Name, AnalyzerConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/analyzer/standard/standard.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/analyzer/standard/standard.go new file mode 100644 index 0000000000..96387bd795 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/analyzer/standard/standard.go @@ -0,0 +1,52 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package standard + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/analysis/lang/en" + "github.com/blevesearch/bleve/v2/analysis/token/lowercase" + "github.com/blevesearch/bleve/v2/analysis/tokenizer/unicode" + "github.com/blevesearch/bleve/v2/registry" +) + +const Name = "standard" + +func AnalyzerConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.Analyzer, error) { + tokenizer, err := cache.TokenizerNamed(unicode.Name) + if err != nil { + return nil, err + } + toLowerFilter, err := cache.TokenFilterNamed(lowercase.Name) + if err != nil { + return nil, err + } + stopEnFilter, err := cache.TokenFilterNamed(en.StopName) + if err != nil { + return nil, err + } + rv := analysis.DefaultAnalyzer{ + Tokenizer: tokenizer, + TokenFilters: []analysis.TokenFilter{ + toLowerFilter, + stopEnFilter, + }, + } + return &rv, nil +} + +func init() { + registry.RegisterAnalyzer(Name, AnalyzerConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/datetime/flexible/flexible.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/datetime/flexible/flexible.go new file mode 100644 index 0000000000..0eba074cd7 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/datetime/flexible/flexible.go @@ -0,0 +1,64 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package flexible + +import ( + "fmt" + "time" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const Name = "flexiblego" + +type DateTimeParser struct { + layouts []string +} + +func New(layouts []string) *DateTimeParser { + return &DateTimeParser{ + layouts: layouts, + } +} + +func (p *DateTimeParser) ParseDateTime(input string) (time.Time, error) { + for _, layout := range p.layouts { + rv, err := time.Parse(layout, input) + if err == nil { + return rv, nil + } + } + return time.Time{}, analysis.ErrInvalidDateTime +} + +func DateTimeParserConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.DateTimeParser, error) { + layouts, ok := config["layouts"].([]interface{}) + if !ok { + return nil, fmt.Errorf("must specify layouts") + } + var layoutStrs []string + for _, layout := range layouts { + layoutStr, ok := layout.(string) + if ok { + layoutStrs = append(layoutStrs, layoutStr) + } + } + return New(layoutStrs), nil +} + +func init() { + registry.RegisterDateTimeParser(Name, DateTimeParserConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/datetime/optional/optional.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/datetime/optional/optional.go new file mode 100644 index 0000000000..196aa25cba --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/datetime/optional/optional.go @@ -0,0 +1,45 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package optional + +import ( + "time" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/analysis/datetime/flexible" + "github.com/blevesearch/bleve/v2/registry" +) + +const Name = "dateTimeOptional" + +const rfc3339NoTimezone = "2006-01-02T15:04:05" +const rfc3339NoTimezoneNoT = "2006-01-02 15:04:05" +const rfc3339NoTime = "2006-01-02" + +var layouts = []string{ + time.RFC3339Nano, + time.RFC3339, + rfc3339NoTimezone, + rfc3339NoTimezoneNoT, + rfc3339NoTime, +} + +func DateTimeParserConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.DateTimeParser, error) { + return flexible.New(layouts), nil +} + +func init() { + registry.RegisterDateTimeParser(Name, DateTimeParserConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/freq.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/freq.go new file mode 100644 index 0000000000..a0fd1a416b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/freq.go @@ -0,0 +1,70 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package analysis + +import ( + index "github.com/blevesearch/bleve_index_api" +) + +func TokenFrequency(tokens TokenStream, arrayPositions []uint64, options index.FieldIndexingOptions) index.TokenFrequencies { + rv := make(map[string]*index.TokenFreq, len(tokens)) + + if options.IncludeTermVectors() { + tls := make([]index.TokenLocation, len(tokens)) + tlNext := 0 + + for _, token := range tokens { + tls[tlNext] = index.TokenLocation{ + ArrayPositions: arrayPositions, + Start: token.Start, + End: token.End, + Position: token.Position, + } + + curr, ok := rv[string(token.Term)] + if ok { + curr.Locations = append(curr.Locations, &tls[tlNext]) + } else { + curr = &index.TokenFreq{ + Term: token.Term, + Locations: []*index.TokenLocation{&tls[tlNext]}, + } + rv[string(token.Term)] = curr + } + + if !options.SkipFreqNorm() { + curr.SetFrequency(curr.Frequency() + 1) + } + + tlNext++ + } + } else { + for _, token := range tokens { + curr, exists := rv[string(token.Term)] + if !exists { + curr = &index.TokenFreq{ + Term: token.Term, + } + rv[string(token.Term)] = curr + } + + if !options.SkipFreqNorm() { + curr.SetFrequency(curr.Frequency() + 1) + } + } + } + + return rv +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/analyzer_ar.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/analyzer_ar.go new file mode 100644 index 0000000000..e15cd25333 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/analyzer_ar.go @@ -0,0 +1,65 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ar + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" + + "github.com/blevesearch/bleve/v2/analysis/token/lowercase" + "github.com/blevesearch/bleve/v2/analysis/token/unicodenorm" + "github.com/blevesearch/bleve/v2/analysis/tokenizer/unicode" +) + +const AnalyzerName = "ar" + +func AnalyzerConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.Analyzer, error) { + tokenizer, err := cache.TokenizerNamed(unicode.Name) + if err != nil { + return nil, err + } + toLowerFilter, err := cache.TokenFilterNamed(lowercase.Name) + if err != nil { + return nil, err + } + normalizeFilter := unicodenorm.MustNewUnicodeNormalizeFilter(unicodenorm.NFKC) + stopArFilter, err := cache.TokenFilterNamed(StopName) + if err != nil { + return nil, err + } + normalizeArFilter, err := cache.TokenFilterNamed(NormalizeName) + if err != nil { + return nil, err + } + stemmerArFilter, err := cache.TokenFilterNamed(StemmerName) + if err != nil { + return nil, err + } + rv := analysis.DefaultAnalyzer{ + Tokenizer: tokenizer, + TokenFilters: []analysis.TokenFilter{ + toLowerFilter, + normalizeFilter, + stopArFilter, + normalizeArFilter, + stemmerArFilter, + }, + } + return &rv, nil +} + +func init() { + registry.RegisterAnalyzer(AnalyzerName, AnalyzerConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/arabic_normalize.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/arabic_normalize.go new file mode 100644 index 0000000000..8fdb89904c --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/arabic_normalize.go @@ -0,0 +1,85 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ar + +import ( + "bytes" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const NormalizeName = "normalize_ar" + +const ( + Alef = '\u0627' + AlefMadda = '\u0622' + AlefHamzaAbove = '\u0623' + AlefHamzaBelow = '\u0625' + Yeh = '\u064A' + DotlessYeh = '\u0649' + TehMarbuta = '\u0629' + Heh = '\u0647' + Tatweel = '\u0640' + Fathatan = '\u064B' + Dammatan = '\u064C' + Kasratan = '\u064D' + Fatha = '\u064E' + Damma = '\u064F' + Kasra = '\u0650' + Shadda = '\u0651' + Sukun = '\u0652' +) + +type ArabicNormalizeFilter struct { +} + +func NewArabicNormalizeFilter() *ArabicNormalizeFilter { + return &ArabicNormalizeFilter{} +} + +func (s *ArabicNormalizeFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + term := normalize(token.Term) + token.Term = term + } + return input +} + +func normalize(input []byte) []byte { + runes := bytes.Runes(input) + for i := 0; i < len(runes); i++ { + switch runes[i] { + case AlefMadda, AlefHamzaAbove, AlefHamzaBelow: + runes[i] = Alef + case DotlessYeh: + runes[i] = Yeh + case TehMarbuta: + runes[i] = Heh + case Tatweel, Kasratan, Dammatan, Fathatan, Fatha, Damma, Kasra, Shadda, Sukun: + runes = analysis.DeleteRune(runes, i) + i-- + } + } + return analysis.BuildTermFromRunes(runes) +} + +func NormalizerFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + return NewArabicNormalizeFilter(), nil +} + +func init() { + registry.RegisterTokenFilter(NormalizeName, NormalizerFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/stemmer_ar.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/stemmer_ar.go new file mode 100644 index 0000000000..d4540e1dda --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/stemmer_ar.go @@ -0,0 +1,118 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ar + +import ( + "bytes" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const StemmerName = "stemmer_ar" + +// These were obtained from org.apache.lucene.analysis.ar.ArabicStemmer +var prefixes = [][]rune{ + []rune("ال"), + []rune("وال"), + []rune("بال"), + []rune("كال"), + []rune("فال"), + []rune("لل"), + []rune("و"), +} +var suffixes = [][]rune{ + []rune("ها"), + []rune("ان"), + []rune("ات"), + []rune("ون"), + []rune("ين"), + []rune("يه"), + []rune("ية"), + []rune("ه"), + []rune("ة"), + []rune("ي"), +} + +type ArabicStemmerFilter struct{} + +func NewArabicStemmerFilter() *ArabicStemmerFilter { + return &ArabicStemmerFilter{} +} + +func (s *ArabicStemmerFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + term := stem(token.Term) + token.Term = term + } + return input +} + +func canStemPrefix(input, prefix []rune) bool { + // Wa- prefix requires at least 3 characters. + if len(prefix) == 1 && len(input) < 4 { + return false + } + // Other prefixes require only 2. + if len(input)-len(prefix) < 2 { + return false + } + for i := range prefix { + if prefix[i] != input[i] { + return false + } + } + return true +} + +func canStemSuffix(input, suffix []rune) bool { + // All suffixes require at least 2 characters after stemming. + if len(input)-len(suffix) < 2 { + return false + } + stemEnd := len(input) - len(suffix) + for i := range suffix { + if suffix[i] != input[stemEnd+i] { + return false + } + } + return true +} + +func stem(input []byte) []byte { + runes := bytes.Runes(input) + // Strip a single prefix. + for _, p := range prefixes { + if canStemPrefix(runes, p) { + runes = runes[len(p):] + break + } + } + // Strip off multiple suffixes, in their order in the suffixes array. + for _, s := range suffixes { + if canStemSuffix(runes, s) { + runes = runes[:len(runes)-len(s)] + } + } + return analysis.BuildTermFromRunes(runes) +} + +func StemmerFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + return NewArabicStemmerFilter(), nil +} + +func init() { + registry.RegisterTokenFilter(StemmerName, StemmerFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/stop_filter_ar.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/stop_filter_ar.go new file mode 100644 index 0000000000..d8af36022f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/stop_filter_ar.go @@ -0,0 +1,33 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ar + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/analysis/token/stop" + "github.com/blevesearch/bleve/v2/registry" +) + +func StopTokenFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + tokenMap, err := cache.TokenMapNamed(StopName) + if err != nil { + return nil, err + } + return stop.NewStopTokensFilter(tokenMap), nil +} + +func init() { + registry.RegisterTokenFilter(StopName, StopTokenFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/stop_words_ar.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/stop_words_ar.go new file mode 100644 index 0000000000..2d1bd56d6a --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ar/stop_words_ar.go @@ -0,0 +1,149 @@ +package ar + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const StopName = "stop_ar" + +// this content was obtained from: +// lucene-4.7.2/analysis/common/src/resources/org/apache/lucene/analysis +// ` was changed to ' to allow for literal string + +var ArabicStopWords = []byte(`# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +# Cleaned on October 11, 2009 (not normalized, so use before normalization) +# This means that when modifying this list, you might need to add some +# redundant entries, for example containing forms with both أ and ا +من +ومن +منها +منه +في +وفي +فيها +فيه +و +ف +ثم +او +أو +ب +بها +به +ا +أ +اى +اي +أي +أى +لا +ولا +الا +ألا +إلا +لكن +ما +وما +كما +فما +عن +مع +اذا +إذا +ان +أن +إن +انها +أنها +إنها +انه +أنه +إنه +بان +بأن +فان +فأن +وان +وأن +وإن +التى +التي +الذى +الذي +الذين +الى +الي +إلى +إلي +على +عليها +عليه +اما +أما +إما +ايضا +أيضا +كل +وكل +لم +ولم +لن +ولن +هى +هي +هو +وهى +وهي +وهو +فهى +فهي +فهو +انت +أنت +لك +لها +له +هذه +هذا +تلك +ذلك +هناك +كانت +كان +يكون +تكون +وكانت +وكان +غير +بعض +قد +نحو +بين +بينما +منذ +ضمن +حيث +الان +الآن +خلال +بعد +قبل +حتى +عند +عندما +لدى +جميع +`) + +func TokenMapConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenMap, error) { + rv := analysis.NewTokenMap() + err := rv.LoadBytes(ArabicStopWords) + return rv, err +} + +func init() { + registry.RegisterTokenMap(StopName, TokenMapConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/analyzer_de.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/analyzer_de.go new file mode 100644 index 0000000000..34ded33d5c --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/analyzer_de.go @@ -0,0 +1,61 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package de + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/analysis/token/lowercase" + "github.com/blevesearch/bleve/v2/analysis/tokenizer/unicode" + "github.com/blevesearch/bleve/v2/registry" +) + +const AnalyzerName = "de" + +func AnalyzerConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.Analyzer, error) { + unicodeTokenizer, err := cache.TokenizerNamed(unicode.Name) + if err != nil { + return nil, err + } + toLowerFilter, err := cache.TokenFilterNamed(lowercase.Name) + if err != nil { + return nil, err + } + stopDeFilter, err := cache.TokenFilterNamed(StopName) + if err != nil { + return nil, err + } + normalizeDeFilter, err := cache.TokenFilterNamed(NormalizeName) + if err != nil { + return nil, err + } + lightStemmerDeFilter, err := cache.TokenFilterNamed(LightStemmerName) + if err != nil { + return nil, err + } + rv := analysis.DefaultAnalyzer{ + Tokenizer: unicodeTokenizer, + TokenFilters: []analysis.TokenFilter{ + toLowerFilter, + stopDeFilter, + normalizeDeFilter, + lightStemmerDeFilter, + }, + } + return &rv, nil +} + +func init() { + registry.RegisterAnalyzer(AnalyzerName, AnalyzerConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/german_normalize.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/german_normalize.go new file mode 100644 index 0000000000..84688f1371 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/german_normalize.go @@ -0,0 +1,95 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package de + +import ( + "bytes" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const NormalizeName = "normalize_de" + +const ( + N = 0 /* ordinary state */ + V = 1 /* stops 'u' from entering umlaut state */ + U = 2 /* umlaut state, allows e-deletion */ +) + +type GermanNormalizeFilter struct { +} + +func NewGermanNormalizeFilter() *GermanNormalizeFilter { + return &GermanNormalizeFilter{} +} + +func (s *GermanNormalizeFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + term := normalize(token.Term) + token.Term = term + } + return input +} + +func normalize(input []byte) []byte { + state := N + runes := bytes.Runes(input) + for i := 0; i < len(runes); i++ { + switch runes[i] { + case 'a', 'o': + state = U + case 'u': + if state == N { + state = U + } else { + state = V + } + case 'e': + if state == U { + runes = analysis.DeleteRune(runes, i) + i-- + } + state = V + case 'i', 'q', 'y': + state = V + case 'ä': + runes[i] = 'a' + state = V + case 'ö': + runes[i] = 'o' + state = V + case 'ü': + runes[i] = 'u' + state = V + case 'ß': + runes[i] = 's' + i++ + runes = analysis.InsertRune(runes, i, 's') + state = N + default: + state = N + } + } + return analysis.BuildTermFromRunes(runes) +} + +func NormalizerFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + return NewGermanNormalizeFilter(), nil +} + +func init() { + registry.RegisterTokenFilter(NormalizeName, NormalizerFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/light_stemmer_de.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/light_stemmer_de.go new file mode 100644 index 0000000000..48bcf274d9 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/light_stemmer_de.go @@ -0,0 +1,116 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package de + +import ( + "bytes" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const LightStemmerName = "stemmer_de_light" + +type GermanLightStemmerFilter struct { +} + +func NewGermanLightStemmerFilter() *GermanLightStemmerFilter { + return &GermanLightStemmerFilter{} +} + +func (s *GermanLightStemmerFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + runes := bytes.Runes(token.Term) + runes = stem(runes) + token.Term = analysis.BuildTermFromRunes(runes) + } + return input +} + +func stem(input []rune) []rune { + + for i, r := range input { + switch r { + case 'ä', 'à', 'á', 'â': + input[i] = 'a' + case 'ö', 'ò', 'ó', 'ô': + input[i] = 'o' + case 'ï', 'ì', 'í', 'î': + input[i] = 'i' + case 'ü', 'ù', 'ú', 'û': + input[i] = 'u' + } + } + + input = step1(input) + return step2(input) +} + +func stEnding(ch rune) bool { + switch ch { + case 'b', 'd', 'f', 'g', 'h', 'k', 'l', 'm', 'n', 't': + return true + } + return false +} + +func step1(s []rune) []rune { + l := len(s) + if l > 5 && s[l-3] == 'e' && s[l-2] == 'r' && s[l-1] == 'n' { + return s[:l-3] + } + + if l > 4 && s[l-2] == 'e' { + switch s[l-1] { + case 'm', 'n', 'r', 's': + return s[:l-2] + } + } + + if l > 3 && s[l-1] == 'e' { + return s[:l-1] + } + + if l > 3 && s[l-1] == 's' && stEnding(s[l-2]) { + return s[:l-1] + } + + return s +} + +func step2(s []rune) []rune { + l := len(s) + if l > 5 && s[l-3] == 'e' && s[l-2] == 's' && s[l-1] == 't' { + return s[:l-3] + } + + if l > 4 && s[l-2] == 'e' && (s[l-1] == 'r' || s[l-1] == 'n') { + return s[:l-2] + } + + if l > 4 && s[l-2] == 's' && s[l-1] == 't' && stEnding(s[l-3]) { + return s[:l-2] + } + + return s +} + +func GermanLightStemmerFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + return NewGermanLightStemmerFilter(), nil +} + +func init() { + registry.RegisterTokenFilter(LightStemmerName, GermanLightStemmerFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/stemmer_de_snowball.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/stemmer_de_snowball.go new file mode 100644 index 0000000000..35afdd96bd --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/stemmer_de_snowball.go @@ -0,0 +1,49 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package de + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" + + "github.com/blevesearch/snowballstem" + "github.com/blevesearch/snowballstem/german" +) + +const SnowballStemmerName = "stemmer_de_snowball" + +type GermanStemmerFilter struct { +} + +func NewGermanStemmerFilter() *GermanStemmerFilter { + return &GermanStemmerFilter{} +} + +func (s *GermanStemmerFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + env := snowballstem.NewEnv(string(token.Term)) + german.Stem(env) + token.Term = []byte(env.Current()) + } + return input +} + +func GermanStemmerFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + return NewGermanStemmerFilter(), nil +} + +func init() { + registry.RegisterTokenFilter(SnowballStemmerName, GermanStemmerFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/stop_filter_de.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/stop_filter_de.go new file mode 100644 index 0000000000..b97d1a185a --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/stop_filter_de.go @@ -0,0 +1,33 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package de + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/analysis/token/stop" + "github.com/blevesearch/bleve/v2/registry" +) + +func StopTokenFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + tokenMap, err := cache.TokenMapNamed(StopName) + if err != nil { + return nil, err + } + return stop.NewStopTokensFilter(tokenMap), nil +} + +func init() { + registry.RegisterTokenFilter(StopName, StopTokenFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/stop_words_de.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/stop_words_de.go new file mode 100644 index 0000000000..83ea0b5579 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/de/stop_words_de.go @@ -0,0 +1,318 @@ +package de + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const StopName = "stop_de" + +// this content was obtained from: +// lucene-4.7.2/analysis/common/src/resources/org/apache/lucene/analysis/snowball/ +// ` was changed to ' to allow for literal string + +var GermanStopWords = []byte(` | From svn.tartarus.org/snowball/trunk/website/algorithms/german/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + | + | NOTE: To use this file with StopFilterFactory, you must specify format="snowball" + + | A German stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | The number of forms in this list is reduced significantly by passing it + | through the German stemmer. + + +aber | but + +alle | all +allem +allen +aller +alles + +als | than, as +also | so +am | an + dem +an | at + +ander | other +andere +anderem +anderen +anderer +anderes +anderm +andern +anderr +anders + +auch | also +auf | on +aus | out of +bei | by +bin | am +bis | until +bist | art +da | there +damit | with it +dann | then + +der | the +den +des +dem +die +das + +daß | that + +derselbe | the same +derselben +denselben +desselben +demselben +dieselbe +dieselben +dasselbe + +dazu | to that + +dein | thy +deine +deinem +deinen +deiner +deines + +denn | because + +derer | of those +dessen | of him + +dich | thee +dir | to thee +du | thou + +dies | this +diese +diesem +diesen +dieser +dieses + + +doch | (several meanings) +dort | (over) there + + +durch | through + +ein | a +eine +einem +einen +einer +eines + +einig | some +einige +einigem +einigen +einiger +einiges + +einmal | once + +er | he +ihn | him +ihm | to him + +es | it +etwas | something + +euer | your +eure +eurem +euren +eurer +eures + +für | for +gegen | towards +gewesen | p.p. of sein +hab | have +habe | have +haben | have +hat | has +hatte | had +hatten | had +hier | here +hin | there +hinter | behind + +ich | I +mich | me +mir | to me + + +ihr | you, to her +ihre +ihrem +ihren +ihrer +ihres +euch | to you + +im | in + dem +in | in +indem | while +ins | in + das +ist | is + +jede | each, every +jedem +jeden +jeder +jedes + +jene | that +jenem +jenen +jener +jenes + +jetzt | now +kann | can + +kein | no +keine +keinem +keinen +keiner +keines + +können | can +könnte | could +machen | do +man | one + +manche | some, many a +manchem +manchen +mancher +manches + +mein | my +meine +meinem +meinen +meiner +meines + +mit | with +muss | must +musste | had to +nach | to(wards) +nicht | not +nichts | nothing +noch | still, yet +nun | now +nur | only +ob | whether +oder | or +ohne | without +sehr | very + +sein | his +seine +seinem +seinen +seiner +seines + +selbst | self +sich | herself + +sie | they, she +ihnen | to them + +sind | are +so | so + +solche | such +solchem +solchen +solcher +solches + +soll | shall +sollte | should +sondern | but +sonst | else +über | over +um | about, around +und | and + +uns | us +unse +unsem +unsen +unser +unses + +unter | under +viel | much +vom | von + dem +von | from +vor | before +während | while +war | was +waren | were +warst | wast +was | what +weg | away, off +weil | because +weiter | further + +welche | which +welchem +welchen +welcher +welches + +wenn | when +werde | will +werden | will +wie | how +wieder | again +will | want +wir | we +wird | will +wirst | willst +wo | where +wollen | want +wollte | wanted +würde | would +würden | would +zu | to +zum | zu + dem +zur | zu + der +zwar | indeed +zwischen | between + +`) + +func TokenMapConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenMap, error) { + rv := analysis.NewTokenMap() + err := rv.LoadBytes(GermanStopWords) + return rv, err +} + +func init() { + registry.RegisterTokenMap(StopName, TokenMapConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/analyzer_en.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/analyzer_en.go new file mode 100644 index 0000000000..44a8d4c211 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/analyzer_en.go @@ -0,0 +1,70 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package en implements an analyzer with reasonable defaults for processing +// English text. +// +// It strips possessive suffixes ('s), transforms tokens to lower case, +// removes stopwords from a built-in list, and applies porter stemming. +// +// The built-in stopwords list is defined in EnglishStopWords. +package en + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" + + "github.com/blevesearch/bleve/v2/analysis/token/lowercase" + "github.com/blevesearch/bleve/v2/analysis/token/porter" + "github.com/blevesearch/bleve/v2/analysis/tokenizer/unicode" +) + +const AnalyzerName = "en" + +func AnalyzerConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.Analyzer, error) { + tokenizer, err := cache.TokenizerNamed(unicode.Name) + if err != nil { + return nil, err + } + possEnFilter, err := cache.TokenFilterNamed(PossessiveName) + if err != nil { + return nil, err + } + toLowerFilter, err := cache.TokenFilterNamed(lowercase.Name) + if err != nil { + return nil, err + } + stopEnFilter, err := cache.TokenFilterNamed(StopName) + if err != nil { + return nil, err + } + stemmerEnFilter, err := cache.TokenFilterNamed(porter.Name) + if err != nil { + return nil, err + } + rv := analysis.DefaultAnalyzer{ + Tokenizer: tokenizer, + TokenFilters: []analysis.TokenFilter{ + possEnFilter, + toLowerFilter, + stopEnFilter, + stemmerEnFilter, + }, + } + return &rv, nil +} + +func init() { + registry.RegisterAnalyzer(AnalyzerName, AnalyzerConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/possessive_filter_en.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/possessive_filter_en.go new file mode 100644 index 0000000000..79c2489e28 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/possessive_filter_en.go @@ -0,0 +1,67 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package en + +import ( + "unicode/utf8" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +// PossessiveName is the name PossessiveFilter is registered as +// in the bleve registry. +const PossessiveName = "possessive_en" + +const rightSingleQuotationMark = '’' +const apostrophe = '\'' +const fullWidthApostrophe = ''' + +const apostropheChars = rightSingleQuotationMark + apostrophe + fullWidthApostrophe + +// PossessiveFilter implements a TokenFilter which +// strips the English possessive suffix ('s) from tokens. +// It handle a variety of apostrophe types, is case-insensitive +// and doesn't distinguish between possessive and contraction. +// (ie "She's So Rad" becomes "She So Rad") +type PossessiveFilter struct { +} + +func NewPossessiveFilter() *PossessiveFilter { + return &PossessiveFilter{} +} + +func (s *PossessiveFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + lastRune, lastRuneSize := utf8.DecodeLastRune(token.Term) + if lastRune == 's' || lastRune == 'S' { + nextLastRune, nextLastRuneSize := utf8.DecodeLastRune(token.Term[:len(token.Term)-lastRuneSize]) + if nextLastRune == rightSingleQuotationMark || + nextLastRune == apostrophe || + nextLastRune == fullWidthApostrophe { + token.Term = token.Term[:len(token.Term)-lastRuneSize-nextLastRuneSize] + } + } + } + return input +} + +func PossessiveFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + return NewPossessiveFilter(), nil +} + +func init() { + registry.RegisterTokenFilter(PossessiveName, PossessiveFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/stemmer_en_snowball.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/stemmer_en_snowball.go new file mode 100644 index 0000000000..ab30b8b195 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/stemmer_en_snowball.go @@ -0,0 +1,49 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package en + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" + + "github.com/blevesearch/snowballstem" + "github.com/blevesearch/snowballstem/english" +) + +const SnowballStemmerName = "stemmer_en_snowball" + +type EnglishStemmerFilter struct { +} + +func NewEnglishStemmerFilter() *EnglishStemmerFilter { + return &EnglishStemmerFilter{} +} + +func (s *EnglishStemmerFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + env := snowballstem.NewEnv(string(token.Term)) + english.Stem(env) + token.Term = []byte(env.Current()) + } + return input +} + +func EnglishStemmerFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + return NewEnglishStemmerFilter(), nil +} + +func init() { + registry.RegisterTokenFilter(SnowballStemmerName, EnglishStemmerFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/stop_filter_en.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/stop_filter_en.go new file mode 100644 index 0000000000..a3f91d2267 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/stop_filter_en.go @@ -0,0 +1,33 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package en + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/analysis/token/stop" + "github.com/blevesearch/bleve/v2/registry" +) + +func StopTokenFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + tokenMap, err := cache.TokenMapNamed(StopName) + if err != nil { + return nil, err + } + return stop.NewStopTokensFilter(tokenMap), nil +} + +func init() { + registry.RegisterTokenFilter(StopName, StopTokenFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/stop_words_en.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/stop_words_en.go new file mode 100644 index 0000000000..9b6ca86a72 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/en/stop_words_en.go @@ -0,0 +1,344 @@ +package en + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const StopName = "stop_en" + +// EnglishStopWords is the built-in list of stopwords used by the "stop_en" TokenFilter. +// +// this content was obtained from: +// lucene-4.7.2/analysis/common/src/resources/org/apache/lucene/analysis/snowball/ +// ` was changed to ' to allow for literal string +var EnglishStopWords = []byte(` | From svn.tartarus.org/snowball/trunk/website/algorithms/english/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + | + | NOTE: To use this file with StopFilterFactory, you must specify format="snowball" + + | An English stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | Many of the forms below are quite rare (e.g. "yourselves") but included for + | completeness. + + | PRONOUNS FORMS + | 1st person sing + +i | subject, always in upper case of course + +me | object +my | possessive adjective + | the possessive pronoun 'mine' is best suppressed, because of the + | sense of coal-mine etc. +myself | reflexive + | 1st person plural +we | subject + +| us | object + | care is required here because US = United States. It is usually + | safe to remove it if it is in lower case. +our | possessive adjective +ours | possessive pronoun +ourselves | reflexive + | second person (archaic 'thou' forms not included) +you | subject and object +your | possessive adjective +yours | possessive pronoun +yourself | reflexive (singular) +yourselves | reflexive (plural) + | third person singular +he | subject +him | object +his | possessive adjective and pronoun +himself | reflexive + +she | subject +her | object and possessive adjective +hers | possessive pronoun +herself | reflexive + +it | subject and object +its | possessive adjective +itself | reflexive + | third person plural +they | subject +them | object +their | possessive adjective +theirs | possessive pronoun +themselves | reflexive + | other forms (demonstratives, interrogatives) +what +which +who +whom +this +that +these +those + + | VERB FORMS (using F.R. Palmer's nomenclature) + | BE +am | 1st person, present +is | -s form (3rd person, present) +are | present +was | 1st person, past +were | past +be | infinitive +been | past participle +being | -ing form + | HAVE +have | simple +has | -s form +had | past +having | -ing form + | DO +do | simple +does | -s form +did | past +doing | -ing form + + | The forms below are, I believe, best omitted, because of the significant + | homonym forms: + + | He made a WILL + | old tin CAN + | merry month of MAY + | a smell of MUST + | fight the good fight with all thy MIGHT + + | would, could, should, ought might however be included + + | | AUXILIARIES + | | WILL + |will + +would + + | | SHALL + |shall + +should + + | | CAN + |can + +could + + | | MAY + |may + |might + | | MUST + |must + | | OUGHT + +ought + + | COMPOUND FORMS, increasingly encountered nowadays in 'formal' writing + | pronoun + verb + +i'm +you're +he's +she's +it's +we're +they're +i've +you've +we've +they've +i'd +you'd +he'd +she'd +we'd +they'd +i'll +you'll +he'll +she'll +we'll +they'll + + | verb + negation + +isn't +aren't +wasn't +weren't +hasn't +haven't +hadn't +doesn't +don't +didn't + + | auxiliary + negation + +won't +wouldn't +shan't +shouldn't +can't +cannot +couldn't +mustn't + + | miscellaneous forms + +let's +that's +who's +what's +here's +there's +when's +where's +why's +how's + + | rarer forms + + | daren't needn't + + | doubtful forms + + | oughtn't mightn't + + | ARTICLES +a +an +the + + | THE REST (Overlap among prepositions, conjunctions, adverbs etc is so + | high, that classification is pointless.) +and +but +if +or +because +as +until +while + +of +at +by +for +with +about +against +between +into +through +during +before +after +above +below +to +from +up +down +in +out +on +off +over +under + +again +further +then +once + +here +there +when +where +why +how + +all +any +both +each +few +more +most +other +some +such + +no +nor +not +only +own +same +so +than +too +very + + | Just for the record, the following words are among the commonest in English + + | one + | every + | least + | less + | many + | now + | ever + | never + | say + | says + | said + | also + | get + | go + | goes + | just + | made + | make + | put + | see + | seen + | whether + | like + | well + | back + | even + | still + | way + | take + | since + | another + | however + | two + | three + | four + | five + | first + | second + | new + | old + | high + | long +`) + +func TokenMapConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenMap, error) { + rv := analysis.NewTokenMap() + err := rv.LoadBytes(EnglishStopWords) + return rv, err +} + +func init() { + registry.RegisterTokenMap(StopName, TokenMapConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/analyzer_es.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/analyzer_es.go new file mode 100644 index 0000000000..e6fcd080c8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/analyzer_es.go @@ -0,0 +1,58 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package es + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" + + "github.com/blevesearch/bleve/v2/analysis/token/lowercase" + "github.com/blevesearch/bleve/v2/analysis/tokenizer/unicode" +) + +const AnalyzerName = "es" + +func AnalyzerConstructor(config map[string]interface{}, + cache *registry.Cache) (analysis.Analyzer, error) { + unicodeTokenizer, err := cache.TokenizerNamed(unicode.Name) + if err != nil { + return nil, err + } + toLowerFilter, err := cache.TokenFilterNamed(lowercase.Name) + if err != nil { + return nil, err + } + stopEsFilter, err := cache.TokenFilterNamed(StopName) + if err != nil { + return nil, err + } + lightStemmerEsFilter, err := cache.TokenFilterNamed(LightStemmerName) + if err != nil { + return nil, err + } + rv := analysis.DefaultAnalyzer{ + Tokenizer: unicodeTokenizer, + TokenFilters: []analysis.TokenFilter{ + toLowerFilter, + stopEsFilter, + lightStemmerEsFilter, + }, + } + return &rv, nil +} + +func init() { + registry.RegisterAnalyzer(AnalyzerName, AnalyzerConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/light_stemmer_es.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/light_stemmer_es.go new file mode 100644 index 0000000000..c1b4749ea3 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/light_stemmer_es.go @@ -0,0 +1,91 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package es + +import ( + "bytes" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const LightStemmerName = "stemmer_es_light" + +type SpanishLightStemmerFilter struct { +} + +func NewSpanishLightStemmerFilter() *SpanishLightStemmerFilter { + return &SpanishLightStemmerFilter{} +} + +func (s *SpanishLightStemmerFilter) Filter( + input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + runes := bytes.Runes(token.Term) + runes = stem(runes) + token.Term = analysis.BuildTermFromRunes(runes) + } + return input +} + +func stem(input []rune) []rune { + l := len(input) + if l < 5 { + return input + } + + for i, r := range input { + switch r { + case 'à', 'á', 'â', 'ä': + input[i] = 'a' + case 'ò', 'ó', 'ô', 'ö': + input[i] = 'o' + case 'è', 'é', 'ê', 'ë': + input[i] = 'e' + case 'ù', 'ú', 'û', 'ü': + input[i] = 'u' + case 'ì', 'í', 'î', 'ï': + input[i] = 'i' + } + } + + switch input[l-1] { + case 'o', 'a', 'e': + return input[:l-1] + case 's': + if input[l-2] == 'e' && input[l-3] == 's' && input[l-4] == 'e' { + return input[:l-2] + } + if input[l-2] == 'e' && input[l-3] == 'c' { + input[l-3] = 'z' + return input[:l-2] + } + if input[l-2] == 'o' || input[l-2] == 'a' || input[l-2] == 'e' { + return input[:l-2] + } + } + + return input +} + +func SpanishLightStemmerFilterConstructor(config map[string]interface{}, + cache *registry.Cache) (analysis.TokenFilter, error) { + return NewSpanishLightStemmerFilter(), nil +} + +func init() { + registry.RegisterTokenFilter(LightStemmerName, + SpanishLightStemmerFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/stemmer_es_snowball.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/stemmer_es_snowball.go new file mode 100644 index 0000000000..8833928567 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/stemmer_es_snowball.go @@ -0,0 +1,49 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package es + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" + + "github.com/blevesearch/snowballstem" + "github.com/blevesearch/snowballstem/spanish" +) + +const SnowballStemmerName = "stemmer_es_snowball" + +type SpanishStemmerFilter struct { +} + +func NewSpanishStemmerFilter() *SpanishStemmerFilter { + return &SpanishStemmerFilter{} +} + +func (s *SpanishStemmerFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + env := snowballstem.NewEnv(string(token.Term)) + spanish.Stem(env) + token.Term = []byte(env.Current()) + } + return input +} + +func SpanishStemmerFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + return NewSpanishStemmerFilter(), nil +} + +func init() { + registry.RegisterTokenFilter(SnowballStemmerName, SpanishStemmerFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/stop_filter_es.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/stop_filter_es.go new file mode 100644 index 0000000000..e968153b06 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/stop_filter_es.go @@ -0,0 +1,33 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package es + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/analysis/token/stop" + "github.com/blevesearch/bleve/v2/registry" +) + +func StopTokenFilterConstructor(config map[string]interface{}, + cache *registry.Cache) (analysis.TokenFilter, error) { + tokenMap, err := cache.TokenMapNamed(StopName) + if err != nil { + return nil, err + } + return stop.NewStopTokensFilter(tokenMap), nil +} + +func init() { + registry.RegisterTokenFilter(StopName, StopTokenFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/stop_words_es.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/stop_words_es.go new file mode 100644 index 0000000000..0f1e51d932 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/es/stop_words_es.go @@ -0,0 +1,380 @@ +package es + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const StopName = "stop_es" + +// this content was obtained from: +// lucene-4.7.2/analysis/common/src/resources/org/apache/lucene/analysis/snowball/ +// ` was changed to ' to allow for literal string + +var SpanishStopWords = []byte(` | From svn.tartarus.org/snowball/trunk/website/algorithms/spanish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + | + | NOTE: To use this file with StopFilterFactory, you must specify format="snowball" + + | A Spanish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + + | The following is a ranked list (commonest to rarest) of stopwords + | deriving from a large sample of text. + + | Extra words have been added at the end. + +de | from, of +la | the, her +que | who, that +el | the +en | in +y | and +a | to +los | the, them +del | de + el +se | himself, from him etc +las | the, them +por | for, by, etc +un | a +para | for +con | with +no | no +una | a +su | his, her +al | a + el + | es from SER +lo | him +como | how +más | more +pero | pero +sus | su plural +le | to him, her +ya | already +o | or + | fue from SER +este | this + | ha from HABER +sí | himself etc +porque | because +esta | this + | son from SER +entre | between + | está from ESTAR +cuando | when +muy | very +sin | without +sobre | on + | ser from SER + | tiene from TENER +también | also +me | me +hasta | until +hay | there is/are +donde | where + | han from HABER +quien | whom, that + | están from ESTAR + | estado from ESTAR +desde | from +todo | all +nos | us +durante | during + | estados from ESTAR +todos | all +uno | a +les | to them +ni | nor +contra | against +otros | other + | fueron from SER +ese | that +eso | that + | había from HABER +ante | before +ellos | they +e | and (variant of y) +esto | this +mí | me +antes | before +algunos | some +qué | what? +unos | a +yo | I +otro | other +otras | other +otra | other +él | he +tanto | so much, many +esa | that +estos | these +mucho | much, many +quienes | who +nada | nothing +muchos | many +cual | who + | sea from SER +poco | few +ella | she +estar | to be + | haber from HABER +estas | these + | estaba from ESTAR + | estamos from ESTAR +algunas | some +algo | something +nosotros | we + + | other forms + +mi | me +mis | mi plural +tú | thou +te | thee +ti | thee +tu | thy +tus | tu plural +ellas | they +nosotras | we +vosotros | you +vosotras | you +os | you +mío | mine +mía | +míos | +mías | +tuyo | thine +tuya | +tuyos | +tuyas | +suyo | his, hers, theirs +suya | +suyos | +suyas | +nuestro | ours +nuestra | +nuestros | +nuestras | +vuestro | yours +vuestra | +vuestros | +vuestras | +esos | those +esas | those + + | forms of estar, to be (not including the infinitive): +estoy +estás +está +estamos +estáis +están +esté +estés +estemos +estéis +estén +estaré +estarás +estará +estaremos +estaréis +estarán +estaría +estarías +estaríamos +estaríais +estarían +estaba +estabas +estábamos +estabais +estaban +estuve +estuviste +estuvo +estuvimos +estuvisteis +estuvieron +estuviera +estuvieras +estuviéramos +estuvierais +estuvieran +estuviese +estuvieses +estuviésemos +estuvieseis +estuviesen +estando +estado +estada +estados +estadas +estad + + | forms of haber, to have (not including the infinitive): +he +has +ha +hemos +habéis +han +haya +hayas +hayamos +hayáis +hayan +habré +habrás +habrá +habremos +habréis +habrán +habría +habrías +habríamos +habríais +habrían +había +habías +habíamos +habíais +habían +hube +hubiste +hubo +hubimos +hubisteis +hubieron +hubiera +hubieras +hubiéramos +hubierais +hubieran +hubiese +hubieses +hubiésemos +hubieseis +hubiesen +habiendo +habido +habida +habidos +habidas + + | forms of ser, to be (not including the infinitive): +soy +eres +es +somos +sois +son +sea +seas +seamos +seáis +sean +seré +serás +será +seremos +seréis +serán +sería +serías +seríamos +seríais +serían +era +eras +éramos +erais +eran +fui +fuiste +fue +fuimos +fuisteis +fueron +fuera +fueras +fuéramos +fuerais +fueran +fuese +fueses +fuésemos +fueseis +fuesen +siendo +sido + | sed also means 'thirst' + + | forms of tener, to have (not including the infinitive): +tengo +tienes +tiene +tenemos +tenéis +tienen +tenga +tengas +tengamos +tengáis +tengan +tendré +tendrás +tendrá +tendremos +tendréis +tendrán +tendría +tendrías +tendríamos +tendríais +tendrían +tenía +tenías +teníamos +teníais +tenían +tuve +tuviste +tuvo +tuvimos +tuvisteis +tuvieron +tuviera +tuvieras +tuviéramos +tuvierais +tuvieran +tuviese +tuvieses +tuviésemos +tuvieseis +tuviesen +teniendo +tenido +tenida +tenidos +tenidas +tened + +`) + +func TokenMapConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenMap, error) { + rv := analysis.NewTokenMap() + err := rv.LoadBytes(SpanishStopWords) + return rv, err +} + +func init() { + registry.RegisterTokenMap(StopName, TokenMapConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fi/analyzer_fi.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fi/analyzer_fi.go new file mode 100644 index 0000000000..c68cc2c1b6 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fi/analyzer_fi.go @@ -0,0 +1,57 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fi + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" + + "github.com/blevesearch/bleve/v2/analysis/token/lowercase" + "github.com/blevesearch/bleve/v2/analysis/tokenizer/unicode" +) + +const AnalyzerName = "fi" + +func AnalyzerConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.Analyzer, error) { + unicodeTokenizer, err := cache.TokenizerNamed(unicode.Name) + if err != nil { + return nil, err + } + toLowerFilter, err := cache.TokenFilterNamed(lowercase.Name) + if err != nil { + return nil, err + } + stopFiFilter, err := cache.TokenFilterNamed(StopName) + if err != nil { + return nil, err + } + stemmerFiFilter, err := cache.TokenFilterNamed(SnowballStemmerName) + if err != nil { + return nil, err + } + rv := analysis.DefaultAnalyzer{ + Tokenizer: unicodeTokenizer, + TokenFilters: []analysis.TokenFilter{ + toLowerFilter, + stopFiFilter, + stemmerFiFilter, + }, + } + return &rv, nil +} + +func init() { + registry.RegisterAnalyzer(AnalyzerName, AnalyzerConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fi/stemmer_fi.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fi/stemmer_fi.go new file mode 100644 index 0000000000..44d39020d9 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fi/stemmer_fi.go @@ -0,0 +1,49 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fi + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" + + "github.com/blevesearch/snowballstem" + "github.com/blevesearch/snowballstem/finnish" +) + +const SnowballStemmerName = "stemmer_fi_snowball" + +type FinnishStemmerFilter struct { +} + +func NewFinnishStemmerFilter() *FinnishStemmerFilter { + return &FinnishStemmerFilter{} +} + +func (s *FinnishStemmerFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + env := snowballstem.NewEnv(string(token.Term)) + finnish.Stem(env) + token.Term = []byte(env.Current()) + } + return input +} + +func FinnishStemmerFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + return NewFinnishStemmerFilter(), nil +} + +func init() { + registry.RegisterTokenFilter(SnowballStemmerName, FinnishStemmerFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fi/stop_filter_fi.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fi/stop_filter_fi.go new file mode 100644 index 0000000000..0445d6942c --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fi/stop_filter_fi.go @@ -0,0 +1,33 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fi + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/analysis/token/stop" + "github.com/blevesearch/bleve/v2/registry" +) + +func StopTokenFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + tokenMap, err := cache.TokenMapNamed(StopName) + if err != nil { + return nil, err + } + return stop.NewStopTokensFilter(tokenMap), nil +} + +func init() { + registry.RegisterTokenFilter(StopName, StopTokenFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fi/stop_words_fi.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fi/stop_words_fi.go new file mode 100644 index 0000000000..93824f4e2b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fi/stop_words_fi.go @@ -0,0 +1,121 @@ +package fi + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const StopName = "stop_fi" + +// this content was obtained from: +// lucene-4.7.2/analysis/common/src/resources/org/apache/lucene/analysis/snowball/ +// ` was changed to ' to allow for literal string + +var FinnishStopWords = []byte(` | From svn.tartarus.org/snowball/trunk/website/algorithms/finnish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + | + | NOTE: To use this file with StopFilterFactory, you must specify format="snowball" + +| forms of BE + +olla +olen +olet +on +olemme +olette +ovat +ole | negative form + +oli +olisi +olisit +olisin +olisimme +olisitte +olisivat +olit +olin +olimme +olitte +olivat +ollut +olleet + +en | negation +et +ei +emme +ette +eivät + +|Nom Gen Acc Part Iness Elat Illat Adess Ablat Allat Ess Trans +minä minun minut minua minussa minusta minuun minulla minulta minulle | I +sinä sinun sinut sinua sinussa sinusta sinuun sinulla sinulta sinulle | you +hän hänen hänet häntä hänessä hänestä häneen hänellä häneltä hänelle | he she +me meidän meidät meitä meissä meistä meihin meillä meiltä meille | we +te teidän teidät teitä teissä teistä teihin teillä teiltä teille | you +he heidän heidät heitä heissä heistä heihin heillä heiltä heille | they + +tämä tämän tätä tässä tästä tähän tallä tältä tälle tänä täksi | this +tuo tuon tuotä tuossa tuosta tuohon tuolla tuolta tuolle tuona tuoksi | that +se sen sitä siinä siitä siihen sillä siltä sille sinä siksi | it +nämä näiden näitä näissä näistä näihin näillä näiltä näille näinä näiksi | these +nuo noiden noita noissa noista noihin noilla noilta noille noina noiksi | those +ne niiden niitä niissä niistä niihin niillä niiltä niille niinä niiksi | they + +kuka kenen kenet ketä kenessä kenestä keneen kenellä keneltä kenelle kenenä keneksi| who +ketkä keiden ketkä keitä keissä keistä keihin keillä keiltä keille keinä keiksi | (pl) +mikä minkä minkä mitä missä mistä mihin millä miltä mille minä miksi | which what +mitkä | (pl) + +joka jonka jota jossa josta johon jolla jolta jolle jona joksi | who which +jotka joiden joita joissa joista joihin joilla joilta joille joina joiksi | (pl) + +| conjunctions + +että | that +ja | and +jos | if +koska | because +kuin | than +mutta | but +niin | so +sekä | and +sillä | for +tai | or +vaan | but +vai | or +vaikka | although + + +| prepositions + +kanssa | with +mukaan | according to +noin | about +poikki | across +yli | over, across + +| other + +kun | when +niin | so +nyt | now +itse | self + +`) + +func TokenMapConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenMap, error) { + rv := analysis.NewTokenMap() + err := rv.LoadBytes(FinnishStopWords) + return rv, err +} + +func init() { + registry.RegisterTokenMap(StopName, TokenMapConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/analyzer_fr.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/analyzer_fr.go new file mode 100644 index 0000000000..6f773a1b16 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/analyzer_fr.go @@ -0,0 +1,62 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fr + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" + + "github.com/blevesearch/bleve/v2/analysis/token/lowercase" + "github.com/blevesearch/bleve/v2/analysis/tokenizer/unicode" +) + +const AnalyzerName = "fr" + +func AnalyzerConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.Analyzer, error) { + tokenizer, err := cache.TokenizerNamed(unicode.Name) + if err != nil { + return nil, err + } + elisionFilter, err := cache.TokenFilterNamed(ElisionName) + if err != nil { + return nil, err + } + toLowerFilter, err := cache.TokenFilterNamed(lowercase.Name) + if err != nil { + return nil, err + } + stopFrFilter, err := cache.TokenFilterNamed(StopName) + if err != nil { + return nil, err + } + stemmerFrFilter, err := cache.TokenFilterNamed(LightStemmerName) + if err != nil { + return nil, err + } + rv := analysis.DefaultAnalyzer{ + Tokenizer: tokenizer, + TokenFilters: []analysis.TokenFilter{ + toLowerFilter, + elisionFilter, + stopFrFilter, + stemmerFrFilter, + }, + } + return &rv, nil +} + +func init() { + registry.RegisterAnalyzer(AnalyzerName, AnalyzerConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/articles_fr.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/articles_fr.go new file mode 100644 index 0000000000..405729b810 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/articles_fr.go @@ -0,0 +1,37 @@ +package fr + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const ArticlesName = "articles_fr" + +// this content was obtained from: +// lucene-4.7.2/analysis/common/src/resources/org/apache/lucene/analysis + +var FrenchArticles = []byte(` +l +m +t +qu +n +s +j +d +c +jusqu +quoiqu +lorsqu +puisqu +`) + +func ArticlesTokenMapConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenMap, error) { + rv := analysis.NewTokenMap() + err := rv.LoadBytes(FrenchArticles) + return rv, err +} + +func init() { + registry.RegisterTokenMap(ArticlesName, ArticlesTokenMapConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/elision_fr.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/elision_fr.go new file mode 100644 index 0000000000..739e2361f5 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/elision_fr.go @@ -0,0 +1,37 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fr + +import ( + "fmt" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/analysis/token/elision" + "github.com/blevesearch/bleve/v2/registry" +) + +const ElisionName = "elision_fr" + +func ElisionFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + articlesTokenMap, err := cache.TokenMapNamed(ArticlesName) + if err != nil { + return nil, fmt.Errorf("error building elision filter: %v", err) + } + return elision.NewElisionFilter(articlesTokenMap), nil +} + +func init() { + registry.RegisterTokenFilter(ElisionName, ElisionFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/light_stemmer_fr.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/light_stemmer_fr.go new file mode 100644 index 0000000000..d0e4076413 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/light_stemmer_fr.go @@ -0,0 +1,306 @@ +// Copyright (c) 2015 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fr + +import ( + "bytes" + "unicode" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const LightStemmerName = "stemmer_fr_light" + +type FrenchLightStemmerFilter struct { +} + +func NewFrenchLightStemmerFilter() *FrenchLightStemmerFilter { + return &FrenchLightStemmerFilter{} +} + +func (s *FrenchLightStemmerFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + runes := bytes.Runes(token.Term) + runes = stem(runes) + token.Term = analysis.BuildTermFromRunes(runes) + } + return input +} + +func stem(input []rune) []rune { + + inputLen := len(input) + + if inputLen > 5 && input[inputLen-1] == 'x' { + if input[inputLen-3] == 'a' && input[inputLen-2] == 'u' && input[inputLen-4] != 'e' { + input[inputLen-2] = 'l' + } + input = input[0 : inputLen-1] + inputLen = len(input) + } + + if inputLen > 3 && input[inputLen-1] == 'x' { + input = input[0 : inputLen-1] + inputLen = len(input) + } + + if inputLen > 3 && input[inputLen-1] == 's' { + input = input[0 : inputLen-1] + inputLen = len(input) + } + + if inputLen > 9 && analysis.RunesEndsWith(input, "issement") { + input = input[0 : inputLen-6] + inputLen = len(input) + input[inputLen-1] = 'r' + return norm(input) + } + + if inputLen > 8 && analysis.RunesEndsWith(input, "issant") { + input = input[0 : inputLen-4] + inputLen = len(input) + input[inputLen-1] = 'r' + return norm(input) + } + + if inputLen > 6 && analysis.RunesEndsWith(input, "ement") { + input = input[0 : inputLen-4] + inputLen = len(input) + if inputLen > 3 && analysis.RunesEndsWith(input, "ive") { + input = input[0 : inputLen-1] + inputLen = len(input) + input[inputLen-1] = 'f' + } + return norm(input) + } + + if inputLen > 11 && analysis.RunesEndsWith(input, "ficatrice") { + input = input[0 : inputLen-5] + inputLen = len(input) + input[inputLen-2] = 'e' + input[inputLen-1] = 'r' + return norm(input) + } + + if inputLen > 10 && analysis.RunesEndsWith(input, "ficateur") { + input = input[0 : inputLen-4] + inputLen = len(input) + input[inputLen-2] = 'e' + input[inputLen-1] = 'r' + return norm(input) + } + + if inputLen > 9 && analysis.RunesEndsWith(input, "catrice") { + input = input[0 : inputLen-3] + inputLen = len(input) + input[inputLen-4] = 'q' + input[inputLen-3] = 'u' + input[inputLen-2] = 'e' + //s[len-1] = 'r' <-- unnecessary, already 'r'. + return norm(input) + } + + if inputLen > 8 && analysis.RunesEndsWith(input, "cateur") { + input = input[0 : inputLen-2] + inputLen = len(input) + input[inputLen-4] = 'q' + input[inputLen-3] = 'u' + input[inputLen-2] = 'e' + input[inputLen-1] = 'r' + return norm(input) + } + + if inputLen > 8 && analysis.RunesEndsWith(input, "atrice") { + input = input[0 : inputLen-4] + inputLen = len(input) + input[inputLen-2] = 'e' + input[inputLen-1] = 'r' + return norm(input) + } + + if inputLen > 7 && analysis.RunesEndsWith(input, "ateur") { + input = input[0 : inputLen-3] + inputLen = len(input) + input[inputLen-2] = 'e' + input[inputLen-1] = 'r' + return norm(input) + } + + if inputLen > 6 && analysis.RunesEndsWith(input, "trice") { + input = input[0 : inputLen-1] + inputLen = len(input) + input[inputLen-3] = 'e' + input[inputLen-2] = 'u' + input[inputLen-1] = 'r' + } + + if inputLen > 5 && analysis.RunesEndsWith(input, "ième") { + return norm(input[0 : inputLen-4]) + } + + if inputLen > 7 && analysis.RunesEndsWith(input, "teuse") { + input = input[0 : inputLen-2] + inputLen = len(input) + input[inputLen-1] = 'r' + return norm(input) + } + + if inputLen > 6 && analysis.RunesEndsWith(input, "teur") { + input = input[0 : inputLen-1] + inputLen = len(input) + input[inputLen-1] = 'r' + return norm(input) + } + + if inputLen > 5 && analysis.RunesEndsWith(input, "euse") { + return norm(input[0 : inputLen-2]) + } + + if inputLen > 8 && analysis.RunesEndsWith(input, "ère") { + input = input[0 : inputLen-1] + inputLen = len(input) + input[inputLen-2] = 'e' + return norm(input) + } + + if inputLen > 7 && analysis.RunesEndsWith(input, "ive") { + input = input[0 : inputLen-1] + inputLen = len(input) + input[inputLen-1] = 'f' + return norm(input) + } + + if inputLen > 4 && + (analysis.RunesEndsWith(input, "folle") || + analysis.RunesEndsWith(input, "molle")) { + input = input[0 : inputLen-2] + inputLen = len(input) + input[inputLen-1] = 'u' + return norm(input) + } + + if inputLen > 9 && analysis.RunesEndsWith(input, "nnelle") { + return norm(input[0 : inputLen-5]) + } + + if inputLen > 9 && analysis.RunesEndsWith(input, "nnel") { + return norm(input[0 : inputLen-3]) + } + + if inputLen > 4 && analysis.RunesEndsWith(input, "ète") { + input = input[0 : inputLen-1] + inputLen = len(input) + input[inputLen-2] = 'e' + } + + if inputLen > 8 && analysis.RunesEndsWith(input, "ique") { + input = input[0 : inputLen-4] + inputLen = len(input) + } + + if inputLen > 8 && analysis.RunesEndsWith(input, "esse") { + return norm(input[0 : inputLen-3]) + } + + if inputLen > 7 && analysis.RunesEndsWith(input, "inage") { + return norm(input[0 : inputLen-3]) + } + + if inputLen > 9 && analysis.RunesEndsWith(input, "isation") { + input = input[0 : inputLen-7] + inputLen = len(input) + if inputLen > 5 && analysis.RunesEndsWith(input, "ual") { + input[inputLen-2] = 'e' + } + return norm(input) + } + + if inputLen > 9 && analysis.RunesEndsWith(input, "isateur") { + return norm(input[0 : inputLen-7]) + } + + if inputLen > 8 && analysis.RunesEndsWith(input, "ation") { + return norm(input[0 : inputLen-5]) + } + + if inputLen > 8 && analysis.RunesEndsWith(input, "ition") { + return norm(input[0 : inputLen-5]) + } + + return norm(input) + +} + +func norm(input []rune) []rune { + + if len(input) > 4 { + for i := 0; i < len(input); i++ { + switch input[i] { + case 'à', 'á', 'â': + input[i] = 'a' + case 'ô': + input[i] = 'o' + case 'è', 'é', 'ê': + input[i] = 'e' + case 'ù', 'û': + input[i] = 'u' + case 'î': + input[i] = 'i' + case 'ç': + input[i] = 'c' + } + + ch := input[0] + for i := 1; i < len(input); i++ { + if input[i] == ch && unicode.IsLetter(ch) { + input = analysis.DeleteRune(input, i) + i -= 1 + } else { + ch = input[i] + } + } + } + } + + if len(input) > 4 && analysis.RunesEndsWith(input, "ie") { + input = input[0 : len(input)-2] + } + + if len(input) > 4 { + if input[len(input)-1] == 'r' { + input = input[0 : len(input)-1] + } + if input[len(input)-1] == 'e' { + input = input[0 : len(input)-1] + } + if input[len(input)-1] == 'e' { + input = input[0 : len(input)-1] + } + if input[len(input)-1] == input[len(input)-2] && unicode.IsLetter(input[len(input)-1]) { + input = input[0 : len(input)-1] + } + } + + return input +} + +func FrenchLightStemmerFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + return NewFrenchLightStemmerFilter(), nil +} + +func init() { + registry.RegisterTokenFilter(LightStemmerName, FrenchLightStemmerFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/minimal_stemmer_fr.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/minimal_stemmer_fr.go new file mode 100644 index 0000000000..93d954bf74 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/minimal_stemmer_fr.go @@ -0,0 +1,79 @@ +// Copyright (c) 2015 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fr + +import ( + "bytes" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const MinimalStemmerName = "stemmer_fr_min" + +type FrenchMinimalStemmerFilter struct { +} + +func NewFrenchMinimalStemmerFilter() *FrenchMinimalStemmerFilter { + return &FrenchMinimalStemmerFilter{} +} + +func (s *FrenchMinimalStemmerFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + runes := bytes.Runes(token.Term) + runes = minstem(runes) + token.Term = analysis.BuildTermFromRunes(runes) + } + return input +} + +func minstem(input []rune) []rune { + + if len(input) < 6 { + return input + } + + if input[len(input)-1] == 'x' { + if input[len(input)-3] == 'a' && input[len(input)-2] == 'u' { + input[len(input)-2] = 'l' + } + return input[0 : len(input)-1] + } + + if input[len(input)-1] == 's' { + input = input[0 : len(input)-1] + } + if input[len(input)-1] == 'r' { + input = input[0 : len(input)-1] + } + if input[len(input)-1] == 'e' { + input = input[0 : len(input)-1] + } + if input[len(input)-1] == 'é' { + input = input[0 : len(input)-1] + } + if input[len(input)-1] == input[len(input)-2] { + input = input[0 : len(input)-1] + } + return input +} + +func FrenchMinimalStemmerFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + return NewFrenchMinimalStemmerFilter(), nil +} + +func init() { + registry.RegisterTokenFilter(MinimalStemmerName, FrenchMinimalStemmerFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/stemmer_fr_snowball.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/stemmer_fr_snowball.go new file mode 100644 index 0000000000..275d66e968 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/stemmer_fr_snowball.go @@ -0,0 +1,49 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fr + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" + + "github.com/blevesearch/snowballstem" + "github.com/blevesearch/snowballstem/french" +) + +const SnowballStemmerName = "stemmer_fr_snowball" + +type FrenchStemmerFilter struct { +} + +func NewFrenchStemmerFilter() *FrenchStemmerFilter { + return &FrenchStemmerFilter{} +} + +func (s *FrenchStemmerFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + env := snowballstem.NewEnv(string(token.Term)) + french.Stem(env) + token.Term = []byte(env.Current()) + } + return input +} + +func FrenchStemmerFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + return NewFrenchStemmerFilter(), nil +} + +func init() { + registry.RegisterTokenFilter(SnowballStemmerName, FrenchStemmerFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/stop_filter_fr.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/stop_filter_fr.go new file mode 100644 index 0000000000..ac7abb10ec --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/stop_filter_fr.go @@ -0,0 +1,33 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fr + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/analysis/token/stop" + "github.com/blevesearch/bleve/v2/registry" +) + +func StopTokenFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + tokenMap, err := cache.TokenMapNamed(StopName) + if err != nil { + return nil, err + } + return stop.NewStopTokensFilter(tokenMap), nil +} + +func init() { + registry.RegisterTokenFilter(StopName, StopTokenFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/stop_words_fr.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/stop_words_fr.go new file mode 100644 index 0000000000..c597575864 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/fr/stop_words_fr.go @@ -0,0 +1,210 @@ +package fr + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const StopName = "stop_fr" + +// this content was obtained from: +// lucene-4.7.2/analysis/common/src/resources/org/apache/lucene/analysis/snowball/ +// ` was changed to ' to allow for literal string + +var FrenchStopWords = []byte(` | From svn.tartarus.org/snowball/trunk/website/algorithms/french/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + | + | NOTE: To use this file with StopFilterFactory, you must specify format="snowball" + + | A French stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + +au | a + le +aux | a + les +avec | with +ce | this +ces | these +dans | with +de | of +des | de + les +du | de + le +elle | she +en | 'of them' etc +et | and +eux | them +il | he +je | I +la | the +le | the +leur | their +lui | him +ma | my (fem) +mais | but +me | me +même | same; as in moi-même (myself) etc +mes | me (pl) +moi | me +mon | my (masc) +ne | not +nos | our (pl) +notre | our +nous | we +on | one +ou | where +par | by +pas | not +pour | for +qu | que before vowel +que | that +qui | who +sa | his, her (fem) +se | oneself +ses | his (pl) +son | his, her (masc) +sur | on +ta | thy (fem) +te | thee +tes | thy (pl) +toi | thee +ton | thy (masc) +tu | thou +un | a +une | a +vos | your (pl) +votre | your +vous | you + + | single letter forms + +c | c' +d | d' +j | j' +l | l' +à | to, at +m | m' +n | n' +s | s' +t | t' +y | there + + | forms of être (not including the infinitive): +été +étée +étées +étés +étant +suis +es +est +sommes +êtes +sont +serai +seras +sera +serons +serez +seront +serais +serait +serions +seriez +seraient +étais +était +étions +étiez +étaient +fus +fut +fûmes +fûtes +furent +sois +soit +soyons +soyez +soient +fusse +fusses +fût +fussions +fussiez +fussent + + | forms of avoir (not including the infinitive): +ayant +eu +eue +eues +eus +ai +as +avons +avez +ont +aurai +auras +aura +aurons +aurez +auront +aurais +aurait +aurions +auriez +auraient +avais +avait +avions +aviez +avaient +eut +eûmes +eûtes +eurent +aie +aies +ait +ayons +ayez +aient +eusse +eusses +eût +eussions +eussiez +eussent + + | Later additions (from Jean-Christophe Deschamps) +ceci | this +cela | that +celà | that +cet | this +cette | this +ici | here +ils | they +les | the (pl) +leurs | their (pl) +quel | which +quels | which +quelle | which +quelles | which +sans | without +soi | oneself + +`) + +func TokenMapConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenMap, error) { + rv := analysis.NewTokenMap() + err := rv.LoadBytes(FrenchStopWords) + return rv, err +} + +func init() { + registry.RegisterTokenMap(StopName, TokenMapConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/analyzer_it.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/analyzer_it.go new file mode 100644 index 0000000000..256b22a2bc --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/analyzer_it.go @@ -0,0 +1,62 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package it + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" + + "github.com/blevesearch/bleve/v2/analysis/token/lowercase" + "github.com/blevesearch/bleve/v2/analysis/tokenizer/unicode" +) + +const AnalyzerName = "it" + +func AnalyzerConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.Analyzer, error) { + tokenizer, err := cache.TokenizerNamed(unicode.Name) + if err != nil { + return nil, err + } + elisionFilter, err := cache.TokenFilterNamed(ElisionName) + if err != nil { + return nil, err + } + toLowerFilter, err := cache.TokenFilterNamed(lowercase.Name) + if err != nil { + return nil, err + } + stopItFilter, err := cache.TokenFilterNamed(StopName) + if err != nil { + return nil, err + } + stemmerItFilter, err := cache.TokenFilterNamed(LightStemmerName) + if err != nil { + return nil, err + } + rv := analysis.DefaultAnalyzer{ + Tokenizer: tokenizer, + TokenFilters: []analysis.TokenFilter{ + toLowerFilter, + elisionFilter, + stopItFilter, + stemmerItFilter, + }, + } + return &rv, nil +} + +func init() { + registry.RegisterAnalyzer(AnalyzerName, AnalyzerConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/articles_it.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/articles_it.go new file mode 100644 index 0000000000..9bd0b6702d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/articles_it.go @@ -0,0 +1,45 @@ +package it + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const ArticlesName = "articles_it" + +// this content was obtained from: +// lucene-4.7.2/analysis/common/src/resources/org/apache/lucene/analysis + +var ItalianArticles = []byte(` +c +l +all +dall +dell +nell +sull +coll +pell +gl +agl +dagl +degl +negl +sugl +un +m +t +s +v +d +`) + +func ArticlesTokenMapConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenMap, error) { + rv := analysis.NewTokenMap() + err := rv.LoadBytes(ItalianArticles) + return rv, err +} + +func init() { + registry.RegisterTokenMap(ArticlesName, ArticlesTokenMapConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/elision_it.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/elision_it.go new file mode 100644 index 0000000000..9526085137 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/elision_it.go @@ -0,0 +1,37 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package it + +import ( + "fmt" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/analysis/token/elision" + "github.com/blevesearch/bleve/v2/registry" +) + +const ElisionName = "elision_it" + +func ElisionFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + articlesTokenMap, err := cache.TokenMapNamed(ArticlesName) + if err != nil { + return nil, fmt.Errorf("error building elision filter: %v", err) + } + return elision.NewElisionFilter(articlesTokenMap), nil +} + +func init() { + registry.RegisterTokenFilter(ElisionName, ElisionFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/light_stemmer_it.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/light_stemmer_it.go new file mode 100644 index 0000000000..daf63a191e --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/light_stemmer_it.go @@ -0,0 +1,101 @@ +// Copyright (c) 2015 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package it + +import ( + "bytes" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const LightStemmerName = "stemmer_it_light" + +type ItalianLightStemmerFilter struct { +} + +func NewItalianLightStemmerFilterFilter() *ItalianLightStemmerFilter { + return &ItalianLightStemmerFilter{} +} + +func (s *ItalianLightStemmerFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + runes := bytes.Runes(token.Term) + runes = stem(runes) + token.Term = analysis.BuildTermFromRunes(runes) + } + return input +} + +func stem(input []rune) []rune { + + inputLen := len(input) + + if inputLen < 6 { + return input + } + + for i := 0; i < inputLen; i++ { + switch input[i] { + case 'à', 'á', 'â', 'ä': + input[i] = 'a' + case 'ò', 'ó', 'ô', 'ö': + input[i] = 'o' + case 'è', 'é', 'ê', 'ë': + input[i] = 'e' + case 'ù', 'ú', 'û', 'ü': + input[i] = 'u' + case 'ì', 'í', 'î', 'ï': + input[i] = 'i' + } + } + + switch input[inputLen-1] { + case 'e': + if input[inputLen-2] == 'i' || input[inputLen-2] == 'h' { + return input[0 : inputLen-2] + } else { + return input[0 : inputLen-1] + } + case 'i': + if input[inputLen-2] == 'h' || input[inputLen-2] == 'i' { + return input[0 : inputLen-2] + } else { + return input[0 : inputLen-1] + } + case 'a': + if input[inputLen-2] == 'i' { + return input[0 : inputLen-2] + } else { + return input[0 : inputLen-1] + } + case 'o': + if input[inputLen-2] == 'i' { + return input[0 : inputLen-2] + } else { + return input[0 : inputLen-1] + } + } + + return input +} + +func ItalianLightStemmerFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + return NewItalianLightStemmerFilterFilter(), nil +} + +func init() { + registry.RegisterTokenFilter(LightStemmerName, ItalianLightStemmerFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/stemmer_it_snowball.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/stemmer_it_snowball.go new file mode 100644 index 0000000000..9faec48ffa --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/stemmer_it_snowball.go @@ -0,0 +1,49 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package it + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" + + "github.com/blevesearch/snowballstem" + "github.com/blevesearch/snowballstem/italian" +) + +const SnowballStemmerName = "stemmer_it_snowball" + +type ItalianStemmerFilter struct { +} + +func NewItalianStemmerFilter() *ItalianStemmerFilter { + return &ItalianStemmerFilter{} +} + +func (s *ItalianStemmerFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + env := snowballstem.NewEnv(string(token.Term)) + italian.Stem(env) + token.Term = []byte(env.Current()) + } + return input +} + +func ItalianStemmerFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + return NewItalianStemmerFilter(), nil +} + +func init() { + registry.RegisterTokenFilter(SnowballStemmerName, ItalianStemmerFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/stop_filter_it.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/stop_filter_it.go new file mode 100644 index 0000000000..79d459c18e --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/stop_filter_it.go @@ -0,0 +1,33 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package it + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/analysis/token/stop" + "github.com/blevesearch/bleve/v2/registry" +) + +func StopTokenFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + tokenMap, err := cache.TokenMapNamed(StopName) + if err != nil { + return nil, err + } + return stop.NewStopTokensFilter(tokenMap), nil +} + +func init() { + registry.RegisterTokenFilter(StopName, StopTokenFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/stop_words_it.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/stop_words_it.go new file mode 100644 index 0000000000..10b3254dc6 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/it/stop_words_it.go @@ -0,0 +1,327 @@ +package it + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const StopName = "stop_it" + +// this content was obtained from: +// lucene-4.7.2/analysis/common/src/resources/org/apache/lucene/analysis/snowball/ +// ` was changed to ' to allow for literal string + +var ItalianStopWords = []byte(` | From svn.tartarus.org/snowball/trunk/website/algorithms/italian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + | + | NOTE: To use this file with StopFilterFactory, you must specify format="snowball" + + | An Italian stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + +ad | a (to) before vowel +al | a + il +allo | a + lo +ai | a + i +agli | a + gli +all | a + l' +agl | a + gl' +alla | a + la +alle | a + le +con | with +col | con + il +coi | con + i (forms collo, cogli etc are now very rare) +da | from +dal | da + il +dallo | da + lo +dai | da + i +dagli | da + gli +dall | da + l' +dagl | da + gll' +dalla | da + la +dalle | da + le +di | of +del | di + il +dello | di + lo +dei | di + i +degli | di + gli +dell | di + l' +degl | di + gl' +della | di + la +delle | di + le +in | in +nel | in + el +nello | in + lo +nei | in + i +negli | in + gli +nell | in + l' +negl | in + gl' +nella | in + la +nelle | in + le +su | on +sul | su + il +sullo | su + lo +sui | su + i +sugli | su + gli +sull | su + l' +sugl | su + gl' +sulla | su + la +sulle | su + le +per | through, by +tra | among +contro | against +io | I +tu | thou +lui | he +lei | she +noi | we +voi | you +loro | they +mio | my +mia | +miei | +mie | +tuo | +tua | +tuoi | thy +tue | +suo | +sua | +suoi | his, her +sue | +nostro | our +nostra | +nostri | +nostre | +vostro | your +vostra | +vostri | +vostre | +mi | me +ti | thee +ci | us, there +vi | you, there +lo | him, the +la | her, the +li | them +le | them, the +gli | to him, the +ne | from there etc +il | the +un | a +uno | a +una | a +ma | but +ed | and +se | if +perché | why, because +anche | also +come | how +dov | where (as dov') +dove | where +che | who, that +chi | who +cui | whom +non | not +più | more +quale | who, that +quanto | how much +quanti | +quanta | +quante | +quello | that +quelli | +quella | +quelle | +questo | this +questi | +questa | +queste | +si | yes +tutto | all +tutti | all + + | single letter forms: + +a | at +c | as c' for ce or ci +e | and +i | the +l | as l' +o | or + + | forms of avere, to have (not including the infinitive): + +ho +hai +ha +abbiamo +avete +hanno +abbia +abbiate +abbiano +avrò +avrai +avrà +avremo +avrete +avranno +avrei +avresti +avrebbe +avremmo +avreste +avrebbero +avevo +avevi +aveva +avevamo +avevate +avevano +ebbi +avesti +ebbe +avemmo +aveste +ebbero +avessi +avesse +avessimo +avessero +avendo +avuto +avuta +avuti +avute + + | forms of essere, to be (not including the infinitive): +sono +sei +è +siamo +siete +sia +siate +siano +sarò +sarai +sarà +saremo +sarete +saranno +sarei +saresti +sarebbe +saremmo +sareste +sarebbero +ero +eri +era +eravamo +eravate +erano +fui +fosti +fu +fummo +foste +furono +fossi +fosse +fossimo +fossero +essendo + + | forms of fare, to do (not including the infinitive, fa, fat-): +faccio +fai +facciamo +fanno +faccia +facciate +facciano +farò +farai +farà +faremo +farete +faranno +farei +faresti +farebbe +faremmo +fareste +farebbero +facevo +facevi +faceva +facevamo +facevate +facevano +feci +facesti +fece +facemmo +faceste +fecero +facessi +facesse +facessimo +facessero +facendo + + | forms of stare, to be (not including the infinitive): +sto +stai +sta +stiamo +stanno +stia +stiate +stiano +starò +starai +starà +staremo +starete +staranno +starei +staresti +starebbe +staremmo +stareste +starebbero +stavo +stavi +stava +stavamo +stavate +stavano +stetti +stesti +stette +stemmo +steste +stettero +stessi +stesse +stessimo +stessero +stando +`) + +func TokenMapConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenMap, error) { + rv := analysis.NewTokenMap() + err := rv.LoadBytes(ItalianStopWords) + return rv, err +} + +func init() { + registry.RegisterTokenMap(StopName, TokenMapConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ru/analyzer_ru.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ru/analyzer_ru.go new file mode 100644 index 0000000000..3126392cc0 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ru/analyzer_ru.go @@ -0,0 +1,57 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ru + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" + + "github.com/blevesearch/bleve/v2/analysis/token/lowercase" + "github.com/blevesearch/bleve/v2/analysis/tokenizer/unicode" +) + +const AnalyzerName = "ru" + +func AnalyzerConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.Analyzer, error) { + tokenizer, err := cache.TokenizerNamed(unicode.Name) + if err != nil { + return nil, err + } + toLowerFilter, err := cache.TokenFilterNamed(lowercase.Name) + if err != nil { + return nil, err + } + stopRuFilter, err := cache.TokenFilterNamed(StopName) + if err != nil { + return nil, err + } + stemmerRuFilter, err := cache.TokenFilterNamed(SnowballStemmerName) + if err != nil { + return nil, err + } + rv := analysis.DefaultAnalyzer{ + Tokenizer: tokenizer, + TokenFilters: []analysis.TokenFilter{ + toLowerFilter, + stopRuFilter, + stemmerRuFilter, + }, + } + return &rv, nil +} + +func init() { + registry.RegisterAnalyzer(AnalyzerName, AnalyzerConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ru/stemmer_ru.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ru/stemmer_ru.go new file mode 100644 index 0000000000..6f051dc5ee --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ru/stemmer_ru.go @@ -0,0 +1,49 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ru + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" + + "github.com/blevesearch/snowballstem" + "github.com/blevesearch/snowballstem/russian" +) + +const SnowballStemmerName = "stemmer_ru_snowball" + +type RussianStemmerFilter struct { +} + +func NewRussianStemmerFilter() *RussianStemmerFilter { + return &RussianStemmerFilter{} +} + +func (s *RussianStemmerFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + env := snowballstem.NewEnv(string(token.Term)) + russian.Stem(env) + token.Term = []byte(env.Current()) + } + return input +} + +func RussianStemmerFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + return NewRussianStemmerFilter(), nil +} + +func init() { + registry.RegisterTokenFilter(SnowballStemmerName, RussianStemmerFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ru/stop_filter_ru.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ru/stop_filter_ru.go new file mode 100644 index 0000000000..e91f1fe2e8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ru/stop_filter_ru.go @@ -0,0 +1,33 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ru + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/analysis/token/stop" + "github.com/blevesearch/bleve/v2/registry" +) + +func StopTokenFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + tokenMap, err := cache.TokenMapNamed(StopName) + if err != nil { + return nil, err + } + return stop.NewStopTokensFilter(tokenMap), nil +} + +func init() { + registry.RegisterTokenFilter(StopName, StopTokenFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ru/stop_words_ru.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ru/stop_words_ru.go new file mode 100644 index 0000000000..cca2f248c6 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/lang/ru/stop_words_ru.go @@ -0,0 +1,267 @@ +package ru + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const StopName = "stop_ru" + +// this content was obtained from: +// lucene-4.7.2/analysis/common/src/resources/org/apache/lucene/analysis/snowball/ +// ` was changed to ' to allow for literal string + +var RussianStopWords = []byte(` | From svn.tartarus.org/snowball/trunk/website/algorithms/russian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + | + | NOTE: To use this file with StopFilterFactory, you must specify format="snowball" + + | a russian stop word list. comments begin with vertical bar. each stop + | word is at the start of a line. + + | this is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + | letter 'ё' is translated to 'е'. + +и | and +в | in/into +во | alternative form +не | not +что | what/that +он | he +на | on/onto +я | i +с | from +со | alternative form +как | how +а | milder form of 'no' (but) +то | conjunction and form of 'that' +все | all +она | she +так | so, thus +его | him +но | but +да | yes/and +ты | thou +к | towards, by +у | around, chez +же | intensifier particle +вы | you +за | beyond, behind +бы | conditional/subj. particle +по | up to, along +только | only +ее | her +мне | to me +было | it was +вот | here is/are, particle +от | away from +меня | me +еще | still, yet, more +нет | no, there isnt/arent +о | about +из | out of +ему | to him +теперь | now +когда | when +даже | even +ну | so, well +вдруг | suddenly +ли | interrogative particle +если | if +уже | already, but homonym of 'narrower' +или | or +ни | neither +быть | to be +был | he was +него | prepositional form of его +до | up to +вас | you accusative +нибудь | indef. suffix preceded by hyphen +опять | again +уж | already, but homonym of 'adder' +вам | to you +сказал | he said +ведь | particle 'after all' +там | there +потом | then +себя | oneself +ничего | nothing +ей | to her +может | usually with 'быть' as 'maybe' +они | they +тут | here +где | where +есть | there is/are +надо | got to, must +ней | prepositional form of ей +для | for +мы | we +тебя | thee +их | them, their +чем | than +была | she was +сам | self +чтоб | in order to +без | without +будто | as if +человек | man, person, one +чего | genitive form of 'what' +раз | once +тоже | also +себе | to oneself +под | beneath +жизнь | life +будет | will be +ж | short form of intensifer particle 'же' +тогда | then +кто | who +этот | this +говорил | was saying +того | genitive form of 'that' +потому | for that reason +этого | genitive form of 'this' +какой | which +совсем | altogether +ним | prepositional form of 'его', 'они' +здесь | here +этом | prepositional form of 'этот' +один | one +почти | almost +мой | my +тем | instrumental/dative plural of 'тот', 'то' +чтобы | full form of 'in order that' +нее | her (acc.) +кажется | it seems +сейчас | now +были | they were +куда | where to +зачем | why +сказать | to say +всех | all (acc., gen. preposn. plural) +никогда | never +сегодня | today +можно | possible, one can +при | by +наконец | finally +два | two +об | alternative form of 'о', about +другой | another +хоть | even +после | after +над | above +больше | more +тот | that one (masc.) +через | across, in +эти | these +нас | us +про | about +всего | in all, only, of all +них | prepositional form of 'они' (they) +какая | which, feminine +много | lots +разве | interrogative particle +сказала | she said +три | three +эту | this, acc. fem. sing. +моя | my, feminine +впрочем | moreover, besides +хорошо | good +свою | ones own, acc. fem. sing. +этой | oblique form of 'эта', fem. 'this' +перед | in front of +иногда | sometimes +лучше | better +чуть | a little +том | preposn. form of 'that one' +нельзя | one must not +такой | such a one +им | to them +более | more +всегда | always +конечно | of course +всю | acc. fem. sing of 'all' +между | between + + + | b: some paradigms + | + | personal pronouns + | + | я меня мне мной [мною] + | ты тебя тебе тобой [тобою] + | он его ему им [него, нему, ним] + | она ее эи ею [нее, нэи, нею] + | оно его ему им [него, нему, ним] + | + | мы нас нам нами + | вы вас вам вами + | они их им ими [них, ним, ними] + | + | себя себе собой [собою] + | + | demonstrative pronouns: этот (this), тот (that) + | + | этот эта это эти + | этого эты это эти + | этого этой этого этих + | этому этой этому этим + | этим этой этим [этою] этими + | этом этой этом этих + | + | тот та то те + | того ту то те + | того той того тех + | тому той тому тем + | тем той тем [тою] теми + | том той том тех + | + | determinative pronouns + | + | (a) весь (all) + | + | весь вся все все + | всего всю все все + | всего всей всего всех + | всему всей всему всем + | всем всей всем [всею] всеми + | всем всей всем всех + | + | (b) сам (himself etc) + | + | сам сама само сами + | самого саму само самих + | самого самой самого самих + | самому самой самому самим + | самим самой самим [самою] самими + | самом самой самом самих + | + | stems of verbs 'to be', 'to have', 'to do' and modal + | + | быть бы буд быв есть суть + | име + | дел + | мог мож мочь + | уме + | хоч хот + | долж + | можн + | нужн + | нельзя + +`) + +func TokenMapConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenMap, error) { + rv := analysis.NewTokenMap() + err := rv.LoadBytes(RussianStopWords) + return rv, err +} + +func init() { + registry.RegisterTokenMap(StopName, TokenMapConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/test_words.txt b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/test_words.txt new file mode 100644 index 0000000000..b86e254bb9 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/test_words.txt @@ -0,0 +1,7 @@ +# full line comment +marty +steve # trailing comment +| different format of comment +dustin +siri | different style trailing comment +multiple words with different whitespace \ No newline at end of file diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/elision/elision.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/elision/elision.go new file mode 100644 index 0000000000..909d24121c --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/elision/elision.go @@ -0,0 +1,74 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package elision + +import ( + "fmt" + "unicode/utf8" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const Name = "elision" + +const RightSingleQuotationMark = '’' +const Apostrophe = '\'' + +type ElisionFilter struct { + articles analysis.TokenMap +} + +func NewElisionFilter(articles analysis.TokenMap) *ElisionFilter { + return &ElisionFilter{ + articles: articles, + } +} + +func (s *ElisionFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + term := token.Term + for i := 0; i < len(term); { + r, size := utf8.DecodeRune(term[i:]) + if r == Apostrophe || r == RightSingleQuotationMark { + // see if the prefix matches one of the articles + prefix := term[0:i] + _, articleMatch := s.articles[string(prefix)] + if articleMatch { + token.Term = term[i+size:] + break + } + } + i += size + } + } + return input +} + +func ElisionFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + articlesTokenMapName, ok := config["articles_token_map"].(string) + if !ok { + return nil, fmt.Errorf("must specify articles_token_map") + } + articlesTokenMap, err := cache.TokenMapNamed(articlesTokenMapName) + if err != nil { + return nil, fmt.Errorf("error building elision filter: %v", err) + } + return NewElisionFilter(articlesTokenMap), nil +} + +func init() { + registry.RegisterTokenFilter(Name, ElisionFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/lowercase/lowercase.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/lowercase/lowercase.go new file mode 100644 index 0000000000..a1b6dbd057 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/lowercase/lowercase.go @@ -0,0 +1,105 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package lowercase implements a TokenFilter which converts +// tokens to lower case according to unicode rules. +package lowercase + +import ( + "bytes" + "unicode" + "unicode/utf8" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +// Name is the name used to register LowerCaseFilter in the bleve registry +const Name = "to_lower" + +type LowerCaseFilter struct { +} + +func NewLowerCaseFilter() *LowerCaseFilter { + return &LowerCaseFilter{} +} + +func (f *LowerCaseFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + token.Term = toLowerDeferredCopy(token.Term) + } + return input +} + +func LowerCaseFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + return NewLowerCaseFilter(), nil +} + +func init() { + registry.RegisterTokenFilter(Name, LowerCaseFilterConstructor) +} + +// toLowerDeferredCopy will function exactly like +// bytes.ToLower() only it will reuse (overwrite) +// the original byte array when possible +// NOTE: because its possible that the lower-case +// form of a rune has a different utf-8 encoded +// length, in these cases a new byte array is allocated +func toLowerDeferredCopy(s []byte) []byte { + j := 0 + for i := 0; i < len(s); { + wid := 1 + r := rune(s[i]) + if r >= utf8.RuneSelf { + r, wid = utf8.DecodeRune(s[i:]) + } + + l := unicode.ToLower(r) + + // If the rune is already lowercased, just move to the + // next rune. + if l == r { + i += wid + j += wid + continue + } + + // Handles the Unicode edge-case where the last + // rune in a word on the greek Σ needs to be converted + // differently. + if l == 'σ' && i+2 == len(s) { + l = 'ς' + } + + lwid := utf8.RuneLen(l) + if lwid > wid { + // utf-8 encoded replacement is wider + // for now, punt and defer + // to bytes.ToLower() for the remainder + // only known to happen with chars + // Rune Ⱥ(570) width 2 - Lower ⱥ(11365) width 3 + // Rune Ⱦ(574) width 2 - Lower ⱦ(11366) width 3 + rest := bytes.ToLower(s[i:]) + rv := make([]byte, j+len(rest)) + copy(rv[:j], s[:j]) + copy(rv[j:], rest) + return rv + } else { + utf8.EncodeRune(s[j:], l) + } + i += wid + j += lwid + } + return s[:j] +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/porter/porter.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/porter/porter.go new file mode 100644 index 0000000000..95af0fa72b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/porter/porter.go @@ -0,0 +1,53 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package porter + +import ( + "bytes" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" + + "github.com/blevesearch/go-porterstemmer" +) + +const Name = "stemmer_porter" + +type PorterStemmer struct { +} + +func NewPorterStemmer() *PorterStemmer { + return &PorterStemmer{} +} + +func (s *PorterStemmer) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + // if it is not a protected keyword, stem it + if !token.KeyWord { + termRunes := bytes.Runes(token.Term) + stemmedRunes := porterstemmer.StemWithoutLowerCasing(termRunes) + token.Term = analysis.BuildTermFromRunes(stemmedRunes) + } + } + return input +} + +func PorterStemmerConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + return NewPorterStemmer(), nil +} + +func init() { + registry.RegisterTokenFilter(Name, PorterStemmerConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/stop/stop.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/stop/stop.go new file mode 100644 index 0000000000..bf4b98db18 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/stop/stop.go @@ -0,0 +1,70 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package stop implements a TokenFilter removing tokens found in +// a TokenMap. +// +// It constructor takes the following arguments: +// +// "stop_token_map" (string): the name of the token map identifying tokens to +// remove. +package stop + +import ( + "fmt" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const Name = "stop_tokens" + +type StopTokensFilter struct { + stopTokens analysis.TokenMap +} + +func NewStopTokensFilter(stopTokens analysis.TokenMap) *StopTokensFilter { + return &StopTokensFilter{ + stopTokens: stopTokens, + } +} + +func (f *StopTokensFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + j := 0 + for _, token := range input { + _, isStopToken := f.stopTokens[string(token.Term)] + if !isStopToken { + input[j] = token + j++ + } + } + + return input[:j] +} + +func StopTokensFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + stopTokenMapName, ok := config["stop_token_map"].(string) + if !ok { + return nil, fmt.Errorf("must specify stop_token_map") + } + stopTokenMap, err := cache.TokenMapNamed(stopTokenMapName) + if err != nil { + return nil, fmt.Errorf("error building stop words filter: %v", err) + } + return NewStopTokensFilter(stopTokenMap), nil +} + +func init() { + registry.RegisterTokenFilter(Name, StopTokensFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/unicodenorm/unicodenorm.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/unicodenorm/unicodenorm.go new file mode 100644 index 0000000000..01b191bc22 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/token/unicodenorm/unicodenorm.go @@ -0,0 +1,79 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package unicodenorm + +import ( + "fmt" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" + "golang.org/x/text/unicode/norm" +) + +const Name = "normalize_unicode" + +const NFC = "nfc" +const NFD = "nfd" +const NFKC = "nfkc" +const NFKD = "nfkd" + +var forms = map[string]norm.Form{ + NFC: norm.NFC, + NFD: norm.NFD, + NFKC: norm.NFKC, + NFKD: norm.NFKD, +} + +type UnicodeNormalizeFilter struct { + form norm.Form +} + +func NewUnicodeNormalizeFilter(formName string) (*UnicodeNormalizeFilter, error) { + form, ok := forms[formName] + if !ok { + return nil, fmt.Errorf("no form named %s", formName) + } + return &UnicodeNormalizeFilter{ + form: form, + }, nil +} + +func MustNewUnicodeNormalizeFilter(formName string) *UnicodeNormalizeFilter { + filter, err := NewUnicodeNormalizeFilter(formName) + if err != nil { + panic(err) + } + return filter +} + +func (s *UnicodeNormalizeFilter) Filter(input analysis.TokenStream) analysis.TokenStream { + for _, token := range input { + token.Term = s.form.Bytes(token.Term) + } + return input +} + +func UnicodeNormalizeFilterConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) { + formVal, ok := config["form"].(string) + if !ok { + return nil, fmt.Errorf("must specify form") + } + form := formVal + return NewUnicodeNormalizeFilter(form) +} + +func init() { + registry.RegisterTokenFilter(Name, UnicodeNormalizeFilterConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/tokenizer/single/single.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/tokenizer/single/single.go new file mode 100644 index 0000000000..a3eac78995 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/tokenizer/single/single.go @@ -0,0 +1,49 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package single + +import ( + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const Name = "single" + +type SingleTokenTokenizer struct { +} + +func NewSingleTokenTokenizer() *SingleTokenTokenizer { + return &SingleTokenTokenizer{} +} + +func (t *SingleTokenTokenizer) Tokenize(input []byte) analysis.TokenStream { + return analysis.TokenStream{ + &analysis.Token{ + Term: input, + Position: 1, + Start: 0, + End: len(input), + Type: analysis.AlphaNumeric, + }, + } +} + +func SingleTokenTokenizerConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.Tokenizer, error) { + return NewSingleTokenTokenizer(), nil +} + +func init() { + registry.RegisterTokenizer(Name, SingleTokenTokenizerConstructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/tokenizer/unicode/unicode.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/tokenizer/unicode/unicode.go new file mode 100644 index 0000000000..ca3cfe76c4 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/tokenizer/unicode/unicode.go @@ -0,0 +1,131 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package unicode + +import ( + "github.com/blevesearch/segment" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/registry" +) + +const Name = "unicode" + +type UnicodeTokenizer struct { +} + +func NewUnicodeTokenizer() *UnicodeTokenizer { + return &UnicodeTokenizer{} +} + +func (rt *UnicodeTokenizer) Tokenize(input []byte) analysis.TokenStream { + rvx := make([]analysis.TokenStream, 0, 10) // When rv gets full, append to rvx. + rv := make(analysis.TokenStream, 0, 1) + + ta := []analysis.Token(nil) + taNext := 0 + + segmenter := segment.NewWordSegmenterDirect(input) + start := 0 + pos := 1 + + guessRemaining := func(end int) int { + avgSegmentLen := end / (len(rv) + 1) + if avgSegmentLen < 1 { + avgSegmentLen = 1 + } + + remainingLen := len(input) - end + + return remainingLen / avgSegmentLen + } + + for segmenter.Segment() { + segmentBytes := segmenter.Bytes() + end := start + len(segmentBytes) + if segmenter.Type() != segment.None { + if taNext >= len(ta) { + remainingSegments := guessRemaining(end) + if remainingSegments > 1000 { + remainingSegments = 1000 + } + if remainingSegments < 1 { + remainingSegments = 1 + } + + ta = make([]analysis.Token, remainingSegments) + taNext = 0 + } + + token := &ta[taNext] + taNext++ + + token.Term = segmentBytes + token.Start = start + token.End = end + token.Position = pos + token.Type = convertType(segmenter.Type()) + + if len(rv) >= cap(rv) { // When rv is full, save it into rvx. + rvx = append(rvx, rv) + + rvCap := cap(rv) * 2 + if rvCap > 256 { + rvCap = 256 + } + + rv = make(analysis.TokenStream, 0, rvCap) // Next rv cap is bigger. + } + + rv = append(rv, token) + pos++ + } + start = end + } + + if len(rvx) > 0 { + n := len(rv) + for _, r := range rvx { + n += len(r) + } + rall := make(analysis.TokenStream, 0, n) + for _, r := range rvx { + rall = append(rall, r...) + } + return append(rall, rv...) + } + + return rv +} + +func UnicodeTokenizerConstructor(config map[string]interface{}, cache *registry.Cache) (analysis.Tokenizer, error) { + return NewUnicodeTokenizer(), nil +} + +func init() { + registry.RegisterTokenizer(Name, UnicodeTokenizerConstructor) +} + +func convertType(segmentWordType int) analysis.TokenType { + switch segmentWordType { + case segment.Ideo: + return analysis.Ideographic + case segment.Kana: + return analysis.Ideographic + case segment.Number: + return analysis.Numeric + } + return analysis.AlphaNumeric +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/tokenmap.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/tokenmap.go new file mode 100644 index 0000000000..aa4ea31587 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/tokenmap.go @@ -0,0 +1,76 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package analysis + +import ( + "bufio" + "bytes" + "io" + "os" + "strings" +) + +type TokenMap map[string]bool + +func NewTokenMap() TokenMap { + return make(TokenMap, 0) +} + +// LoadFile reads in a list of tokens from a text file, +// one per line. +// Comments are supported using `#` or `|` +func (t TokenMap) LoadFile(filename string) error { + data, err := os.ReadFile(filename) + if err != nil { + return err + } + return t.LoadBytes(data) +} + +// LoadBytes reads in a list of tokens from memory, +// one per line. +// Comments are supported using `#` or `|` +func (t TokenMap) LoadBytes(data []byte) error { + bytesReader := bytes.NewReader(data) + bufioReader := bufio.NewReader(bytesReader) + line, err := bufioReader.ReadString('\n') + for err == nil { + t.LoadLine(line) + line, err = bufioReader.ReadString('\n') + } + // if the err was EOF we still need to process the last value + if err == io.EOF { + t.LoadLine(line) + return nil + } + return err +} + +func (t TokenMap) LoadLine(line string) { + // find the start of a comment, if any + startComment := strings.IndexAny(line, "#|") + if startComment >= 0 { + line = line[:startComment] + } + + tokens := strings.Fields(line) + for _, token := range tokens { + t.AddToken(token) + } +} + +func (t TokenMap) AddToken(token string) { + t[token] = true +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/type.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/type.go new file mode 100644 index 0000000000..9e7bfa16d2 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/type.go @@ -0,0 +1,108 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package analysis + +import ( + "fmt" + "time" +) + +type CharFilter interface { + Filter([]byte) []byte +} + +type TokenType int + +const ( + AlphaNumeric TokenType = iota + Ideographic + Numeric + DateTime + Shingle + Single + Double + Boolean + IP +) + +// Token represents one occurrence of a term at a particular location in a +// field. +type Token struct { + // Start specifies the byte offset of the beginning of the term in the + // field. + Start int `json:"start"` + + // End specifies the byte offset of the end of the term in the field. + End int `json:"end"` + Term []byte `json:"term"` + + // Position specifies the 1-based index of the token in the sequence of + // occurrences of its term in the field. + Position int `json:"position"` + Type TokenType `json:"type"` + KeyWord bool `json:"keyword"` +} + +func (t *Token) String() string { + return fmt.Sprintf("Start: %d End: %d Position: %d Token: %s Type: %d", t.Start, t.End, t.Position, string(t.Term), t.Type) +} + +type TokenStream []*Token + +// A Tokenizer splits an input string into tokens, the usual behaviour being to +// map words to tokens. +type Tokenizer interface { + Tokenize([]byte) TokenStream +} + +// A TokenFilter adds, transforms or removes tokens from a token stream. +type TokenFilter interface { + Filter(TokenStream) TokenStream +} + +type Analyzer interface { + Analyze([]byte) TokenStream +} + +type DefaultAnalyzer struct { + CharFilters []CharFilter + Tokenizer Tokenizer + TokenFilters []TokenFilter +} + +func (a *DefaultAnalyzer) Analyze(input []byte) TokenStream { + if a.CharFilters != nil { + for _, cf := range a.CharFilters { + input = cf.Filter(input) + } + } + tokens := a.Tokenizer.Tokenize(input) + if a.TokenFilters != nil { + for _, tf := range a.TokenFilters { + tokens = tf.Filter(tokens) + } + } + return tokens +} + +var ErrInvalidDateTime = fmt.Errorf("unable to parse datetime with any of the layouts") + +type DateTimeParser interface { + ParseDateTime(string) (time.Time, error) +} + +type ByteArrayConverter interface { + Convert([]byte) (interface{}, error) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/analysis/util.go b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/util.go new file mode 100644 index 0000000000..8e4348a1ac --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/analysis/util.go @@ -0,0 +1,92 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package analysis + +import ( + "bytes" + "unicode/utf8" +) + +func DeleteRune(in []rune, pos int) []rune { + if pos >= len(in) { + return in + } + copy(in[pos:], in[pos+1:]) + return in[:len(in)-1] +} + +func InsertRune(in []rune, pos int, r rune) []rune { + // create a new slice 1 rune larger + rv := make([]rune, len(in)+1) + // copy the characters before the insert pos + copy(rv[0:pos], in[0:pos]) + // set the inserted rune + rv[pos] = r + // copy the characters after the insert pos + copy(rv[pos+1:], in[pos:]) + return rv +} + +// BuildTermFromRunesOptimistic will build a term from the provided runes +// AND optimistically attempt to encode into the provided buffer +// if at any point it appears the buffer is too small, a new buffer is +// allocated and that is used instead +// this should be used in cases where frequently the new term is the same +// length or shorter than the original term (in number of bytes) +func BuildTermFromRunesOptimistic(buf []byte, runes []rune) []byte { + rv := buf + used := 0 + for _, r := range runes { + nextLen := utf8.RuneLen(r) + if used+nextLen > len(rv) { + // alloc new buf + buf = make([]byte, len(runes)*utf8.UTFMax) + // copy work we've already done + copy(buf, rv[:used]) + rv = buf + } + written := utf8.EncodeRune(rv[used:], r) + used += written + } + return rv[:used] +} + +func BuildTermFromRunes(runes []rune) []byte { + return BuildTermFromRunesOptimistic(make([]byte, len(runes)*utf8.UTFMax), runes) +} + +func TruncateRunes(input []byte, num int) []byte { + runes := bytes.Runes(input) + runes = runes[:len(runes)-num] + out := BuildTermFromRunes(runes) + return out +} + +func RunesEndsWith(input []rune, suffix string) bool { + inputLen := len(input) + suffixRunes := []rune(suffix) + suffixLen := len(suffixRunes) + if suffixLen > inputLen { + return false + } + + for i := suffixLen - 1; i >= 0; i-- { + if input[inputLen-(suffixLen-i)] != suffixRunes[i] { + return false + } + } + + return true +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/builder.go b/backend/vendor/github.com/blevesearch/bleve/v2/builder.go new file mode 100644 index 0000000000..dbb7e3ed44 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/builder.go @@ -0,0 +1,94 @@ +// Copyright (c) 2019 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bleve + +import ( + "encoding/json" + "fmt" + + "github.com/blevesearch/bleve/v2/document" + "github.com/blevesearch/bleve/v2/index/scorch" + "github.com/blevesearch/bleve/v2/mapping" + index "github.com/blevesearch/bleve_index_api" +) + +type builderImpl struct { + b index.IndexBuilder + m mapping.IndexMapping +} + +func (b *builderImpl) Index(id string, data interface{}) error { + if id == "" { + return ErrorEmptyID + } + + doc := document.NewDocument(id) + err := b.m.MapDocument(doc, data) + if err != nil { + return err + } + err = b.b.Index(doc) + return err +} + +func (b *builderImpl) Close() error { + return b.b.Close() +} + +func newBuilder(path string, mapping mapping.IndexMapping, config map[string]interface{}) (Builder, error) { + if path == "" { + return nil, fmt.Errorf("builder requires path") + } + + err := mapping.Validate() + if err != nil { + return nil, err + } + + if config == nil { + config = map[string]interface{}{} + } + + // the builder does not have an API to interact with internal storage + // however we can pass k/v pairs through the config + mappingBytes, err := json.Marshal(mapping) + if err != nil { + return nil, err + } + config["internal"] = map[string][]byte{ + string(mappingInternalKey): mappingBytes, + } + + // do not use real config, as these are options for the builder, + // not the resulting index + meta := newIndexMeta(scorch.Name, scorch.Name, map[string]interface{}{}) + err = meta.Save(path) + if err != nil { + return nil, err + } + + config["path"] = indexStorePath(path) + + b, err := scorch.NewBuilder(config) + if err != nil { + return nil, err + } + rv := &builderImpl{ + b: b, + m: mapping, + } + + return rv, nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/config.go b/backend/vendor/github.com/blevesearch/bleve/v2/config.go new file mode 100644 index 0000000000..0622b359db --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/config.go @@ -0,0 +1,95 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bleve + +import ( + "expvar" + "io/ioutil" + "log" + "time" + + "github.com/blevesearch/bleve/v2/index/scorch" + "github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap" + "github.com/blevesearch/bleve/v2/registry" + "github.com/blevesearch/bleve/v2/search/highlight/highlighter/html" + index "github.com/blevesearch/bleve_index_api" +) + +var bleveExpVar = expvar.NewMap("bleve") + +type configuration struct { + Cache *registry.Cache + DefaultHighlighter string + DefaultKVStore string + DefaultMemKVStore string + DefaultIndexType string + SlowSearchLogThreshold time.Duration + analysisQueue *index.AnalysisQueue +} + +func (c *configuration) SetAnalysisQueueSize(n int) { + if c.analysisQueue != nil { + c.analysisQueue.Close() + } + c.analysisQueue = index.NewAnalysisQueue(n) +} + +func (c *configuration) Shutdown() { + c.SetAnalysisQueueSize(0) +} + +func newConfiguration() *configuration { + return &configuration{ + Cache: registry.NewCache(), + analysisQueue: index.NewAnalysisQueue(4), + } +} + +// Config contains library level configuration +var Config *configuration + +func init() { + bootStart := time.Now() + + // build the default configuration + Config = newConfiguration() + + // set the default highlighter + Config.DefaultHighlighter = html.Name + + // default kv store + Config.DefaultKVStore = "" + + // default mem only kv store + Config.DefaultMemKVStore = gtreap.Name + + // default index + Config.DefaultIndexType = scorch.Name + + bootDuration := time.Since(bootStart) + bleveExpVar.Add("bootDuration", int64(bootDuration)) + indexStats = NewIndexStats() + bleveExpVar.Set("indexes", indexStats) + + initDisk() +} + +var logger = log.New(ioutil.Discard, "bleve", log.LstdFlags) + +// SetLog sets the logger used for logging +// by default log messages are sent to ioutil.Discard +func SetLog(l *log.Logger) { + logger = l +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/config_app.go b/backend/vendor/github.com/blevesearch/bleve/v2/config_app.go new file mode 100644 index 0000000000..60b1db3e89 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/config_app.go @@ -0,0 +1,24 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build appengine || appenginevm +// +build appengine appenginevm + +package bleve + +// in the appengine environment we cannot support disk based indexes +// so we do no extra configuration in this method +func initDisk() { + +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/config_disk.go b/backend/vendor/github.com/blevesearch/bleve/v2/config_disk.go new file mode 100644 index 0000000000..a9ab1e41c9 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/config_disk.go @@ -0,0 +1,26 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !appengine && !appenginevm +// +build !appengine,!appenginevm + +package bleve + +import "github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb" + +// in normal environments we configure boltdb as the default storage +func initDisk() { + // default kv store + Config.DefaultKVStore = boltdb.Name +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/doc.go b/backend/vendor/github.com/blevesearch/bleve/v2/doc.go new file mode 100644 index 0000000000..b9580cbe8d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/doc.go @@ -0,0 +1,37 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* +Package bleve is a library for indexing and searching text. + +Example Opening New Index, Indexing Data + + message := struct{ + Id: "example" + From: "marty.schoch@gmail.com", + Body: "bleve indexing is easy", + } + + mapping := bleve.NewIndexMapping() + index, _ := bleve.New("example.bleve", mapping) + index.Index(message.Id, message) + +Example Opening Existing Index, Searching Data + + index, _ := bleve.Open("example.bleve") + query := bleve.NewQueryStringQuery("bleve") + searchRequest := bleve.NewSearchRequest(query) + searchResult, _ := index.Search(searchRequest) +*/ +package bleve diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/document/document.go b/backend/vendor/github.com/blevesearch/bleve/v2/document/document.go new file mode 100644 index 0000000000..54fd6d442b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/document/document.go @@ -0,0 +1,135 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package document + +import ( + "fmt" + "reflect" + + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeDocument int + +func init() { + var d Document + reflectStaticSizeDocument = int(reflect.TypeOf(d).Size()) +} + +type Document struct { + id string `json:"id"` + Fields []Field `json:"fields"` + CompositeFields []*CompositeField + StoredFieldsSize uint64 +} + +func (d *Document) StoredFieldsBytes() uint64 { + return d.StoredFieldsSize +} + +func NewDocument(id string) *Document { + return &Document{ + id: id, + Fields: make([]Field, 0), + CompositeFields: make([]*CompositeField, 0), + } +} + +func (d *Document) Size() int { + sizeInBytes := reflectStaticSizeDocument + size.SizeOfPtr + + len(d.id) + + for _, entry := range d.Fields { + sizeInBytes += entry.Size() + } + + for _, entry := range d.CompositeFields { + sizeInBytes += entry.Size() + } + + return sizeInBytes +} + +func (d *Document) AddField(f Field) *Document { + switch f := f.(type) { + case *CompositeField: + d.CompositeFields = append(d.CompositeFields, f) + default: + d.Fields = append(d.Fields, f) + } + return d +} + +func (d *Document) GoString() string { + fields := "" + for i, field := range d.Fields { + if i != 0 { + fields += ", " + } + fields += fmt.Sprintf("%#v", field) + } + compositeFields := "" + for i, field := range d.CompositeFields { + if i != 0 { + compositeFields += ", " + } + compositeFields += fmt.Sprintf("%#v", field) + } + return fmt.Sprintf("&document.Document{ID:%s, Fields: %s, CompositeFields: %s}", d.ID(), fields, compositeFields) +} + +func (d *Document) NumPlainTextBytes() uint64 { + rv := uint64(0) + for _, field := range d.Fields { + rv += field.NumPlainTextBytes() + } + for _, compositeField := range d.CompositeFields { + for _, field := range d.Fields { + if compositeField.includesField(field.Name()) { + rv += field.NumPlainTextBytes() + } + } + } + return rv +} + +func (d *Document) ID() string { + return d.id +} + +func (d *Document) SetID(id string) { + d.id = id +} + +func (d *Document) AddIDField() { + d.AddField(NewTextFieldCustom("_id", nil, []byte(d.ID()), index.IndexField|index.StoreField, nil)) +} + +func (d *Document) VisitFields(visitor index.FieldVisitor) { + for _, f := range d.Fields { + visitor(f) + } +} + +func (d *Document) VisitComposite(visitor index.CompositeFieldVisitor) { + for _, f := range d.CompositeFields { + visitor(f) + } +} + +func (d *Document) HasComposite() bool { + return len(d.CompositeFields) > 0 +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/document/field.go b/backend/vendor/github.com/blevesearch/bleve/v2/document/field.go new file mode 100644 index 0000000000..eb104e2dfe --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/document/field.go @@ -0,0 +1,45 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package document + +import ( + index "github.com/blevesearch/bleve_index_api" +) + +type Field interface { + // Name returns the path of the field from the root DocumentMapping. + // A root field path is "field", a subdocument field is "parent.field". + Name() string + // ArrayPositions returns the intermediate document and field indices + // required to resolve the field value in the document. For example, if the + // field path is "doc1.doc2.field" where doc1 and doc2 are slices or + // arrays, ArrayPositions returns 2 indices used to resolve "doc2" value in + // "doc1", then "field" in "doc2". + ArrayPositions() []uint64 + Options() index.FieldIndexingOptions + Analyze() + Value() []byte + + // NumPlainTextBytes should return the number of plain text bytes + // that this field represents - this is a common metric for tracking + // the rate of indexing + NumPlainTextBytes() uint64 + + Size() int + + EncodedFieldType() byte + AnalyzedLength() int + AnalyzedTokenFrequencies() index.TokenFrequencies +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/document/field_boolean.go b/backend/vendor/github.com/blevesearch/bleve/v2/document/field_boolean.go new file mode 100644 index 0000000000..fdf3cc0e53 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/document/field_boolean.go @@ -0,0 +1,137 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package document + +import ( + "fmt" + "reflect" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeBooleanField int + +func init() { + var f BooleanField + reflectStaticSizeBooleanField = int(reflect.TypeOf(f).Size()) +} + +const DefaultBooleanIndexingOptions = index.StoreField | index.IndexField | index.DocValues + +type BooleanField struct { + name string + arrayPositions []uint64 + options index.FieldIndexingOptions + value []byte + numPlainTextBytes uint64 + length int + frequencies index.TokenFrequencies +} + +func (b *BooleanField) Size() int { + return reflectStaticSizeBooleanField + size.SizeOfPtr + + len(b.name) + + len(b.arrayPositions)*size.SizeOfUint64 + + len(b.value) +} + +func (b *BooleanField) Name() string { + return b.name +} + +func (b *BooleanField) ArrayPositions() []uint64 { + return b.arrayPositions +} + +func (b *BooleanField) Options() index.FieldIndexingOptions { + return b.options +} + +func (b *BooleanField) Analyze() { + tokens := make(analysis.TokenStream, 0) + tokens = append(tokens, &analysis.Token{ + Start: 0, + End: len(b.value), + Term: b.value, + Position: 1, + Type: analysis.Boolean, + }) + + b.length = len(tokens) + b.frequencies = analysis.TokenFrequency(tokens, b.arrayPositions, b.options) +} + +func (b *BooleanField) Value() []byte { + return b.value +} + +func (b *BooleanField) Boolean() (bool, error) { + if len(b.value) == 1 { + return b.value[0] == 'T', nil + } + return false, fmt.Errorf("boolean field has %d bytes", len(b.value)) +} + +func (b *BooleanField) GoString() string { + return fmt.Sprintf("&document.BooleanField{Name:%s, Options: %s, Value: %s}", b.name, b.options, b.value) +} + +func (b *BooleanField) NumPlainTextBytes() uint64 { + return b.numPlainTextBytes +} + +func (b *BooleanField) EncodedFieldType() byte { + return 'b' +} + +func (b *BooleanField) AnalyzedLength() int { + return b.length +} + +func (b *BooleanField) AnalyzedTokenFrequencies() index.TokenFrequencies { + return b.frequencies +} + +func NewBooleanFieldFromBytes(name string, arrayPositions []uint64, value []byte) *BooleanField { + return &BooleanField{ + name: name, + arrayPositions: arrayPositions, + value: value, + options: DefaultNumericIndexingOptions, + numPlainTextBytes: uint64(len(value)), + } +} + +func NewBooleanField(name string, arrayPositions []uint64, b bool) *BooleanField { + return NewBooleanFieldWithIndexingOptions(name, arrayPositions, b, DefaultNumericIndexingOptions) +} + +func NewBooleanFieldWithIndexingOptions(name string, arrayPositions []uint64, b bool, options index.FieldIndexingOptions) *BooleanField { + numPlainTextBytes := 5 + v := []byte("F") + if b { + numPlainTextBytes = 4 + v = []byte("T") + } + return &BooleanField{ + name: name, + arrayPositions: arrayPositions, + value: v, + options: options, + numPlainTextBytes: uint64(numPlainTextBytes), + } +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/document/field_composite.go b/backend/vendor/github.com/blevesearch/bleve/v2/document/field_composite.go new file mode 100644 index 0000000000..8c47643f5b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/document/field_composite.go @@ -0,0 +1,135 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package document + +import ( + "reflect" + + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeCompositeField int + +func init() { + var cf CompositeField + reflectStaticSizeCompositeField = int(reflect.TypeOf(cf).Size()) +} + +const DefaultCompositeIndexingOptions = index.IndexField + +type CompositeField struct { + name string + includedFields map[string]bool + excludedFields map[string]bool + defaultInclude bool + options index.FieldIndexingOptions + totalLength int + compositeFrequencies index.TokenFrequencies +} + +func NewCompositeField(name string, defaultInclude bool, include []string, exclude []string) *CompositeField { + return NewCompositeFieldWithIndexingOptions(name, defaultInclude, include, exclude, DefaultCompositeIndexingOptions) +} + +func NewCompositeFieldWithIndexingOptions(name string, defaultInclude bool, include []string, exclude []string, options index.FieldIndexingOptions) *CompositeField { + rv := &CompositeField{ + name: name, + options: options, + defaultInclude: defaultInclude, + includedFields: make(map[string]bool, len(include)), + excludedFields: make(map[string]bool, len(exclude)), + compositeFrequencies: make(index.TokenFrequencies), + } + + for _, i := range include { + rv.includedFields[i] = true + } + for _, e := range exclude { + rv.excludedFields[e] = true + } + + return rv +} + +func (c *CompositeField) Size() int { + sizeInBytes := reflectStaticSizeCompositeField + size.SizeOfPtr + + len(c.name) + + for k, _ := range c.includedFields { + sizeInBytes += size.SizeOfString + len(k) + size.SizeOfBool + } + + for k, _ := range c.excludedFields { + sizeInBytes += size.SizeOfString + len(k) + size.SizeOfBool + } + + return sizeInBytes +} + +func (c *CompositeField) Name() string { + return c.name +} + +func (c *CompositeField) ArrayPositions() []uint64 { + return []uint64{} +} + +func (c *CompositeField) Options() index.FieldIndexingOptions { + return c.options +} + +func (c *CompositeField) Analyze() { +} + +func (c *CompositeField) Value() []byte { + return []byte{} +} + +func (c *CompositeField) NumPlainTextBytes() uint64 { + return 0 +} + +func (c *CompositeField) includesField(field string) bool { + shouldInclude := c.defaultInclude + _, fieldShouldBeIncluded := c.includedFields[field] + if fieldShouldBeIncluded { + shouldInclude = true + } + _, fieldShouldBeExcluded := c.excludedFields[field] + if fieldShouldBeExcluded { + shouldInclude = false + } + return shouldInclude +} + +func (c *CompositeField) Compose(field string, length int, freq index.TokenFrequencies) { + if c.includesField(field) { + c.totalLength += length + c.compositeFrequencies.MergeAll(field, freq) + } +} + +func (c *CompositeField) EncodedFieldType() byte { + return 'c' +} + +func (c *CompositeField) AnalyzedLength() int { + return c.totalLength +} + +func (c *CompositeField) AnalyzedTokenFrequencies() index.TokenFrequencies { + return c.compositeFrequencies +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/document/field_datetime.go b/backend/vendor/github.com/blevesearch/bleve/v2/document/field_datetime.go new file mode 100644 index 0000000000..6506405501 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/document/field_datetime.go @@ -0,0 +1,173 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package document + +import ( + "fmt" + "math" + "reflect" + "time" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/numeric" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeDateTimeField int + +func init() { + var f DateTimeField + reflectStaticSizeDateTimeField = int(reflect.TypeOf(f).Size()) +} + +const DefaultDateTimeIndexingOptions = index.StoreField | index.IndexField | index.DocValues +const DefaultDateTimePrecisionStep uint = 4 + +var MinTimeRepresentable = time.Unix(0, math.MinInt64) +var MaxTimeRepresentable = time.Unix(0, math.MaxInt64) + +type DateTimeField struct { + name string + arrayPositions []uint64 + options index.FieldIndexingOptions + value numeric.PrefixCoded + numPlainTextBytes uint64 + length int + frequencies index.TokenFrequencies +} + +func (n *DateTimeField) Size() int { + return reflectStaticSizeDateTimeField + size.SizeOfPtr + + len(n.name) + + len(n.arrayPositions)*size.SizeOfUint64 +} + +func (n *DateTimeField) Name() string { + return n.name +} + +func (n *DateTimeField) ArrayPositions() []uint64 { + return n.arrayPositions +} + +func (n *DateTimeField) Options() index.FieldIndexingOptions { + return n.options +} + +func (n *DateTimeField) EncodedFieldType() byte { + return 'd' +} + +func (n *DateTimeField) AnalyzedLength() int { + return n.length +} + +func (n *DateTimeField) AnalyzedTokenFrequencies() index.TokenFrequencies { + return n.frequencies +} + +func (n *DateTimeField) Analyze() { + tokens := make(analysis.TokenStream, 0) + tokens = append(tokens, &analysis.Token{ + Start: 0, + End: len(n.value), + Term: n.value, + Position: 1, + Type: analysis.DateTime, + }) + + original, err := n.value.Int64() + if err == nil { + + shift := DefaultDateTimePrecisionStep + for shift < 64 { + shiftEncoded, err := numeric.NewPrefixCodedInt64(original, shift) + if err != nil { + break + } + token := analysis.Token{ + Start: 0, + End: len(shiftEncoded), + Term: shiftEncoded, + Position: 1, + Type: analysis.DateTime, + } + tokens = append(tokens, &token) + shift += DefaultDateTimePrecisionStep + } + } + + n.length = len(tokens) + n.frequencies = analysis.TokenFrequency(tokens, n.arrayPositions, n.options) +} + +func (n *DateTimeField) Value() []byte { + return n.value +} + +func (n *DateTimeField) DateTime() (time.Time, error) { + i64, err := n.value.Int64() + if err != nil { + return time.Time{}, err + } + return time.Unix(0, i64).UTC(), nil +} + +func (n *DateTimeField) GoString() string { + return fmt.Sprintf("&document.DateField{Name:%s, Options: %s, Value: %s}", n.name, n.options, n.value) +} + +func (n *DateTimeField) NumPlainTextBytes() uint64 { + return n.numPlainTextBytes +} + +func NewDateTimeFieldFromBytes(name string, arrayPositions []uint64, value []byte) *DateTimeField { + return &DateTimeField{ + name: name, + arrayPositions: arrayPositions, + value: value, + options: DefaultDateTimeIndexingOptions, + numPlainTextBytes: uint64(len(value)), + } +} + +func NewDateTimeField(name string, arrayPositions []uint64, dt time.Time) (*DateTimeField, error) { + return NewDateTimeFieldWithIndexingOptions(name, arrayPositions, dt, DefaultDateTimeIndexingOptions) +} + +func NewDateTimeFieldWithIndexingOptions(name string, arrayPositions []uint64, dt time.Time, options index.FieldIndexingOptions) (*DateTimeField, error) { + if canRepresent(dt) { + dtInt64 := dt.UnixNano() + prefixCoded := numeric.MustNewPrefixCodedInt64(dtInt64, 0) + return &DateTimeField{ + name: name, + arrayPositions: arrayPositions, + value: prefixCoded, + options: options, + // not correct, just a place holder until we revisit how fields are + // represented and can fix this better + numPlainTextBytes: uint64(8), + }, nil + } + return nil, fmt.Errorf("cannot represent %s in this type", dt) +} + +func canRepresent(dt time.Time) bool { + if dt.Before(MinTimeRepresentable) || dt.After(MaxTimeRepresentable) { + return false + } + return true +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/document/field_geopoint.go b/backend/vendor/github.com/blevesearch/bleve/v2/document/field_geopoint.go new file mode 100644 index 0000000000..719d18c35c --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/document/field_geopoint.go @@ -0,0 +1,193 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package document + +import ( + "fmt" + "reflect" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/geo" + "github.com/blevesearch/bleve/v2/numeric" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeGeoPointField int + +func init() { + var f GeoPointField + reflectStaticSizeGeoPointField = int(reflect.TypeOf(f).Size()) +} + +var GeoPrecisionStep uint = 9 + +type GeoPointField struct { + name string + arrayPositions []uint64 + options index.FieldIndexingOptions + value numeric.PrefixCoded + numPlainTextBytes uint64 + length int + frequencies index.TokenFrequencies + + spatialplugin index.SpatialAnalyzerPlugin +} + +func (n *GeoPointField) Size() int { + return reflectStaticSizeGeoPointField + size.SizeOfPtr + + len(n.name) + + len(n.arrayPositions)*size.SizeOfUint64 +} + +func (n *GeoPointField) Name() string { + return n.name +} + +func (n *GeoPointField) ArrayPositions() []uint64 { + return n.arrayPositions +} + +func (n *GeoPointField) Options() index.FieldIndexingOptions { + return n.options +} + +func (n *GeoPointField) EncodedFieldType() byte { + return 'g' +} + +func (n *GeoPointField) AnalyzedLength() int { + return n.length +} + +func (n *GeoPointField) AnalyzedTokenFrequencies() index.TokenFrequencies { + return n.frequencies +} + +func (n *GeoPointField) Analyze() { + tokens := make(analysis.TokenStream, 0, 8) + tokens = append(tokens, &analysis.Token{ + Start: 0, + End: len(n.value), + Term: n.value, + Position: 1, + Type: analysis.Numeric, + }) + + if n.spatialplugin != nil { + lat, _ := n.Lat() + lon, _ := n.Lon() + p := &geo.Point{Lat: lat, Lon: lon} + terms := n.spatialplugin.GetIndexTokens(p) + + for _, term := range terms { + token := analysis.Token{ + Start: 0, + End: len(term), + Term: []byte(term), + Position: 1, + Type: analysis.AlphaNumeric, + } + tokens = append(tokens, &token) + } + } else { + original, err := n.value.Int64() + if err == nil { + + shift := GeoPrecisionStep + for shift < 64 { + shiftEncoded, err := numeric.NewPrefixCodedInt64(original, shift) + if err != nil { + break + } + token := analysis.Token{ + Start: 0, + End: len(shiftEncoded), + Term: shiftEncoded, + Position: 1, + Type: analysis.Numeric, + } + tokens = append(tokens, &token) + shift += GeoPrecisionStep + } + } + } + + n.length = len(tokens) + n.frequencies = analysis.TokenFrequency(tokens, n.arrayPositions, n.options) +} + +func (n *GeoPointField) Value() []byte { + return n.value +} + +func (n *GeoPointField) Lon() (float64, error) { + i64, err := n.value.Int64() + if err != nil { + return 0.0, err + } + return geo.MortonUnhashLon(uint64(i64)), nil +} + +func (n *GeoPointField) Lat() (float64, error) { + i64, err := n.value.Int64() + if err != nil { + return 0.0, err + } + return geo.MortonUnhashLat(uint64(i64)), nil +} + +func (n *GeoPointField) GoString() string { + return fmt.Sprintf("&document.GeoPointField{Name:%s, Options: %s, Value: %s}", n.name, n.options, n.value) +} + +func (n *GeoPointField) NumPlainTextBytes() uint64 { + return n.numPlainTextBytes +} + +func NewGeoPointFieldFromBytes(name string, arrayPositions []uint64, value []byte) *GeoPointField { + return &GeoPointField{ + name: name, + arrayPositions: arrayPositions, + value: value, + options: DefaultNumericIndexingOptions, + numPlainTextBytes: uint64(len(value)), + } +} + +func NewGeoPointField(name string, arrayPositions []uint64, lon, lat float64) *GeoPointField { + return NewGeoPointFieldWithIndexingOptions(name, arrayPositions, lon, lat, DefaultNumericIndexingOptions) +} + +func NewGeoPointFieldWithIndexingOptions(name string, arrayPositions []uint64, lon, lat float64, options index.FieldIndexingOptions) *GeoPointField { + mhash := geo.MortonHash(lon, lat) + prefixCoded := numeric.MustNewPrefixCodedInt64(int64(mhash), 0) + return &GeoPointField{ + name: name, + arrayPositions: arrayPositions, + value: prefixCoded, + options: options, + // not correct, just a place holder until we revisit how fields are + // represented and can fix this better + numPlainTextBytes: uint64(8), + } +} + +// SetSpatialAnalyzerPlugin implements the +// index.TokenisableSpatialField interface. +func (n *GeoPointField) SetSpatialAnalyzerPlugin( + plugin index.SpatialAnalyzerPlugin) { + n.spatialplugin = plugin +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/document/field_geoshape.go b/backend/vendor/github.com/blevesearch/bleve/v2/document/field_geoshape.go new file mode 100644 index 0000000000..a20ff1837e --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/document/field_geoshape.go @@ -0,0 +1,235 @@ +// Copyright (c) 2022 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package document + +import ( + "fmt" + "reflect" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/geo" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" + "github.com/blevesearch/geo/geojson" +) + +var reflectStaticSizeGeoShapeField int + +func init() { + var f GeoShapeField + reflectStaticSizeGeoShapeField = int(reflect.TypeOf(f).Size()) +} + +const DefaultGeoShapeIndexingOptions = index.IndexField | index.DocValues + +type GeoShapeField struct { + name string + shape index.GeoJSON + arrayPositions []uint64 + options index.FieldIndexingOptions + numPlainTextBytes uint64 + length int + encodedValue []byte + value []byte + + frequencies index.TokenFrequencies +} + +func (n *GeoShapeField) Size() int { + return reflectStaticSizeGeoShapeField + size.SizeOfPtr + + len(n.name) + + len(n.arrayPositions)*size.SizeOfUint64 +} + +func (n *GeoShapeField) Name() string { + return n.name +} + +func (n *GeoShapeField) ArrayPositions() []uint64 { + return n.arrayPositions +} + +func (n *GeoShapeField) Options() index.FieldIndexingOptions { + return n.options +} + +func (n *GeoShapeField) EncodedFieldType() byte { + return 's' +} + +func (n *GeoShapeField) AnalyzedLength() int { + return n.length +} + +func (n *GeoShapeField) AnalyzedTokenFrequencies() index.TokenFrequencies { + return n.frequencies +} + +func (n *GeoShapeField) Analyze() { + // compute the bytes representation for the coordinates + tokens := make(analysis.TokenStream, 0) + tokens = append(tokens, &analysis.Token{ + Start: 0, + End: len(n.encodedValue), + Term: n.encodedValue, + Position: 1, + Type: analysis.AlphaNumeric, + }) + + rti := geo.GetSpatialAnalyzerPlugin("s2") + terms := rti.GetIndexTokens(n.shape) + + for _, term := range terms { + token := analysis.Token{ + Start: 0, + End: len(term), + Term: []byte(term), + Position: 1, + Type: analysis.AlphaNumeric, + } + tokens = append(tokens, &token) + } + + n.length = len(tokens) + n.frequencies = analysis.TokenFrequency(tokens, n.arrayPositions, n.options) +} + +func (n *GeoShapeField) Value() []byte { + return n.value +} + +func (n *GeoShapeField) GoString() string { + return fmt.Sprintf("&document.GeoShapeField{Name:%s, Options: %s, Value: %s}", + n.name, n.options, n.value) +} + +func (n *GeoShapeField) NumPlainTextBytes() uint64 { + return n.numPlainTextBytes +} + +func NewGeoShapeField(name string, arrayPositions []uint64, + coordinates [][][][]float64, typ string) *GeoShapeField { + return NewGeoShapeFieldWithIndexingOptions(name, arrayPositions, + coordinates, typ, DefaultGeoShapeIndexingOptions) +} + +func NewGeoShapeFieldFromBytes(name string, arrayPositions []uint64, + value []byte) *GeoShapeField { + return &GeoShapeField{ + name: name, + arrayPositions: arrayPositions, + value: value, + options: DefaultGeoShapeIndexingOptions, + numPlainTextBytes: uint64(len(value)), + } +} + +func NewGeoShapeFieldWithIndexingOptions(name string, arrayPositions []uint64, + coordinates [][][][]float64, typ string, + options index.FieldIndexingOptions) *GeoShapeField { + shape, encodedValue, err := geo.NewGeoJsonShape(coordinates, typ) + if err != nil { + return nil + } + + // extra glue bytes to work around the term splitting logic from interfering + // the custom encoding of the geoshape coordinates inside the docvalues. + encodedValue = append(geo.GlueBytes, append(encodedValue, geo.GlueBytes...)...) + + // get the byte value for the geoshape. + value, err := shape.Value() + if err != nil { + return nil + } + + options = options | DefaultGeoShapeIndexingOptions + + return &GeoShapeField{ + shape: shape, + name: name, + arrayPositions: arrayPositions, + options: options, + encodedValue: encodedValue, + value: value, + numPlainTextBytes: uint64(len(value)), + } +} + +func NewGeometryCollectionFieldWithIndexingOptions(name string, + arrayPositions []uint64, coordinates [][][][][]float64, types []string, + options index.FieldIndexingOptions) *GeoShapeField { + shape, encodedValue, err := geo.NewGeometryCollection(coordinates, types) + if err != nil { + return nil + } + + // extra glue bytes to work around the term splitting logic from interfering + // the custom encoding of the geoshape coordinates inside the docvalues. + encodedValue = append(geo.GlueBytes, append(encodedValue, geo.GlueBytes...)...) + + // get the byte value for the geometryCollection. + value, err := shape.Value() + if err != nil { + return nil + } + + options = options | DefaultGeoShapeIndexingOptions + + return &GeoShapeField{ + shape: shape, + name: name, + arrayPositions: arrayPositions, + options: options, + encodedValue: encodedValue, + value: value, + numPlainTextBytes: uint64(len(value)), + } +} + +func NewGeoCircleFieldWithIndexingOptions(name string, arrayPositions []uint64, + centerPoint []float64, radius string, + options index.FieldIndexingOptions) *GeoShapeField { + shape, encodedValue, err := geo.NewGeoCircleShape(centerPoint, radius) + if err != nil { + return nil + } + + // extra glue bytes to work around the term splitting logic from interfering + // the custom encoding of the geoshape coordinates inside the docvalues. + encodedValue = append(geo.GlueBytes, append(encodedValue, geo.GlueBytes...)...) + + // get the byte value for the circle. + value, err := shape.Value() + if err != nil { + return nil + } + + options = options | DefaultGeoShapeIndexingOptions + + return &GeoShapeField{ + shape: shape, + name: name, + arrayPositions: arrayPositions, + options: options, + encodedValue: encodedValue, + value: value, + numPlainTextBytes: uint64(len(value)), + } +} + +// GeoShape is an implementation of the index.GeoShapeField interface. +func (n *GeoShapeField) GeoShape() (index.GeoJSON, error) { + return geojson.ParseGeoJSONShape(n.value) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/document/field_ip.go b/backend/vendor/github.com/blevesearch/bleve/v2/document/field_ip.go new file mode 100644 index 0000000000..1e5be5006a --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/document/field_ip.go @@ -0,0 +1,132 @@ +// Copyright (c) 2021 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package document + +import ( + "fmt" + "net" + "reflect" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeIPField int + +func init() { + var f IPField + reflectStaticSizeIPField = int(reflect.TypeOf(f).Size()) +} + +const DefaultIPIndexingOptions = index.StoreField | index.IndexField | index.DocValues | index.IncludeTermVectors + +type IPField struct { + name string + arrayPositions []uint64 + options index.FieldIndexingOptions + value net.IP + numPlainTextBytes uint64 + length int + frequencies index.TokenFrequencies +} + +func (b *IPField) Size() int { + return reflectStaticSizeIPField + size.SizeOfPtr + + len(b.name) + + len(b.arrayPositions)*size.SizeOfUint64 + + len(b.value) +} + +func (b *IPField) Name() string { + return b.name +} + +func (b *IPField) ArrayPositions() []uint64 { + return b.arrayPositions +} + +func (b *IPField) Options() index.FieldIndexingOptions { + return b.options +} + +func (n *IPField) EncodedFieldType() byte { + return 'i' +} + +func (n *IPField) AnalyzedLength() int { + return n.length +} + +func (n *IPField) AnalyzedTokenFrequencies() index.TokenFrequencies { + return n.frequencies +} + +func (b *IPField) Analyze() { + + tokens := analysis.TokenStream{ + &analysis.Token{ + Start: 0, + End: len(b.value), + Term: b.value, + Position: 1, + Type: analysis.IP, + }, + } + b.length = 1 + b.frequencies = analysis.TokenFrequency(tokens, b.arrayPositions, b.options) +} + +func (b *IPField) Value() []byte { + return b.value +} + +func (b *IPField) IP() (net.IP, error) { + return net.IP(b.value), nil +} + +func (b *IPField) GoString() string { + return fmt.Sprintf("&document.IPField{Name:%s, Options: %s, Value: %s}", b.name, b.options, net.IP(b.value)) +} + +func (b *IPField) NumPlainTextBytes() uint64 { + return b.numPlainTextBytes +} + +func NewIPFieldFromBytes(name string, arrayPositions []uint64, value []byte) *IPField { + return &IPField{ + name: name, + arrayPositions: arrayPositions, + value: value, + options: DefaultNumericIndexingOptions, + numPlainTextBytes: uint64(len(value)), + } +} + +func NewIPField(name string, arrayPositions []uint64, v net.IP) *IPField { + return NewIPFieldWithIndexingOptions(name, arrayPositions, v, DefaultIPIndexingOptions) +} + +func NewIPFieldWithIndexingOptions(name string, arrayPositions []uint64, b net.IP, options index.FieldIndexingOptions) *IPField { + v := b.To16() + + return &IPField{ + name: name, + arrayPositions: arrayPositions, + value: v, + options: options, + numPlainTextBytes: net.IPv6len, + } +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/document/field_numeric.go b/backend/vendor/github.com/blevesearch/bleve/v2/document/field_numeric.go new file mode 100644 index 0000000000..a54b082b48 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/document/field_numeric.go @@ -0,0 +1,159 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package document + +import ( + "fmt" + "reflect" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/numeric" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeNumericField int + +func init() { + var f NumericField + reflectStaticSizeNumericField = int(reflect.TypeOf(f).Size()) +} + +const DefaultNumericIndexingOptions = index.StoreField | index.IndexField | index.DocValues + +const DefaultPrecisionStep uint = 4 + +type NumericField struct { + name string + arrayPositions []uint64 + options index.FieldIndexingOptions + value numeric.PrefixCoded + numPlainTextBytes uint64 + length int + frequencies index.TokenFrequencies +} + +func (n *NumericField) Size() int { + return reflectStaticSizeNumericField + size.SizeOfPtr + + len(n.name) + + len(n.arrayPositions)*size.SizeOfPtr +} + +func (n *NumericField) Name() string { + return n.name +} + +func (n *NumericField) ArrayPositions() []uint64 { + return n.arrayPositions +} + +func (n *NumericField) Options() index.FieldIndexingOptions { + return n.options +} + +func (n *NumericField) EncodedFieldType() byte { + return 'n' +} + +func (n *NumericField) AnalyzedLength() int { + return n.length +} + +func (n *NumericField) AnalyzedTokenFrequencies() index.TokenFrequencies { + return n.frequencies +} + +func (n *NumericField) Analyze() { + tokens := make(analysis.TokenStream, 0) + tokens = append(tokens, &analysis.Token{ + Start: 0, + End: len(n.value), + Term: n.value, + Position: 1, + Type: analysis.Numeric, + }) + + original, err := n.value.Int64() + if err == nil { + + shift := DefaultPrecisionStep + for shift < 64 { + shiftEncoded, err := numeric.NewPrefixCodedInt64(original, shift) + if err != nil { + break + } + token := analysis.Token{ + Start: 0, + End: len(shiftEncoded), + Term: shiftEncoded, + Position: 1, + Type: analysis.Numeric, + } + tokens = append(tokens, &token) + shift += DefaultPrecisionStep + } + } + + n.length = len(tokens) + n.frequencies = analysis.TokenFrequency(tokens, n.arrayPositions, n.options) +} + +func (n *NumericField) Value() []byte { + return n.value +} + +func (n *NumericField) Number() (float64, error) { + i64, err := n.value.Int64() + if err != nil { + return 0.0, err + } + return numeric.Int64ToFloat64(i64), nil +} + +func (n *NumericField) GoString() string { + return fmt.Sprintf("&document.NumericField{Name:%s, Options: %s, Value: %s}", n.name, n.options, n.value) +} + +func (n *NumericField) NumPlainTextBytes() uint64 { + return n.numPlainTextBytes +} + +func NewNumericFieldFromBytes(name string, arrayPositions []uint64, value []byte) *NumericField { + return &NumericField{ + name: name, + arrayPositions: arrayPositions, + value: value, + options: DefaultNumericIndexingOptions, + numPlainTextBytes: uint64(len(value)), + } +} + +func NewNumericField(name string, arrayPositions []uint64, number float64) *NumericField { + return NewNumericFieldWithIndexingOptions(name, arrayPositions, number, DefaultNumericIndexingOptions) +} + +func NewNumericFieldWithIndexingOptions(name string, arrayPositions []uint64, number float64, options index.FieldIndexingOptions) *NumericField { + numberInt64 := numeric.Float64ToInt64(number) + prefixCoded := numeric.MustNewPrefixCodedInt64(numberInt64, 0) + return &NumericField{ + name: name, + arrayPositions: arrayPositions, + value: prefixCoded, + options: options, + // not correct, just a place holder until we revisit how fields are + // represented and can fix this better + numPlainTextBytes: uint64(8), + } +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/document/field_text.go b/backend/vendor/github.com/blevesearch/bleve/v2/document/field_text.go new file mode 100644 index 0000000000..fddc59d09e --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/document/field_text.go @@ -0,0 +1,157 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package document + +import ( + "fmt" + "reflect" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeTextField int + +func init() { + var f TextField + reflectStaticSizeTextField = int(reflect.TypeOf(f).Size()) +} + +const DefaultTextIndexingOptions = index.IndexField | index.DocValues + +type TextField struct { + name string + arrayPositions []uint64 + options index.FieldIndexingOptions + analyzer analysis.Analyzer + value []byte + numPlainTextBytes uint64 + length int + frequencies index.TokenFrequencies +} + +func (t *TextField) Size() int { + return reflectStaticSizeTextField + size.SizeOfPtr + + len(t.name) + + len(t.arrayPositions)*size.SizeOfUint64 + + len(t.value) +} + +func (t *TextField) Name() string { + return t.name +} + +func (t *TextField) ArrayPositions() []uint64 { + return t.arrayPositions +} + +func (t *TextField) Options() index.FieldIndexingOptions { + return t.options +} + +func (t *TextField) EncodedFieldType() byte { + return 't' +} + +func (t *TextField) AnalyzedLength() int { + return t.length +} + +func (t *TextField) AnalyzedTokenFrequencies() index.TokenFrequencies { + return t.frequencies +} + +func (t *TextField) Analyze() { + var tokens analysis.TokenStream + if t.analyzer != nil { + bytesToAnalyze := t.Value() + if t.options.IsStored() { + // need to copy + bytesCopied := make([]byte, len(bytesToAnalyze)) + copy(bytesCopied, bytesToAnalyze) + bytesToAnalyze = bytesCopied + } + tokens = t.analyzer.Analyze(bytesToAnalyze) + } else { + tokens = analysis.TokenStream{ + &analysis.Token{ + Start: 0, + End: len(t.value), + Term: t.value, + Position: 1, + Type: analysis.AlphaNumeric, + }, + } + } + t.length = len(tokens) // number of tokens in this doc field + t.frequencies = analysis.TokenFrequency(tokens, t.arrayPositions, t.options) +} + +func (t *TextField) Analyzer() analysis.Analyzer { + return t.analyzer +} + +func (t *TextField) Value() []byte { + return t.value +} + +func (t *TextField) Text() string { + return string(t.value) +} + +func (t *TextField) GoString() string { + return fmt.Sprintf("&document.TextField{Name:%s, Options: %s, Analyzer: %v, Value: %s, ArrayPositions: %v}", t.name, t.options, t.analyzer, t.value, t.arrayPositions) +} + +func (t *TextField) NumPlainTextBytes() uint64 { + return t.numPlainTextBytes +} + +func NewTextField(name string, arrayPositions []uint64, value []byte) *TextField { + return NewTextFieldWithIndexingOptions(name, arrayPositions, value, DefaultTextIndexingOptions) +} + +func NewTextFieldWithIndexingOptions(name string, arrayPositions []uint64, value []byte, options index.FieldIndexingOptions) *TextField { + return &TextField{ + name: name, + arrayPositions: arrayPositions, + options: options, + value: value, + numPlainTextBytes: uint64(len(value)), + } +} + +func NewTextFieldWithAnalyzer(name string, arrayPositions []uint64, value []byte, analyzer analysis.Analyzer) *TextField { + return &TextField{ + name: name, + arrayPositions: arrayPositions, + options: DefaultTextIndexingOptions, + analyzer: analyzer, + value: value, + numPlainTextBytes: uint64(len(value)), + } +} + +func NewTextFieldCustom(name string, arrayPositions []uint64, value []byte, options index.FieldIndexingOptions, analyzer analysis.Analyzer) *TextField { + return &TextField{ + name: name, + arrayPositions: arrayPositions, + options: options, + analyzer: analyzer, + value: value, + numPlainTextBytes: uint64(len(value)), + } +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/error.go b/backend/vendor/github.com/blevesearch/bleve/v2/error.go new file mode 100644 index 0000000000..7dd21194c8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/error.go @@ -0,0 +1,50 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bleve + +// Constant Error values which can be compared to determine the type of error +const ( + ErrorIndexPathExists Error = iota + ErrorIndexPathDoesNotExist + ErrorIndexMetaMissing + ErrorIndexMetaCorrupt + ErrorIndexClosed + ErrorAliasMulti + ErrorAliasEmpty + ErrorUnknownIndexType + ErrorEmptyID + ErrorIndexReadInconsistency +) + +// Error represents a more strongly typed bleve error for detecting +// and handling specific types of errors. +type Error int + +func (e Error) Error() string { + return errorMessages[e] +} + +var errorMessages = map[Error]string{ + ErrorIndexPathExists: "cannot create new index, path already exists", + ErrorIndexPathDoesNotExist: "cannot open index, path does not exist", + ErrorIndexMetaMissing: "cannot open index, metadata missing", + ErrorIndexMetaCorrupt: "cannot open index, metadata corrupt", + ErrorIndexClosed: "index is closed", + ErrorAliasMulti: "cannot perform single index operation on multiple index alias", + ErrorAliasEmpty: "cannot perform operation on empty alias", + ErrorUnknownIndexType: "unknown index type", + ErrorEmptyID: "document ID cannot be empty", + ErrorIndexReadInconsistency: "index read inconsistency detected", +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/geo/README.md b/backend/vendor/github.com/blevesearch/bleve/v2/geo/README.md new file mode 100644 index 0000000000..6112ff5da0 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/geo/README.md @@ -0,0 +1,277 @@ +# geo support in bleve + +Latest bleve spatial capabilities are powered by spatial hierarchical tokens generated from s2geometry. +You can find more details about the [s2geometry basics here](http://s2geometry.io/), and explore the +extended functionality of our forked golang port of [s2geometry lib here](https://github.com/blevesearch/geo). + +Users can continue to index and query `geopoint` field type and the existing queries like, + +- Point Distance +- Bounded Rectangle +- Bounded Polygon + +as before. + +## New Spatial Field Type - geoshape + +We have introduced a field type (`geoshape`) for representing the new spatial types. + +Using the new `geoshape` field type, users can unblock the spatial capabilities +for the [geojson](https://datatracker.ietf.org/doc/html/rfc7946) shapes like, + +- Point +- LineString +- Polygon +- MultiPoint +- MultiLineString +- MultiPolygon +- GeometryCollection + +In addition to these shapes, bleve will also support additional shapes like, + +- Circle +- Envelope (Bounded box) + +To specify GeoJSON data, use a nested field with: + +- a field named type that specifies the GeoJSON object type and the type value will be case-insensitive. +- a field named coordinates that specifies the object's coordinates. + +``` + "fieldName": { + "type": "GeoJSON Type", + "coordinates": + } +``` + +- If specifying latitude and longitude coordinates, list the longitude first and then latitude. +- Valid longitude values are between -180 and 180, both inclusive. +- Valid latitude values are between -90 and 90, both inclusive. +- Shapes would be internally represented as geodesics. +- The GeoJSON specification strongly suggests splitting geometries so that neither of their parts crosses the antimeridian. + + +Examples for the various geojson shapes representations are as below. + +## Point + +The following specifies a [Point](https://tools.ietf.org/html/rfc7946#section-3.1.2) field in a document: + +``` + { + "type": "point", + "coordinates": [75.05687713623047,22.53539059204079] + } +``` + +## Linestring + +The following specifies a [Linestring](https://tools.ietf.org/html/rfc7946#section-3.1.4) field in a document: + + +``` +{ + "type": "linestring", + "coordinates": [ + [ 77.01416015625, 23.0797317624497], + [ 78.134765625, 20.385825381874263] + ] +} +``` + + +## Polygon + +The following specifies a [Polygon](https://tools.ietf.org/html/rfc7946#section-3.1.6) field in a document: + +``` +{ + "type": "polygon", + "coordinates": [ [ [ 85.605, 57.207], + [ 86.396, 55.998], + [ 87.033, 56.716], + [ 85.605, 57.207] + ] ] +} +``` + + +The first and last coordinates must match in order to close the polygon. +And the exterior coordinates have to be in Counter Clockwise Order in a polygon. (CCW) + + +## MultiPoint + +The following specifies a [Multipoint](https://tools.ietf.org/html/rfc7946#section-3.1.3) field in a document: + +``` +{ + "type": "multipoint", + "coordinates": [ + [ -115.8343505859375, 38.45789034424927], + [ -115.81237792968749, 38.19502155795575], + [ -120.80017089843749, 36.54053616262899], + [ -120.67932128906249, 36.33725319397006] + ] +} +``` + +## MultiLineString + +The following specifies a [MultiLineString](https://tools.ietf.org/html/rfc7946#section-3.1.5) field in a document: + +``` +{ + "type": "multilinestring", + "coordinates": [ + [ [ -118.31726074, 35.250105158],[ -117.509765624, 35.3756141] ], + [ [ -118.6962890, 34.624167789],[ -118.317260742, 35.03899204] ], + [ [ -117.9492187, 35.146862906], [ -117.6745605, 34.41144164] ] +] +} +``` + +## MultiPolygon + +The following specifies a [MultiPolygon](https://tools.ietf.org/html/rfc7946#section-3.1.7) field in a document: + +``` +{ + "type": "multipolygon", + "coordinates": [ + [ [ [ -73.958, 40.8003 ], [ -73.9498, 40.7968 ], + [ -73.9737, 40.7648 ], [ -73.9814, 40.7681 ], + [ -73.958, 40.8003 ] ] ], + + + [ [ [ -73.958, 40.8003 ], [ -73.9498, 40.7968 ], + [ -73.9737, 40.7648 ], [ -73.958, 40.8003 ] ] ] + ] +} +``` + + +## GeometryCollection + +The following specifies a [GeometryCollection](https://tools.ietf.org/html/rfc7946#section-3.1.8) field in a document: + +``` +{ + "type": "geometrycollection", + "geometries": [ + { + "type": "multipoint", + "coordinates": [ + [ -73.9580, 40.8003 ], + [ -73.9498, 40.7968 ], + [ -73.9737, 40.7648 ], + [ -73.9814, 40.7681 ] + ] + }, + { + "type": "multilinestring", + "coordinates": [ + [ [ -73.96943, 40.78519 ], [ -73.96082, 40.78095 ] ], + [ [ -73.96415, 40.79229 ], [ -73.95544, 40.78854 ] ], + [ [ -73.97162, 40.78205 ], [ -73.96374, 40.77715 ] ], + [ [ -73.97880, 40.77247 ], [ -73.97036, 40.76811 ] ] + ] + }, + { + "type" : "polygon", + "coordinates" : [ + [ [ 0 , 0 ] , [ 3 , 6 ] , [ 6 , 1 ] , [ 0 , 0 ] ], + [ [ 2 , 2 ] , [ 3 , 3 ] , [ 4 , 2 ] , [ 2 , 2 ] ] + ] + } +] +} +``` + + +## Circle + +If the user wishes to cover a circular region over the earth’s surface, then they could use this shape. +A sample circular shape is as below. + +``` +{ + "type": "circle", + "coordinates": [75.05687713623047,22.53539059204079], + "radius": "1000m" +} +``` + + +Circle is specified over the center point coordinates along with the radius. +Example formats supported for radius are: +"5in" , "5inch" , "7yd" , "7yards", "9ft" , "9feet", "11km", "11kilometers", "3nm" +"3nauticalmiles", "13mm" , "13millimeters", "15cm", "15centimeters", "17mi", "17miles" "19m" or "19meters". + +If the unit cannot be determined, the entire string is parsed and the unit of meters is assumed. + + +## Envelope + +Envelope type, which consists of coordinates for upper left and lower right points of the shape +to represent a bounding rectangle in the format [[minLon, maxLat], [maxLon, minLat]]. + +``` +{ + "type": "envelope", + "coordinates": [ + [72.83, 18.979], + [78.508,17.4555] + ] +} +``` + + +## GeoShape Query + +Geoshape query support three types/filters of spatial querying capability across those +heterogeneous types of documents indexed. + +### Query Structure: + +``` +{ + "query": { + "geometry": { + "shape": { + "type": "", + "coordinates": [[[ ]]] + }, + "relation": "<>" + } + } +} +``` + + +*shapeType* => can be any of the aforementioned types like Point, LineString, Polygon, MultiPoint, +Geometrycollection, MultiLineString, MultiPolygon, Circle and Envelope. + +*filterName* => can be any of the 3 types like *intersects*, *contains* and *within*. + +### Relation + +| FilterName | Description | +| :-----------:| :-----------------------------------------------------------------: | +| `intersects` | Return all documents whose shape field intersects the query geometry. | +| `contains` | Return all documents whose shape field contains the query geometry | +| `within` | Return all documents whose shape field is within the query geometry. | + +------------------------------------------------------------------------------------------------------------------------ + + + +### Older Implementation + +First, all of this geo code is a Go adaptation of the [Lucene 5.3.2 sandbox geo support](https://lucene.apache.org/core/5_3_2/sandbox/org/apache/lucene/util/package-summary.html). + +## Notes + +- All of the APIs will use float64 for lon/lat values. +- When describing a point in function arguments or return values, we always use the order lon, lat. +- High level APIs will use TopLeft and BottomRight to describe bounding boxes. This may not map cleanly to min/max lon/lat when crossing the dateline. The lower level APIs will use min/max lon/lat and require the higher-level code to split boxes accordingly. diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/geo/geo.go b/backend/vendor/github.com/blevesearch/bleve/v2/geo/geo.go new file mode 100644 index 0000000000..55eace1df0 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/geo/geo.go @@ -0,0 +1,210 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package geo + +import ( + "fmt" + "math" + + "github.com/blevesearch/bleve/v2/numeric" +) + +// GeoBits is the number of bits used for a single geo point +// Currently this is 32bits for lon and 32bits for lat +var GeoBits uint = 32 + +var minLon = -180.0 +var minLat = -90.0 +var maxLon = 180.0 +var maxLat = 90.0 +var minLonRad = minLon * degreesToRadian +var minLatRad = minLat * degreesToRadian +var maxLonRad = maxLon * degreesToRadian +var maxLatRad = maxLat * degreesToRadian +var geoTolerance = 1e-6 +var lonScale = float64((uint64(0x1)<> 1)) +} + +func unscaleLon(lon uint64) float64 { + return (float64(lon) / lonScale) + minLon +} + +func unscaleLat(lat uint64) float64 { + return (float64(lat) / latScale) + minLat +} + +// compareGeo will compare two float values and see if they are the same +// taking into consideration a known geo tolerance. +func compareGeo(a, b float64) float64 { + compare := a - b + if math.Abs(compare) <= geoTolerance { + return 0 + } + return compare +} + +// RectIntersects checks whether rectangles a and b intersect +func RectIntersects(aMinX, aMinY, aMaxX, aMaxY, bMinX, bMinY, bMaxX, bMaxY float64) bool { + return !(aMaxX < bMinX || aMinX > bMaxX || aMaxY < bMinY || aMinY > bMaxY) +} + +// RectWithin checks whether box a is within box b +func RectWithin(aMinX, aMinY, aMaxX, aMaxY, bMinX, bMinY, bMaxX, bMaxY float64) bool { + rv := !(aMinX < bMinX || aMinY < bMinY || aMaxX > bMaxX || aMaxY > bMaxY) + return rv +} + +// BoundingBoxContains checks whether the lon/lat point is within the box +func BoundingBoxContains(lon, lat, minLon, minLat, maxLon, maxLat float64) bool { + return compareGeo(lon, minLon) >= 0 && compareGeo(lon, maxLon) <= 0 && + compareGeo(lat, minLat) >= 0 && compareGeo(lat, maxLat) <= 0 +} + +const degreesToRadian = math.Pi / 180 +const radiansToDegrees = 180 / math.Pi + +// DegreesToRadians converts an angle in degrees to radians +func DegreesToRadians(d float64) float64 { + return d * degreesToRadian +} + +// RadiansToDegrees converts an angle in radians to degress +func RadiansToDegrees(r float64) float64 { + return r * radiansToDegrees +} + +var earthMeanRadiusMeters = 6371008.7714 + +func RectFromPointDistance(lon, lat, dist float64) (float64, float64, float64, float64, error) { + err := checkLongitude(lon) + if err != nil { + return 0, 0, 0, 0, err + } + err = checkLatitude(lat) + if err != nil { + return 0, 0, 0, 0, err + } + radLon := DegreesToRadians(lon) + radLat := DegreesToRadians(lat) + radDistance := (dist + 7e-2) / earthMeanRadiusMeters + + minLatL := radLat - radDistance + maxLatL := radLat + radDistance + + var minLonL, maxLonL float64 + if minLatL > minLatRad && maxLatL < maxLatRad { + deltaLon := asin(sin(radDistance) / cos(radLat)) + minLonL = radLon - deltaLon + if minLonL < minLonRad { + minLonL += 2 * math.Pi + } + maxLonL = radLon + deltaLon + if maxLonL > maxLonRad { + maxLonL -= 2 * math.Pi + } + } else { + // pole is inside distance + minLatL = math.Max(minLatL, minLatRad) + maxLatL = math.Min(maxLatL, maxLatRad) + minLonL = minLonRad + maxLonL = maxLonRad + } + + return RadiansToDegrees(minLonL), + RadiansToDegrees(maxLatL), + RadiansToDegrees(maxLonL), + RadiansToDegrees(minLatL), + nil +} + +func checkLatitude(latitude float64) error { + if math.IsNaN(latitude) || latitude < minLat || latitude > maxLat { + return fmt.Errorf("invalid latitude %f; must be between %f and %f", latitude, minLat, maxLat) + } + return nil +} + +func checkLongitude(longitude float64) error { + if math.IsNaN(longitude) || longitude < minLon || longitude > maxLon { + return fmt.Errorf("invalid longitude %f; must be between %f and %f", longitude, minLon, maxLon) + } + return nil +} + +func BoundingRectangleForPolygon(polygon []Point) ( + float64, float64, float64, float64, error) { + err := checkLongitude(polygon[0].Lon) + if err != nil { + return 0, 0, 0, 0, err + } + err = checkLatitude(polygon[0].Lat) + if err != nil { + return 0, 0, 0, 0, err + } + maxY, minY := polygon[0].Lat, polygon[0].Lat + maxX, minX := polygon[0].Lon, polygon[0].Lon + for i := 1; i < len(polygon); i++ { + err := checkLongitude(polygon[i].Lon) + if err != nil { + return 0, 0, 0, 0, err + } + err = checkLatitude(polygon[i].Lat) + if err != nil { + return 0, 0, 0, 0, err + } + + maxY = math.Max(maxY, polygon[i].Lat) + minY = math.Min(minY, polygon[i].Lat) + + maxX = math.Max(maxX, polygon[i].Lon) + minX = math.Min(minX, polygon[i].Lon) + } + + return minX, maxY, maxX, minY, nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/geo/geo_dist.go b/backend/vendor/github.com/blevesearch/bleve/v2/geo/geo_dist.go new file mode 100644 index 0000000000..d3ae0ed9e3 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/geo/geo_dist.go @@ -0,0 +1,98 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package geo + +import ( + "fmt" + "math" + "strconv" + "strings" +) + +type distanceUnit struct { + conv float64 + suffixes []string +} + +var inch = distanceUnit{0.0254, []string{"in", "inch"}} +var yard = distanceUnit{0.9144, []string{"yd", "yards"}} +var feet = distanceUnit{0.3048, []string{"ft", "feet"}} +var kilom = distanceUnit{1000, []string{"km", "kilometers"}} +var nauticalm = distanceUnit{1852.0, []string{"nm", "nauticalmiles"}} +var millim = distanceUnit{0.001, []string{"mm", "millimeters"}} +var centim = distanceUnit{0.01, []string{"cm", "centimeters"}} +var miles = distanceUnit{1609.344, []string{"mi", "miles"}} +var meters = distanceUnit{1, []string{"m", "meters"}} + +var distanceUnits = []*distanceUnit{ + &inch, &yard, &feet, &kilom, &nauticalm, &millim, ¢im, &miles, &meters, +} + +// ParseDistance attempts to parse a distance string and return distance in +// meters. Example formats supported: +// "5in" "5inch" "7yd" "7yards" "9ft" "9feet" "11km" "11kilometers" +// "3nm" "3nauticalmiles" "13mm" "13millimeters" "15cm" "15centimeters" +// "17mi" "17miles" "19m" "19meters" +// If the unit cannot be determined, the entire string is parsed and the +// unit of meters is assumed. +// If the number portion cannot be parsed, 0 and the parse error are returned. +func ParseDistance(d string) (float64, error) { + for _, unit := range distanceUnits { + for _, unitSuffix := range unit.suffixes { + if strings.HasSuffix(d, unitSuffix) { + parsedNum, err := strconv.ParseFloat(d[0:len(d)-len(unitSuffix)], 64) + if err != nil { + return 0, err + } + return parsedNum * unit.conv, nil + } + } + } + // no unit matched, try assuming meters? + parsedNum, err := strconv.ParseFloat(d, 64) + if err != nil { + return 0, err + } + return parsedNum, nil +} + +// ParseDistanceUnit attempts to parse a distance unit and return the +// multiplier for converting this to meters. If the unit cannot be parsed +// then 0 and the error message is returned. +func ParseDistanceUnit(u string) (float64, error) { + for _, unit := range distanceUnits { + for _, unitSuffix := range unit.suffixes { + if u == unitSuffix { + return unit.conv, nil + } + } + } + return 0, fmt.Errorf("unknown distance unit: %s", u) +} + +// Haversin computes the distance between two points. +// This implemenation uses the sloppy math implemenations which trade off +// accuracy for performance. The distance returned is in kilometers. +func Haversin(lon1, lat1, lon2, lat2 float64) float64 { + x1 := lat1 * degreesToRadian + x2 := lat2 * degreesToRadian + h1 := 1 - cos(x1-x2) + h2 := 1 - cos((lon1-lon2)*degreesToRadian) + h := (h1 + cos(x1)*cos(x2)*h2) / 2 + avgLat := (x1 + x2) / 2 + diameter := earthDiameter(avgLat) + + return diameter * asin(math.Min(1, math.Sqrt(h))) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/geo/geo_s2plugin_impl.go b/backend/vendor/github.com/blevesearch/bleve/v2/geo/geo_s2plugin_impl.go new file mode 100644 index 0000000000..f743d87fc7 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/geo/geo_s2plugin_impl.go @@ -0,0 +1,450 @@ +// Copyright (c) 2022 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package geo + +import ( + "encoding/json" + "sync" + + index "github.com/blevesearch/bleve_index_api" + + "github.com/blevesearch/geo/geojson" + "github.com/blevesearch/geo/s2" +) + +const ( + PointType = "point" + MultiPointType = "multipoint" + LineStringType = "linestring" + MultiLineStringType = "multilinestring" + PolygonType = "polygon" + MultiPolygonType = "multipolygon" + GeometryCollectionType = "geometrycollection" + CircleType = "circle" + EnvelopeType = "envelope" +) + +// spatialPluginsMap is spatial plugin cache. +var ( + spatialPluginsMap = make(map[string]index.SpatialAnalyzerPlugin) + pluginsMapLock = sync.RWMutex{} +) + +func init() { + registerS2RegionTermIndexer() +} + +func registerS2RegionTermIndexer() { + spatialPlugin := S2SpatialAnalyzerPlugin{ + s2Indexer: s2.NewRegionTermIndexerWithOptions(initS2IndexerOptions()), + s2Searcher: s2.NewRegionTermIndexerWithOptions(initS2SearcherOptions()), + s2GeoPointsRegionTermIndexer: s2.NewRegionTermIndexerWithOptions(initS2OptionsForGeoPoints()), + } + + RegisterSpatialAnalyzerPlugin(&spatialPlugin) +} + +// RegisterSpatialAnalyzerPlugin registers the given plugin implementation. +func RegisterSpatialAnalyzerPlugin(plugin index.SpatialAnalyzerPlugin) { + pluginsMapLock.Lock() + spatialPluginsMap[plugin.Type()] = plugin + pluginsMapLock.Unlock() +} + +// GetSpatialAnalyzerPlugin retrieves the given implementation type. +func GetSpatialAnalyzerPlugin(typ string) index.SpatialAnalyzerPlugin { + pluginsMapLock.RLock() + rv := spatialPluginsMap[typ] + pluginsMapLock.RUnlock() + return rv +} + +// initS2IndexerOptions returns the options for s2's region +// term indexer for the index time tokens of geojson shapes. +func initS2IndexerOptions() s2.Options { + options := s2.Options{} + // maxLevel control the maximum size of the + // S2Cells used to approximate regions. + options.SetMaxLevel(16) + + // minLevel control the minimum size of the + // S2Cells used to approximate regions. + options.SetMinLevel(2) + + // levelMod value greater than 1 increases the effective branching + // factor of the S2Cell hierarchy by skipping some levels. + options.SetLevelMod(1) + + // maxCells controls the maximum number of cells + // when approximating each s2 region. + options.SetMaxCells(20) + + return options +} + +// initS2SearcherOptions returns the options for s2's region +// term indexer for the query time tokens of geojson shapes. +func initS2SearcherOptions() s2.Options { + options := s2.Options{} + // maxLevel control the maximum size of the + // S2Cells used to approximate regions. + options.SetMaxLevel(16) + + // minLevel control the minimum size of the + // S2Cells used to approximate regions. + options.SetMinLevel(2) + + // levelMod value greater than 1 increases the effective branching + // factor of the S2Cell hierarchy by skipping some levels. + options.SetLevelMod(1) + + // maxCells controls the maximum number of cells + // when approximating each s2 region. + options.SetMaxCells(8) + + return options +} + +// initS2OptionsForGeoPoints returns the options for +// s2's region term indexer for the original geopoints. +func initS2OptionsForGeoPoints() s2.Options { + options := s2.Options{} + // maxLevel control the maximum size of the + // S2Cells used to approximate regions. + options.SetMaxLevel(16) + + // minLevel control the minimum size of the + // S2Cells used to approximate regions. + options.SetMinLevel(4) + + // levelMod value greater than 1 increases the effective branching + // factor of the S2Cell hierarchy by skipping some levels. + options.SetLevelMod(2) + + // maxCells controls the maximum number of cells + // when approximating each s2 region. + options.SetMaxCells(8) + + // explicit for geo points. + options.SetPointsOnly(true) + + return options +} + +// S2SpatialAnalyzerPlugin is an implementation of +// the index.SpatialAnalyzerPlugin interface. +type S2SpatialAnalyzerPlugin struct { + s2Indexer *s2.RegionTermIndexer + s2Searcher *s2.RegionTermIndexer + s2GeoPointsRegionTermIndexer *s2.RegionTermIndexer +} + +func (s *S2SpatialAnalyzerPlugin) Type() string { + return "s2" +} + +func (s *S2SpatialAnalyzerPlugin) GetIndexTokens(queryShape index.GeoJSON) []string { + var rv []string + shapes := []index.GeoJSON{queryShape} + if gc, ok := queryShape.(*geojson.GeometryCollection); ok { + shapes = gc.Shapes + } + + for _, shape := range shapes { + if s2t, ok := shape.(s2Tokenizable); ok { + rv = append(rv, s2t.IndexTokens(s.s2Indexer)...) + } else if s2t, ok := shape.(s2TokenizableEx); ok { + rv = append(rv, s2t.IndexTokens(s)...) + } + } + + return geojson.DeduplicateTerms(rv) +} + +func (s *S2SpatialAnalyzerPlugin) GetQueryTokens(queryShape index.GeoJSON) []string { + var rv []string + shapes := []index.GeoJSON{queryShape} + if gc, ok := queryShape.(*geojson.GeometryCollection); ok { + shapes = gc.Shapes + } + + for _, shape := range shapes { + if s2t, ok := shape.(s2Tokenizable); ok { + rv = append(rv, s2t.QueryTokens(s.s2Searcher)...) + } else if s2t, ok := shape.(s2TokenizableEx); ok { + rv = append(rv, s2t.QueryTokens(s)...) + } + } + + return geojson.DeduplicateTerms(rv) +} + +// ------------------------------------------------------------------------ +// s2Tokenizable is an optional interface for shapes that support +// the generation of s2 based tokens that can be used for both +// indexing and querying. + +type s2Tokenizable interface { + // IndexTokens returns the tokens for indexing. + IndexTokens(*s2.RegionTermIndexer) []string + + // QueryTokens returns the tokens for searching. + QueryTokens(*s2.RegionTermIndexer) []string +} + +// ------------------------------------------------------------------------ +// s2TokenizableEx is an optional interface for shapes that support +// the generation of s2 based tokens that can be used for both +// indexing and querying. This is intended for the older geopoint +// indexing and querying. +type s2TokenizableEx interface { + // IndexTokens returns the tokens for indexing. + IndexTokens(*S2SpatialAnalyzerPlugin) []string + + // QueryTokens returns the tokens for searching. + QueryTokens(*S2SpatialAnalyzerPlugin) []string +} + +//---------------------------------------------------------------------------------- + +func (p *Point) Type() string { + return PointType +} + +func (p *Point) Value() ([]byte, error) { + return json.Marshal(p) +} + +func (p *Point) Intersects(s index.GeoJSON) (bool, error) { + // placeholder implementation + return false, nil +} + +func (p *Point) Contains(s index.GeoJSON) (bool, error) { + // placeholder implementation + return false, nil +} + +func (p *Point) IndexTokens(s *S2SpatialAnalyzerPlugin) []string { + return s.s2GeoPointsRegionTermIndexer.GetIndexTermsForPoint(s2.PointFromLatLng( + s2.LatLngFromDegrees(p.Lat, p.Lon)), "") +} + +func (p *Point) QueryTokens(s *S2SpatialAnalyzerPlugin) []string { + return nil +} + +//---------------------------------------------------------------------------------- + +type boundedRectangle struct { + minLat float64 + maxLat float64 + minLon float64 + maxLon float64 +} + +func NewBoundedRectangle(minLat, minLon, maxLat, + maxLon float64) *boundedRectangle { + return &boundedRectangle{minLat: minLat, + maxLat: maxLat, minLon: minLon, maxLon: maxLon} +} + +func (br *boundedRectangle) Type() string { + // placeholder implementation + return "boundedRectangle" +} + +func (br *boundedRectangle) Value() ([]byte, error) { + return json.Marshal(br) +} + +func (p *boundedRectangle) Intersects(s index.GeoJSON) (bool, error) { + // placeholder implementation + return false, nil +} + +func (p *boundedRectangle) Contains(s index.GeoJSON) (bool, error) { + // placeholder implementation + return false, nil +} + +func (br *boundedRectangle) IndexTokens(s *S2SpatialAnalyzerPlugin) []string { + return nil +} + +func (br *boundedRectangle) QueryTokens(s *S2SpatialAnalyzerPlugin) []string { + rect := s2.RectFromDegrees(br.minLat, br.minLon, br.maxLat, br.maxLon) + + // obtain the terms to be searched for the given bounding box. + terms := s.s2GeoPointsRegionTermIndexer.GetQueryTermsForRegion(rect, "") + + return geojson.StripCoveringTerms(terms) +} + +//---------------------------------------------------------------------------------- + +type boundedPolygon struct { + coordinates []Point +} + +func NewBoundedPolygon(coordinates []Point) *boundedPolygon { + return &boundedPolygon{coordinates: coordinates} +} + +func (bp *boundedPolygon) Type() string { + // placeholder implementation + return "boundedPolygon" +} + +func (bp *boundedPolygon) Value() ([]byte, error) { + return json.Marshal(bp) +} + +func (p *boundedPolygon) Intersects(s index.GeoJSON) (bool, error) { + // placeholder implementation + return false, nil +} + +func (p *boundedPolygon) Contains(s index.GeoJSON) (bool, error) { + // placeholder implementation + return false, nil +} + +func (bp *boundedPolygon) IndexTokens(s *S2SpatialAnalyzerPlugin) []string { + return nil +} + +func (bp *boundedPolygon) QueryTokens(s *S2SpatialAnalyzerPlugin) []string { + vertices := make([]s2.Point, len(bp.coordinates)) + for i, point := range bp.coordinates { + vertices[i] = s2.PointFromLatLng( + s2.LatLngFromDegrees(point.Lat, point.Lon)) + } + s2polygon := s2.PolygonFromOrientedLoops([]*s2.Loop{s2.LoopFromPoints(vertices)}) + + // obtain the terms to be searched for the given polygon. + terms := s.s2GeoPointsRegionTermIndexer.GetQueryTermsForRegion( + s2polygon.CapBound(), "") + + return geojson.StripCoveringTerms(terms) +} + +//---------------------------------------------------------------------------------- + +type pointDistance struct { + dist float64 + centerLat float64 + centerLon float64 +} + +func (p *pointDistance) Type() string { + // placeholder implementation + return "pointDistance" +} + +func (p *pointDistance) Value() ([]byte, error) { + return json.Marshal(p) +} + +func NewPointDistance(centerLat, centerLon, + dist float64) *pointDistance { + return &pointDistance{centerLat: centerLat, + centerLon: centerLon, dist: dist} +} + +func (p *pointDistance) Intersects(s index.GeoJSON) (bool, error) { + // placeholder implementation + return false, nil +} + +func (p *pointDistance) Contains(s index.GeoJSON) (bool, error) { + // placeholder implementation + return false, nil +} + +func (pd *pointDistance) IndexTokens(s *S2SpatialAnalyzerPlugin) []string { + return nil +} + +func (pd *pointDistance) QueryTokens(s *S2SpatialAnalyzerPlugin) []string { + // obtain the covering query region from the given points. + queryRegion := s2.CapFromCenterAndRadius(pd.centerLat, + pd.centerLon, pd.dist) + + // obtain the query terms for the query region. + terms := s.s2GeoPointsRegionTermIndexer.GetQueryTermsForRegion(queryRegion, "") + + return geojson.StripCoveringTerms(terms) +} + +// ------------------------------------------------------------------------ + +// NewGeometryCollection instantiate a geometrycollection +// and prefix the byte contents with certain glue bytes that +// can be used later while filering the doc values. +func NewGeometryCollection(coordinates [][][][][]float64, + typs []string) (index.GeoJSON, []byte, error) { + + return geojson.NewGeometryCollection(coordinates, typs) +} + +// NewGeoCircleShape instantiate a circle shape and +// prefix the byte contents with certain glue bytes that +// can be used later while filering the doc values. +func NewGeoCircleShape(cp []float64, + radius string) (index.GeoJSON, []byte, error) { + return geojson.NewGeoCircleShape(cp, radius) +} + +func NewGeoJsonShape(coordinates [][][][]float64, typ string) ( + index.GeoJSON, []byte, error) { + return geojson.NewGeoJsonShape(coordinates, typ) +} + +func NewGeoJsonPoint(points []float64) index.GeoJSON { + return geojson.NewGeoJsonPoint(points) +} + +func NewGeoJsonMultiPoint(points [][]float64) index.GeoJSON { + return geojson.NewGeoJsonMultiPoint(points) +} + +func NewGeoJsonLinestring(points [][]float64) index.GeoJSON { + return geojson.NewGeoJsonLinestring(points) +} + +func NewGeoJsonMultilinestring(points [][][]float64) index.GeoJSON { + return geojson.NewGeoJsonMultilinestring(points) +} + +func NewGeoJsonPolygon(points [][][]float64) index.GeoJSON { + return geojson.NewGeoJsonPolygon(points) +} + +func NewGeoJsonMultiPolygon(points [][][][]float64) index.GeoJSON { + return geojson.NewGeoJsonMultiPolygon(points) +} + +func NewGeoCircle(points []float64, radius string) index.GeoJSON { + return geojson.NewGeoCircle(points, radius) +} + +func NewGeoEnvelope(points [][]float64) index.GeoJSON { + return geojson.NewGeoEnvelope(points) +} + +func ParseGeoJSONShape(input json.RawMessage) (index.GeoJSON, error) { + return geojson.ParseGeoJSONShape(input) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/geo/geohash.go b/backend/vendor/github.com/blevesearch/bleve/v2/geo/geohash.go new file mode 100644 index 0000000000..d3d4dfa8b5 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/geo/geohash.go @@ -0,0 +1,111 @@ +// Copyright (c) 2019 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// This implementation is inspired from the geohash-js +// ref: https://github.com/davetroy/geohash-js + +package geo + +// encoding encapsulates an encoding defined by a given base32 alphabet. +type encoding struct { + enc string + dec [256]byte +} + +// newEncoding constructs a new encoding defined by the given alphabet, +// which must be a 32-byte string. +func newEncoding(encoder string) *encoding { + e := new(encoding) + e.enc = encoder + for i := 0; i < len(e.dec); i++ { + e.dec[i] = 0xff + } + for i := 0; i < len(encoder); i++ { + e.dec[encoder[i]] = byte(i) + } + return e +} + +// base32encoding with the Geohash alphabet. +var base32encoding = newEncoding("0123456789bcdefghjkmnpqrstuvwxyz") + +var masks = []uint64{16, 8, 4, 2, 1} + +// DecodeGeoHash decodes the string geohash faster with +// higher precision. This api is in experimental phase. +func DecodeGeoHash(geoHash string) (float64, float64) { + even := true + lat := []float64{-90.0, 90.0} + lon := []float64{-180.0, 180.0} + + for i := 0; i < len(geoHash); i++ { + cd := uint64(base32encoding.dec[geoHash[i]]) + for j := 0; j < 5; j++ { + if even { + if cd&masks[j] > 0 { + lon[0] = (lon[0] + lon[1]) / 2 + } else { + lon[1] = (lon[0] + lon[1]) / 2 + } + } else { + if cd&masks[j] > 0 { + lat[0] = (lat[0] + lat[1]) / 2 + } else { + lat[1] = (lat[0] + lat[1]) / 2 + } + } + even = !even + } + } + + return (lat[0] + lat[1]) / 2, (lon[0] + lon[1]) / 2 +} + +func EncodeGeoHash(lat, lon float64) string { + even := true + lats := []float64{-90.0, 90.0} + lons := []float64{-180.0, 180.0} + precision := 12 + var ch, bit uint64 + var geoHash string + + for len(geoHash) < precision { + if even { + mid := (lons[0] + lons[1]) / 2 + if lon > mid { + ch |= masks[bit] + lons[0] = mid + } else { + lons[1] = mid + } + } else { + mid := (lats[0] + lats[1]) / 2 + if lat > mid { + ch |= masks[bit] + lats[0] = mid + } else { + lats[1] = mid + } + } + even = !even + if bit < 4 { + bit++ + } else { + geoHash += string(base32encoding.enc[ch]) + ch = 0 + bit = 0 + } + } + + return geoHash +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/geo/parse.go b/backend/vendor/github.com/blevesearch/bleve/v2/geo/parse.go new file mode 100644 index 0000000000..cc7beddc88 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/geo/parse.go @@ -0,0 +1,458 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package geo + +import ( + "reflect" + "strconv" + "strings" +) + +// ExtractGeoPoint takes an arbitrary interface{} and tries it's best to +// interpret it is as geo point. Supported formats: +// Container: +// slice length 2 (GeoJSON) +// first element lon, second element lat +// string (coordinates separated by comma, or a geohash) +// first element lat, second element lon +// map[string]interface{} +// exact keys lat and lon or lng +// struct +// w/exported fields case-insensitive match on lat and lon or lng +// struct +// satisfying Later and Loner or Lnger interfaces +// +// in all cases values must be some sort of numeric-like thing: int/uint/float +func ExtractGeoPoint(thing interface{}) (lon, lat float64, success bool) { + var foundLon, foundLat bool + + thingVal := reflect.ValueOf(thing) + if !thingVal.IsValid() { + return lon, lat, false + } + + thingTyp := thingVal.Type() + + // is it a slice + if thingVal.Kind() == reflect.Slice { + // must be length 2 + if thingVal.Len() == 2 { + first := thingVal.Index(0) + if first.CanInterface() { + firstVal := first.Interface() + lon, foundLon = extractNumericVal(firstVal) + } + second := thingVal.Index(1) + if second.CanInterface() { + secondVal := second.Interface() + lat, foundLat = extractNumericVal(secondVal) + } + } + } + + // is it a string + if thingVal.Kind() == reflect.String { + geoStr := thingVal.Interface().(string) + if strings.Contains(geoStr, ",") { + // geo point with coordinates split by comma + points := strings.Split(geoStr, ",") + for i, point := range points { + // trim any leading or trailing white spaces + points[i] = strings.TrimSpace(point) + } + if len(points) == 2 { + var err error + lat, err = strconv.ParseFloat(points[0], 64) + if err == nil { + foundLat = true + } + lon, err = strconv.ParseFloat(points[1], 64) + if err == nil { + foundLon = true + } + } + } else { + // geohash + if len(geoStr) <= geoHashMaxLength { + lat, lon = DecodeGeoHash(geoStr) + foundLat = true + foundLon = true + } + } + } + + // is it a map + if l, ok := thing.(map[string]interface{}); ok { + if lval, ok := l["lon"]; ok { + lon, foundLon = extractNumericVal(lval) + } else if lval, ok := l["lng"]; ok { + lon, foundLon = extractNumericVal(lval) + } + if lval, ok := l["lat"]; ok { + lat, foundLat = extractNumericVal(lval) + } + } + + // now try reflection on struct fields + if thingVal.Kind() == reflect.Struct { + for i := 0; i < thingVal.NumField(); i++ { + fieldName := thingTyp.Field(i).Name + if strings.HasPrefix(strings.ToLower(fieldName), "lon") { + if thingVal.Field(i).CanInterface() { + fieldVal := thingVal.Field(i).Interface() + lon, foundLon = extractNumericVal(fieldVal) + } + } + if strings.HasPrefix(strings.ToLower(fieldName), "lng") { + if thingVal.Field(i).CanInterface() { + fieldVal := thingVal.Field(i).Interface() + lon, foundLon = extractNumericVal(fieldVal) + } + } + if strings.HasPrefix(strings.ToLower(fieldName), "lat") { + if thingVal.Field(i).CanInterface() { + fieldVal := thingVal.Field(i).Interface() + lat, foundLat = extractNumericVal(fieldVal) + } + } + } + } + + // last hope, some interfaces + // lon + if l, ok := thing.(loner); ok { + lon = l.Lon() + foundLon = true + } else if l, ok := thing.(lnger); ok { + lon = l.Lng() + foundLon = true + } + // lat + if l, ok := thing.(later); ok { + lat = l.Lat() + foundLat = true + } + + return lon, lat, foundLon && foundLat +} + +// extract numeric value (if possible) and returns a float64 +func extractNumericVal(v interface{}) (float64, bool) { + val := reflect.ValueOf(v) + if !val.IsValid() { + return 0, false + } + typ := val.Type() + switch typ.Kind() { + case reflect.Float32, reflect.Float64: + return val.Float(), true + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return float64(val.Int()), true + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return float64(val.Uint()), true + } + + return 0, false +} + +// various support interfaces which can be used to find lat/lon +type loner interface { + Lon() float64 +} + +type later interface { + Lat() float64 +} + +type lnger interface { + Lng() float64 +} + +// GlueBytes primarily for quicker filtering of docvalues +// during the filtering phase. +var GlueBytes = []byte("##") + +var GlueBytesOffset = len(GlueBytes) + +func extractCoordinates(thing interface{}) []float64 { + thingVal := reflect.ValueOf(thing) + if !thingVal.IsValid() { + return nil + } + + if thingVal.Kind() == reflect.Slice { + // must be length 2 + if thingVal.Len() == 2 { + var foundLon, foundLat bool + var lon, lat float64 + first := thingVal.Index(0) + if first.CanInterface() { + firstVal := first.Interface() + lon, foundLon = extractNumericVal(firstVal) + } + second := thingVal.Index(1) + if second.CanInterface() { + secondVal := second.Interface() + lat, foundLat = extractNumericVal(secondVal) + } + + if !foundLon || !foundLat { + return nil + } + + return []float64{lon, lat} + } + } + return nil +} + +func extract2DCoordinates(thing interface{}) [][]float64 { + thingVal := reflect.ValueOf(thing) + if !thingVal.IsValid() { + return nil + } + + rv := make([][]float64, 0, 8) + if thingVal.Kind() == reflect.Slice { + for j := 0; j < thingVal.Len(); j++ { + edges := thingVal.Index(j).Interface() + if es, ok := edges.([]interface{}); ok { + v := extractCoordinates(es) + if len(v) == 2 { + rv = append(rv, v) + } + } + } + + return rv + } + + return nil +} + +func extract3DCoordinates(thing interface{}) (c [][][]float64) { + coords := reflect.ValueOf(thing) + for i := 0; i < coords.Len(); i++ { + vals := coords.Index(i) + + edges := vals.Interface() + if es, ok := edges.([]interface{}); ok { + loop := extract2DCoordinates(es) + if len(loop) > 0 { + c = append(c, loop) + } + } + } + + return c +} + +func extract4DCoordinates(thing interface{}) (rv [][][][]float64) { + thingVal := reflect.ValueOf(thing) + if !thingVal.IsValid() { + return nil + } + + if thingVal.Kind() == reflect.Slice { + for j := 0; j < thingVal.Len(); j++ { + c := extract3DCoordinates(thingVal.Index(j).Interface()) + rv = append(rv, c) + } + } + + return rv +} + +func ParseGeoShapeField(thing interface{}) (interface{}, string, error) { + thingVal := reflect.ValueOf(thing) + if !thingVal.IsValid() { + return nil, "", nil + } + + var shape string + var coordValue interface{} + + if thingVal.Kind() == reflect.Map { + iter := thingVal.MapRange() + for iter.Next() { + if iter.Key().String() == "type" { + shape = iter.Value().Interface().(string) + continue + } + + if iter.Key().String() == "coordinates" { + coordValue = iter.Value().Interface() + } + } + } + + return coordValue, strings.ToLower(shape), nil +} + +func extractGeoShape(thing interface{}) ([][][][]float64, string, bool) { + coordValue, typ, err := ParseGeoShapeField(thing) + if err != nil { + return nil, "", false + } + + return ExtractGeoShapeCoordinates(coordValue, typ) +} + +// ExtractGeometryCollection takes an interface{} and tries it's best to +// interpret all the member geojson shapes within it. +func ExtractGeometryCollection(thing interface{}) ([][][][][]float64, []string, bool) { + thingVal := reflect.ValueOf(thing) + if !thingVal.IsValid() { + return nil, nil, false + } + var rv [][][][][]float64 + var types []string + var f bool + + if thingVal.Kind() == reflect.Map { + iter := thingVal.MapRange() + for iter.Next() { + + if iter.Key().String() == "type" { + continue + } + + if iter.Key().String() == "geometries" { + collection := iter.Value().Interface() + items := reflect.ValueOf(collection) + + for j := 0; j < items.Len(); j++ { + coords, shape, found := extractGeoShape(items.Index(j).Interface()) + if found { + f = found + rv = append(rv, coords) + types = append(types, shape) + } + } + } + } + } + + return rv, types, f +} + +// ExtractCircle takes an interface{} and tries it's best to +// interpret the center point coordinates and the radius for a +// given circle shape. +func ExtractCircle(thing interface{}) ([]float64, string, bool) { + thingVal := reflect.ValueOf(thing) + if !thingVal.IsValid() { + return nil, "", false + } + var rv []float64 + var radiusStr string + + if thingVal.Kind() == reflect.Map { + iter := thingVal.MapRange() + for iter.Next() { + + if iter.Key().String() == "radius" { + radiusStr = iter.Value().Interface().(string) + continue + } + + if iter.Key().String() == "coordinates" { + lng, lat, found := ExtractGeoPoint(iter.Value().Interface()) + if !found { + return nil, radiusStr, false + } + rv = append(rv, lng) + rv = append(rv, lat) + } + } + } + + return rv, radiusStr, true +} + +// ExtractGeoShapeCoordinates takes an interface{} and tries it's best to +// interpret the coordinates for any of the given geoshape typ like +// a point, multipoint, linestring, multilinestring, polygon, multipolygon, +func ExtractGeoShapeCoordinates(coordValue interface{}, + typ string) ([][][][]float64, string, bool) { + var rv [][][][]float64 + if typ == PointType { + point := extractCoordinates(coordValue) + + // ignore the contents with invalid entry. + if len(point) < 2 { + return nil, typ, false + } + + rv = [][][][]float64{{{point}}} + return rv, typ, true + } + + if typ == MultiPointType || typ == LineStringType || + typ == EnvelopeType { + coords := extract2DCoordinates(coordValue) + + // ignore the contents with invalid entry. + if len(coords) == 0 { + return nil, typ, false + } + + if typ == EnvelopeType && len(coords) != 2 { + return nil, typ, false + } + + if typ == LineStringType && len(coords) < 2 { + return nil, typ, false + } + + rv = [][][][]float64{{coords}} + return rv, typ, true + } + + if typ == PolygonType || typ == MultiLineStringType { + coords := extract3DCoordinates(coordValue) + + // ignore the contents with invalid entry. + if len(coords) == 0 { + return nil, typ, false + } + + if typ == PolygonType && len(coords[0]) < 3 || + typ == MultiLineStringType && len(coords[0]) < 2 { + return nil, typ, false + } + + rv = [][][][]float64{coords} + return rv, typ, true + } + + if typ == MultiPolygonType { + rv = extract4DCoordinates(coordValue) + + // ignore the contents with invalid entry. + if len(rv) == 0 || len(rv[0]) == 0 { + return nil, typ, false + + } + + if len(rv[0][0]) < 3 { + return nil, typ, false + } + + return rv, typ, true + } + + return rv, typ, false +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/geo/sloppy.go b/backend/vendor/github.com/blevesearch/bleve/v2/geo/sloppy.go new file mode 100644 index 0000000000..0ce646d74a --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/geo/sloppy.go @@ -0,0 +1,212 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package geo + +import ( + "math" +) + +var earthDiameterPerLatitude []float64 +var sinTab []float64 +var cosTab []float64 +var asinTab []float64 +var asinDer1DivF1Tab []float64 +var asinDer2DivF2Tab []float64 +var asinDer3DivF3Tab []float64 +var asinDer4DivF4Tab []float64 + +const radiusTabsSize = (1 << 10) + 1 +const radiusDelta = (math.Pi / 2) / (radiusTabsSize - 1) +const radiusIndexer = 1 / radiusDelta +const sinCosTabsSize = (1 << 11) + 1 +const asinTabsSize = (1 << 13) + 1 +const oneDivF2 = 1 / 2.0 +const oneDivF3 = 1 / 6.0 +const oneDivF4 = 1 / 24.0 + +// 1.57079632673412561417e+00 first 33 bits of pi/2 +var pio2Hi = math.Float64frombits(0x3FF921FB54400000) + +// 6.07710050650619224932e-11 pi/2 - PIO2_HI +var pio2Lo = math.Float64frombits(0x3DD0B4611A626331) + +var asinPio2Hi = math.Float64frombits(0x3FF921FB54442D18) // 1.57079632679489655800e+00 +var asinPio2Lo = math.Float64frombits(0x3C91A62633145C07) // 6.12323399573676603587e-17 +var asinPs0 = math.Float64frombits(0x3fc5555555555555) // 1.66666666666666657415e-01 +var asinPs1 = math.Float64frombits(0xbfd4d61203eb6f7d) // -3.25565818622400915405e-01 +var asinPs2 = math.Float64frombits(0x3fc9c1550e884455) // 2.01212532134862925881e-01 +var asinPs3 = math.Float64frombits(0xbfa48228b5688f3b) // -4.00555345006794114027e-02 +var asinPs4 = math.Float64frombits(0x3f49efe07501b288) // 7.91534994289814532176e-04 +var asinPs5 = math.Float64frombits(0x3f023de10dfdf709) // 3.47933107596021167570e-05 +var asinQs1 = math.Float64frombits(0xc0033a271c8a2d4b) // -2.40339491173441421878e+00 +var asinQs2 = math.Float64frombits(0x40002ae59c598ac8) // 2.02094576023350569471e+00 +var asinQs3 = math.Float64frombits(0xbfe6066c1b8d0159) // -6.88283971605453293030e-01 +var asinQs4 = math.Float64frombits(0x3fb3b8c5b12e9282) // 7.70381505559019352791e-02 + +var twoPiHi = 4 * pio2Hi +var twoPiLo = 4 * pio2Lo +var sinCosDeltaHi = twoPiHi/sinCosTabsSize - 1 +var sinCosDeltaLo = twoPiLo/sinCosTabsSize - 1 +var sinCosIndexer = 1 / (sinCosDeltaHi + sinCosDeltaLo) +var sinCosMaxValueForIntModulo = ((math.MaxInt64 >> 9) / sinCosIndexer) * 0.99 +var asinMaxValueForTabs = math.Sin(73.0 * degreesToRadian) + +var asinDelta = asinMaxValueForTabs / (asinTabsSize - 1) +var asinIndexer = 1 / asinDelta + +func init() { + // initializes the tables used for the sloppy math functions + + // sin and cos + sinTab = make([]float64, sinCosTabsSize) + cosTab = make([]float64, sinCosTabsSize) + sinCosPiIndex := (sinCosTabsSize - 1) / 2 + sinCosPiMul2Index := 2 * sinCosPiIndex + sinCosPiMul05Index := sinCosPiIndex / 2 + sinCosPiMul15Index := 3 * sinCosPiIndex / 2 + for i := 0; i < sinCosTabsSize; i++ { + // angle: in [0,2*PI]. + angle := float64(i)*sinCosDeltaHi + float64(i)*sinCosDeltaLo + sinAngle := math.Sin(angle) + cosAngle := math.Cos(angle) + // For indexes corresponding to null cosine or sine, we make sure the value is zero + // and not an epsilon. This allows for a much better accuracy for results close to zero. + if i == sinCosPiIndex { + sinAngle = 0.0 + } else if i == sinCosPiMul2Index { + sinAngle = 0.0 + } else if i == sinCosPiMul05Index { + sinAngle = 0.0 + } else if i == sinCosPiMul15Index { + sinAngle = 0.0 + } + sinTab[i] = sinAngle + cosTab[i] = cosAngle + } + + // asin + asinTab = make([]float64, asinTabsSize) + asinDer1DivF1Tab = make([]float64, asinTabsSize) + asinDer2DivF2Tab = make([]float64, asinTabsSize) + asinDer3DivF3Tab = make([]float64, asinTabsSize) + asinDer4DivF4Tab = make([]float64, asinTabsSize) + for i := 0; i < asinTabsSize; i++ { + // x: in [0,ASIN_MAX_VALUE_FOR_TABS]. + x := float64(i) * asinDelta + asinTab[i] = math.Asin(x) + oneMinusXSqInv := 1.0 / (1 - x*x) + oneMinusXSqInv05 := math.Sqrt(oneMinusXSqInv) + oneMinusXSqInv15 := oneMinusXSqInv05 * oneMinusXSqInv + oneMinusXSqInv25 := oneMinusXSqInv15 * oneMinusXSqInv + oneMinusXSqInv35 := oneMinusXSqInv25 * oneMinusXSqInv + asinDer1DivF1Tab[i] = oneMinusXSqInv05 + asinDer2DivF2Tab[i] = (x * oneMinusXSqInv15) * oneDivF2 + asinDer3DivF3Tab[i] = ((1 + 2*x*x) * oneMinusXSqInv25) * oneDivF3 + asinDer4DivF4Tab[i] = ((5 + 2*x*(2+x*(5-2*x))) * oneMinusXSqInv35) * oneDivF4 + } + + // earth radius + a := 6378137.0 + b := 6356752.31420 + a2 := a * a + b2 := b * b + earthDiameterPerLatitude = make([]float64, radiusTabsSize) + earthDiameterPerLatitude[0] = 2.0 * a / 1000 + earthDiameterPerLatitude[radiusTabsSize-1] = 2.0 * b / 1000 + for i := 1; i < radiusTabsSize-1; i++ { + lat := math.Pi * float64(i) / (2*radiusTabsSize - 1) + one := math.Pow(a2*math.Cos(lat), 2) + two := math.Pow(b2*math.Sin(lat), 2) + three := math.Pow(float64(a)*math.Cos(lat), 2) + four := math.Pow(b*math.Sin(lat), 2) + radius := math.Sqrt((one + two) / (three + four)) + earthDiameterPerLatitude[i] = 2 * radius / 1000 + } +} + +// earthDiameter returns an estimation of the earth's diameter at the specified +// latitude in kilometers +func earthDiameter(lat float64) float64 { + index := math.Mod(math.Abs(lat)*radiusIndexer+0.5, float64(len(earthDiameterPerLatitude))) + if math.IsNaN(index) { + return 0 + } + return earthDiameterPerLatitude[int(index)] +} + +var pio2 = math.Pi / 2 + +func sin(a float64) float64 { + return cos(a - pio2) +} + +// cos is a sloppy math (faster) implementation of math.Cos +func cos(a float64) float64 { + if a < 0.0 { + a = -a + } + if a > sinCosMaxValueForIntModulo { + return math.Cos(a) + } + // index: possibly outside tables range. + index := int(a*sinCosIndexer + 0.5) + delta := (a - float64(index)*sinCosDeltaHi) - float64(index)*sinCosDeltaLo + // Making sure index is within tables range. + // Last value of each table is the same than first, so we ignore it (tabs size minus one) for modulo. + index &= (sinCosTabsSize - 2) // index % (SIN_COS_TABS_SIZE-1) + indexCos := cosTab[index] + indexSin := sinTab[index] + return indexCos + delta*(-indexSin+delta*(-indexCos*oneDivF2+delta*(indexSin*oneDivF3+delta*indexCos*oneDivF4))) +} + +// asin is a sloppy math (faster) implementation of math.Asin +func asin(a float64) float64 { + var negateResult bool + if a < 0 { + a = -a + negateResult = true + } + if a <= asinMaxValueForTabs { + index := int(a*asinIndexer + 0.5) + delta := a - float64(index)*asinDelta + result := asinTab[index] + delta*(asinDer1DivF1Tab[index]+delta*(asinDer2DivF2Tab[index]+delta*(asinDer3DivF3Tab[index]+delta*asinDer4DivF4Tab[index]))) + if negateResult { + return -result + } + return result + } + // value > ASIN_MAX_VALUE_FOR_TABS, or value is NaN + // This part is derived from fdlibm. + if a < 1 { + t := (1.0 - a) * 0.5 + p := t * (asinPs0 + t*(asinPs1+t*(asinPs2+t*(asinPs3+t*(asinPs4+t+asinPs5))))) + q := 1.0 + t*(asinQs1+t*(asinQs2+t*(asinQs3+t*asinQs4))) + s := math.Sqrt(t) + z := s + s*(p/q) + result := asinPio2Hi - ((z + z) - asinPio2Lo) + if negateResult { + return -result + } + return result + } + // value >= 1.0, or value is NaN + if a == 1.0 { + if negateResult { + return -math.Pi / 2 + } + return math.Pi / 2 + } + return math.NaN() +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index.go b/backend/vendor/github.com/blevesearch/bleve/v2/index.go new file mode 100644 index 0000000000..7d4c9be9be --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index.go @@ -0,0 +1,322 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bleve + +import ( + "context" + + "github.com/blevesearch/bleve/v2/index/upsidedown" + + "github.com/blevesearch/bleve/v2/document" + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +// A Batch groups together multiple Index and Delete +// operations you would like performed at the same +// time. The Batch structure is NOT thread-safe. +// You should only perform operations on a batch +// from a single thread at a time. Once batch +// execution has started, you may not modify it. +type Batch struct { + index Index + internal *index.Batch + + lastDocSize uint64 + totalSize uint64 +} + +// Index adds the specified index operation to the +// batch. NOTE: the bleve Index is not updated +// until the batch is executed. +func (b *Batch) Index(id string, data interface{}) error { + if id == "" { + return ErrorEmptyID + } + doc := document.NewDocument(id) + err := b.index.Mapping().MapDocument(doc, data) + if err != nil { + return err + } + b.internal.Update(doc) + + b.lastDocSize = uint64(doc.Size() + + len(id) + size.SizeOfString) // overhead from internal + b.totalSize += b.lastDocSize + + return nil +} + +func (b *Batch) LastDocSize() uint64 { + return b.lastDocSize +} + +func (b *Batch) TotalDocsSize() uint64 { + return b.totalSize +} + +// IndexAdvanced adds the specified index operation to the +// batch which skips the mapping. NOTE: the bleve Index is not updated +// until the batch is executed. +func (b *Batch) IndexAdvanced(doc *document.Document) (err error) { + if doc.ID() == "" { + return ErrorEmptyID + } + b.internal.Update(doc) + return nil +} + +// Delete adds the specified delete operation to the +// batch. NOTE: the bleve Index is not updated until +// the batch is executed. +func (b *Batch) Delete(id string) { + if id != "" { + b.internal.Delete(id) + } +} + +// SetInternal adds the specified set internal +// operation to the batch. NOTE: the bleve Index is +// not updated until the batch is executed. +func (b *Batch) SetInternal(key, val []byte) { + b.internal.SetInternal(key, val) +} + +// DeleteInternal adds the specified delete internal +// operation to the batch. NOTE: the bleve Index is +// not updated until the batch is executed. +func (b *Batch) DeleteInternal(key []byte) { + b.internal.DeleteInternal(key) +} + +// Size returns the total number of operations inside the batch +// including normal index operations and internal operations. +func (b *Batch) Size() int { + return len(b.internal.IndexOps) + len(b.internal.InternalOps) +} + +// String prints a user friendly string representation of what +// is inside this batch. +func (b *Batch) String() string { + return b.internal.String() +} + +// Reset returns a Batch to the empty state so that it can +// be re-used in the future. +func (b *Batch) Reset() { + b.internal.Reset() + b.lastDocSize = 0 + b.totalSize = 0 +} + +func (b *Batch) Merge(o *Batch) { + if o != nil && o.internal != nil { + b.internal.Merge(o.internal) + if o.LastDocSize() > 0 { + b.lastDocSize = o.LastDocSize() + } + b.totalSize = uint64(b.internal.TotalDocSize()) + } +} + +func (b *Batch) SetPersistedCallback(f index.BatchCallback) { + b.internal.SetPersistedCallback(f) +} + +func (b *Batch) PersistedCallback() index.BatchCallback { + return b.internal.PersistedCallback() +} + +// An Index implements all the indexing and searching +// capabilities of bleve. An Index can be created +// using the New() and Open() methods. +// +// Index() takes an input value, deduces a DocumentMapping for its type, +// assigns string paths to its fields or values then applies field mappings on +// them. +// +// The DocumentMapping used to index a value is deduced by the following rules: +// 1. If value implements mapping.bleveClassifier interface, resolve the mapping +// from BleveType(). +// 2. If value implements mapping.Classifier interface, resolve the mapping +// from Type(). +// 3. If value has a string field or value at IndexMapping.TypeField. +// +// (defaulting to "_type"), use it to resolve the mapping. Fields addressing +// is described below. +// 4) If IndexMapping.DefaultType is registered, return it. +// 5) Return IndexMapping.DefaultMapping. +// +// Each field or nested field of the value is identified by a string path, then +// mapped to one or several FieldMappings which extract the result for analysis. +// +// Struct values fields are identified by their "json:" tag, or by their name. +// Nested fields are identified by prefixing with their parent identifier, +// separated by a dot. +// +// Map values entries are identified by their string key. Entries not indexed +// by strings are ignored. Entry values are identified recursively like struct +// fields. +// +// Slice and array values are identified by their field name. Their elements +// are processed sequentially with the same FieldMapping. +// +// String, float64 and time.Time values are identified by their field name. +// Other types are ignored. +// +// Each value identifier is decomposed in its parts and recursively address +// SubDocumentMappings in the tree starting at the root DocumentMapping. If a +// mapping is found, all its FieldMappings are applied to the value. If no +// mapping is found and the root DocumentMapping is dynamic, default mappings +// are used based on value type and IndexMapping default configurations. +// +// Finally, mapped values are analyzed, indexed or stored. See +// FieldMapping.Analyzer to know how an analyzer is resolved for a given field. +// +// Examples: +// +// type Date struct { +// Day string `json:"day"` +// Month string +// Year string +// } +// +// type Person struct { +// FirstName string `json:"first_name"` +// LastName string +// BirthDate Date `json:"birth_date"` +// } +// +// A Person value FirstName is mapped by the SubDocumentMapping at +// "first_name". Its LastName is mapped by the one at "LastName". The day of +// BirthDate is mapped to the SubDocumentMapping "day" of the root +// SubDocumentMapping "birth_date". It will appear as the "birth_date.day" +// field in the index. The month is mapped to "birth_date.Month". +type Index interface { + // Index analyzes, indexes or stores mapped data fields. Supplied + // identifier is bound to analyzed data and will be retrieved by search + // requests. See Index interface documentation for details about mapping + // rules. + Index(id string, data interface{}) error + Delete(id string) error + + NewBatch() *Batch + Batch(b *Batch) error + + // Document returns specified document or nil if the document is not + // indexed or stored. + Document(id string) (index.Document, error) + // DocCount returns the number of documents in the index. + DocCount() (uint64, error) + + Search(req *SearchRequest) (*SearchResult, error) + SearchInContext(ctx context.Context, req *SearchRequest) (*SearchResult, error) + + Fields() ([]string, error) + + FieldDict(field string) (index.FieldDict, error) + FieldDictRange(field string, startTerm []byte, endTerm []byte) (index.FieldDict, error) + FieldDictPrefix(field string, termPrefix []byte) (index.FieldDict, error) + + Close() error + + Mapping() mapping.IndexMapping + + Stats() *IndexStat + StatsMap() map[string]interface{} + + GetInternal(key []byte) ([]byte, error) + SetInternal(key, val []byte) error + DeleteInternal(key []byte) error + + // Name returns the name of the index (by default this is the path) + Name() string + // SetName lets you assign your own logical name to this index + SetName(string) + + // Advanced returns the internal index implementation + Advanced() (index.Index, error) +} + +// New index at the specified path, must not exist. +// The provided mapping will be used for all +// Index/Search operations. +func New(path string, mapping mapping.IndexMapping) (Index, error) { + return newIndexUsing(path, mapping, Config.DefaultIndexType, Config.DefaultKVStore, nil) +} + +// NewMemOnly creates a memory-only index. +// The contents of the index is NOT persisted, +// and will be lost once closed. +// The provided mapping will be used for all +// Index/Search operations. +func NewMemOnly(mapping mapping.IndexMapping) (Index, error) { + return newIndexUsing("", mapping, upsidedown.Name, Config.DefaultMemKVStore, nil) +} + +// NewUsing creates index at the specified path, +// which must not already exist. +// The provided mapping will be used for all +// Index/Search operations. +// The specified index type will be used. +// The specified kvstore implementation will be used +// and the provided kvconfig will be passed to its +// constructor. Note that currently the values of kvconfig must +// be able to be marshaled and unmarshaled using the encoding/json library (used +// when reading/writing the index metadata file). +func NewUsing(path string, mapping mapping.IndexMapping, indexType string, kvstore string, kvconfig map[string]interface{}) (Index, error) { + return newIndexUsing(path, mapping, indexType, kvstore, kvconfig) +} + +// Open index at the specified path, must exist. +// The mapping used when it was created will be used for all Index/Search operations. +func Open(path string) (Index, error) { + return openIndexUsing(path, nil) +} + +// OpenUsing opens index at the specified path, must exist. +// The mapping used when it was created will be used for all Index/Search operations. +// The provided runtimeConfig can override settings +// persisted when the kvstore was created. +func OpenUsing(path string, runtimeConfig map[string]interface{}) (Index, error) { + return openIndexUsing(path, runtimeConfig) +} + +// Builder is a limited interface, used to build indexes in an offline mode. +// Items cannot be updated or deleted, and the caller MUST ensure a document is +// indexed only once. +type Builder interface { + Index(id string, data interface{}) error + Close() error +} + +// NewBuilder creates a builder, which will build an index at the specified path, +// using the specified mapping and options. +func NewBuilder(path string, mapping mapping.IndexMapping, config map[string]interface{}) (Builder, error) { + return newBuilder(path, mapping, config) +} + +// IndexCopyable is an index which supports an online copy operation +// of the index. +type IndexCopyable interface { + // CopyTo creates a fully functional copy of the index at the + // specified destination directory implementation. + CopyTo(d index.Directory) error +} + +// FileSystemDirectory is the default implementation for the +// index.Directory interface. +type FileSystemDirectory string diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/README.md b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/README.md new file mode 100644 index 0000000000..9794aed707 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/README.md @@ -0,0 +1,367 @@ +# scorch + +## Definitions + +Batch +- A collection of Documents to mutate in the index. + +Document +- Has a unique identifier (arbitrary bytes). +- Is comprised of a list of fields. + +Field +- Has a name (string). +- Has a type (text, number, date, geopoint). +- Has a value (depending on type). +- Can be indexed, stored, or both. +- If indexed, can be analyzed. +-m If indexed, can optionally store term vectors. + +## Scope + +Scorch *MUST* implement the bleve.index API without requiring any changes to this API. + +Scorch *MAY* introduce new interfaces, which can be discovered to allow use of new capabilities not in the current API. + +## Implementation + +The scorch implementation starts with the concept of a segmented index. + +A segment is simply a slice, subset, or portion of the entire index. A segmented index is one which is composed of one or more segments. Although segments are created in a particular order, knowing this ordering is not required to achieve correct semantics when querying. Because there is no ordering, this means that when searching an index, you can (and should) search all the segments concurrently. + +### Internal Wrapper + +In order to accommodate the existing APIs while also improving the implementation, the scorch implementation includes some wrapper functionality that must be described. + +#### \_id field + +In scorch, field 0 is prearranged to be named \_id. All documents have a value for this field, which is the documents external identifier. In this version the field *MUST* be both indexed AND stored. The scorch wrapper adds this field, as it will not be present in the Document from the calling bleve code. + +NOTE: If a document already contains a field \_id, it will be replaced. If this is problematic, the caller must ensure such a scenario does not happen. + +### Proposed Structures + +``` +type Segment interface { + + Dictionary(field string) TermDictionary + +} + +type TermDictionary interface { + + PostingsList(term string, excluding PostingsList) PostingsList + +} + +type PostingsList interface { + + Next() Posting + + And(other PostingsList) PostingsList + Or(other PostingsList) PostingsList + +} + +type Posting interface { + Number() uint64 + + Frequency() uint64 + Norm() float64 + + Locations() Locations +} + +type Locations interface { + Start() uint64 + End() uint64 + Pos() uint64 + ArrayPositions() ... +} + +type DeletedDocs { + +} + +type SegmentSnapshot struct { + segment Segment + deleted PostingsList +} + +type IndexSnapshot struct { + segment []SegmentSnapshot +} +``` +**What about errors?** +**What about memory mgmnt or context?** +**Postings List separate iterator to separate stateful from stateless** +### Mutating the Index + +The bleve.index API has methods for directly making individual mutations (Update/Delete/SetInternal/DeleteInternal), however for this first implementation, we assume that all of these calls can simply be turned into a Batch of size 1. This may be highly inefficient, but it will be correct. This decision is made based on the fact that Couchbase FTS always uses Batches. + +NOTE: As a side-effect of this decision, it should be clear that performance tuning may depend on the batch size, which may in-turn require changes in FTS. + +From this point forward, only Batch mutations will be discussed. + +Sequence of Operations: + +1. For each document in the batch, search through all existing segments. The goal is to build up a per-segment bitset which tells us which documents in that segment are obsoleted by the addition of the new segment we're currently building. NOTE: we're not ready for this change to take effect yet, so rather than this operation mutating anything, they simply return bitsets, which we can apply later. Logically, this is something like: + + ``` + foreach segment { + dict := segment.Dictionary("\_id") + postings := empty postings list + foreach docID { + postings = postings.Or(dict.PostingsList(docID, nil)) + } + } + ``` + + NOTE: it is illustrated above as nested for loops, but some or all of these could be concurrently. The end result is that for each segment, we have (possibly empty) bitset. + +2. Also concurrent with 1, the documents in the batch are analyzed. This analysis proceeds using the existing analyzer pool. + +3. (after 2 completes) Analyzed documents are fed into a function which builds a new Segment representing this information. + +4. We now have everything we need to update the state of the system to include this new snapshot. + + - Acquire a lock + - Create a new IndexSnapshot + - For each SegmentSnapshot in the IndexSnapshot, take the deleted PostingsList and OR it with the new postings list for this Segment. Construct a new SegmentSnapshot for the segment using this new deleted PostingsList. Append this SegmentSnapshot to the IndexSnapshot. + - Create a new SegmentSnapshot wrapping our new segment with nil deleted docs. + - Append the new SegmentSnapshot to the IndexSnapshot + - Release the lock + +An ASCII art example: + ``` + 0 - Empty Index + + No segments + + IndexSnapshot + segments [] + deleted [] + + + 1 - Index Batch [ A B C ] + + segment 0 + numbers [ 1 2 3 ] + \_id [ A B C ] + + IndexSnapshot + segments [ 0 ] + deleted [ nil ] + + + 2 - Index Batch [ B' ] + + segment 0 1 + numbers [ 1 2 3 ] [ 1 ] + \_id [ A B C ] [ B ] + + Compute bitset segment-0-deleted-by-1: + [ 0 1 0 ] + + OR it with previous (nil) (call it 0-1) + [ 0 1 0 ] + + IndexSnapshot + segments [ 0 1 ] + deleted [ 0-1 nil ] + + 3 - Index Batch [ C' ] + + segment 0 1 2 + numbers [ 1 2 3 ] [ 1 ] [ 1 ] + \_id [ A B C ] [ B ] [ C ] + + Compute bitset segment-0-deleted-by-2: + [ 0 0 1 ] + + OR it with previous ([ 0 1 0 ]) (call it 0-12) + [ 0 1 1 ] + + Compute bitset segment-1-deleted-by-2: + [ 0 ] + + OR it with previous (nil) + still just nil + + + IndexSnapshot + segments [ 0 1 2 ] + deleted [ 0-12 nil nil ] + ``` + +**is there opportunity to stop early when doc is found in one segment** +**also, more efficient way to find bits for long lists of ids?** + +### Searching + +In the bleve.index API all searching starts by getting an IndexReader, which represents a snapshot of the index at a point in time. + +As described in the section above, our index implementation maintains a pointer to the current IndexSnapshot. When a caller gets an IndexReader, they get a copy of this pointer, and can use it as long as they like. The IndexSnapshot contains SegmentSnapshots, which only contain pointers to immutable segments. The deleted posting lists associated with a segment change over time, but the particular deleted posting list in YOUR snapshot is immutable. This gives a stable view of the data. + +#### Term Search + +Term search is the only searching primitive exposed in today's bleve.index API. This ultimately could limit our ability to take advantage of the indexing improvements, but it also means it will be easier to get a first version of this working. + +A term search for term T in field F will look something like this: + +``` + searchResultPostings = empty + foreach segment { + dict := segment.Dictionary(F) + segmentResultPostings = dict.PostingsList(T, segmentSnapshotDeleted) + // make segmentLocal numbers into global numbers, and flip bits in searchResultPostings + } +``` + +The searchResultPostings will be a new implementation of the TermFieldReader inteface. + +As a reminder this interface is: + +``` +// TermFieldReader is the interface exposing the enumeration of documents +// containing a given term in a given field. Documents are returned in byte +// lexicographic order over their identifiers. +type TermFieldReader interface { + // Next returns the next document containing the term in this field, or nil + // when it reaches the end of the enumeration. The preAlloced TermFieldDoc + // is optional, and when non-nil, will be used instead of allocating memory. + Next(preAlloced *TermFieldDoc) (*TermFieldDoc, error) + + // Advance resets the enumeration at specified document or its immediate + // follower. + Advance(ID IndexInternalID, preAlloced *TermFieldDoc) (*TermFieldDoc, error) + + // Count returns the number of documents contains the term in this field. + Count() uint64 + Close() error +} +``` + +At first glance this appears problematic, we have no way to return documents in order of their identifiers. But it turns out the wording of this perhaps too strong, or a bit ambiguous. Originally, this referred to the external identifiers, but with the introduction of a distinction between internal/external identifiers, returning them in order of their internal identifiers is also acceptable. **ASIDE**: the reason for this is that most callers just use Next() and literally don't care what the order is, they could be in any order and it would be fine. There is only one search that cares and that is the ConjunctionSearcher, which relies on Next/Advance having very specific semantics. Later in this document we will have a proposal to split into multiple interfaces: + +- The weakest interface, only supports Next() no ordering at all. +- Ordered, supporting Advance() +- And/Or'able capable of internally efficiently doing these ops with like interfaces (if not capable then can always fall back to external walking) + +But, the good news is that we don't even have to do that for our first implementation. As long as the global numbers we use for internal identifiers are consistent within this IndexSnapshot, then Next() will be ordered by ascending document number, and Advance() will still work correctly. + +NOTE: there is another place where we rely on the ordering of these hits, and that is in the "\_id" sort order. Previously this was the natural order, and a NOOP for the collector, now it must be implemented by actually sorting on the "\_id" field. We probably should introduce at least a marker interface to detect this. + +An ASCII art example: + +``` +Let's start with the IndexSnapshot we ended with earlier: + +3 - Index Batch [ C' ] + + segment 0 1 2 + numbers [ 1 2 3 ] [ 1 ] [ 1 ] + \_id [ A B C ] [ B ] [ C ] + + Compute bitset segment-0-deleted-by-2: + [ 0 0 1 ] + + OR it with previous ([ 0 1 0 ]) (call it 0-12) + [ 0 1 1 ] + +Compute bitset segment-1-deleted-by-2: + [ 0 0 0 ] + +OR it with previous (nil) + still just nil + + + IndexSnapshot + segments [ 0 1 2 ] + deleted [ 0-12 nil nil ] + +Now let's search for the term 'cat' in the field 'desc' and let's assume that Document C (both versions) would match it. + +Concurrently: + + - Segment 0 + - Get Term Dictionary For Field 'desc' + - From it get Postings List for term 'cat' EXCLUDING 0-12 + - raw segment matches [ 0 0 1 ] but excluding [ 0 1 1 ] gives [ 0 0 0 ] + - Segment 1 + - Get Term Dictionary For Field 'desc' + - From it get Postings List for term 'cat' excluding nil + - [ 0 ] + - Segment 2 + - Get Term Dictionary For Field 'desc' + - From it get Postings List for term 'cat' excluding nil + - [ 1 ] + +Map local bitsets into global number space (global meaning cross-segment but still unique to this snapshot) + +IndexSnapshot already should have mapping something like: +0 - Offset 0 +1 - Offset 3 (because segment 0 had 3 docs) +2 - Offset 4 (because segment 1 had 1 doc) + +This maps to search result bitset: + +[ 0 0 0 0 1] + +Caller would call Next() and get doc number 5 (assuming 1 based indexing for now) + +Caller could then ask to get term locations, stored fields, external doc ID for document number 5. Internally in the IndexSnapshot, we can now convert that back, and realize doc number 5 comes from segment 2, 5-4=1 so we're looking for doc number 1 in segment 2. That happens to be C... + +``` + +#### Future improvements + +In the future, interfaces to detect these non-serially operating TermFieldReaders could expose their own And() and Or() up to the higher level Conjunction/Disjunction searchers. Doing this alone offers some win, but also means there would be greater burden on the Searcher code rewriting logical expressions for maximum performance. + +Another related topic is that of peak memory usage. With serially operating TermFieldReaders it was necessary to start them all at the same time and operate in unison. However, with these non-serially operating TermFieldReaders we have the option of doing a few at a time, consolidating them, dispoting the intermediaries, and then doing a few more. For very complex queries with many clauses this could reduce peak memory usage. + + +### Memory Tracking + +All segments must be able to produce two statistics, an estimate of their explicit memory usage, and their actual size on disk (if any). For in-memory segments, disk usage could be zero, and the memory usage represents the entire information content. For mmap-based disk segments, the memory could be as low as the size of tracking structure itself (say just a few pointers). + +This would allow the implementation to throttle or block incoming mutations when a threshold memory usage has (or would be) exceeded. + +### Persistence + +Obviously, we want to support (but maybe not require) asynchronous persistence of segments. My expectation is that segments are initially built in memory. At some point they are persisted to disk. This poses some interesting challenges. + +At runtime, the state of an index (it's IndexSnapshot) is not only the contents of the segments, but also the bitmasks of deleted documents. These bitmasks indirectly encode an ordering in which the segments were added. The reason is that the bitmasks encode which items have been obsoleted by other (subsequent or more future) segments. In the runtime implementation we compute bitmask deltas and then merge them at the same time we bring the new segment in. One idea is that we could take a similar approach on disk. When we persist a segment, we persist the bitmask deltas of segments known to exist at that time, and eventually these can get merged up into a base segment deleted bitmask. + +This also relates to the topic rollback, addressed next... + + +### Rollback + +One desirable property in the Couchbase ecosystem is the ability to rollback to some previous (though typically not long ago) state. One idea for keeping this property in this design is to protect some of the most recent segments from merging. Then, if necessary, they could be "undone" to reveal previous states of the system. In these scenarios "undone" has to properly undo the deleted bitmasks on the other segments. Again, the current thinking is that rather than "undo" anything, it could be work that was deferred in the first place, thus making it easier to logically undo. + +Another possibly related approach would be to tie this into our existing snapshot mechanism. Perhaps simulating a slow reader (holding onto index snapshots) for some period of time, can be the mechanism to achieve the desired end goal. + + +### Internal Storage + +The bleve.index API has support for "internal storage". The ability to store information under a separate name space. + +This is not used for high volume storage, so it is tempting to think we could just put a small k/v store alongside the rest of the index. But, the reality is that this storage is used to maintain key information related to the rollback scenario. Because of this, its crucial that ordering and overwriting of key/value pairs correspond with actual segment persistence in the index. Based on this, I believe its important to put the internal key/value pairs inside the segments themselves. But, this also means that they must follow a similar "deleted" bitmask approach to obsolete values in older segments. But, this also seems to substantially increase the complexity of the solution because of the separate name space, it would appear to require its own bitmask. Further keys aren't numeric, which then implies yet another mapping from internal key to number, etc. + +More thought is required here. + +### Merging + +The segmented index approach requires merging to prevent the number of segments from growing too large. + +Recent experience with LSMs has taught us that having the correct merge strategy can make a huge difference in the overall performance of the system. In particular, a simple merge strategy which merges segments too aggressively can lead to high write amplification and unnecessarily rendering cached data useless. + +A few simple principles have been identified. + +- Roughly we merge multiple smaller segments into a single larger one. +- The larger a segment gets the less likely we should be to ever merge it. +- Segments with large numbers of deleted/obsoleted items are good candidates as the merge will result in a space savings. +- Segments with all items deleted/obsoleted can be dropped. + +Merging of a segment should be able to proceed even if that segment is held by an ongoing snapshot, it should only delay the removal of it. diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/builder.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/builder.go new file mode 100644 index 0000000000..04e5bd1b27 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/builder.go @@ -0,0 +1,332 @@ +// Copyright (c) 2019 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorch + +import ( + "fmt" + "os" + "sync" + + "github.com/RoaringBitmap/roaring" + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + bolt "go.etcd.io/bbolt" +) + +const DefaultBuilderBatchSize = 1000 +const DefaultBuilderMergeMax = 10 + +type Builder struct { + m sync.Mutex + segCount uint64 + path string + buildPath string + segPaths []string + batchSize int + mergeMax int + batch *index.Batch + internal map[string][]byte + segPlugin SegmentPlugin +} + +func NewBuilder(config map[string]interface{}) (*Builder, error) { + path, ok := config["path"].(string) + if !ok { + return nil, fmt.Errorf("must specify path") + } + + buildPathPrefix, _ := config["buildPathPrefix"].(string) + buildPath, err := os.MkdirTemp(buildPathPrefix, "scorch-offline-build") + if err != nil { + return nil, err + } + + rv := &Builder{ + path: path, + buildPath: buildPath, + mergeMax: DefaultBuilderMergeMax, + batchSize: DefaultBuilderBatchSize, + batch: index.NewBatch(), + segPlugin: defaultSegmentPlugin, + } + + err = rv.parseConfig(config) + if err != nil { + return nil, fmt.Errorf("error parsing builder config: %v", err) + } + + return rv, nil +} + +func (o *Builder) parseConfig(config map[string]interface{}) (err error) { + if v, ok := config["mergeMax"]; ok { + var t int + if t, err = parseToInteger(v); err != nil { + return fmt.Errorf("mergeMax parse err: %v", err) + } + if t > 0 { + o.mergeMax = t + } + } + + if v, ok := config["batchSize"]; ok { + var t int + if t, err = parseToInteger(v); err != nil { + return fmt.Errorf("batchSize parse err: %v", err) + } + if t > 0 { + o.batchSize = t + } + } + + if v, ok := config["internal"]; ok { + if vinternal, ok := v.(map[string][]byte); ok { + o.internal = vinternal + } + } + + forcedSegmentType, forcedSegmentVersion, err := configForceSegmentTypeVersion(config) + if err != nil { + return err + } + if forcedSegmentType != "" && forcedSegmentVersion != 0 { + segPlugin, err := chooseSegmentPlugin(forcedSegmentType, + uint32(forcedSegmentVersion)) + if err != nil { + return err + } + o.segPlugin = segPlugin + } + + return nil +} + +// Index will place the document into the index. +// It is invalid to index the same document multiple times. +func (o *Builder) Index(doc index.Document) error { + o.m.Lock() + defer o.m.Unlock() + + o.batch.Update(doc) + + return o.maybeFlushBatchLOCKED(o.batchSize) +} + +func (o *Builder) maybeFlushBatchLOCKED(moreThan int) error { + if len(o.batch.IndexOps) >= moreThan { + defer o.batch.Reset() + return o.executeBatchLOCKED(o.batch) + } + return nil +} + +func (o *Builder) executeBatchLOCKED(batch *index.Batch) (err error) { + analysisResults := make([]index.Document, 0, len(batch.IndexOps)) + for _, doc := range batch.IndexOps { + if doc != nil { + // insert _id field + doc.AddIDField() + // perform analysis directly + analyze(doc, nil) + analysisResults = append(analysisResults, doc) + } + } + + seg, _, err := o.segPlugin.New(analysisResults) + if err != nil { + return fmt.Errorf("error building segment base: %v", err) + } + + filename := zapFileName(o.segCount) + o.segCount++ + path := o.buildPath + string(os.PathSeparator) + filename + + if segUnpersisted, ok := seg.(segment.UnpersistedSegment); ok { + err = segUnpersisted.Persist(path) + if err != nil { + return fmt.Errorf("error persisting segment base to %s: %v", path, err) + } + + o.segPaths = append(o.segPaths, path) + return nil + } + + return fmt.Errorf("new segment does not implement unpersisted: %T", seg) +} + +func (o *Builder) doMerge() error { + // as long as we have more than 1 segment, keep merging + for len(o.segPaths) > 1 { + + // merge the next number of segments into one new one + // or, if there are fewer than remaining, merge them all + mergeCount := o.mergeMax + if mergeCount > len(o.segPaths) { + mergeCount = len(o.segPaths) + } + + mergePaths := o.segPaths[0:mergeCount] + o.segPaths = o.segPaths[mergeCount:] + + // open each of the segments to be merged + mergeSegs := make([]segment.Segment, 0, mergeCount) + + // closeOpenedSegs attempts to close all opened + // segments even if an error occurs, in which case + // the first error is returned + closeOpenedSegs := func() error { + var err error + for _, seg := range mergeSegs { + clErr := seg.Close() + if clErr != nil && err == nil { + err = clErr + } + } + return err + } + + for _, mergePath := range mergePaths { + seg, err := o.segPlugin.Open(mergePath) + if err != nil { + _ = closeOpenedSegs() + return fmt.Errorf("error opening segment (%s) for merge: %v", mergePath, err) + } + mergeSegs = append(mergeSegs, seg) + } + + // do the merge + mergedSegPath := o.buildPath + string(os.PathSeparator) + zapFileName(o.segCount) + drops := make([]*roaring.Bitmap, mergeCount) + _, _, err := o.segPlugin.Merge(mergeSegs, drops, mergedSegPath, nil, nil) + if err != nil { + _ = closeOpenedSegs() + return fmt.Errorf("error merging segments (%v): %v", mergePaths, err) + } + o.segCount++ + o.segPaths = append(o.segPaths, mergedSegPath) + + // close segments opened for merge + err = closeOpenedSegs() + if err != nil { + return fmt.Errorf("error closing opened segments: %v", err) + } + + // remove merged segments + for _, mergePath := range mergePaths { + err = os.RemoveAll(mergePath) + if err != nil { + return fmt.Errorf("error removing segment %s after merge: %v", mergePath, err) + } + } + } + + return nil +} + +func (o *Builder) Close() error { + o.m.Lock() + defer o.m.Unlock() + + // see if there is a partial batch + err := o.maybeFlushBatchLOCKED(1) + if err != nil { + return fmt.Errorf("error flushing batch before close: %v", err) + } + + // perform all the merging + err = o.doMerge() + if err != nil { + return fmt.Errorf("error while merging: %v", err) + } + + // ensure the store path exists + err = os.MkdirAll(o.path, 0700) + if err != nil { + return err + } + + // move final segment into place + // segment id 2 is chosen to match the behavior of a scorch + // index which indexes a single batch of data + finalSegPath := o.path + string(os.PathSeparator) + zapFileName(2) + err = os.Rename(o.segPaths[0], finalSegPath) + if err != nil { + return fmt.Errorf("error moving final segment into place: %v", err) + } + + // remove the buildPath, as it is no longer needed + err = os.RemoveAll(o.buildPath) + if err != nil { + return fmt.Errorf("error removing build path: %v", err) + } + + // prepare wrapping + seg, err := o.segPlugin.Open(finalSegPath) + if err != nil { + return fmt.Errorf("error opening final segment") + } + + // create a segment snapshot for this segment + ss := &SegmentSnapshot{ + segment: seg, + } + is := &IndexSnapshot{ + epoch: 3, // chosen to match scorch behavior when indexing a single batch + segment: []*SegmentSnapshot{ss}, + creator: "scorch-builder", + internal: o.internal, + } + + // create the root bolt + rootBoltPath := o.path + string(os.PathSeparator) + "root.bolt" + rootBolt, err := bolt.Open(rootBoltPath, 0600, nil) + if err != nil { + return err + } + + // start a write transaction + tx, err := rootBolt.Begin(true) + if err != nil { + return err + } + + // fill the root bolt with this fake index snapshot + _, _, err = prepareBoltSnapshot(is, tx, o.path, o.segPlugin, nil) + if err != nil { + _ = tx.Rollback() + _ = rootBolt.Close() + return fmt.Errorf("error preparing bolt snapshot in root.bolt: %v", err) + } + + // commit bolt data + err = tx.Commit() + if err != nil { + _ = rootBolt.Close() + return fmt.Errorf("error committing bolt tx in root.bolt: %v", err) + } + + // close bolt + err = rootBolt.Close() + if err != nil { + return fmt.Errorf("error closing root.bolt: %v", err) + } + + // close final segment + err = seg.Close() + if err != nil { + return fmt.Errorf("error closing final segment: %v", err) + } + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/empty.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/empty.go new file mode 100644 index 0000000000..34619d422b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/empty.go @@ -0,0 +1,41 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorch + +import segment "github.com/blevesearch/scorch_segment_api/v2" + +type emptyPostingsIterator struct{} + +func (e *emptyPostingsIterator) Next() (segment.Posting, error) { + return nil, nil +} + +func (e *emptyPostingsIterator) Advance(uint64) (segment.Posting, error) { + return nil, nil +} + +func (e *emptyPostingsIterator) Size() int { + return 0 +} + +func (e *emptyPostingsIterator) BytesRead() uint64 { + return 0 +} + +func (e *emptyPostingsIterator) ResetBytesRead(uint64) {} + +func (e *emptyPostingsIterator) BytesWritten() uint64 { return 0 } + +var anEmptyPostingsIterator = &emptyPostingsIterator{} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/event.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/event.go new file mode 100644 index 0000000000..31c9e80c96 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/event.go @@ -0,0 +1,64 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorch + +import "time" + +// RegistryAsyncErrorCallbacks should be treated as read-only after +// process init()'ialization. +var RegistryAsyncErrorCallbacks = map[string]func(error, string){} + +// RegistryEventCallbacks should be treated as read-only after +// process init()'ialization. +var RegistryEventCallbacks = map[string]func(Event){} + +// Event represents the information provided in an OnEvent() callback. +type Event struct { + Kind EventKind + Scorch *Scorch + Duration time.Duration +} + +// EventKind represents an event code for OnEvent() callbacks. +type EventKind int + +// EventKindCloseStart is fired when a Scorch.Close() has begun. +var EventKindCloseStart = EventKind(1) + +// EventKindClose is fired when a scorch index has been fully closed. +var EventKindClose = EventKind(2) + +// EventKindMergerProgress is fired when the merger has completed a +// round of merge processing. +var EventKindMergerProgress = EventKind(3) + +// EventKindPersisterProgress is fired when the persister has completed +// a round of persistence processing. +var EventKindPersisterProgress = EventKind(4) + +// EventKindBatchIntroductionStart is fired when Batch() is invoked which +// introduces a new segment. +var EventKindBatchIntroductionStart = EventKind(5) + +// EventKindBatchIntroduction is fired when Batch() completes. +var EventKindBatchIntroduction = EventKind(6) + +// EventKindMergeTaskIntroductionStart is fired when the merger is about to +// start the introduction of merged segment from a single merge task. +var EventKindMergeTaskIntroductionStart = EventKind(7) + +// EventKindMergeTaskIntroduction is fired when the merger has completed +// the introduction of merged segment from a single merge task. +var EventKindMergeTaskIntroduction = EventKind(8) diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/int.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/int.go new file mode 100644 index 0000000000..4fa6d7f71f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/int.go @@ -0,0 +1,92 @@ +// Copyright 2014 The Cockroach Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +// implied. See the License for the specific language governing +// permissions and limitations under the License. + +// This code originated from: +// https://github.com/cockroachdb/cockroach/blob/2dd65dde5d90c157f4b93f92502ca1063b904e1d/pkg/util/encoding/encoding.go + +// Modified to not use pkg/errors + +package scorch + +import "fmt" + +const ( + // intMin is chosen such that the range of int tags does not overlap the + // ascii character set that is frequently used in testing. + intMin = 0x80 // 128 + intMaxWidth = 8 + intZero = intMin + intMaxWidth // 136 + intSmall = intMax - intZero - intMaxWidth // 109 + // intMax is the maximum int tag value. + intMax = 0xfd // 253 +) + +// encodeUvarintAscending encodes the uint64 value using a variable length +// (length-prefixed) representation. The length is encoded as a single +// byte indicating the number of encoded bytes (-8) to follow. See +// EncodeVarintAscending for rationale. The encoded bytes are appended to the +// supplied buffer and the final buffer is returned. +func encodeUvarintAscending(b []byte, v uint64) []byte { + switch { + case v <= intSmall: + return append(b, intZero+byte(v)) + case v <= 0xff: + return append(b, intMax-7, byte(v)) + case v <= 0xffff: + return append(b, intMax-6, byte(v>>8), byte(v)) + case v <= 0xffffff: + return append(b, intMax-5, byte(v>>16), byte(v>>8), byte(v)) + case v <= 0xffffffff: + return append(b, intMax-4, byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) + case v <= 0xffffffffff: + return append(b, intMax-3, byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), + byte(v)) + case v <= 0xffffffffffff: + return append(b, intMax-2, byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), + byte(v>>8), byte(v)) + case v <= 0xffffffffffffff: + return append(b, intMax-1, byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), + byte(v>>16), byte(v>>8), byte(v)) + default: + return append(b, intMax, byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), + byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) + } +} + +// decodeUvarintAscending decodes a varint encoded uint64 from the input +// buffer. The remainder of the input buffer and the decoded uint64 +// are returned. +func decodeUvarintAscending(b []byte) ([]byte, uint64, error) { + if len(b) == 0 { + return nil, 0, fmt.Errorf("insufficient bytes to decode uvarint value") + } + length := int(b[0]) - intZero + b = b[1:] // skip length byte + if length <= intSmall { + return b, uint64(length), nil + } + length -= intSmall + if length < 0 || length > 8 { + return nil, 0, fmt.Errorf("invalid uvarint length of %d", length) + } else if len(b) < length { + return nil, 0, fmt.Errorf("insufficient bytes to decode uvarint value: %q", b) + } + var v uint64 + // It is faster to range over the elements in a slice than to index + // into the slice on each loop iteration. + for _, t := range b[:length] { + v = (v << 8) | uint64(t) + } + return b[length:], v, nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/introducer.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/introducer.go new file mode 100644 index 0000000000..123e71d63d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/introducer.go @@ -0,0 +1,483 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorch + +import ( + "fmt" + "path/filepath" + "sync/atomic" + + "github.com/RoaringBitmap/roaring" + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" +) + +type segmentIntroduction struct { + id uint64 + data segment.Segment + obsoletes map[uint64]*roaring.Bitmap + ids []string + internal map[string][]byte + + applied chan error + persisted chan error + persistedCallback index.BatchCallback +} + +type persistIntroduction struct { + persisted map[uint64]segment.Segment + applied notificationChan +} + +type epochWatcher struct { + epoch uint64 + notifyCh notificationChan +} + +func (s *Scorch) introducerLoop() { + defer func() { + if r := recover(); r != nil { + s.fireAsyncError(&AsyncPanicError{ + Source: "introducer", + Path: s.path, + }) + } + + s.asyncTasks.Done() + }() + + var epochWatchers []*epochWatcher +OUTER: + for { + atomic.AddUint64(&s.stats.TotIntroduceLoop, 1) + + select { + case <-s.closeCh: + break OUTER + + case epochWatcher := <-s.introducerNotifier: + epochWatchers = append(epochWatchers, epochWatcher) + + case nextMerge := <-s.merges: + s.introduceMerge(nextMerge) + + case next := <-s.introductions: + err := s.introduceSegment(next) + if err != nil { + continue OUTER + } + + case persist := <-s.persists: + s.introducePersist(persist) + + } + + var epochCurr uint64 + s.rootLock.RLock() + if s.root != nil { + epochCurr = s.root.epoch + } + s.rootLock.RUnlock() + var epochWatchersNext []*epochWatcher + for _, w := range epochWatchers { + if w.epoch < epochCurr { + close(w.notifyCh) + } else { + epochWatchersNext = append(epochWatchersNext, w) + } + } + epochWatchers = epochWatchersNext + } +} + +func (s *Scorch) introduceSegment(next *segmentIntroduction) error { + atomic.AddUint64(&s.stats.TotIntroduceSegmentBeg, 1) + defer atomic.AddUint64(&s.stats.TotIntroduceSegmentEnd, 1) + + s.rootLock.RLock() + root := s.root + root.AddRef() + s.rootLock.RUnlock() + + defer func() { _ = root.DecRef() }() + + nsegs := len(root.segment) + + // prepare new index snapshot + newSnapshot := &IndexSnapshot{ + parent: s, + segment: make([]*SegmentSnapshot, 0, nsegs+1), + offsets: make([]uint64, 0, nsegs+1), + internal: make(map[string][]byte, len(root.internal)), + refs: 1, + creator: "introduceSegment", + } + + // iterate through current segments + var running uint64 + var docsToPersistCount, memSegments, fileSegments uint64 + var droppedSegmentFiles []string + for i := range root.segment { + // see if optimistic work included this segment + delta, ok := next.obsoletes[root.segment[i].id] + if !ok { + var err error + delta, err = root.segment[i].segment.DocNumbers(next.ids) + if err != nil { + next.applied <- fmt.Errorf("error computing doc numbers: %v", err) + close(next.applied) + _ = newSnapshot.DecRef() + return err + } + } + + newss := &SegmentSnapshot{ + id: root.segment[i].id, + segment: root.segment[i].segment, + cachedDocs: root.segment[i].cachedDocs, + creator: root.segment[i].creator, + } + + // apply new obsoletions + if root.segment[i].deleted == nil { + newss.deleted = delta + } else { + newss.deleted = roaring.Or(root.segment[i].deleted, delta) + } + if newss.deleted.IsEmpty() { + newss.deleted = nil + } + + // check for live size before copying + if newss.LiveSize() > 0 { + newSnapshot.segment = append(newSnapshot.segment, newss) + root.segment[i].segment.AddRef() + newSnapshot.offsets = append(newSnapshot.offsets, running) + running += newss.segment.Count() + } else if seg, ok := newss.segment.(segment.PersistedSegment); ok { + droppedSegmentFiles = append(droppedSegmentFiles, + filepath.Base(seg.Path())) + } + + if isMemorySegment(root.segment[i]) { + docsToPersistCount += root.segment[i].Count() + memSegments++ + } else { + fileSegments++ + } + } + + atomic.StoreUint64(&s.stats.TotItemsToPersist, docsToPersistCount) + atomic.StoreUint64(&s.stats.TotMemorySegmentsAtRoot, memSegments) + atomic.StoreUint64(&s.stats.TotFileSegmentsAtRoot, fileSegments) + + // append new segment, if any, to end of the new index snapshot + if next.data != nil { + newSegmentSnapshot := &SegmentSnapshot{ + id: next.id, + segment: next.data, // take ownership of next.data's ref-count + cachedDocs: &cachedDocs{cache: nil}, + creator: "introduceSegment", + } + newSnapshot.segment = append(newSnapshot.segment, newSegmentSnapshot) + newSnapshot.offsets = append(newSnapshot.offsets, running) + + // increment numItemsIntroduced which tracks the number of items + // queued for persistence. + atomic.AddUint64(&s.stats.TotIntroducedItems, newSegmentSnapshot.Count()) + atomic.AddUint64(&s.stats.TotIntroducedSegmentsBatch, 1) + } + // copy old values + for key, oldVal := range root.internal { + newSnapshot.internal[key] = oldVal + } + // set new values and apply deletes + for key, newVal := range next.internal { + if newVal != nil { + newSnapshot.internal[key] = newVal + } else { + delete(newSnapshot.internal, key) + } + } + + newSnapshot.updateSize() + s.rootLock.Lock() + if next.persisted != nil { + s.rootPersisted = append(s.rootPersisted, next.persisted) + } + if next.persistedCallback != nil { + s.persistedCallbacks = append(s.persistedCallbacks, next.persistedCallback) + } + // swap in new index snapshot + newSnapshot.epoch = s.nextSnapshotEpoch + s.nextSnapshotEpoch++ + rootPrev := s.root + s.root = newSnapshot + atomic.StoreUint64(&s.stats.CurRootEpoch, s.root.epoch) + // release lock + s.rootLock.Unlock() + + if rootPrev != nil { + _ = rootPrev.DecRef() + } + + // update the removal eligibility for those segment files + // that are not a part of the latest root. + for _, filename := range droppedSegmentFiles { + s.unmarkIneligibleForRemoval(filename) + } + + close(next.applied) + + return nil +} + +func (s *Scorch) introducePersist(persist *persistIntroduction) { + atomic.AddUint64(&s.stats.TotIntroducePersistBeg, 1) + defer atomic.AddUint64(&s.stats.TotIntroducePersistEnd, 1) + + s.rootLock.Lock() + root := s.root + root.AddRef() + nextSnapshotEpoch := s.nextSnapshotEpoch + s.nextSnapshotEpoch++ + s.rootLock.Unlock() + + defer func() { _ = root.DecRef() }() + + newIndexSnapshot := &IndexSnapshot{ + parent: s, + epoch: nextSnapshotEpoch, + segment: make([]*SegmentSnapshot, len(root.segment)), + offsets: make([]uint64, len(root.offsets)), + internal: make(map[string][]byte, len(root.internal)), + refs: 1, + creator: "introducePersist", + } + + var docsToPersistCount, memSegments, fileSegments uint64 + for i, segmentSnapshot := range root.segment { + // see if this segment has been replaced + if replacement, ok := persist.persisted[segmentSnapshot.id]; ok { + newSegmentSnapshot := &SegmentSnapshot{ + id: segmentSnapshot.id, + segment: replacement, + deleted: segmentSnapshot.deleted, + cachedDocs: segmentSnapshot.cachedDocs, + creator: "introducePersist", + mmaped: 1, + } + newIndexSnapshot.segment[i] = newSegmentSnapshot + delete(persist.persisted, segmentSnapshot.id) + + // update items persisted incase of a new segment snapshot + atomic.AddUint64(&s.stats.TotPersistedItems, newSegmentSnapshot.Count()) + atomic.AddUint64(&s.stats.TotPersistedSegments, 1) + fileSegments++ + } else { + newIndexSnapshot.segment[i] = root.segment[i] + newIndexSnapshot.segment[i].segment.AddRef() + + if isMemorySegment(root.segment[i]) { + docsToPersistCount += root.segment[i].Count() + memSegments++ + } else { + fileSegments++ + } + } + newIndexSnapshot.offsets[i] = root.offsets[i] + } + + for k, v := range root.internal { + newIndexSnapshot.internal[k] = v + } + + atomic.StoreUint64(&s.stats.TotItemsToPersist, docsToPersistCount) + atomic.StoreUint64(&s.stats.TotMemorySegmentsAtRoot, memSegments) + atomic.StoreUint64(&s.stats.TotFileSegmentsAtRoot, fileSegments) + newIndexSnapshot.updateSize() + s.rootLock.Lock() + rootPrev := s.root + s.root = newIndexSnapshot + atomic.StoreUint64(&s.stats.CurRootEpoch, s.root.epoch) + s.rootLock.Unlock() + + if rootPrev != nil { + _ = rootPrev.DecRef() + } + + close(persist.applied) +} + +// The introducer should definitely handle the segmentMerge.notify +// channel before exiting the introduceMerge. +func (s *Scorch) introduceMerge(nextMerge *segmentMerge) { + atomic.AddUint64(&s.stats.TotIntroduceMergeBeg, 1) + defer atomic.AddUint64(&s.stats.TotIntroduceMergeEnd, 1) + + s.rootLock.RLock() + root := s.root + root.AddRef() + s.rootLock.RUnlock() + + defer func() { _ = root.DecRef() }() + + newSnapshot := &IndexSnapshot{ + parent: s, + internal: root.internal, + refs: 1, + creator: "introduceMerge", + } + + // iterate through current segments + newSegmentDeleted := roaring.NewBitmap() + var running, docsToPersistCount, memSegments, fileSegments uint64 + var droppedSegmentFiles []string + for i := range root.segment { + segmentID := root.segment[i].id + if segSnapAtMerge, ok := nextMerge.old[segmentID]; ok { + // this segment is going away, see if anything else was deleted since we started the merge + if segSnapAtMerge != nil && root.segment[i].deleted != nil { + // assume all these deletes are new + deletedSince := root.segment[i].deleted + // if we already knew about some of them, remove + if segSnapAtMerge.deleted != nil { + deletedSince = roaring.AndNot(root.segment[i].deleted, segSnapAtMerge.deleted) + } + deletedSinceItr := deletedSince.Iterator() + for deletedSinceItr.HasNext() { + oldDocNum := deletedSinceItr.Next() + newDocNum := nextMerge.oldNewDocNums[segmentID][oldDocNum] + newSegmentDeleted.Add(uint32(newDocNum)) + } + } + // clean up the old segment map to figure out the + // obsolete segments wrt root in meantime, whatever + // segments left behind in old map after processing + // the root segments would be the obsolete segment set + delete(nextMerge.old, segmentID) + } else if root.segment[i].LiveSize() > 0 { + // this segment is staying + newSnapshot.segment = append(newSnapshot.segment, &SegmentSnapshot{ + id: root.segment[i].id, + segment: root.segment[i].segment, + deleted: root.segment[i].deleted, + cachedDocs: root.segment[i].cachedDocs, + creator: root.segment[i].creator, + }) + root.segment[i].segment.AddRef() + newSnapshot.offsets = append(newSnapshot.offsets, running) + running += root.segment[i].segment.Count() + + if isMemorySegment(root.segment[i]) { + docsToPersistCount += root.segment[i].Count() + memSegments++ + } else { + fileSegments++ + } + } else if root.segment[i].LiveSize() == 0 { + if seg, ok := root.segment[i].segment.(segment.PersistedSegment); ok { + droppedSegmentFiles = append(droppedSegmentFiles, + filepath.Base(seg.Path())) + } + } + } + + // before the newMerge introduction, need to clean the newly + // merged segment wrt the current root segments, hence + // applying the obsolete segment contents to newly merged segment + for segID, ss := range nextMerge.old { + obsoleted := ss.DocNumbersLive() + if obsoleted != nil { + obsoletedIter := obsoleted.Iterator() + for obsoletedIter.HasNext() { + oldDocNum := obsoletedIter.Next() + newDocNum := nextMerge.oldNewDocNums[segID][oldDocNum] + newSegmentDeleted.Add(uint32(newDocNum)) + } + } + } + var skipped bool + // In case where all the docs in the newly merged segment getting + // deleted by the time we reach here, can skip the introduction. + if nextMerge.new != nil && + nextMerge.new.Count() > newSegmentDeleted.GetCardinality() { + + // put new segment at end + newSnapshot.segment = append(newSnapshot.segment, &SegmentSnapshot{ + id: nextMerge.id, + segment: nextMerge.new, // take ownership for nextMerge.new's ref-count + deleted: newSegmentDeleted, + cachedDocs: &cachedDocs{cache: nil}, + creator: "introduceMerge", + mmaped: nextMerge.mmaped, + }) + newSnapshot.offsets = append(newSnapshot.offsets, running) + atomic.AddUint64(&s.stats.TotIntroducedSegmentsMerge, 1) + + switch nextMerge.new.(type) { + case segment.PersistedSegment: + fileSegments++ + default: + docsToPersistCount += nextMerge.new.Count() - newSegmentDeleted.GetCardinality() + memSegments++ + } + } else { + skipped = true + atomic.AddUint64(&s.stats.TotFileMergeIntroductionsObsoleted, 1) + } + + atomic.StoreUint64(&s.stats.TotItemsToPersist, docsToPersistCount) + atomic.StoreUint64(&s.stats.TotMemorySegmentsAtRoot, memSegments) + atomic.StoreUint64(&s.stats.TotFileSegmentsAtRoot, fileSegments) + + newSnapshot.AddRef() // 1 ref for the nextMerge.notify response + + newSnapshot.updateSize() + s.rootLock.Lock() + // swap in new index snapshot + newSnapshot.epoch = s.nextSnapshotEpoch + s.nextSnapshotEpoch++ + rootPrev := s.root + s.root = newSnapshot + atomic.StoreUint64(&s.stats.CurRootEpoch, s.root.epoch) + // release lock + s.rootLock.Unlock() + + if rootPrev != nil { + _ = rootPrev.DecRef() + } + + // update the removal eligibility for those segment files + // that are not a part of the latest root. + for _, filename := range droppedSegmentFiles { + s.unmarkIneligibleForRemoval(filename) + } + + // notify requester that we incorporated this + nextMerge.notifyCh <- &mergeTaskIntroStatus{ + indexSnapshot: newSnapshot, + skipped: skipped} + close(nextMerge.notifyCh) +} + +func isMemorySegment(s *SegmentSnapshot) bool { + switch s.segment.(type) { + case segment.PersistedSegment: + return false + default: + return true + } +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/merge.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/merge.go new file mode 100644 index 0000000000..c5f0e79e24 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/merge.go @@ -0,0 +1,527 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorch + +import ( + "context" + "encoding/json" + "fmt" + "os" + "strings" + "sync/atomic" + "time" + + "github.com/RoaringBitmap/roaring" + "github.com/blevesearch/bleve/v2/index/scorch/mergeplan" + segment "github.com/blevesearch/scorch_segment_api/v2" +) + +func (s *Scorch) mergerLoop() { + defer func() { + if r := recover(); r != nil { + s.fireAsyncError(&AsyncPanicError{ + Source: "merger", + Path: s.path, + }) + } + + s.asyncTasks.Done() + }() + + var lastEpochMergePlanned uint64 + var ctrlMsg *mergerCtrl + mergePlannerOptions, err := s.parseMergePlannerOptions() + if err != nil { + s.fireAsyncError(fmt.Errorf("mergePlannerOption json parsing err: %v", err)) + return + } + ctrlMsgDflt := &mergerCtrl{ctx: context.Background(), + options: mergePlannerOptions, + doneCh: nil} + +OUTER: + for { + atomic.AddUint64(&s.stats.TotFileMergeLoopBeg, 1) + + select { + case <-s.closeCh: + break OUTER + + default: + // check to see if there is a new snapshot to persist + s.rootLock.Lock() + ourSnapshot := s.root + ourSnapshot.AddRef() + atomic.StoreUint64(&s.iStats.mergeSnapshotSize, uint64(ourSnapshot.Size())) + atomic.StoreUint64(&s.iStats.mergeEpoch, ourSnapshot.epoch) + s.rootLock.Unlock() + + if ctrlMsg == nil && ourSnapshot.epoch != lastEpochMergePlanned { + ctrlMsg = ctrlMsgDflt + } + if ctrlMsg != nil { + startTime := time.Now() + + // lets get started + err := s.planMergeAtSnapshot(ctrlMsg.ctx, ctrlMsg.options, + ourSnapshot) + if err != nil { + atomic.StoreUint64(&s.iStats.mergeEpoch, 0) + if err == segment.ErrClosed { + // index has been closed + _ = ourSnapshot.DecRef() + + // continue the workloop on a user triggered cancel + if ctrlMsg.doneCh != nil { + close(ctrlMsg.doneCh) + ctrlMsg = nil + continue OUTER + } + + // exit the workloop on index closure + ctrlMsg = nil + break OUTER + } + s.fireAsyncError(fmt.Errorf("merging err: %v", err)) + _ = ourSnapshot.DecRef() + atomic.AddUint64(&s.stats.TotFileMergeLoopErr, 1) + continue OUTER + } + + if ctrlMsg.doneCh != nil { + close(ctrlMsg.doneCh) + } + ctrlMsg = nil + + lastEpochMergePlanned = ourSnapshot.epoch + + atomic.StoreUint64(&s.stats.LastMergedEpoch, ourSnapshot.epoch) + + s.fireEvent(EventKindMergerProgress, time.Since(startTime)) + } + _ = ourSnapshot.DecRef() + + // tell the persister we're waiting for changes + // first make a epochWatcher chan + ew := &epochWatcher{ + epoch: lastEpochMergePlanned, + notifyCh: make(notificationChan, 1), + } + + // give it to the persister + select { + case <-s.closeCh: + break OUTER + case s.persisterNotifier <- ew: + case ctrlMsg = <-s.forceMergeRequestCh: + continue OUTER + } + + // now wait for persister (but also detect close) + select { + case <-s.closeCh: + break OUTER + case <-ew.notifyCh: + case ctrlMsg = <-s.forceMergeRequestCh: + } + } + + atomic.AddUint64(&s.stats.TotFileMergeLoopEnd, 1) + } +} + +type mergerCtrl struct { + ctx context.Context + options *mergeplan.MergePlanOptions + doneCh chan struct{} +} + +// ForceMerge helps users trigger a merge operation on +// an online scorch index. +func (s *Scorch) ForceMerge(ctx context.Context, + mo *mergeplan.MergePlanOptions) error { + // check whether force merge is already under processing + s.rootLock.Lock() + if s.stats.TotFileMergeForceOpsStarted > + s.stats.TotFileMergeForceOpsCompleted { + s.rootLock.Unlock() + return fmt.Errorf("force merge already in progress") + } + + s.stats.TotFileMergeForceOpsStarted++ + s.rootLock.Unlock() + + if mo != nil { + err := mergeplan.ValidateMergePlannerOptions(mo) + if err != nil { + return err + } + } else { + // assume the default single segment merge policy + mo = &mergeplan.SingleSegmentMergePlanOptions + } + msg := &mergerCtrl{options: mo, + doneCh: make(chan struct{}), + ctx: ctx, + } + + // request the merger perform a force merge + select { + case s.forceMergeRequestCh <- msg: + case <-s.closeCh: + return nil + } + + // wait for the force merge operation completion + select { + case <-msg.doneCh: + atomic.AddUint64(&s.stats.TotFileMergeForceOpsCompleted, 1) + case <-s.closeCh: + } + + return nil +} + +func (s *Scorch) parseMergePlannerOptions() (*mergeplan.MergePlanOptions, + error) { + mergePlannerOptions := mergeplan.DefaultMergePlanOptions + if v, ok := s.config["scorchMergePlanOptions"]; ok { + b, err := json.Marshal(v) + if err != nil { + return &mergePlannerOptions, err + } + + err = json.Unmarshal(b, &mergePlannerOptions) + if err != nil { + return &mergePlannerOptions, err + } + + err = mergeplan.ValidateMergePlannerOptions(&mergePlannerOptions) + if err != nil { + return nil, err + } + } + return &mergePlannerOptions, nil +} + +type closeChWrapper struct { + ch1 chan struct{} + ctx context.Context + closeCh chan struct{} + cancelCh chan struct{} +} + +func newCloseChWrapper(ch1 chan struct{}, + ctx context.Context) *closeChWrapper { + return &closeChWrapper{ + ch1: ch1, + ctx: ctx, + closeCh: make(chan struct{}), + cancelCh: make(chan struct{}), + } +} + +func (w *closeChWrapper) close() { + close(w.closeCh) +} + +func (w *closeChWrapper) listen() { + select { + case <-w.ch1: + close(w.cancelCh) + case <-w.ctx.Done(): + close(w.cancelCh) + case <-w.closeCh: + } +} + +func (s *Scorch) planMergeAtSnapshot(ctx context.Context, + options *mergeplan.MergePlanOptions, ourSnapshot *IndexSnapshot) error { + // build list of persisted segments in this snapshot + var onlyPersistedSnapshots []mergeplan.Segment + for _, segmentSnapshot := range ourSnapshot.segment { + if _, ok := segmentSnapshot.segment.(segment.PersistedSegment); ok { + onlyPersistedSnapshots = append(onlyPersistedSnapshots, segmentSnapshot) + } + } + + atomic.AddUint64(&s.stats.TotFileMergePlan, 1) + + // give this list to the planner + resultMergePlan, err := mergeplan.Plan(onlyPersistedSnapshots, options) + if err != nil { + atomic.AddUint64(&s.stats.TotFileMergePlanErr, 1) + return fmt.Errorf("merge planning err: %v", err) + } + if resultMergePlan == nil { + // nothing to do + atomic.AddUint64(&s.stats.TotFileMergePlanNone, 1) + return nil + } + atomic.AddUint64(&s.stats.TotFileMergePlanOk, 1) + + atomic.AddUint64(&s.stats.TotFileMergePlanTasks, uint64(len(resultMergePlan.Tasks))) + + // process tasks in serial for now + var filenames []string + + cw := newCloseChWrapper(s.closeCh, ctx) + defer cw.close() + + go cw.listen() + + for _, task := range resultMergePlan.Tasks { + if len(task.Segments) == 0 { + atomic.AddUint64(&s.stats.TotFileMergePlanTasksSegmentsEmpty, 1) + continue + } + + atomic.AddUint64(&s.stats.TotFileMergePlanTasksSegments, uint64(len(task.Segments))) + + oldMap := make(map[uint64]*SegmentSnapshot) + newSegmentID := atomic.AddUint64(&s.nextSegmentID, 1) + segmentsToMerge := make([]segment.Segment, 0, len(task.Segments)) + docsToDrop := make([]*roaring.Bitmap, 0, len(task.Segments)) + + for _, planSegment := range task.Segments { + if segSnapshot, ok := planSegment.(*SegmentSnapshot); ok { + oldMap[segSnapshot.id] = segSnapshot + if persistedSeg, ok := segSnapshot.segment.(segment.PersistedSegment); ok { + if segSnapshot.LiveSize() == 0 { + atomic.AddUint64(&s.stats.TotFileMergeSegmentsEmpty, 1) + oldMap[segSnapshot.id] = nil + } else { + segmentsToMerge = append(segmentsToMerge, segSnapshot.segment) + docsToDrop = append(docsToDrop, segSnapshot.deleted) + } + // track the files getting merged for unsetting the + // removal ineligibility. This helps to unflip files + // even with fast merger, slow persister work flows. + path := persistedSeg.Path() + filenames = append(filenames, + strings.TrimPrefix(path, s.path+string(os.PathSeparator))) + } + } + } + + var oldNewDocNums map[uint64][]uint64 + var seg segment.Segment + var filename string + if len(segmentsToMerge) > 0 { + filename = zapFileName(newSegmentID) + s.markIneligibleForRemoval(filename) + path := s.path + string(os.PathSeparator) + filename + + fileMergeZapStartTime := time.Now() + + atomic.AddUint64(&s.stats.TotFileMergeZapBeg, 1) + prevBytesReadTotal := cumulateBytesRead(segmentsToMerge) + newDocNums, _, err := s.segPlugin.Merge(segmentsToMerge, docsToDrop, path, + cw.cancelCh, s) + atomic.AddUint64(&s.stats.TotFileMergeZapEnd, 1) + + fileMergeZapTime := uint64(time.Since(fileMergeZapStartTime)) + atomic.AddUint64(&s.stats.TotFileMergeZapTime, fileMergeZapTime) + if atomic.LoadUint64(&s.stats.MaxFileMergeZapTime) < fileMergeZapTime { + atomic.StoreUint64(&s.stats.MaxFileMergeZapTime, fileMergeZapTime) + } + + if err != nil { + s.unmarkIneligibleForRemoval(filename) + atomic.AddUint64(&s.stats.TotFileMergePlanTasksErr, 1) + if err == segment.ErrClosed { + return err + } + return fmt.Errorf("merging failed: %v", err) + } + + seg, err = s.segPlugin.Open(path) + if err != nil { + s.unmarkIneligibleForRemoval(filename) + atomic.AddUint64(&s.stats.TotFileMergePlanTasksErr, 1) + return err + } + + totalBytesRead := seg.BytesRead() + prevBytesReadTotal + seg.ResetBytesRead(totalBytesRead) + + oldNewDocNums = make(map[uint64][]uint64) + for i, segNewDocNums := range newDocNums { + oldNewDocNums[task.Segments[i].Id()] = segNewDocNums + } + + atomic.AddUint64(&s.stats.TotFileMergeSegments, uint64(len(segmentsToMerge))) + } + + sm := &segmentMerge{ + id: newSegmentID, + old: oldMap, + oldNewDocNums: oldNewDocNums, + new: seg, + notifyCh: make(chan *mergeTaskIntroStatus), + mmaped: 1, + } + + s.fireEvent(EventKindMergeTaskIntroductionStart, 0) + + // give it to the introducer + select { + case <-s.closeCh: + _ = seg.Close() + return segment.ErrClosed + case s.merges <- sm: + atomic.AddUint64(&s.stats.TotFileMergeIntroductions, 1) + } + + introStartTime := time.Now() + // it is safe to blockingly wait for the merge introduction + // here as the introducer is bound to handle the notify channel. + introStatus := <-sm.notifyCh + introTime := uint64(time.Since(introStartTime)) + atomic.AddUint64(&s.stats.TotFileMergeZapIntroductionTime, introTime) + if atomic.LoadUint64(&s.stats.MaxFileMergeZapIntroductionTime) < introTime { + atomic.StoreUint64(&s.stats.MaxFileMergeZapIntroductionTime, introTime) + } + atomic.AddUint64(&s.stats.TotFileMergeIntroductionsDone, 1) + if introStatus != nil && introStatus.indexSnapshot != nil { + _ = introStatus.indexSnapshot.DecRef() + if introStatus.skipped { + // close the segment on skipping introduction. + s.unmarkIneligibleForRemoval(filename) + _ = seg.Close() + } + } + + atomic.AddUint64(&s.stats.TotFileMergePlanTasksDone, 1) + + s.fireEvent(EventKindMergeTaskIntroduction, 0) + } + + // once all the newly merged segment introductions are done, + // its safe to unflip the removal ineligibility for the replaced + // older segments + for _, f := range filenames { + s.unmarkIneligibleForRemoval(f) + } + + return nil +} + +type mergeTaskIntroStatus struct { + indexSnapshot *IndexSnapshot + skipped bool +} + +type segmentMerge struct { + id uint64 + old map[uint64]*SegmentSnapshot + oldNewDocNums map[uint64][]uint64 + new segment.Segment + notifyCh chan *mergeTaskIntroStatus + mmaped uint32 +} + +func cumulateBytesRead(sbs []segment.Segment) uint64 { + var rv uint64 + for _, seg := range sbs { + rv += seg.BytesRead() + } + return rv +} + +// perform a merging of the given SegmentBase instances into a new, +// persisted segment, and synchronously introduce that new segment +// into the root +func (s *Scorch) mergeSegmentBases(snapshot *IndexSnapshot, + sbs []segment.Segment, sbsDrops []*roaring.Bitmap, + sbsIndexes []int) (*IndexSnapshot, uint64, error) { + atomic.AddUint64(&s.stats.TotMemMergeBeg, 1) + + memMergeZapStartTime := time.Now() + + atomic.AddUint64(&s.stats.TotMemMergeZapBeg, 1) + + newSegmentID := atomic.AddUint64(&s.nextSegmentID, 1) + filename := zapFileName(newSegmentID) + path := s.path + string(os.PathSeparator) + filename + + newDocNums, _, err := + s.segPlugin.Merge(sbs, sbsDrops, path, s.closeCh, s) + + atomic.AddUint64(&s.stats.TotMemMergeZapEnd, 1) + + memMergeZapTime := uint64(time.Since(memMergeZapStartTime)) + atomic.AddUint64(&s.stats.TotMemMergeZapTime, memMergeZapTime) + if atomic.LoadUint64(&s.stats.MaxMemMergeZapTime) < memMergeZapTime { + atomic.StoreUint64(&s.stats.MaxMemMergeZapTime, memMergeZapTime) + } + + if err != nil { + atomic.AddUint64(&s.stats.TotMemMergeErr, 1) + return nil, 0, err + } + + seg, err := s.segPlugin.Open(path) + if err != nil { + atomic.AddUint64(&s.stats.TotMemMergeErr, 1) + return nil, 0, err + } + + // update persisted stats + atomic.AddUint64(&s.stats.TotPersistedItems, seg.Count()) + atomic.AddUint64(&s.stats.TotPersistedSegments, 1) + + sm := &segmentMerge{ + id: newSegmentID, + old: make(map[uint64]*SegmentSnapshot), + oldNewDocNums: make(map[uint64][]uint64), + new: seg, + notifyCh: make(chan *mergeTaskIntroStatus), + } + + for i, idx := range sbsIndexes { + ss := snapshot.segment[idx] + sm.old[ss.id] = ss + sm.oldNewDocNums[ss.id] = newDocNums[i] + } + + select { // send to introducer + case <-s.closeCh: + _ = seg.DecRef() + return nil, 0, segment.ErrClosed + case s.merges <- sm: + } + + // blockingly wait for the introduction to complete + var newSnapshot *IndexSnapshot + introStatus := <-sm.notifyCh + if introStatus != nil && introStatus.indexSnapshot != nil { + newSnapshot = introStatus.indexSnapshot + atomic.AddUint64(&s.stats.TotMemMergeSegments, uint64(len(sbs))) + atomic.AddUint64(&s.stats.TotMemMergeDone, 1) + if introStatus.skipped { + // close the segment on skipping introduction. + _ = newSnapshot.DecRef() + _ = seg.Close() + newSnapshot = nil + } + } + + return newSnapshot, newSegmentID, nil +} + +func (s *Scorch) ReportBytesWritten(bytesWritten uint64) { + atomic.AddUint64(&s.stats.TotFileMergeWrittenBytes, bytesWritten) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/mergeplan/merge_plan.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/mergeplan/merge_plan.go new file mode 100644 index 0000000000..7523506626 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/mergeplan/merge_plan.go @@ -0,0 +1,397 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package mergeplan provides a segment merge planning approach that's +// inspired by Lucene's TieredMergePolicy.java and descriptions like +// http://blog.mikemccandless.com/2011/02/visualizing-lucenes-segment-merges.html +package mergeplan + +import ( + "errors" + "fmt" + "math" + "sort" + "strings" +) + +// A Segment represents the information that the planner needs to +// calculate segment merging. +type Segment interface { + // Unique id of the segment -- used for sorting. + Id() uint64 + + // Full segment size (the size before any logical deletions). + FullSize() int64 + + // Size of the live data of the segment; i.e., FullSize() minus + // any logical deletions. + LiveSize() int64 +} + +// Plan() will functionally compute a merge plan. A segment will be +// assigned to at most a single MergeTask in the output MergePlan. A +// segment not assigned to any MergeTask means the segment should +// remain unmerged. +func Plan(segments []Segment, o *MergePlanOptions) (*MergePlan, error) { + return plan(segments, o) +} + +// A MergePlan is the result of the Plan() API. +// +// The planner doesn’t know how or whether these tasks are executed -- +// that’s up to a separate merge execution system, which might execute +// these tasks concurrently or not, and which might execute all the +// tasks or not. +type MergePlan struct { + Tasks []*MergeTask +} + +// A MergeTask represents several segments that should be merged +// together into a single segment. +type MergeTask struct { + Segments []Segment +} + +// The MergePlanOptions is designed to be reusable between planning calls. +type MergePlanOptions struct { + // Max # segments per logarithmic tier, or max width of any + // logarithmic “step”. Smaller values mean more merging but fewer + // segments. Should be >= SegmentsPerMergeTask, else you'll have + // too much merging. + MaxSegmentsPerTier int + + // Max size of any segment produced after merging. Actual + // merging, however, may produce segment sizes different than the + // planner’s predicted sizes. + MaxSegmentSize int64 + + // The growth factor for each tier in a staircase of idealized + // segments computed by CalcBudget(). + TierGrowth float64 + + // The number of segments in any resulting MergeTask. e.g., + // len(result.Tasks[ * ].Segments) == SegmentsPerMergeTask. + SegmentsPerMergeTask int + + // Small segments are rounded up to this size, i.e., treated as + // equal (floor) size for consideration. This is to prevent lots + // of tiny segments from resulting in a long tail in the index. + FloorSegmentSize int64 + + // Controls how aggressively merges that reclaim more deletions + // are favored. Higher values will more aggressively target + // merges that reclaim deletions, but be careful not to go so high + // that way too much merging takes place; a value of 3.0 is + // probably nearly too high. A value of 0.0 means deletions don't + // impact merge selection. + ReclaimDeletesWeight float64 + + // Optional, defaults to mergeplan.CalcBudget(). + CalcBudget func(totalSize int64, firstTierSize int64, + o *MergePlanOptions) (budgetNumSegments int) + + // Optional, defaults to mergeplan.ScoreSegments(). + ScoreSegments func(segments []Segment, o *MergePlanOptions) float64 + + // Optional. + Logger func(string) +} + +// Returns the higher of the input or FloorSegmentSize. +func (o *MergePlanOptions) RaiseToFloorSegmentSize(s int64) int64 { + if s > o.FloorSegmentSize { + return s + } + return o.FloorSegmentSize +} + +// MaxSegmentSizeLimit represents the maximum size of a segment, +// this limit comes with hit-1 optimisation/max encoding limit uint31. +const MaxSegmentSizeLimit = 1<<31 - 1 + +// ErrMaxSegmentSizeTooLarge is returned when the size of the segment +// exceeds the MaxSegmentSizeLimit +var ErrMaxSegmentSizeTooLarge = errors.New("MaxSegmentSize exceeds the size limit") + +// DefaultMergePlanOptions suggests the default options. +var DefaultMergePlanOptions = MergePlanOptions{ + MaxSegmentsPerTier: 10, + MaxSegmentSize: 5000000, + TierGrowth: 10.0, + SegmentsPerMergeTask: 10, + FloorSegmentSize: 2000, + ReclaimDeletesWeight: 2.0, +} + +// SingleSegmentMergePlanOptions helps in creating a +// single segment index. +var SingleSegmentMergePlanOptions = MergePlanOptions{ + MaxSegmentsPerTier: 1, + MaxSegmentSize: 1 << 30, + TierGrowth: 1.0, + SegmentsPerMergeTask: 10, + FloorSegmentSize: 1 << 30, + ReclaimDeletesWeight: 2.0, +} + +// ------------------------------------------- + +func plan(segmentsIn []Segment, o *MergePlanOptions) (*MergePlan, error) { + if len(segmentsIn) <= 1 { + return nil, nil + } + + if o == nil { + o = &DefaultMergePlanOptions + } + + segments := append([]Segment(nil), segmentsIn...) // Copy. + + sort.Sort(byLiveSizeDescending(segments)) + + var minLiveSize int64 = math.MaxInt64 + + var eligibles []Segment + var eligiblesLiveSize int64 + + for _, segment := range segments { + if minLiveSize > segment.LiveSize() { + minLiveSize = segment.LiveSize() + } + + // Only small-enough segments are eligible. + if segment.LiveSize() < o.MaxSegmentSize/2 { + eligibles = append(eligibles, segment) + eligiblesLiveSize += segment.LiveSize() + } + } + + minLiveSize = o.RaiseToFloorSegmentSize(minLiveSize) + + calcBudget := o.CalcBudget + if calcBudget == nil { + calcBudget = CalcBudget + } + + budgetNumSegments := calcBudget(eligiblesLiveSize, minLiveSize, o) + + scoreSegments := o.ScoreSegments + if scoreSegments == nil { + scoreSegments = ScoreSegments + } + + rv := &MergePlan{} + + var empties []Segment + for _, eligible := range eligibles { + if eligible.LiveSize() <= 0 { + empties = append(empties, eligible) + } + } + if len(empties) > 0 { + rv.Tasks = append(rv.Tasks, &MergeTask{Segments: empties}) + eligibles = removeSegments(eligibles, empties) + } + + // While we’re over budget, keep looping, which might produce + // another MergeTask. + for len(eligibles) > 0 && (len(eligibles)+len(rv.Tasks)) > budgetNumSegments { + // Track a current best roster as we examine and score + // potential rosters of merges. + var bestRoster []Segment + var bestRosterScore float64 // Lower score is better. + + for startIdx := 0; startIdx < len(eligibles); startIdx++ { + var roster []Segment + var rosterLiveSize int64 + + for idx := startIdx; idx < len(eligibles) && len(roster) < o.SegmentsPerMergeTask; idx++ { + eligible := eligibles[idx] + + if rosterLiveSize+eligible.LiveSize() < o.MaxSegmentSize { + roster = append(roster, eligible) + rosterLiveSize += eligible.LiveSize() + } + } + + if len(roster) > 0 { + rosterScore := scoreSegments(roster, o) + + if len(bestRoster) == 0 || rosterScore < bestRosterScore { + bestRoster = roster + bestRosterScore = rosterScore + } + } + } + + if len(bestRoster) == 0 { + return rv, nil + } + + rv.Tasks = append(rv.Tasks, &MergeTask{Segments: bestRoster}) + + eligibles = removeSegments(eligibles, bestRoster) + } + + return rv, nil +} + +// Compute the number of segments that would be needed to cover the +// totalSize, by climbing up a logarithmically growing staircase of +// segment tiers. +func CalcBudget(totalSize int64, firstTierSize int64, o *MergePlanOptions) ( + budgetNumSegments int) { + tierSize := firstTierSize + if tierSize < 1 { + tierSize = 1 + } + + maxSegmentsPerTier := o.MaxSegmentsPerTier + if maxSegmentsPerTier < 1 { + maxSegmentsPerTier = 1 + } + + tierGrowth := o.TierGrowth + if tierGrowth < 1.0 { + tierGrowth = 1.0 + } + + for totalSize > 0 { + segmentsInTier := float64(totalSize) / float64(tierSize) + if segmentsInTier < float64(maxSegmentsPerTier) { + budgetNumSegments += int(math.Ceil(segmentsInTier)) + break + } + + budgetNumSegments += maxSegmentsPerTier + totalSize -= int64(maxSegmentsPerTier) * tierSize + tierSize = int64(float64(tierSize) * tierGrowth) + } + + return budgetNumSegments +} + +// Of note, removeSegments() keeps the ordering of the results stable. +func removeSegments(segments []Segment, toRemove []Segment) []Segment { + rv := make([]Segment, 0, len(segments)-len(toRemove)) +OUTER: + for _, segment := range segments { + for _, r := range toRemove { + if segment == r { + continue OUTER + } + } + rv = append(rv, segment) + } + return rv +} + +// Smaller result score is better. +func ScoreSegments(segments []Segment, o *MergePlanOptions) float64 { + var totBeforeSize int64 + var totAfterSize int64 + var totAfterSizeFloored int64 + + for _, segment := range segments { + totBeforeSize += segment.FullSize() + totAfterSize += segment.LiveSize() + totAfterSizeFloored += o.RaiseToFloorSegmentSize(segment.LiveSize()) + } + + if totBeforeSize <= 0 || totAfterSize <= 0 || totAfterSizeFloored <= 0 { + return 0 + } + + // Roughly guess the "balance" of the segments -- whether the + // segments are about the same size. + balance := + float64(o.RaiseToFloorSegmentSize(segments[0].LiveSize())) / + float64(totAfterSizeFloored) + + // Gently favor smaller merges over bigger ones. We don't want to + // make the exponent too large else we end up with poor merges of + // small segments in order to avoid the large merges. + score := balance * math.Pow(float64(totAfterSize), 0.05) + + // Strongly favor merges that reclaim deletes. + nonDelRatio := float64(totAfterSize) / float64(totBeforeSize) + + score *= math.Pow(nonDelRatio, o.ReclaimDeletesWeight) + + return score +} + +// ------------------------------------------ + +// ToBarChart returns an ASCII rendering of the segments and the plan. +// The barMax is the max width of the bars in the bar chart. +func ToBarChart(prefix string, barMax int, segments []Segment, plan *MergePlan) string { + rv := make([]string, 0, len(segments)) + + var maxFullSize int64 + for _, segment := range segments { + if maxFullSize < segment.FullSize() { + maxFullSize = segment.FullSize() + } + } + if maxFullSize < 0 { + maxFullSize = 1 + } + + for _, segment := range segments { + barFull := int(segment.FullSize()) + barLive := int(segment.LiveSize()) + + if maxFullSize > int64(barMax) { + barFull = int(float64(barMax) * float64(barFull) / float64(maxFullSize)) + barLive = int(float64(barMax) * float64(barLive) / float64(maxFullSize)) + } + + barKind := " " + barChar := "." + + if plan != nil { + TASK_LOOP: + for taski, task := range plan.Tasks { + for _, taskSegment := range task.Segments { + if taskSegment == segment { + barKind = "*" + barChar = fmt.Sprintf("%d", taski) + break TASK_LOOP + } + } + } + } + + bar := + strings.Repeat(barChar, barLive)[0:barLive] + + strings.Repeat("x", barFull-barLive)[0:barFull-barLive] + + rv = append(rv, fmt.Sprintf("%s %5d: %5d /%5d - %s %s", prefix, + segment.Id(), + segment.LiveSize(), + segment.FullSize(), + barKind, bar)) + } + + return strings.Join(rv, "\n") +} + +// ValidateMergePlannerOptions validates the merge planner options +func ValidateMergePlannerOptions(options *MergePlanOptions) error { + if options.MaxSegmentSize > MaxSegmentSizeLimit { + return ErrMaxSegmentSizeTooLarge + } + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/mergeplan/sort.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/mergeplan/sort.go new file mode 100644 index 0000000000..d044b8d7c9 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/mergeplan/sort.go @@ -0,0 +1,28 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mergeplan + +type byLiveSizeDescending []Segment + +func (a byLiveSizeDescending) Len() int { return len(a) } + +func (a byLiveSizeDescending) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +func (a byLiveSizeDescending) Less(i, j int) bool { + if a[i].LiveSize() != a[j].LiveSize() { + return a[i].LiveSize() > a[j].LiveSize() + } + return a[i].Id() < a[j].Id() +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/optimize.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/optimize.go new file mode 100644 index 0000000000..3c7969fa9e --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/optimize.go @@ -0,0 +1,396 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorch + +import ( + "fmt" + "github.com/RoaringBitmap/roaring" + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + "sync/atomic" +) + +var OptimizeConjunction = true +var OptimizeConjunctionUnadorned = true +var OptimizeDisjunctionUnadorned = true + +func (s *IndexSnapshotTermFieldReader) Optimize(kind string, + octx index.OptimizableContext) (index.OptimizableContext, error) { + if OptimizeConjunction && kind == "conjunction" { + return s.optimizeConjunction(octx) + } + + if OptimizeConjunctionUnadorned && kind == "conjunction:unadorned" { + return s.optimizeConjunctionUnadorned(octx) + } + + if OptimizeDisjunctionUnadorned && kind == "disjunction:unadorned" { + return s.optimizeDisjunctionUnadorned(octx) + } + + return nil, nil +} + +var OptimizeDisjunctionUnadornedMinChildCardinality = uint64(256) + +// ---------------------------------------------------------------- + +func (s *IndexSnapshotTermFieldReader) optimizeConjunction( + octx index.OptimizableContext) (index.OptimizableContext, error) { + if octx == nil { + octx = &OptimizeTFRConjunction{snapshot: s.snapshot} + } + + o, ok := octx.(*OptimizeTFRConjunction) + if !ok { + return octx, nil + } + + if o.snapshot != s.snapshot { + return nil, fmt.Errorf("tried to optimize conjunction across different snapshots") + } + + o.tfrs = append(o.tfrs, s) + + return o, nil +} + +type OptimizeTFRConjunction struct { + snapshot *IndexSnapshot + + tfrs []*IndexSnapshotTermFieldReader +} + +func (o *OptimizeTFRConjunction) Finish() (index.Optimized, error) { + if len(o.tfrs) <= 1 { + return nil, nil + } + + for i := range o.snapshot.segment { + itr0, ok := o.tfrs[0].iterators[i].(segment.OptimizablePostingsIterator) + if !ok || itr0.ActualBitmap() == nil { + continue + } + + itr1, ok := o.tfrs[1].iterators[i].(segment.OptimizablePostingsIterator) + if !ok || itr1.ActualBitmap() == nil { + continue + } + + bm := roaring.And(itr0.ActualBitmap(), itr1.ActualBitmap()) + + for _, tfr := range o.tfrs[2:] { + itr, ok := tfr.iterators[i].(segment.OptimizablePostingsIterator) + if !ok || itr.ActualBitmap() == nil { + continue + } + + bm.And(itr.ActualBitmap()) + } + + // in this conjunction optimization, the postings iterators + // will all share the same AND'ed together actual bitmap. The + // regular conjunction searcher machinery will still be used, + // but the underlying bitmap will be smaller. + for _, tfr := range o.tfrs { + itr, ok := tfr.iterators[i].(segment.OptimizablePostingsIterator) + if ok && itr.ActualBitmap() != nil { + itr.ReplaceActual(bm) + } + } + } + + return nil, nil +} + +// ---------------------------------------------------------------- + +// An "unadorned" conjunction optimization is appropriate when +// additional or subsidiary information like freq-norm's and +// term-vectors are not required, and instead only the internal-id's +// are needed. +func (s *IndexSnapshotTermFieldReader) optimizeConjunctionUnadorned( + octx index.OptimizableContext) (index.OptimizableContext, error) { + if octx == nil { + octx = &OptimizeTFRConjunctionUnadorned{snapshot: s.snapshot} + } + + o, ok := octx.(*OptimizeTFRConjunctionUnadorned) + if !ok { + return nil, nil + } + + if o.snapshot != s.snapshot { + return nil, fmt.Errorf("tried to optimize unadorned conjunction across different snapshots") + } + + o.tfrs = append(o.tfrs, s) + + return o, nil +} + +type OptimizeTFRConjunctionUnadorned struct { + snapshot *IndexSnapshot + + tfrs []*IndexSnapshotTermFieldReader +} + +var OptimizeTFRConjunctionUnadornedTerm = []byte("") +var OptimizeTFRConjunctionUnadornedField = "*" + +// Finish of an unadorned conjunction optimization will compute a +// termFieldReader with an "actual" bitmap that represents the +// constituent bitmaps AND'ed together. This termFieldReader cannot +// provide any freq-norm or termVector associated information. +func (o *OptimizeTFRConjunctionUnadorned) Finish() (rv index.Optimized, err error) { + if len(o.tfrs) <= 1 { + return nil, nil + } + + // We use an artificial term and field because the optimized + // termFieldReader can represent multiple terms and fields. + oTFR := o.snapshot.unadornedTermFieldReader( + OptimizeTFRConjunctionUnadornedTerm, OptimizeTFRConjunctionUnadornedField) + + var actualBMs []*roaring.Bitmap // Collected from regular posting lists. + +OUTER: + for i := range o.snapshot.segment { + actualBMs = actualBMs[:0] + + var docNum1HitLast uint64 + var docNum1HitLastOk bool + + for _, tfr := range o.tfrs { + if _, ok := tfr.iterators[i].(*emptyPostingsIterator); ok { + // An empty postings iterator means the entire AND is empty. + oTFR.iterators[i] = anEmptyPostingsIterator + continue OUTER + } + + itr, ok := tfr.iterators[i].(segment.OptimizablePostingsIterator) + if !ok { + // We only optimize postings iterators that support this operation. + return nil, nil + } + + // If the postings iterator is "1-hit" optimized, then we + // can perform several optimizations up-front here. + docNum1Hit, ok := itr.DocNum1Hit() + if ok { + if docNum1HitLastOk && docNum1HitLast != docNum1Hit { + // The docNum1Hit doesn't match the previous + // docNum1HitLast, so the entire AND is empty. + oTFR.iterators[i] = anEmptyPostingsIterator + continue OUTER + } + + docNum1HitLast = docNum1Hit + docNum1HitLastOk = true + + continue + } + + if itr.ActualBitmap() == nil { + // An empty actual bitmap means the entire AND is empty. + oTFR.iterators[i] = anEmptyPostingsIterator + continue OUTER + } + + // Collect the actual bitmap for more processing later. + actualBMs = append(actualBMs, itr.ActualBitmap()) + } + + if docNum1HitLastOk { + // We reach here if all the 1-hit optimized posting + // iterators had the same 1-hit docNum, so we can check if + // our collected actual bitmaps also have that docNum. + for _, bm := range actualBMs { + if !bm.Contains(uint32(docNum1HitLast)) { + // The docNum1Hit isn't in one of our actual + // bitmaps, so the entire AND is empty. + oTFR.iterators[i] = anEmptyPostingsIterator + continue OUTER + } + } + + // The actual bitmaps and docNum1Hits all contain or have + // the same 1-hit docNum, so that's our AND'ed result. + oTFR.iterators[i] = newUnadornedPostingsIteratorFrom1Hit(docNum1HitLast) + + continue OUTER + } + + if len(actualBMs) == 0 { + // If we've collected no actual bitmaps at this point, + // then the entire AND is empty. + oTFR.iterators[i] = anEmptyPostingsIterator + continue OUTER + } + + if len(actualBMs) == 1 { + // If we've only 1 actual bitmap, then that's our result. + oTFR.iterators[i] = newUnadornedPostingsIteratorFromBitmap(actualBMs[0]) + + continue OUTER + } + + // Else, AND together our collected bitmaps as our result. + bm := roaring.And(actualBMs[0], actualBMs[1]) + + for _, actualBM := range actualBMs[2:] { + bm.And(actualBM) + } + + oTFR.iterators[i] = newUnadornedPostingsIteratorFromBitmap(bm) + } + + atomic.AddUint64(&o.snapshot.parent.stats.TotTermSearchersStarted, uint64(1)) + return oTFR, nil +} + +// ---------------------------------------------------------------- + +// An "unadorned" disjunction optimization is appropriate when +// additional or subsidiary information like freq-norm's and +// term-vectors are not required, and instead only the internal-id's +// are needed. +func (s *IndexSnapshotTermFieldReader) optimizeDisjunctionUnadorned( + octx index.OptimizableContext) (index.OptimizableContext, error) { + if octx == nil { + octx = &OptimizeTFRDisjunctionUnadorned{ + snapshot: s.snapshot, + } + } + + o, ok := octx.(*OptimizeTFRDisjunctionUnadorned) + if !ok { + return nil, nil + } + + if o.snapshot != s.snapshot { + return nil, fmt.Errorf("tried to optimize unadorned disjunction across different snapshots") + } + + o.tfrs = append(o.tfrs, s) + + return o, nil +} + +type OptimizeTFRDisjunctionUnadorned struct { + snapshot *IndexSnapshot + + tfrs []*IndexSnapshotTermFieldReader +} + +var OptimizeTFRDisjunctionUnadornedTerm = []byte("") +var OptimizeTFRDisjunctionUnadornedField = "*" + +// Finish of an unadorned disjunction optimization will compute a +// termFieldReader with an "actual" bitmap that represents the +// constituent bitmaps OR'ed together. This termFieldReader cannot +// provide any freq-norm or termVector associated information. +func (o *OptimizeTFRDisjunctionUnadorned) Finish() (rv index.Optimized, err error) { + if len(o.tfrs) <= 1 { + return nil, nil + } + + for i := range o.snapshot.segment { + var cMax uint64 + + for _, tfr := range o.tfrs { + itr, ok := tfr.iterators[i].(segment.OptimizablePostingsIterator) + if !ok { + return nil, nil + } + + if itr.ActualBitmap() != nil { + c := itr.ActualBitmap().GetCardinality() + if cMax < c { + cMax = c + } + } + } + } + + // We use an artificial term and field because the optimized + // termFieldReader can represent multiple terms and fields. + oTFR := o.snapshot.unadornedTermFieldReader( + OptimizeTFRDisjunctionUnadornedTerm, OptimizeTFRDisjunctionUnadornedField) + + var docNums []uint32 // Collected docNum's from 1-hit posting lists. + var actualBMs []*roaring.Bitmap // Collected from regular posting lists. + + for i := range o.snapshot.segment { + docNums = docNums[:0] + actualBMs = actualBMs[:0] + + for _, tfr := range o.tfrs { + itr, ok := tfr.iterators[i].(segment.OptimizablePostingsIterator) + if !ok { + return nil, nil + } + + docNum, ok := itr.DocNum1Hit() + if ok { + docNums = append(docNums, uint32(docNum)) + continue + } + + if itr.ActualBitmap() != nil { + actualBMs = append(actualBMs, itr.ActualBitmap()) + } + } + + var bm *roaring.Bitmap + if len(actualBMs) > 2 { + bm = roaring.HeapOr(actualBMs...) + } else if len(actualBMs) == 2 { + bm = roaring.Or(actualBMs[0], actualBMs[1]) + } else if len(actualBMs) == 1 { + bm = actualBMs[0].Clone() + } + + if bm == nil { + bm = roaring.New() + } + + bm.AddMany(docNums) + + oTFR.iterators[i] = newUnadornedPostingsIteratorFromBitmap(bm) + } + + atomic.AddUint64(&o.snapshot.parent.stats.TotTermSearchersStarted, uint64(1)) + return oTFR, nil +} + +// ---------------------------------------------------------------- + +func (i *IndexSnapshot) unadornedTermFieldReader( + term []byte, field string) *IndexSnapshotTermFieldReader { + // This IndexSnapshotTermFieldReader will not be recycled, more + // conversation here: https://github.com/blevesearch/bleve/pull/1438 + return &IndexSnapshotTermFieldReader{ + term: term, + field: field, + snapshot: i, + iterators: make([]segment.PostingsIterator, len(i.segment)), + segmentOffset: 0, + includeFreq: false, + includeNorm: false, + includeTermVectors: false, + recycle: false, + } +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/persister.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/persister.go new file mode 100644 index 0000000000..b90899f257 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/persister.go @@ -0,0 +1,1267 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorch + +import ( + "bytes" + "encoding/binary" + "encoding/json" + "fmt" + "io" + "log" + "math" + "os" + "path/filepath" + "sort" + "strconv" + "strings" + "sync/atomic" + "time" + + "github.com/RoaringBitmap/roaring" + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + bolt "go.etcd.io/bbolt" +) + +// DefaultPersisterNapTimeMSec is kept to zero as this helps in direct +// persistence of segments with the default safe batch option. +// If the default safe batch option results in high number of +// files on disk, then users may initialise this configuration parameter +// with higher values so that the persister will nap a bit within it's +// work loop to favour better in-memory merging of segments to result +// in fewer segment files on disk. But that may come with an indexing +// performance overhead. +// Unsafe batch users are advised to override this to higher value +// for better performance especially with high data density. +var DefaultPersisterNapTimeMSec int = 0 // ms + +// DefaultPersisterNapUnderNumFiles helps in controlling the pace of +// persister. At times of a slow merger progress with heavy file merging +// operations, its better to pace down the persister for letting the merger +// to catch up within a range defined by this parameter. +// Fewer files on disk (as per the merge plan) would result in keeping the +// file handle usage under limit, faster disk merger and a healthier index. +// Its been observed that such a loosely sync'ed introducer-persister-merger +// trio results in better overall performance. +var DefaultPersisterNapUnderNumFiles int = 1000 + +var DefaultMemoryPressurePauseThreshold uint64 = math.MaxUint64 + +type persisterOptions struct { + // PersisterNapTimeMSec controls the wait/delay injected into + // persistence workloop to improve the chances for + // a healthier and heavier in-memory merging + PersisterNapTimeMSec int + + // PersisterNapTimeMSec > 0, and the number of files is less than + // PersisterNapUnderNumFiles, then the persister will sleep + // PersisterNapTimeMSec amount of time to improve the chances for + // a healthier and heavier in-memory merging + PersisterNapUnderNumFiles int + + // MemoryPressurePauseThreshold let persister to have a better leeway + // for prudently performing the memory merge of segments on a memory + // pressure situation. Here the config value is an upper threshold + // for the number of paused application threads. The default value would + // be a very high number to always favour the merging of memory segments. + MemoryPressurePauseThreshold uint64 +} + +type notificationChan chan struct{} + +func (s *Scorch) persisterLoop() { + defer func() { + if r := recover(); r != nil { + s.fireAsyncError(&AsyncPanicError{ + Source: "persister", + Path: s.path, + }) + } + + s.asyncTasks.Done() + }() + + var persistWatchers []*epochWatcher + var lastPersistedEpoch, lastMergedEpoch uint64 + var ew *epochWatcher + + var unpersistedCallbacks []index.BatchCallback + + po, err := s.parsePersisterOptions() + if err != nil { + s.fireAsyncError(fmt.Errorf("persisterOptions json parsing err: %v", err)) + return + } + +OUTER: + for { + atomic.AddUint64(&s.stats.TotPersistLoopBeg, 1) + + select { + case <-s.closeCh: + break OUTER + case ew = <-s.persisterNotifier: + persistWatchers = append(persistWatchers, ew) + default: + } + if ew != nil && ew.epoch > lastMergedEpoch { + lastMergedEpoch = ew.epoch + } + lastMergedEpoch, persistWatchers = s.pausePersisterForMergerCatchUp(lastPersistedEpoch, + lastMergedEpoch, persistWatchers, po) + + var ourSnapshot *IndexSnapshot + var ourPersisted []chan error + var ourPersistedCallbacks []index.BatchCallback + + // check to see if there is a new snapshot to persist + s.rootLock.Lock() + if s.root != nil && s.root.epoch > lastPersistedEpoch { + ourSnapshot = s.root + ourSnapshot.AddRef() + ourPersisted = s.rootPersisted + s.rootPersisted = nil + ourPersistedCallbacks = s.persistedCallbacks + s.persistedCallbacks = nil + atomic.StoreUint64(&s.iStats.persistSnapshotSize, uint64(ourSnapshot.Size())) + atomic.StoreUint64(&s.iStats.persistEpoch, ourSnapshot.epoch) + } + s.rootLock.Unlock() + + if ourSnapshot != nil { + startTime := time.Now() + + err := s.persistSnapshot(ourSnapshot, po) + for _, ch := range ourPersisted { + if err != nil { + ch <- err + } + close(ch) + } + if err != nil { + atomic.StoreUint64(&s.iStats.persistEpoch, 0) + if err == segment.ErrClosed { + // index has been closed + _ = ourSnapshot.DecRef() + break OUTER + } + + // save this current snapshot's persistedCallbacks, to invoke during + // the retry attempt + unpersistedCallbacks = append(unpersistedCallbacks, ourPersistedCallbacks...) + + s.fireAsyncError(fmt.Errorf("got err persisting snapshot: %v", err)) + _ = ourSnapshot.DecRef() + atomic.AddUint64(&s.stats.TotPersistLoopErr, 1) + continue OUTER + } + + if unpersistedCallbacks != nil { + // in the event of this being a retry attempt for persisting a snapshot + // that had earlier failed, prepend the persistedCallbacks associated + // with earlier segment(s) to the latest persistedCallbacks + ourPersistedCallbacks = append(unpersistedCallbacks, ourPersistedCallbacks...) + unpersistedCallbacks = nil + } + + for i := range ourPersistedCallbacks { + ourPersistedCallbacks[i](err) + } + + atomic.StoreUint64(&s.stats.LastPersistedEpoch, ourSnapshot.epoch) + + lastPersistedEpoch = ourSnapshot.epoch + for _, ew := range persistWatchers { + close(ew.notifyCh) + } + + persistWatchers = nil + _ = ourSnapshot.DecRef() + + changed := false + s.rootLock.RLock() + if s.root != nil && s.root.epoch != lastPersistedEpoch { + changed = true + } + s.rootLock.RUnlock() + + s.fireEvent(EventKindPersisterProgress, time.Since(startTime)) + + if changed { + atomic.AddUint64(&s.stats.TotPersistLoopProgress, 1) + continue OUTER + } + } + + // tell the introducer we're waiting for changes + w := &epochWatcher{ + epoch: lastPersistedEpoch, + notifyCh: make(notificationChan, 1), + } + + select { + case <-s.closeCh: + break OUTER + case s.introducerNotifier <- w: + } + + s.removeOldData() // might as well cleanup while waiting + + atomic.AddUint64(&s.stats.TotPersistLoopWait, 1) + + select { + case <-s.closeCh: + break OUTER + case <-w.notifyCh: + // woken up, next loop should pick up work + atomic.AddUint64(&s.stats.TotPersistLoopWaitNotified, 1) + case ew = <-s.persisterNotifier: + // if the watchers are already caught up then let them wait, + // else let them continue to do the catch up + persistWatchers = append(persistWatchers, ew) + } + + atomic.AddUint64(&s.stats.TotPersistLoopEnd, 1) + } +} + +func notifyMergeWatchers(lastPersistedEpoch uint64, + persistWatchers []*epochWatcher) []*epochWatcher { + var watchersNext []*epochWatcher + for _, w := range persistWatchers { + if w.epoch < lastPersistedEpoch { + close(w.notifyCh) + } else { + watchersNext = append(watchersNext, w) + } + } + return watchersNext +} + +func (s *Scorch) pausePersisterForMergerCatchUp(lastPersistedEpoch uint64, + lastMergedEpoch uint64, persistWatchers []*epochWatcher, + po *persisterOptions) (uint64, []*epochWatcher) { + + // First, let the watchers proceed if they lag behind + persistWatchers = notifyMergeWatchers(lastPersistedEpoch, persistWatchers) + + // Check the merger lag by counting the segment files on disk, + numFilesOnDisk, _, _ := s.diskFileStats(nil) + + // On finding fewer files on disk, persister takes a short pause + // for sufficient in-memory segments to pile up for the next + // memory merge cum persist loop. + if numFilesOnDisk < uint64(po.PersisterNapUnderNumFiles) && + po.PersisterNapTimeMSec > 0 && s.NumEventsBlocking() == 0 { + select { + case <-s.closeCh: + case <-time.After(time.Millisecond * time.Duration(po.PersisterNapTimeMSec)): + atomic.AddUint64(&s.stats.TotPersisterNapPauseCompleted, 1) + + case ew := <-s.persisterNotifier: + // unblock the merger in meantime + persistWatchers = append(persistWatchers, ew) + lastMergedEpoch = ew.epoch + persistWatchers = notifyMergeWatchers(lastPersistedEpoch, persistWatchers) + atomic.AddUint64(&s.stats.TotPersisterMergerNapBreak, 1) + } + return lastMergedEpoch, persistWatchers + } + + // Finding too many files on disk could be due to two reasons. + // 1. Too many older snapshots awaiting the clean up. + // 2. The merger could be lagging behind on merging the disk files. + if numFilesOnDisk > uint64(po.PersisterNapUnderNumFiles) { + s.removeOldData() + numFilesOnDisk, _, _ = s.diskFileStats(nil) + } + + // Persister pause until the merger catches up to reduce the segment + // file count under the threshold. + // But if there is memory pressure, then skip this sleep maneuvers. +OUTER: + for po.PersisterNapUnderNumFiles > 0 && + numFilesOnDisk >= uint64(po.PersisterNapUnderNumFiles) && + lastMergedEpoch < lastPersistedEpoch { + atomic.AddUint64(&s.stats.TotPersisterSlowMergerPause, 1) + + select { + case <-s.closeCh: + break OUTER + case ew := <-s.persisterNotifier: + persistWatchers = append(persistWatchers, ew) + lastMergedEpoch = ew.epoch + } + + atomic.AddUint64(&s.stats.TotPersisterSlowMergerResume, 1) + + // let the watchers proceed if they lag behind + persistWatchers = notifyMergeWatchers(lastPersistedEpoch, persistWatchers) + + numFilesOnDisk, _, _ = s.diskFileStats(nil) + } + + return lastMergedEpoch, persistWatchers +} + +func (s *Scorch) parsePersisterOptions() (*persisterOptions, error) { + po := persisterOptions{ + PersisterNapTimeMSec: DefaultPersisterNapTimeMSec, + PersisterNapUnderNumFiles: DefaultPersisterNapUnderNumFiles, + MemoryPressurePauseThreshold: DefaultMemoryPressurePauseThreshold, + } + if v, ok := s.config["scorchPersisterOptions"]; ok { + b, err := json.Marshal(v) + if err != nil { + return &po, err + } + + err = json.Unmarshal(b, &po) + if err != nil { + return &po, err + } + } + return &po, nil +} + +func (s *Scorch) persistSnapshot(snapshot *IndexSnapshot, + po *persisterOptions) error { + // Perform in-memory segment merging only when the memory pressure is + // below the configured threshold, else the persister performs the + // direct persistence of segments. + if s.NumEventsBlocking() < po.MemoryPressurePauseThreshold { + persisted, err := s.persistSnapshotMaybeMerge(snapshot) + if err != nil { + return err + } + if persisted { + return nil + } + } + + return s.persistSnapshotDirect(snapshot) +} + +// DefaultMinSegmentsForInMemoryMerge represents the default number of +// in-memory zap segments that persistSnapshotMaybeMerge() needs to +// see in an IndexSnapshot before it decides to merge and persist +// those segments +var DefaultMinSegmentsForInMemoryMerge = 2 + +// persistSnapshotMaybeMerge examines the snapshot and might merge and +// persist the in-memory zap segments if there are enough of them +func (s *Scorch) persistSnapshotMaybeMerge(snapshot *IndexSnapshot) ( + bool, error) { + // collect the in-memory zap segments (SegmentBase instances) + var sbs []segment.Segment + var sbsDrops []*roaring.Bitmap + var sbsIndexes []int + + for i, segmentSnapshot := range snapshot.segment { + if _, ok := segmentSnapshot.segment.(segment.PersistedSegment); !ok { + sbs = append(sbs, segmentSnapshot.segment) + sbsDrops = append(sbsDrops, segmentSnapshot.deleted) + sbsIndexes = append(sbsIndexes, i) + } + } + + if len(sbs) < DefaultMinSegmentsForInMemoryMerge { + return false, nil + } + + newSnapshot, newSegmentID, err := s.mergeSegmentBases( + snapshot, sbs, sbsDrops, sbsIndexes) + if err != nil { + return false, err + } + if newSnapshot == nil { + return false, nil + } + + defer func() { + _ = newSnapshot.DecRef() + }() + + mergedSegmentIDs := map[uint64]struct{}{} + for _, idx := range sbsIndexes { + mergedSegmentIDs[snapshot.segment[idx].id] = struct{}{} + } + + // construct a snapshot that's logically equivalent to the input + // snapshot, but with merged segments replaced by the new segment + equiv := &IndexSnapshot{ + parent: snapshot.parent, + segment: make([]*SegmentSnapshot, 0, len(snapshot.segment)), + internal: snapshot.internal, + epoch: snapshot.epoch, + creator: "persistSnapshotMaybeMerge", + } + + // copy to the equiv the segments that weren't replaced + for _, segment := range snapshot.segment { + if _, wasMerged := mergedSegmentIDs[segment.id]; !wasMerged { + equiv.segment = append(equiv.segment, segment) + } + } + + // append to the equiv the new segment + for _, segment := range newSnapshot.segment { + if segment.id == newSegmentID { + equiv.segment = append(equiv.segment, &SegmentSnapshot{ + id: newSegmentID, + segment: segment.segment, + deleted: nil, // nil since merging handled deletions + }) + break + } + } + + err = s.persistSnapshotDirect(equiv) + if err != nil { + return false, err + } + + return true, nil +} + +func copyToDirectory(srcPath string, d index.Directory) (int64, error) { + if d == nil { + return 0, nil + } + + dest, err := d.GetWriter(filepath.Join("store", filepath.Base(srcPath))) + if err != nil { + return 0, fmt.Errorf("GetWriter err: %v", err) + } + + sourceFileStat, err := os.Stat(srcPath) + if err != nil { + return 0, err + } + + if !sourceFileStat.Mode().IsRegular() { + return 0, fmt.Errorf("%s is not a regular file", srcPath) + } + + source, err := os.Open(srcPath) + if err != nil { + return 0, err + } + defer source.Close() + defer dest.Close() + return io.Copy(dest, source) +} + +func persistToDirectory(seg segment.UnpersistedSegment, d index.Directory, + path string) error { + if d == nil { + return seg.Persist(path) + } + + sg, ok := seg.(io.WriterTo) + if !ok { + return fmt.Errorf("no io.WriterTo segment implementation found") + } + + w, err := d.GetWriter(filepath.Join("store", filepath.Base(path))) + if err != nil { + return err + } + + _, err = sg.WriteTo(w) + w.Close() + + return err +} + +func prepareBoltSnapshot(snapshot *IndexSnapshot, tx *bolt.Tx, path string, + segPlugin SegmentPlugin, d index.Directory) ( + []string, map[uint64]string, error) { + snapshotsBucket, err := tx.CreateBucketIfNotExists(boltSnapshotsBucket) + if err != nil { + return nil, nil, err + } + newSnapshotKey := encodeUvarintAscending(nil, snapshot.epoch) + snapshotBucket, err := snapshotsBucket.CreateBucketIfNotExists(newSnapshotKey) + if err != nil { + return nil, nil, err + } + + // persist meta values + metaBucket, err := snapshotBucket.CreateBucketIfNotExists(boltMetaDataKey) + if err != nil { + return nil, nil, err + } + err = metaBucket.Put(boltMetaDataSegmentTypeKey, []byte(segPlugin.Type())) + if err != nil { + return nil, nil, err + } + buf := make([]byte, binary.MaxVarintLen32) + binary.BigEndian.PutUint32(buf, segPlugin.Version()) + err = metaBucket.Put(boltMetaDataSegmentVersionKey, buf) + if err != nil { + return nil, nil, err + } + + // Storing the timestamp at which the current indexSnapshot + // was persisted, useful when you want to spread the + // numSnapshotsToKeep reasonably better than consecutive + // epochs. + currTimeStamp := time.Now() + timeStampBinary, err := currTimeStamp.MarshalText() + if err != nil { + return nil, nil, err + } + err = metaBucket.Put(boltMetaDataTimeStamp, timeStampBinary) + if err != nil { + return nil, nil, err + } + + // persist internal values + internalBucket, err := snapshotBucket.CreateBucketIfNotExists(boltInternalKey) + if err != nil { + return nil, nil, err + } + // TODO optimize writing these in order? + for k, v := range snapshot.internal { + err = internalBucket.Put([]byte(k), v) + if err != nil { + return nil, nil, err + } + } + + if snapshot.parent != nil { + val := make([]byte, 8) + bytesWritten := atomic.LoadUint64(&snapshot.parent.stats.TotBytesWrittenAtIndexTime) + binary.LittleEndian.PutUint64(val, bytesWritten) + internalBucket.Put(TotBytesWrittenKey, val) + } + + var filenames []string + newSegmentPaths := make(map[uint64]string) + + // first ensure that each segment in this snapshot has been persisted + for _, segmentSnapshot := range snapshot.segment { + snapshotSegmentKey := encodeUvarintAscending(nil, segmentSnapshot.id) + snapshotSegmentBucket, err := snapshotBucket.CreateBucketIfNotExists(snapshotSegmentKey) + if err != nil { + return nil, nil, err + } + switch seg := segmentSnapshot.segment.(type) { + case segment.PersistedSegment: + segPath := seg.Path() + _, err = copyToDirectory(segPath, d) + if err != nil { + return nil, nil, fmt.Errorf("segment: %s copy err: %v", segPath, err) + } + filename := filepath.Base(segPath) + err = snapshotSegmentBucket.Put(boltPathKey, []byte(filename)) + if err != nil { + return nil, nil, err + } + filenames = append(filenames, filename) + case segment.UnpersistedSegment: + // need to persist this to disk + filename := zapFileName(segmentSnapshot.id) + path := filepath.Join(path, filename) + err := persistToDirectory(seg, d, path) + if err != nil { + return nil, nil, fmt.Errorf("segment: %s persist err: %v", path, err) + } + newSegmentPaths[segmentSnapshot.id] = path + err = snapshotSegmentBucket.Put(boltPathKey, []byte(filename)) + if err != nil { + return nil, nil, err + } + filenames = append(filenames, filename) + default: + return nil, nil, fmt.Errorf("unknown segment type: %T", seg) + } + // store current deleted bits + var roaringBuf bytes.Buffer + if segmentSnapshot.deleted != nil { + _, err = segmentSnapshot.deleted.WriteTo(&roaringBuf) + if err != nil { + return nil, nil, fmt.Errorf("error persisting roaring bytes: %v", err) + } + err = snapshotSegmentBucket.Put(boltDeletedKey, roaringBuf.Bytes()) + if err != nil { + return nil, nil, err + } + } + } + + return filenames, newSegmentPaths, nil +} + +func (s *Scorch) persistSnapshotDirect(snapshot *IndexSnapshot) (err error) { + // start a write transaction + tx, err := s.rootBolt.Begin(true) + if err != nil { + return err + } + // defer rollback on error + defer func() { + if err != nil { + _ = tx.Rollback() + } + }() + + filenames, newSegmentPaths, err := prepareBoltSnapshot(snapshot, tx, s.path, s.segPlugin, nil) + if err != nil { + return err + } + + // we need to swap in a new root only when we've persisted 1 or + // more segments -- whereby the new root would have 1-for-1 + // replacements of in-memory segments with file-based segments + // + // other cases like updates to internal values only, and/or when + // there are only deletions, are already covered and persisted by + // the newly populated boltdb snapshotBucket above + if len(newSegmentPaths) > 0 { + // now try to open all the new snapshots + newSegments := make(map[uint64]segment.Segment) + defer func() { + for _, s := range newSegments { + if s != nil { + // cleanup segments that were opened but not + // swapped into the new root + _ = s.Close() + } + } + }() + for segmentID, path := range newSegmentPaths { + newSegments[segmentID], err = s.segPlugin.Open(path) + if err != nil { + return fmt.Errorf("error opening new segment at %s, %v", path, err) + } + } + + persist := &persistIntroduction{ + persisted: newSegments, + applied: make(notificationChan), + } + + select { + case <-s.closeCh: + return segment.ErrClosed + case s.persists <- persist: + } + + select { + case <-s.closeCh: + return segment.ErrClosed + case <-persist.applied: + } + } + + err = tx.Commit() + if err != nil { + return err + } + + err = s.rootBolt.Sync() + if err != nil { + return err + } + + // allow files to become eligible for removal after commit, such + // as file segments from snapshots that came from the merger + s.rootLock.Lock() + for _, filename := range filenames { + delete(s.ineligibleForRemoval, filename) + } + s.rootLock.Unlock() + + return nil +} + +func zapFileName(epoch uint64) string { + return fmt.Sprintf("%012x.zap", epoch) +} + +// bolt snapshot code + +var boltSnapshotsBucket = []byte{'s'} +var boltPathKey = []byte{'p'} +var boltDeletedKey = []byte{'d'} +var boltInternalKey = []byte{'i'} +var boltMetaDataKey = []byte{'m'} +var boltMetaDataSegmentTypeKey = []byte("type") +var boltMetaDataSegmentVersionKey = []byte("version") +var boltMetaDataTimeStamp = []byte("timeStamp") +var TotBytesWrittenKey = []byte("TotBytesWritten") + +func (s *Scorch) loadFromBolt() error { + return s.rootBolt.View(func(tx *bolt.Tx) error { + snapshots := tx.Bucket(boltSnapshotsBucket) + if snapshots == nil { + return nil + } + foundRoot := false + c := snapshots.Cursor() + for k, _ := c.Last(); k != nil; k, _ = c.Prev() { + _, snapshotEpoch, err := decodeUvarintAscending(k) + if err != nil { + log.Printf("unable to parse segment epoch %x, continuing", k) + continue + } + if foundRoot { + s.AddEligibleForRemoval(snapshotEpoch) + continue + } + snapshot := snapshots.Bucket(k) + if snapshot == nil { + log.Printf("snapshot key, but bucket missing %x, continuing", k) + s.AddEligibleForRemoval(snapshotEpoch) + continue + } + indexSnapshot, err := s.loadSnapshot(snapshot) + if err != nil { + log.Printf("unable to load snapshot, %v, continuing", err) + s.AddEligibleForRemoval(snapshotEpoch) + continue + } + indexSnapshot.epoch = snapshotEpoch + // set the nextSegmentID + s.nextSegmentID, err = s.maxSegmentIDOnDisk() + if err != nil { + return err + } + s.nextSegmentID++ + s.rootLock.Lock() + s.nextSnapshotEpoch = snapshotEpoch + 1 + rootPrev := s.root + s.root = indexSnapshot + s.rootLock.Unlock() + + if rootPrev != nil { + _ = rootPrev.DecRef() + } + + foundRoot = true + } + return nil + }) +} + +// LoadSnapshot loads the segment with the specified epoch +// NOTE: this is currently ONLY intended to be used by the command-line tool +func (s *Scorch) LoadSnapshot(epoch uint64) (rv *IndexSnapshot, err error) { + err = s.rootBolt.View(func(tx *bolt.Tx) error { + snapshots := tx.Bucket(boltSnapshotsBucket) + if snapshots == nil { + return nil + } + snapshotKey := encodeUvarintAscending(nil, epoch) + snapshot := snapshots.Bucket(snapshotKey) + if snapshot == nil { + return fmt.Errorf("snapshot with epoch: %v - doesn't exist", epoch) + } + rv, err = s.loadSnapshot(snapshot) + return err + }) + if err != nil { + return nil, err + } + return rv, nil +} + +func (s *Scorch) loadSnapshot(snapshot *bolt.Bucket) (*IndexSnapshot, error) { + + rv := &IndexSnapshot{ + parent: s, + internal: make(map[string][]byte), + refs: 1, + creator: "loadSnapshot", + } + // first we look for the meta-data bucket, this will tell us + // which segment type/version was used for this snapshot + // all operations for this scorch will use this type/version + metaBucket := snapshot.Bucket(boltMetaDataKey) + if metaBucket == nil { + _ = rv.DecRef() + return nil, fmt.Errorf("meta-data bucket missing") + } + segmentType := string(metaBucket.Get(boltMetaDataSegmentTypeKey)) + segmentVersion := binary.BigEndian.Uint32( + metaBucket.Get(boltMetaDataSegmentVersionKey)) + err := s.loadSegmentPlugin(segmentType, segmentVersion) + if err != nil { + _ = rv.DecRef() + return nil, fmt.Errorf( + "unable to load correct segment wrapper: %v", err) + } + var running uint64 + c := snapshot.Cursor() + for k, _ := c.First(); k != nil; k, _ = c.Next() { + if k[0] == boltInternalKey[0] { + internalBucket := snapshot.Bucket(k) + err := internalBucket.ForEach(func(key []byte, val []byte) error { + copiedVal := append([]byte(nil), val...) + rv.internal[string(key)] = copiedVal + return nil + }) + if err != nil { + _ = rv.DecRef() + return nil, err + } + } else if k[0] != boltMetaDataKey[0] { + segmentBucket := snapshot.Bucket(k) + if segmentBucket == nil { + _ = rv.DecRef() + return nil, fmt.Errorf("segment key, but bucket missing % x", k) + } + segmentSnapshot, err := s.loadSegment(segmentBucket) + if err != nil { + _ = rv.DecRef() + return nil, fmt.Errorf("failed to load segment: %v", err) + } + _, segmentSnapshot.id, err = decodeUvarintAscending(k) + if err != nil { + _ = rv.DecRef() + return nil, fmt.Errorf("failed to decode segment id: %v", err) + } + rv.segment = append(rv.segment, segmentSnapshot) + rv.offsets = append(rv.offsets, running) + running += segmentSnapshot.segment.Count() + } + } + return rv, nil +} + +func (s *Scorch) loadSegment(segmentBucket *bolt.Bucket) (*SegmentSnapshot, error) { + pathBytes := segmentBucket.Get(boltPathKey) + if pathBytes == nil { + return nil, fmt.Errorf("segment path missing") + } + segmentPath := s.path + string(os.PathSeparator) + string(pathBytes) + segment, err := s.segPlugin.Open(segmentPath) + if err != nil { + return nil, fmt.Errorf("error opening bolt segment: %v", err) + } + + rv := &SegmentSnapshot{ + segment: segment, + cachedDocs: &cachedDocs{cache: nil}, + } + deletedBytes := segmentBucket.Get(boltDeletedKey) + if deletedBytes != nil { + deletedBitmap := roaring.NewBitmap() + r := bytes.NewReader(deletedBytes) + _, err := deletedBitmap.ReadFrom(r) + if err != nil { + _ = segment.Close() + return nil, fmt.Errorf("error reading deleted bytes: %v", err) + } + if !deletedBitmap.IsEmpty() { + rv.deleted = deletedBitmap + } + } + + return rv, nil +} + +func (s *Scorch) removeOldData() { + removed, err := s.removeOldBoltSnapshots() + if err != nil { + s.fireAsyncError(fmt.Errorf("got err removing old bolt snapshots: %v", err)) + } + atomic.AddUint64(&s.stats.TotSnapshotsRemovedFromMetaStore, uint64(removed)) + + err = s.removeOldZapFiles() + if err != nil { + s.fireAsyncError(fmt.Errorf("got err removing old zap files: %v", err)) + } +} + +// NumSnapshotsToKeep represents how many recent, old snapshots to +// keep around per Scorch instance. Useful for apps that require +// rollback'ability. +var NumSnapshotsToKeep = 1 + +// RollbackSamplingInterval controls how far back we are looking +// in the history to get the rollback points. +// For example, a value of 10 minutes ensures that the +// protected snapshots (NumSnapshotsToKeep = 3) are: +// +// the very latest snapshot(ie the current one), +// the snapshot that was persisted 10 minutes before the current one, +// the snapshot that was persisted 20 minutes before the current one +// +// By default however, the timeseries way of protecting snapshots is +// disabled, and we protect the latest three contiguous snapshots +var RollbackSamplingInterval = 0 * time.Minute + +// Controls what portion of the earlier rollback points to retain during +// a infrequent/sparse mutation scenario +var RollbackRetentionFactor = float64(0.5) + +func getTimeSeriesSnapshots(maxDataPoints int, interval time.Duration, + snapshots []*snapshotMetaData) (int, map[uint64]time.Time) { + if interval == 0 { + return len(snapshots), map[uint64]time.Time{} + } + // the map containing the time series snapshots, i.e the timeseries of snapshots + // each of which is separated by rollbackSamplingInterval + rv := make(map[uint64]time.Time) + // the last point in the "time series", i.e. the timeseries of snapshots + // each of which is separated by rollbackSamplingInterval + ptr := len(snapshots) - 1 + rv[snapshots[ptr].epoch] = snapshots[ptr].timeStamp + numSnapshotsProtected := 1 + + // traverse the list in reverse order, older timestamps to newer ones. + for i := ptr - 1; i >= 0; i-- { + // If we find a timeStamp which is the next datapoint in our + // timeseries of snapshots, and newer by RollbackSamplingInterval duration + // (comparison in terms of minutes), which is the interval of our time + // series. In this case, add the epoch rv + if snapshots[i].timeStamp.Sub(snapshots[ptr].timeStamp).Minutes() > + interval.Minutes() { + if _, ok := rv[snapshots[i+1].epoch]; !ok { + rv[snapshots[i+1].epoch] = snapshots[i+1].timeStamp + ptr = i + 1 + numSnapshotsProtected++ + } + } else if snapshots[i].timeStamp.Sub(snapshots[ptr].timeStamp).Minutes() == + interval.Minutes() { + if _, ok := rv[snapshots[i].epoch]; !ok { + rv[snapshots[i].epoch] = snapshots[i].timeStamp + ptr = i + numSnapshotsProtected++ + } + } + + if numSnapshotsProtected >= maxDataPoints { + break + } + } + return ptr, rv +} + +// getProtectedEpochs aims to fetch the epochs keep based on a timestamp basis. +// It tries to get NumSnapshotsToKeep snapshots, each of which are separated +// by a time duration of RollbackSamplingInterval. +func getProtectedSnapshots(rollbackSamplingInterval time.Duration, + numSnapshotsToKeep int, + persistedSnapshots []*snapshotMetaData) map[uint64]time.Time { + + lastPoint, protectedEpochs := getTimeSeriesSnapshots(numSnapshotsToKeep, + rollbackSamplingInterval, persistedSnapshots) + if len(protectedEpochs) < numSnapshotsToKeep { + numSnapshotsNeeded := numSnapshotsToKeep - len(protectedEpochs) + // we protected the contiguous snapshots from the last point in time series + for i := 0; i < numSnapshotsNeeded && i < lastPoint; i++ { + protectedEpochs[persistedSnapshots[i].epoch] = persistedSnapshots[i].timeStamp + } + } + + return protectedEpochs +} + +func newCheckPoints(snapshots map[uint64]time.Time) []*snapshotMetaData { + rv := make([]*snapshotMetaData, 0) + + keys := make([]uint64, 0, len(snapshots)) + for k := range snapshots { + keys = append(keys, k) + } + + sort.SliceStable(keys, func(i, j int) bool { + return snapshots[keys[i]].Sub(snapshots[keys[j]]) > 0 + }) + + for _, key := range keys { + rv = append(rv, &snapshotMetaData{ + epoch: key, + timeStamp: snapshots[key], + }) + } + + return rv +} + +// Removes enough snapshots from the rootBolt so that the +// s.eligibleForRemoval stays under the NumSnapshotsToKeep policy. +func (s *Scorch) removeOldBoltSnapshots() (numRemoved int, err error) { + persistedSnapshots, err := s.rootBoltSnapshotMetaData() + if err != nil { + return 0, err + } + + if len(persistedSnapshots) <= s.numSnapshotsToKeep { + // we need to keep everything + return 0, nil + } + + protectedSnapshots := getProtectedSnapshots(s.rollbackSamplingInterval, + s.numSnapshotsToKeep, persistedSnapshots) + + var epochsToRemove []uint64 + var newEligible []uint64 + s.rootLock.Lock() + for _, epoch := range s.eligibleForRemoval { + if _, ok := protectedSnapshots[epoch]; ok { + // protected + newEligible = append(newEligible, epoch) + } else { + epochsToRemove = append(epochsToRemove, epoch) + } + } + s.eligibleForRemoval = newEligible + s.rootLock.Unlock() + s.checkPoints = newCheckPoints(protectedSnapshots) + + if len(epochsToRemove) == 0 { + return 0, nil + } + + tx, err := s.rootBolt.Begin(true) + if err != nil { + return 0, err + } + defer func() { + if err == nil { + err = tx.Commit() + } else { + _ = tx.Rollback() + } + if err == nil { + err = s.rootBolt.Sync() + } + }() + + snapshots := tx.Bucket(boltSnapshotsBucket) + if snapshots == nil { + return 0, nil + } + + for _, epochToRemove := range epochsToRemove { + k := encodeUvarintAscending(nil, epochToRemove) + err = snapshots.DeleteBucket(k) + if err == bolt.ErrBucketNotFound { + err = nil + } + if err == nil { + numRemoved++ + } + } + + return numRemoved, err +} + +func (s *Scorch) maxSegmentIDOnDisk() (uint64, error) { + files, err := os.ReadDir(s.path) + if err != nil { + return 0, err + } + + var rv uint64 + for _, f := range files { + fname := f.Name() + if filepath.Ext(fname) == ".zap" { + prefix := strings.TrimSuffix(fname, ".zap") + id, err2 := strconv.ParseUint(prefix, 16, 64) + if err2 != nil { + return 0, err2 + } + if id > rv { + rv = id + } + } + } + return rv, err +} + +// Removes any *.zap files which aren't listed in the rootBolt. +func (s *Scorch) removeOldZapFiles() error { + liveFileNames, err := s.loadZapFileNames() + if err != nil { + return err + } + + files, err := os.ReadDir(s.path) + if err != nil { + return err + } + + s.rootLock.RLock() + + for _, f := range files { + fname := f.Name() + if filepath.Ext(fname) == ".zap" { + if _, exists := liveFileNames[fname]; !exists && !s.ineligibleForRemoval[fname] { + err := os.Remove(s.path + string(os.PathSeparator) + fname) + if err != nil { + log.Printf("got err removing file: %s, err: %v", fname, err) + } + } + } + } + + s.rootLock.RUnlock() + + return nil +} + +// In sparse mutation scenario, it can so happen that all protected +// snapshots are older than the numSnapshotsToKeep * rollbackSamplingInterval +// duration. This results in all of them being purged from the boltDB +// and the next iteration of the removeOldData() would end up protecting +// latest contiguous snapshot which is a poor pattern in the rollback checkpoints. +// Hence we try to retain atleast retentionFactor portion worth of old snapshots +// in such a scenario using the following function +func getBoundaryCheckPoint(retentionFactor float64, + checkPoints []*snapshotMetaData, timeStamp time.Time) time.Time { + if checkPoints != nil { + boundary := checkPoints[int(math.Floor(float64(len(checkPoints))* + retentionFactor))] + if timeStamp.Sub(boundary.timeStamp) < 0 { + // too less checkPoints would be left. + return boundary.timeStamp + } + } + return timeStamp +} + +type snapshotMetaData struct { + epoch uint64 + timeStamp time.Time +} + +func (s *Scorch) rootBoltSnapshotMetaData() ([]*snapshotMetaData, error) { + var rv []*snapshotMetaData + currTime := time.Now() + expirationDuration := time.Duration(s.numSnapshotsToKeep) * s.rollbackSamplingInterval + + err := s.rootBolt.View(func(tx *bolt.Tx) error { + snapshots := tx.Bucket(boltSnapshotsBucket) + if snapshots == nil { + return nil + } + sc := snapshots.Cursor() + var found bool + for sk, _ := sc.Last(); sk != nil; sk, _ = sc.Prev() { + _, snapshotEpoch, err := decodeUvarintAscending(sk) + if err != nil { + continue + } + + if expirationDuration == 0 { + rv = append(rv, &snapshotMetaData{ + epoch: snapshotEpoch, + }) + continue + } + + snapshot := snapshots.Bucket(sk) + metaBucket := snapshot.Bucket(boltMetaDataKey) + if metaBucket == nil { + continue + } + timeStampBytes := metaBucket.Get(boltMetaDataTimeStamp) + var timeStamp time.Time + err = timeStamp.UnmarshalText(timeStampBytes) + if err != nil { + continue + } + // Don't keep snapshots older than + // expiration duration (numSnapshotsToKeep * + // rollbackSamplingInterval, by default) + if currTime.Sub(timeStamp) <= expirationDuration { + rv = append(rv, &snapshotMetaData{ + epoch: snapshotEpoch, + timeStamp: timeStamp, + }) + } else { + if !found { + found = true + boundary := getBoundaryCheckPoint(s.rollbackRetentionFactor, + s.checkPoints, timeStamp) + expirationDuration = currTime.Sub(boundary) + continue + } + k := encodeUvarintAscending(nil, snapshotEpoch) + err = snapshots.DeleteBucket(k) + if err == bolt.ErrBucketNotFound { + err = nil + } + } + + } + return nil + }) + return rv, err +} + +func (s *Scorch) RootBoltSnapshotEpochs() ([]uint64, error) { + var rv []uint64 + err := s.rootBolt.View(func(tx *bolt.Tx) error { + snapshots := tx.Bucket(boltSnapshotsBucket) + if snapshots == nil { + return nil + } + sc := snapshots.Cursor() + for sk, _ := sc.Last(); sk != nil; sk, _ = sc.Prev() { + _, snapshotEpoch, err := decodeUvarintAscending(sk) + if err != nil { + continue + } + rv = append(rv, snapshotEpoch) + } + return nil + }) + return rv, err +} + +// Returns the *.zap file names that are listed in the rootBolt. +func (s *Scorch) loadZapFileNames() (map[string]struct{}, error) { + rv := map[string]struct{}{} + err := s.rootBolt.View(func(tx *bolt.Tx) error { + snapshots := tx.Bucket(boltSnapshotsBucket) + if snapshots == nil { + return nil + } + sc := snapshots.Cursor() + for sk, _ := sc.First(); sk != nil; sk, _ = sc.Next() { + snapshot := snapshots.Bucket(sk) + if snapshot == nil { + continue + } + segc := snapshot.Cursor() + for segk, _ := segc.First(); segk != nil; segk, _ = segc.Next() { + if segk[0] == boltInternalKey[0] { + continue + } + segmentBucket := snapshot.Bucket(segk) + if segmentBucket == nil { + continue + } + pathBytes := segmentBucket.Get(boltPathKey) + if pathBytes == nil { + continue + } + pathString := string(pathBytes) + rv[string(pathString)] = struct{}{} + } + } + return nil + }) + + return rv, err +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/regexp.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/regexp.go new file mode 100644 index 0000000000..5a3584f51a --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/regexp.go @@ -0,0 +1,63 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorch + +import ( + "regexp/syntax" + + "github.com/blevesearch/vellum/regexp" +) + +func parseRegexp(pattern string) (a *regexp.Regexp, prefixBeg, prefixEnd []byte, err error) { + // TODO: potential optimization where syntax.Regexp supports a Simplify() API? + + parsed, err := syntax.Parse(pattern, syntax.Perl) + if err != nil { + return nil, nil, nil, err + } + + re, err := regexp.NewParsedWithLimit(pattern, parsed, regexp.DefaultLimit) + if err != nil { + return nil, nil, nil, err + } + + prefix := literalPrefix(parsed) + if prefix != "" { + prefixBeg := []byte(prefix) + prefixEnd := calculateExclusiveEndFromPrefix(prefixBeg) + return re, prefixBeg, prefixEnd, nil + } + + return re, nil, nil, nil +} + +// Returns the literal prefix given the parse tree for a regexp +func literalPrefix(s *syntax.Regexp) string { + // traverse the left-most branch in the parse tree as long as the + // node represents a concatenation + for s != nil && s.Op == syntax.OpConcat { + if len(s.Sub) < 1 { + return "" + } + + s = s.Sub[0] + } + + if s.Op == syntax.OpLiteral && (s.Flags&syntax.FoldCase == 0) { + return string(s.Rune) + } + + return "" // no literal prefix +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/rollback.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/rollback.go new file mode 100644 index 0000000000..067220e6ff --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/rollback.go @@ -0,0 +1,212 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorch + +import ( + "fmt" + "log" + "os" + + bolt "go.etcd.io/bbolt" +) + +type RollbackPoint struct { + epoch uint64 + meta map[string][]byte +} + +func (r *RollbackPoint) GetInternal(key []byte) []byte { + return r.meta[string(key)] +} + +// RollbackPoints returns an array of rollback points available for +// the application to rollback to, with more recent rollback points +// (higher epochs) coming first. +func RollbackPoints(path string) ([]*RollbackPoint, error) { + if len(path) == 0 { + return nil, fmt.Errorf("RollbackPoints: invalid path") + } + + rootBoltPath := path + string(os.PathSeparator) + "root.bolt" + rootBoltOpt := &bolt.Options{ + ReadOnly: true, + } + rootBolt, err := bolt.Open(rootBoltPath, 0600, rootBoltOpt) + if err != nil || rootBolt == nil { + return nil, err + } + + // start a read-only bolt transaction + tx, err := rootBolt.Begin(false) + if err != nil { + return nil, fmt.Errorf("RollbackPoints: failed to start" + + " read-only transaction") + } + + // read-only bolt transactions to be rolled back + defer func() { + _ = tx.Rollback() + _ = rootBolt.Close() + }() + + snapshots := tx.Bucket(boltSnapshotsBucket) + if snapshots == nil { + return nil, nil + } + + rollbackPoints := []*RollbackPoint{} + + c1 := snapshots.Cursor() + for k, _ := c1.Last(); k != nil; k, _ = c1.Prev() { + _, snapshotEpoch, err := decodeUvarintAscending(k) + if err != nil { + log.Printf("RollbackPoints:"+ + " unable to parse segment epoch %x, continuing", k) + continue + } + + snapshot := snapshots.Bucket(k) + if snapshot == nil { + log.Printf("RollbackPoints:"+ + " snapshot key, but bucket missing %x, continuing", k) + continue + } + + meta := map[string][]byte{} + c2 := snapshot.Cursor() + for j, _ := c2.First(); j != nil; j, _ = c2.Next() { + if j[0] == boltInternalKey[0] { + internalBucket := snapshot.Bucket(j) + err = internalBucket.ForEach(func(key []byte, val []byte) error { + copiedVal := append([]byte(nil), val...) + meta[string(key)] = copiedVal + return nil + }) + if err != nil { + break + } + } + } + + if err != nil { + log.Printf("RollbackPoints:"+ + " failed in fetching internal data: %v", err) + continue + } + + rollbackPoints = append(rollbackPoints, &RollbackPoint{ + epoch: snapshotEpoch, + meta: meta, + }) + } + + return rollbackPoints, nil +} + +// Rollback atomically and durably brings the store back to the point +// in time as represented by the RollbackPoint. +// Rollback() should only be passed a RollbackPoint that came from the +// same store using the RollbackPoints() API along with the index path. +func Rollback(path string, to *RollbackPoint) error { + if to == nil { + return fmt.Errorf("Rollback: RollbackPoint is nil") + } + if len(path) == 0 { + return fmt.Errorf("Rollback: index path is empty") + } + + rootBoltPath := path + string(os.PathSeparator) + "root.bolt" + rootBoltOpt := &bolt.Options{ + ReadOnly: false, + } + rootBolt, err := bolt.Open(rootBoltPath, 0600, rootBoltOpt) + if err != nil || rootBolt == nil { + return err + } + defer func() { + err1 := rootBolt.Close() + if err1 != nil && err == nil { + err = err1 + } + }() + + // pick all the younger persisted epochs in bolt store + // including the target one. + var found bool + var eligibleEpochs []uint64 + err = rootBolt.View(func(tx *bolt.Tx) error { + snapshots := tx.Bucket(boltSnapshotsBucket) + if snapshots == nil { + return nil + } + sc := snapshots.Cursor() + for sk, _ := sc.Last(); sk != nil && !found; sk, _ = sc.Prev() { + _, snapshotEpoch, err := decodeUvarintAscending(sk) + if err != nil { + continue + } + if snapshotEpoch == to.epoch { + found = true + } + eligibleEpochs = append(eligibleEpochs, snapshotEpoch) + } + return nil + }) + + if len(eligibleEpochs) == 0 { + return fmt.Errorf("Rollback: no persisted epochs found in bolt") + } + if !found { + return fmt.Errorf("Rollback: target epoch %d not found in bolt", to.epoch) + } + + // start a write transaction + tx, err := rootBolt.Begin(true) + if err != nil { + return err + } + + defer func() { + if err == nil { + err = tx.Commit() + } else { + _ = tx.Rollback() + } + if err == nil { + err = rootBolt.Sync() + } + }() + + snapshots := tx.Bucket(boltSnapshotsBucket) + if snapshots == nil { + return nil + } + for _, epoch := range eligibleEpochs { + k := encodeUvarintAscending(nil, epoch) + if err != nil { + continue + } + if epoch == to.epoch { + // return here as it already processed until the given epoch + return nil + } + err = snapshots.DeleteBucket(k) + if err == bolt.ErrBucketNotFound { + err = nil + } + } + + return err +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/scorch.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/scorch.go new file mode 100644 index 0000000000..a4c88b765d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/scorch.go @@ -0,0 +1,760 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorch + +import ( + "encoding/json" + "fmt" + "os" + "sync" + "sync/atomic" + "time" + + "github.com/RoaringBitmap/roaring" + "github.com/blevesearch/bleve/v2/registry" + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + bolt "go.etcd.io/bbolt" +) + +const Name = "scorch" + +const Version uint8 = 2 + +var ErrClosed = fmt.Errorf("scorch closed") + +type Scorch struct { + nextSegmentID uint64 + stats Stats + iStats internalStats + + readOnly bool + version uint8 + config map[string]interface{} + analysisQueue *index.AnalysisQueue + path string + + unsafeBatch bool + + rootLock sync.RWMutex + root *IndexSnapshot // holds 1 ref-count on the root + rootPersisted []chan error // closed when root is persisted + persistedCallbacks []index.BatchCallback + nextSnapshotEpoch uint64 + eligibleForRemoval []uint64 // Index snapshot epochs that are safe to GC. + ineligibleForRemoval map[string]bool // Filenames that should not be GC'ed yet. + + numSnapshotsToKeep int + rollbackRetentionFactor float64 + checkPoints []*snapshotMetaData + rollbackSamplingInterval time.Duration + closeCh chan struct{} + introductions chan *segmentIntroduction + persists chan *persistIntroduction + merges chan *segmentMerge + introducerNotifier chan *epochWatcher + persisterNotifier chan *epochWatcher + rootBolt *bolt.DB + asyncTasks sync.WaitGroup + + onEvent func(event Event) + onAsyncError func(err error, path string) + + forceMergeRequestCh chan *mergerCtrl + + segPlugin SegmentPlugin + + spatialPlugin index.SpatialAnalyzerPlugin +} + +// AsyncPanicError is passed to scorch asyncErrorHandler when panic occurs in scorch background process +type AsyncPanicError struct { + Source string + Path string +} + +func (e *AsyncPanicError) Error() string { + return fmt.Sprintf("%s panic when processing %s", e.Source, e.Path) +} + +type internalStats struct { + persistEpoch uint64 + persistSnapshotSize uint64 + mergeEpoch uint64 + mergeSnapshotSize uint64 + newSegBufBytesAdded uint64 + newSegBufBytesRemoved uint64 + analysisBytesAdded uint64 + analysisBytesRemoved uint64 +} + +func NewScorch(storeName string, + config map[string]interface{}, + analysisQueue *index.AnalysisQueue) (index.Index, error) { + rv := &Scorch{ + version: Version, + config: config, + analysisQueue: analysisQueue, + nextSnapshotEpoch: 1, + closeCh: make(chan struct{}), + ineligibleForRemoval: map[string]bool{}, + forceMergeRequestCh: make(chan *mergerCtrl, 1), + segPlugin: defaultSegmentPlugin, + } + + forcedSegmentType, forcedSegmentVersion, err := configForceSegmentTypeVersion(config) + if err != nil { + return nil, err + } + if forcedSegmentType != "" && forcedSegmentVersion != 0 { + err := rv.loadSegmentPlugin(forcedSegmentType, + uint32(forcedSegmentVersion)) + if err != nil { + return nil, err + } + } + + typ, ok := config["spatialPlugin"].(string) + if ok { + rv.loadSpatialAnalyzerPlugin(typ) + } + + rv.root = &IndexSnapshot{parent: rv, refs: 1, creator: "NewScorch"} + ro, ok := config["read_only"].(bool) + if ok { + rv.readOnly = ro + } + ub, ok := config["unsafe_batch"].(bool) + if ok { + rv.unsafeBatch = ub + } + ecbName, ok := config["eventCallbackName"].(string) + if ok { + rv.onEvent = RegistryEventCallbacks[ecbName] + } + aecbName, ok := config["asyncErrorCallbackName"].(string) + if ok { + rv.onAsyncError = RegistryAsyncErrorCallbacks[aecbName] + } + + return rv, nil +} + +// configForceSegmentTypeVersion checks if the caller has requested a +// specific segment type/version +func configForceSegmentTypeVersion(config map[string]interface{}) (string, uint32, error) { + forcedSegmentVersion, err := parseToInteger(config["forceSegmentVersion"]) + if err != nil { + return "", 0, nil + } + + forcedSegmentType, ok := config["forceSegmentType"].(string) + if !ok { + return "", 0, fmt.Errorf( + "forceSegmentVersion set to %d, must also specify forceSegmentType", forcedSegmentVersion) + } + + return forcedSegmentType, uint32(forcedSegmentVersion), nil +} + +func (s *Scorch) NumEventsBlocking() uint64 { + eventsCompleted := atomic.LoadUint64(&s.stats.TotEventTriggerCompleted) + eventsStarted := atomic.LoadUint64(&s.stats.TotEventTriggerStarted) + return eventsStarted - eventsCompleted +} + +func (s *Scorch) fireEvent(kind EventKind, dur time.Duration) { + if s.onEvent != nil { + atomic.AddUint64(&s.stats.TotEventTriggerStarted, 1) + s.onEvent(Event{Kind: kind, Scorch: s, Duration: dur}) + atomic.AddUint64(&s.stats.TotEventTriggerCompleted, 1) + } +} + +func (s *Scorch) fireAsyncError(err error) { + if s.onAsyncError != nil { + s.onAsyncError(err, s.path) + } + atomic.AddUint64(&s.stats.TotOnErrors, 1) +} + +func (s *Scorch) Open() error { + err := s.openBolt() + if err != nil { + return err + } + + s.asyncTasks.Add(1) + go s.introducerLoop() + + if !s.readOnly && s.path != "" { + s.asyncTasks.Add(1) + go s.persisterLoop() + s.asyncTasks.Add(1) + go s.mergerLoop() + } + + return nil +} + +func (s *Scorch) openBolt() error { + var ok bool + s.path, ok = s.config["path"].(string) + if !ok { + return fmt.Errorf("must specify path") + } + if s.path == "" { + s.unsafeBatch = true + } + + var rootBoltOpt = *bolt.DefaultOptions + if s.readOnly { + rootBoltOpt.ReadOnly = true + rootBoltOpt.OpenFile = func(path string, flag int, mode os.FileMode) (*os.File, error) { + // Bolt appends an O_CREATE flag regardless. + // See - https://github.com/etcd-io/bbolt/blob/v1.3.5/db.go#L210 + // Use os.O_RDONLY only if path exists (#1623) + if _, err := os.Stat(path); os.IsNotExist(err) { + return os.OpenFile(path, flag, mode) + } + return os.OpenFile(path, os.O_RDONLY, mode) + } + } else { + if s.path != "" { + err := os.MkdirAll(s.path, 0700) + if err != nil { + return err + } + } + } + + if boltTimeoutStr, ok := s.config["bolt_timeout"].(string); ok { + var err error + boltTimeout, err := time.ParseDuration(boltTimeoutStr) + if err != nil { + return fmt.Errorf("invalid duration specified for bolt_timeout: %v", err) + } + rootBoltOpt.Timeout = boltTimeout + } + + rootBoltPath := s.path + string(os.PathSeparator) + "root.bolt" + var err error + if s.path != "" { + s.rootBolt, err = bolt.Open(rootBoltPath, 0600, &rootBoltOpt) + if err != nil { + return err + } + + // now see if there is any existing state to load + err = s.loadFromBolt() + if err != nil { + _ = s.Close() + return err + } + } + + atomic.StoreUint64(&s.stats.TotFileSegmentsAtRoot, uint64(len(s.root.segment))) + + s.introductions = make(chan *segmentIntroduction) + s.persists = make(chan *persistIntroduction) + s.merges = make(chan *segmentMerge) + s.introducerNotifier = make(chan *epochWatcher, 1) + s.persisterNotifier = make(chan *epochWatcher, 1) + s.closeCh = make(chan struct{}) + s.forceMergeRequestCh = make(chan *mergerCtrl, 1) + + if !s.readOnly && s.path != "" { + err := s.removeOldZapFiles() // Before persister or merger create any new files. + if err != nil { + _ = s.Close() + return err + } + } + + s.numSnapshotsToKeep = NumSnapshotsToKeep + if v, ok := s.config["numSnapshotsToKeep"]; ok { + var t int + if t, err = parseToInteger(v); err != nil { + return fmt.Errorf("numSnapshotsToKeep parse err: %v", err) + } + if t > 0 { + s.numSnapshotsToKeep = t + } + } + + s.rollbackSamplingInterval = RollbackSamplingInterval + if v, ok := s.config["rollbackSamplingInterval"]; ok { + var t time.Duration + if t, err = parseToTimeDuration(v); err != nil { + return fmt.Errorf("rollbackSamplingInterval parse err: %v", err) + } + s.rollbackSamplingInterval = t + } + + s.rollbackRetentionFactor = RollbackRetentionFactor + if v, ok := s.config["rollbackRetentionFactor"]; ok { + var r float64 + if r, ok = v.(float64); ok { + return fmt.Errorf("rollbackRetentionFactor parse err: %v", err) + } + s.rollbackRetentionFactor = r + } + + typ, ok := s.config["spatialPlugin"].(string) + if ok { + s.loadSpatialAnalyzerPlugin(typ) + } + + return nil +} + +func (s *Scorch) Close() (err error) { + startTime := time.Now() + defer func() { + s.fireEvent(EventKindClose, time.Since(startTime)) + }() + + s.fireEvent(EventKindCloseStart, 0) + + // signal to async tasks we want to close + close(s.closeCh) + // wait for them to close + s.asyncTasks.Wait() + // now close the root bolt + if s.rootBolt != nil { + err = s.rootBolt.Close() + s.rootLock.Lock() + if s.root != nil { + err2 := s.root.DecRef() + if err == nil { + err = err2 + } + } + s.root = nil + s.rootLock.Unlock() + } + + return +} + +func (s *Scorch) Update(doc index.Document) error { + b := index.NewBatch() + b.Update(doc) + return s.Batch(b) +} + +func (s *Scorch) Delete(id string) error { + b := index.NewBatch() + b.Delete(id) + return s.Batch(b) +} + +// Batch applices a batch of changes to the index atomically +func (s *Scorch) Batch(batch *index.Batch) (err error) { + start := time.Now() + + defer func() { + s.fireEvent(EventKindBatchIntroduction, time.Since(start)) + }() + + resultChan := make(chan index.Document, len(batch.IndexOps)) + + var numUpdates uint64 + var numDeletes uint64 + var numPlainTextBytes uint64 + var ids []string + for docID, doc := range batch.IndexOps { + if doc != nil { + // insert _id field + doc.AddIDField() + numUpdates++ + numPlainTextBytes += doc.NumPlainTextBytes() + } else { + numDeletes++ + } + ids = append(ids, docID) + } + + // FIXME could sort ids list concurrent with analysis? + + if numUpdates > 0 { + go func() { + for k := range batch.IndexOps { + doc := batch.IndexOps[k] + if doc != nil { + // put the work on the queue + s.analysisQueue.Queue(func() { + analyze(doc, s.setSpatialAnalyzerPlugin) + resultChan <- doc + }) + } + } + }() + } + + // wait for analysis result + analysisResults := make([]index.Document, int(numUpdates)) + var itemsDeQueued uint64 + var totalAnalysisSize int + for itemsDeQueued < numUpdates { + result := <-resultChan + resultSize := result.Size() + atomic.AddUint64(&s.iStats.analysisBytesAdded, uint64(resultSize)) + totalAnalysisSize += resultSize + analysisResults[itemsDeQueued] = result + itemsDeQueued++ + } + close(resultChan) + defer atomic.AddUint64(&s.iStats.analysisBytesRemoved, uint64(totalAnalysisSize)) + + atomic.AddUint64(&s.stats.TotAnalysisTime, uint64(time.Since(start))) + + indexStart := time.Now() + + // notify handlers that we're about to introduce a segment + s.fireEvent(EventKindBatchIntroductionStart, 0) + + var newSegment segment.Segment + var bufBytes uint64 + if len(analysisResults) > 0 { + newSegment, bufBytes, err = s.segPlugin.New(analysisResults) + if err != nil { + return err + } + if segB, ok := newSegment.(segment.DiskStatsReporter); ok { + atomic.AddUint64(&s.stats.TotBytesWrittenAtIndexTime, + segB.BytesWritten()) + } + atomic.AddUint64(&s.iStats.newSegBufBytesAdded, bufBytes) + } else { + atomic.AddUint64(&s.stats.TotBatchesEmpty, 1) + } + + err = s.prepareSegment(newSegment, ids, batch.InternalOps, batch.PersistedCallback()) + if err != nil { + if newSegment != nil { + _ = newSegment.Close() + } + atomic.AddUint64(&s.stats.TotOnErrors, 1) + } else { + atomic.AddUint64(&s.stats.TotUpdates, numUpdates) + atomic.AddUint64(&s.stats.TotDeletes, numDeletes) + atomic.AddUint64(&s.stats.TotBatches, 1) + atomic.AddUint64(&s.stats.TotIndexedPlainTextBytes, numPlainTextBytes) + } + + atomic.AddUint64(&s.iStats.newSegBufBytesRemoved, bufBytes) + atomic.AddUint64(&s.stats.TotIndexTime, uint64(time.Since(indexStart))) + + return err +} + +func (s *Scorch) prepareSegment(newSegment segment.Segment, ids []string, + internalOps map[string][]byte, persistedCallback index.BatchCallback) error { + + // new introduction + introduction := &segmentIntroduction{ + id: atomic.AddUint64(&s.nextSegmentID, 1), + data: newSegment, + ids: ids, + obsoletes: make(map[uint64]*roaring.Bitmap), + internal: internalOps, + applied: make(chan error), + persistedCallback: persistedCallback, + } + + if !s.unsafeBatch { + introduction.persisted = make(chan error, 1) + } + + // optimistically prepare obsoletes outside of rootLock + s.rootLock.RLock() + root := s.root + root.AddRef() + s.rootLock.RUnlock() + + defer func() { _ = root.DecRef() }() + + for _, seg := range root.segment { + delta, err := seg.segment.DocNumbers(ids) + if err != nil { + return err + } + introduction.obsoletes[seg.id] = delta + } + + introStartTime := time.Now() + + s.introductions <- introduction + + // block until this segment is applied + err := <-introduction.applied + if err != nil { + return err + } + + if introduction.persisted != nil { + err = <-introduction.persisted + } + + introTime := uint64(time.Since(introStartTime)) + atomic.AddUint64(&s.stats.TotBatchIntroTime, introTime) + if atomic.LoadUint64(&s.stats.MaxBatchIntroTime) < introTime { + atomic.StoreUint64(&s.stats.MaxBatchIntroTime, introTime) + } + + return err +} + +func (s *Scorch) SetInternal(key, val []byte) error { + b := index.NewBatch() + b.SetInternal(key, val) + return s.Batch(b) +} + +func (s *Scorch) DeleteInternal(key []byte) error { + b := index.NewBatch() + b.DeleteInternal(key) + return s.Batch(b) +} + +// Reader returns a low-level accessor on the index data. Close it to +// release associated resources. +func (s *Scorch) Reader() (index.IndexReader, error) { + return s.currentSnapshot(), nil +} + +func (s *Scorch) currentSnapshot() *IndexSnapshot { + s.rootLock.RLock() + rv := s.root + if rv != nil { + rv.AddRef() + } + s.rootLock.RUnlock() + return rv +} + +func (s *Scorch) Stats() json.Marshaler { + return &s.stats +} + +func (s *Scorch) BytesReadQueryTime() uint64 { + return s.stats.TotBytesReadAtQueryTime +} + +func (s *Scorch) diskFileStats(rootSegmentPaths map[string]struct{}) (uint64, + uint64, uint64) { + var numFilesOnDisk, numBytesUsedDisk, numBytesOnDiskByRoot uint64 + if s.path != "" { + files, err := os.ReadDir(s.path) + if err == nil { + for _, f := range files { + if !f.IsDir() { + if finfo, err := f.Info(); err == nil { + numBytesUsedDisk += uint64(finfo.Size()) + numFilesOnDisk++ + if rootSegmentPaths != nil { + fname := s.path + string(os.PathSeparator) + finfo.Name() + if _, fileAtRoot := rootSegmentPaths[fname]; fileAtRoot { + numBytesOnDiskByRoot += uint64(finfo.Size()) + } + } + } + } + } + } + } + // if no root files path given, then consider all disk files. + if rootSegmentPaths == nil { + return numFilesOnDisk, numBytesUsedDisk, numBytesUsedDisk + } + + return numFilesOnDisk, numBytesUsedDisk, numBytesOnDiskByRoot +} + +func (s *Scorch) StatsMap() map[string]interface{} { + m := s.stats.ToMap() + + indexSnapshot := s.currentSnapshot() + defer func() { + _ = indexSnapshot.Close() + }() + + rootSegPaths := indexSnapshot.diskSegmentsPaths() + + s.rootLock.RLock() + m["CurFilesIneligibleForRemoval"] = uint64(len(s.ineligibleForRemoval)) + s.rootLock.RUnlock() + + numFilesOnDisk, numBytesUsedDisk, numBytesOnDiskByRoot := s.diskFileStats(rootSegPaths) + + m["CurOnDiskBytes"] = numBytesUsedDisk + m["CurOnDiskFiles"] = numFilesOnDisk + + // TODO: consider one day removing these backwards compatible + // names for apps using the old names + m["updates"] = m["TotUpdates"] + m["deletes"] = m["TotDeletes"] + m["batches"] = m["TotBatches"] + m["errors"] = m["TotOnErrors"] + m["analysis_time"] = m["TotAnalysisTime"] + m["index_time"] = m["TotIndexTime"] + m["term_searchers_started"] = m["TotTermSearchersStarted"] + m["term_searchers_finished"] = m["TotTermSearchersFinished"] + m["num_bytes_read_at_query_time"] = m["TotBytesReadAtQueryTime"] + m["num_plain_text_bytes_indexed"] = m["TotIndexedPlainTextBytes"] + m["num_bytes_written_at_index_time"] = m["TotBytesWrittenAtIndexTime"] + m["num_items_introduced"] = m["TotIntroducedItems"] + m["num_items_persisted"] = m["TotPersistedItems"] + m["num_recs_to_persist"] = m["TotItemsToPersist"] + // total disk bytes found in index directory inclusive of older snapshots + m["num_bytes_used_disk"] = numBytesUsedDisk + // total disk bytes by the latest root index, exclusive of older snapshots + m["num_bytes_used_disk_by_root"] = numBytesOnDiskByRoot + // num_bytes_used_disk_by_root_reclaimable is an approximation about the + // reclaimable disk space in an index. (eg: from a full compaction) + m["num_bytes_used_disk_by_root_reclaimable"] = uint64(float64(numBytesOnDiskByRoot) * + indexSnapshot.reClaimableDocsRatio()) + m["num_files_on_disk"] = numFilesOnDisk + m["num_root_memorysegments"] = m["TotMemorySegmentsAtRoot"] + m["num_root_filesegments"] = m["TotFileSegmentsAtRoot"] + m["num_persister_nap_pause_completed"] = m["TotPersisterNapPauseCompleted"] + m["num_persister_nap_merger_break"] = m["TotPersisterMergerNapBreak"] + m["total_compaction_written_bytes"] = m["TotFileMergeWrittenBytes"] + + return m +} + +func (s *Scorch) Analyze(d index.Document) { + analyze(d, s.setSpatialAnalyzerPlugin) +} + +type customAnalyzerPluginInitFunc func(field index.Field) + +func (s *Scorch) setSpatialAnalyzerPlugin(f index.Field) { + if s.segPlugin != nil { + // check whether the current field is a custom tokenizable + // spatial field then set the spatial analyser plugin for + // overriding the tokenisation during the analysis stage. + if sf, ok := f.(index.TokenizableSpatialField); ok { + sf.SetSpatialAnalyzerPlugin(s.spatialPlugin) + } + } +} + +func analyze(d index.Document, fn customAnalyzerPluginInitFunc) { + d.VisitFields(func(field index.Field) { + if field.Options().IsIndexed() { + if fn != nil { + fn(field) + } + + field.Analyze() + + if d.HasComposite() && field.Name() != "_id" { + // see if any of the composite fields need this + d.VisitComposite(func(cf index.CompositeField) { + cf.Compose(field.Name(), field.AnalyzedLength(), field.AnalyzedTokenFrequencies()) + }) + } + } + }) +} + +func (s *Scorch) AddEligibleForRemoval(epoch uint64) { + s.rootLock.Lock() + if s.root == nil || s.root.epoch != epoch { + s.eligibleForRemoval = append(s.eligibleForRemoval, epoch) + } + s.rootLock.Unlock() +} + +func (s *Scorch) MemoryUsed() (memUsed uint64) { + indexSnapshot := s.currentSnapshot() + if indexSnapshot == nil { + return + } + + defer func() { + _ = indexSnapshot.Close() + }() + + // Account for current root snapshot overhead + memUsed += uint64(indexSnapshot.Size()) + + // Account for snapshot that the persister may be working on + persistEpoch := atomic.LoadUint64(&s.iStats.persistEpoch) + persistSnapshotSize := atomic.LoadUint64(&s.iStats.persistSnapshotSize) + if persistEpoch != 0 && indexSnapshot.epoch > persistEpoch { + // the snapshot that the persister is working on isn't the same as + // the current snapshot + memUsed += persistSnapshotSize + } + + // Account for snapshot that the merger may be working on + mergeEpoch := atomic.LoadUint64(&s.iStats.mergeEpoch) + mergeSnapshotSize := atomic.LoadUint64(&s.iStats.mergeSnapshotSize) + if mergeEpoch != 0 && indexSnapshot.epoch > mergeEpoch { + // the snapshot that the merger is working on isn't the same as + // the current snapshot + memUsed += mergeSnapshotSize + } + + memUsed += (atomic.LoadUint64(&s.iStats.newSegBufBytesAdded) - + atomic.LoadUint64(&s.iStats.newSegBufBytesRemoved)) + + memUsed += (atomic.LoadUint64(&s.iStats.analysisBytesAdded) - + atomic.LoadUint64(&s.iStats.analysisBytesRemoved)) + + return memUsed +} + +func (s *Scorch) markIneligibleForRemoval(filename string) { + s.rootLock.Lock() + s.ineligibleForRemoval[filename] = true + s.rootLock.Unlock() +} + +func (s *Scorch) unmarkIneligibleForRemoval(filename string) { + s.rootLock.Lock() + delete(s.ineligibleForRemoval, filename) + s.rootLock.Unlock() +} + +func init() { + registry.RegisterIndexType(Name, NewScorch) +} + +func parseToTimeDuration(i interface{}) (time.Duration, error) { + switch v := i.(type) { + case string: + return time.ParseDuration(v) + + default: + return 0, fmt.Errorf("expects a duration string") + } +} + +func parseToInteger(i interface{}) (int, error) { + switch v := i.(type) { + case float64: + return int(v), nil + case int: + return v, nil + + default: + return 0, fmt.Errorf("expects int or float64 value") + } +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/segment_plugin.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/segment_plugin.go new file mode 100644 index 0000000000..a84d2d55ff --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/segment_plugin.go @@ -0,0 +1,143 @@ +// Copyright (c) 2019 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorch + +import ( + "fmt" + + "github.com/RoaringBitmap/roaring" + index "github.com/blevesearch/bleve_index_api" + + "github.com/blevesearch/bleve/v2/geo" + segment "github.com/blevesearch/scorch_segment_api/v2" + + zapv11 "github.com/blevesearch/zapx/v11" + zapv12 "github.com/blevesearch/zapx/v12" + zapv13 "github.com/blevesearch/zapx/v13" + zapv14 "github.com/blevesearch/zapx/v14" + zapv15 "github.com/blevesearch/zapx/v15" +) + +// SegmentPlugin represents the essential functions required by a package to plug in +// it's segment implementation +type SegmentPlugin interface { + + // Type is the name for this segment plugin + Type() string + + // Version is a numeric value identifying a specific version of this type. + // When incompatible changes are made to a particular type of plugin, the + // version must be incremented. + Version() uint32 + + // New takes a set of Documents and turns them into a new Segment + New(results []index.Document) (segment.Segment, uint64, error) + + // Open attempts to open the file at the specified path and + // return the corresponding Segment + Open(path string) (segment.Segment, error) + + // Merge takes a set of Segments, and creates a new segment on disk at + // the specified path. + // Drops is a set of bitmaps (one for each segment) indicating which + // documents can be dropped from the segments during the merge. + // If the closeCh channel is closed, Merge will cease doing work at + // the next opportunity, and return an error (closed). + // StatsReporter can optionally be provided, in which case progress + // made during the merge is reported while operation continues. + // Returns: + // A slice of new document numbers (one for each input segment), + // this allows the caller to know a particular document's new + // document number in the newly merged segment. + // The number of bytes written to the new segment file. + // An error, if any occurred. + Merge(segments []segment.Segment, drops []*roaring.Bitmap, path string, + closeCh chan struct{}, s segment.StatsReporter) ( + [][]uint64, uint64, error) +} + +var supportedSegmentPlugins map[string]map[uint32]SegmentPlugin +var defaultSegmentPlugin SegmentPlugin + +func init() { + ResetSegmentPlugins() + RegisterSegmentPlugin(&zapv15.ZapPlugin{}, true) + RegisterSegmentPlugin(&zapv14.ZapPlugin{}, false) + RegisterSegmentPlugin(&zapv13.ZapPlugin{}, false) + RegisterSegmentPlugin(&zapv12.ZapPlugin{}, false) + RegisterSegmentPlugin(&zapv11.ZapPlugin{}, false) +} + +func ResetSegmentPlugins() { + supportedSegmentPlugins = map[string]map[uint32]SegmentPlugin{} +} + +func RegisterSegmentPlugin(plugin SegmentPlugin, makeDefault bool) { + if _, ok := supportedSegmentPlugins[plugin.Type()]; !ok { + supportedSegmentPlugins[plugin.Type()] = map[uint32]SegmentPlugin{} + } + supportedSegmentPlugins[plugin.Type()][plugin.Version()] = plugin + if makeDefault { + defaultSegmentPlugin = plugin + } +} + +func SupportedSegmentTypes() (rv []string) { + for k := range supportedSegmentPlugins { + rv = append(rv, k) + } + return +} + +func SupportedSegmentTypeVersions(typ string) (rv []uint32) { + for k := range supportedSegmentPlugins[typ] { + rv = append(rv, k) + } + return rv +} + +func chooseSegmentPlugin(forcedSegmentType string, + forcedSegmentVersion uint32) (SegmentPlugin, error) { + if versions, ok := supportedSegmentPlugins[forcedSegmentType]; ok { + if segPlugin, ok := versions[uint32(forcedSegmentVersion)]; ok { + return segPlugin, nil + } + return nil, fmt.Errorf( + "unsupported version %d for segment type: %s, supported: %v", + forcedSegmentVersion, forcedSegmentType, + SupportedSegmentTypeVersions(forcedSegmentType)) + } + return nil, fmt.Errorf("unsupported segment type: %s, supported: %v", + forcedSegmentType, SupportedSegmentTypes()) +} + +func (s *Scorch) loadSegmentPlugin(forcedSegmentType string, + forcedSegmentVersion uint32) error { + segPlugin, err := chooseSegmentPlugin(forcedSegmentType, + forcedSegmentVersion) + if err != nil { + return err + } + s.segPlugin = segPlugin + return nil +} + +func (s *Scorch) loadSpatialAnalyzerPlugin(typ string) error { + s.spatialPlugin = geo.GetSpatialAnalyzerPlugin(typ) + if s.spatialPlugin == nil { + return fmt.Errorf("unsupported spatial plugin type: %s", typ) + } + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_index.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_index.go new file mode 100644 index 0000000000..59828e8750 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_index.go @@ -0,0 +1,907 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorch + +import ( + "container/heap" + "context" + "encoding/binary" + "fmt" + "os" + "path/filepath" + "reflect" + "sort" + "sync" + "sync/atomic" + + "github.com/RoaringBitmap/roaring" + "github.com/blevesearch/bleve/v2/document" + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" + lev "github.com/blevesearch/vellum/levenshtein" + bolt "go.etcd.io/bbolt" +) + +// re usable, threadsafe levenshtein builders +var lb1, lb2 *lev.LevenshteinAutomatonBuilder + +type asynchSegmentResult struct { + dict segment.TermDictionary + dictItr segment.DictionaryIterator + + index int + docs *roaring.Bitmap + + postings segment.PostingsList + + err error +} + +var reflectStaticSizeIndexSnapshot int + +// DefaultFieldTFRCacheThreshold limits the number of TermFieldReaders(TFR) for +// a field in an index snapshot. Without this limit, when recycling TFRs, it is +// possible that a very large number of TFRs may be added to the recycle +// cache, which could eventually lead to significant memory consumption. +// This threshold can be overwritten by users at the library level by changing the +// exported variable, or at the index level by setting the FieldTFRCacheThreshold +// in the kvConfig. +var DefaultFieldTFRCacheThreshold uint64 = 10 + +func init() { + var is interface{} = IndexSnapshot{} + reflectStaticSizeIndexSnapshot = int(reflect.TypeOf(is).Size()) + var err error + lb1, err = lev.NewLevenshteinAutomatonBuilder(1, true) + if err != nil { + panic(fmt.Errorf("Levenshtein automaton ed1 builder err: %v", err)) + } + lb2, err = lev.NewLevenshteinAutomatonBuilder(2, true) + if err != nil { + panic(fmt.Errorf("Levenshtein automaton ed2 builder err: %v", err)) + } +} + +type IndexSnapshot struct { + parent *Scorch + segment []*SegmentSnapshot + offsets []uint64 + internal map[string][]byte + epoch uint64 + size uint64 + creator string + + m sync.Mutex // Protects the fields that follow. + refs int64 + + m2 sync.Mutex // Protects the fields that follow. + fieldTFRs map[string][]*IndexSnapshotTermFieldReader // keyed by field, recycled TFR's +} + +func (i *IndexSnapshot) Segments() []*SegmentSnapshot { + return i.segment +} + +func (i *IndexSnapshot) Internal() map[string][]byte { + return i.internal +} + +func (i *IndexSnapshot) AddRef() { + i.m.Lock() + i.refs++ + i.m.Unlock() +} + +func (i *IndexSnapshot) DecRef() (err error) { + i.m.Lock() + i.refs-- + if i.refs == 0 { + for _, s := range i.segment { + if s != nil { + err2 := s.segment.DecRef() + if err == nil { + err = err2 + } + } + } + if i.parent != nil { + go i.parent.AddEligibleForRemoval(i.epoch) + } + } + i.m.Unlock() + return err +} + +func (i *IndexSnapshot) Close() error { + return i.DecRef() +} + +func (i *IndexSnapshot) Size() int { + return int(i.size) +} + +func (i *IndexSnapshot) updateSize() { + i.size += uint64(reflectStaticSizeIndexSnapshot) + for _, s := range i.segment { + i.size += uint64(s.Size()) + } +} + +func (is *IndexSnapshot) newIndexSnapshotFieldDict(field string, + makeItr func(i segment.TermDictionary) segment.DictionaryIterator, + randomLookup bool) (*IndexSnapshotFieldDict, error) { + + results := make(chan *asynchSegmentResult) + var totalBytesRead uint64 + for _, s := range is.segment { + go func(s *SegmentSnapshot) { + dict, err := s.segment.Dictionary(field) + if err != nil { + results <- &asynchSegmentResult{err: err} + } else { + if dictStats, ok := dict.(segment.DiskStatsReporter); ok { + atomic.AddUint64(&totalBytesRead, dictStats.BytesRead()) + } + if randomLookup { + results <- &asynchSegmentResult{dict: dict} + } else { + results <- &asynchSegmentResult{dictItr: makeItr(dict)} + } + } + }(s) + } + + var err error + rv := &IndexSnapshotFieldDict{ + snapshot: is, + cursors: make([]*segmentDictCursor, 0, len(is.segment)), + } + for count := 0; count < len(is.segment); count++ { + asr := <-results + if asr.err != nil && err == nil { + err = asr.err + } else { + if !randomLookup { + next, err2 := asr.dictItr.Next() + if err2 != nil && err == nil { + err = err2 + } + if next != nil { + rv.cursors = append(rv.cursors, &segmentDictCursor{ + itr: asr.dictItr, + curr: *next, + }) + } + } else { + rv.cursors = append(rv.cursors, &segmentDictCursor{ + dict: asr.dict, + }) + } + } + } + rv.bytesRead = totalBytesRead + // after ensuring we've read all items on channel + if err != nil { + return nil, err + } + + if !randomLookup { + // prepare heap + heap.Init(rv) + } + + return rv, nil +} + +func (is *IndexSnapshot) FieldDict(field string) (index.FieldDict, error) { + return is.newIndexSnapshotFieldDict(field, func(is segment.TermDictionary) segment.DictionaryIterator { + return is.AutomatonIterator(nil, nil, nil) + }, false) +} + +// calculateExclusiveEndFromInclusiveEnd produces the next key +// when sorting using memcmp style comparisons, suitable to +// use as the end key in a traditional (inclusive, exclusive] +// start/end range +func calculateExclusiveEndFromInclusiveEnd(inclusiveEnd []byte) []byte { + rv := inclusiveEnd + if len(inclusiveEnd) > 0 { + rv = make([]byte, len(inclusiveEnd)) + copy(rv, inclusiveEnd) + if rv[len(rv)-1] < 0xff { + // last byte can be incremented by one + rv[len(rv)-1]++ + } else { + // last byte is already 0xff, so append 0 + // next key is simply one byte longer + rv = append(rv, 0x0) + } + } + return rv +} + +func (is *IndexSnapshot) FieldDictRange(field string, startTerm []byte, + endTerm []byte) (index.FieldDict, error) { + return is.newIndexSnapshotFieldDict(field, func(is segment.TermDictionary) segment.DictionaryIterator { + endTermExclusive := calculateExclusiveEndFromInclusiveEnd(endTerm) + return is.AutomatonIterator(nil, startTerm, endTermExclusive) + }, false) +} + +// calculateExclusiveEndFromPrefix produces the first key that +// does not have the same prefix as the input bytes, suitable +// to use as the end key in a traditional (inclusive, exclusive] +// start/end range +func calculateExclusiveEndFromPrefix(in []byte) []byte { + rv := make([]byte, len(in)) + copy(rv, in) + for i := len(rv) - 1; i >= 0; i-- { + rv[i] = rv[i] + 1 + if rv[i] != 0 { + return rv // didn't overflow, so stop + } + } + // all bytes were 0xff, so return nil + // as there is no end key for this prefix + return nil +} + +func (is *IndexSnapshot) FieldDictPrefix(field string, + termPrefix []byte) (index.FieldDict, error) { + termPrefixEnd := calculateExclusiveEndFromPrefix(termPrefix) + return is.newIndexSnapshotFieldDict(field, func(is segment.TermDictionary) segment.DictionaryIterator { + return is.AutomatonIterator(nil, termPrefix, termPrefixEnd) + }, false) +} + +func (is *IndexSnapshot) FieldDictRegexp(field string, + termRegex string) (index.FieldDict, error) { + // TODO: potential optimization where the literal prefix represents the, + // entire regexp, allowing us to use PrefixIterator(prefixTerm)? + + a, prefixBeg, prefixEnd, err := parseRegexp(termRegex) + if err != nil { + return nil, err + } + + return is.newIndexSnapshotFieldDict(field, func(is segment.TermDictionary) segment.DictionaryIterator { + return is.AutomatonIterator(a, prefixBeg, prefixEnd) + }, false) +} + +func (is *IndexSnapshot) getLevAutomaton(term string, + fuzziness uint8) (vellum.Automaton, error) { + if fuzziness == 1 { + return lb1.BuildDfa(term, fuzziness) + } else if fuzziness == 2 { + return lb2.BuildDfa(term, fuzziness) + } + return nil, fmt.Errorf("fuzziness exceeds the max limit") +} + +func (is *IndexSnapshot) FieldDictFuzzy(field string, + term string, fuzziness int, prefix string) (index.FieldDict, error) { + a, err := is.getLevAutomaton(term, uint8(fuzziness)) + if err != nil { + return nil, err + } + + var prefixBeg, prefixEnd []byte + if prefix != "" { + prefixBeg = []byte(prefix) + prefixEnd = calculateExclusiveEndFromPrefix(prefixBeg) + } + + return is.newIndexSnapshotFieldDict(field, func(is segment.TermDictionary) segment.DictionaryIterator { + return is.AutomatonIterator(a, prefixBeg, prefixEnd) + }, false) +} + +func (is *IndexSnapshot) FieldDictContains(field string) (index.FieldDictContains, error) { + return is.newIndexSnapshotFieldDict(field, nil, true) +} + +func (is *IndexSnapshot) DocIDReaderAll() (index.DocIDReader, error) { + results := make(chan *asynchSegmentResult) + for index, segment := range is.segment { + go func(index int, segment *SegmentSnapshot) { + results <- &asynchSegmentResult{ + index: index, + docs: segment.DocNumbersLive(), + } + }(index, segment) + } + + return is.newDocIDReader(results) +} + +func (is *IndexSnapshot) DocIDReaderOnly(ids []string) (index.DocIDReader, error) { + results := make(chan *asynchSegmentResult) + for index, segment := range is.segment { + go func(index int, segment *SegmentSnapshot) { + docs, err := segment.DocNumbers(ids) + if err != nil { + results <- &asynchSegmentResult{err: err} + } else { + results <- &asynchSegmentResult{ + index: index, + docs: docs, + } + } + }(index, segment) + } + + return is.newDocIDReader(results) +} + +func (is *IndexSnapshot) newDocIDReader(results chan *asynchSegmentResult) (index.DocIDReader, error) { + rv := &IndexSnapshotDocIDReader{ + snapshot: is, + iterators: make([]roaring.IntIterable, len(is.segment)), + } + var err error + for count := 0; count < len(is.segment); count++ { + asr := <-results + if asr.err != nil { + if err == nil { + // returns the first error encountered + err = asr.err + } + } else if err == nil { + rv.iterators[asr.index] = asr.docs.Iterator() + } + } + + if err != nil { + return nil, err + } + + return rv, nil +} + +func (is *IndexSnapshot) Fields() ([]string, error) { + // FIXME not making this concurrent for now as it's not used in hot path + // of any searches at the moment (just a debug aid) + fieldsMap := map[string]struct{}{} + for _, segment := range is.segment { + fields := segment.Fields() + for _, field := range fields { + fieldsMap[field] = struct{}{} + } + } + rv := make([]string, 0, len(fieldsMap)) + for k := range fieldsMap { + rv = append(rv, k) + } + return rv, nil +} + +func (is *IndexSnapshot) GetInternal(key []byte) ([]byte, error) { + return is.internal[string(key)], nil +} + +func (is *IndexSnapshot) DocCount() (uint64, error) { + var rv uint64 + for _, segment := range is.segment { + rv += segment.Count() + } + return rv, nil +} + +func (is *IndexSnapshot) Document(id string) (rv index.Document, err error) { + // FIXME could be done more efficiently directly, but reusing for simplicity + tfr, err := is.TermFieldReader(nil, []byte(id), "_id", false, false, false) + if err != nil { + return nil, err + } + defer func() { + if cerr := tfr.Close(); err == nil && cerr != nil { + err = cerr + } + }() + + next, err := tfr.Next(nil) + if err != nil { + return nil, err + } + + if next == nil { + // no such doc exists + return nil, nil + } + + docNum, err := docInternalToNumber(next.ID) + if err != nil { + return nil, err + } + segmentIndex, localDocNum := is.segmentIndexAndLocalDocNumFromGlobal(docNum) + + rvd := document.NewDocument(id) + + err = is.segment[segmentIndex].VisitDocument(localDocNum, func(name string, typ byte, val []byte, pos []uint64) bool { + if name == "_id" { + return true + } + + // track uncompressed stored fields bytes as part of IO stats. + // However, ideally we'd need to track the compressed on-disk value + // Keeping that TODO for now until we have a cleaner way. + rvd.StoredFieldsSize += uint64(len(val)) + + // copy value, array positions to preserve them beyond the scope of this callback + value := append([]byte(nil), val...) + arrayPos := append([]uint64(nil), pos...) + + switch typ { + case 't': + rvd.AddField(document.NewTextField(name, arrayPos, value)) + case 'n': + rvd.AddField(document.NewNumericFieldFromBytes(name, arrayPos, value)) + case 'i': + rvd.AddField(document.NewIPFieldFromBytes(name, arrayPos, value)) + case 'd': + rvd.AddField(document.NewDateTimeFieldFromBytes(name, arrayPos, value)) + case 'b': + rvd.AddField(document.NewBooleanFieldFromBytes(name, arrayPos, value)) + case 'g': + rvd.AddField(document.NewGeoPointFieldFromBytes(name, arrayPos, value)) + case 's': + rvd.AddField(document.NewGeoShapeFieldFromBytes(name, arrayPos, value)) + } + + return true + }) + if err != nil { + return nil, err + } + + return rvd, nil +} + +func (is *IndexSnapshot) segmentIndexAndLocalDocNumFromGlobal(docNum uint64) (int, uint64) { + segmentIndex := sort.Search(len(is.offsets), + func(x int) bool { + return is.offsets[x] > docNum + }) - 1 + + localDocNum := docNum - is.offsets[segmentIndex] + return int(segmentIndex), localDocNum +} + +func (is *IndexSnapshot) ExternalID(id index.IndexInternalID) (string, error) { + docNum, err := docInternalToNumber(id) + if err != nil { + return "", err + } + segmentIndex, localDocNum := is.segmentIndexAndLocalDocNumFromGlobal(docNum) + + v, err := is.segment[segmentIndex].DocID(localDocNum) + if err != nil { + return "", err + } + if v == nil { + return "", fmt.Errorf("document number %d not found", docNum) + } + + return string(v), nil +} + +func (is *IndexSnapshot) InternalID(id string) (rv index.IndexInternalID, err error) { + // FIXME could be done more efficiently directly, but reusing for simplicity + tfr, err := is.TermFieldReader(nil, []byte(id), "_id", false, false, false) + if err != nil { + return nil, err + } + defer func() { + if cerr := tfr.Close(); err == nil && cerr != nil { + err = cerr + } + }() + + next, err := tfr.Next(nil) + if err != nil || next == nil { + return nil, err + } + + return next.ID, nil +} + +func (is *IndexSnapshot) TermFieldReader(ctx context.Context, term []byte, field string, includeFreq, + includeNorm, includeTermVectors bool) (index.TermFieldReader, error) { + rv := is.allocTermFieldReaderDicts(field) + + rv.ctx = ctx + rv.term = term + rv.field = field + rv.snapshot = is + if rv.postings == nil { + rv.postings = make([]segment.PostingsList, len(is.segment)) + } + if rv.iterators == nil { + rv.iterators = make([]segment.PostingsIterator, len(is.segment)) + } + rv.segmentOffset = 0 + rv.includeFreq = includeFreq + rv.includeNorm = includeNorm + rv.includeTermVectors = includeTermVectors + rv.currPosting = nil + rv.currID = rv.currID[:0] + + if rv.dicts == nil { + rv.dicts = make([]segment.TermDictionary, len(is.segment)) + for i, s := range is.segment { + // the intention behind this compare and swap operation is + // to make sure that the accounting of the metadata is happening + // only once(which corresponds to this persisted segment's most + // recent segPlugin.Open() call), and any subsequent queries won't + // incur this cost which would essentially be a double counting. + if atomic.CompareAndSwapUint32(&s.mmaped, 1, 0) { + segBytesRead := s.segment.BytesRead() + rv.incrementBytesRead(segBytesRead) + } + dict, err := s.segment.Dictionary(field) + if err != nil { + return nil, err + } + if dictStats, ok := dict.(segment.DiskStatsReporter); ok { + bytesRead := dictStats.BytesRead() + rv.incrementBytesRead(bytesRead) + } + rv.dicts[i] = dict + } + } + + for i, s := range is.segment { + var prevBytesReadPL uint64 + if rv.postings[i] != nil { + prevBytesReadPL = rv.postings[i].BytesRead() + } + pl, err := rv.dicts[i].PostingsList(term, s.deleted, rv.postings[i]) + if err != nil { + return nil, err + } + rv.postings[i] = pl + + var prevBytesReadItr uint64 + if rv.iterators[i] != nil { + prevBytesReadItr = rv.iterators[i].BytesRead() + } + rv.iterators[i] = pl.Iterator(includeFreq, includeNorm, includeTermVectors, rv.iterators[i]) + + if bytesRead := rv.postings[i].BytesRead(); prevBytesReadPL < bytesRead { + rv.incrementBytesRead(bytesRead - prevBytesReadPL) + } + + if bytesRead := rv.iterators[i].BytesRead(); prevBytesReadItr < bytesRead { + rv.incrementBytesRead(bytesRead - prevBytesReadItr) + } + } + atomic.AddUint64(&is.parent.stats.TotTermSearchersStarted, uint64(1)) + return rv, nil +} + +func (is *IndexSnapshot) allocTermFieldReaderDicts(field string) (tfr *IndexSnapshotTermFieldReader) { + is.m2.Lock() + if is.fieldTFRs != nil { + tfrs := is.fieldTFRs[field] + last := len(tfrs) - 1 + if last >= 0 { + tfr = tfrs[last] + tfrs[last] = nil + is.fieldTFRs[field] = tfrs[:last] + is.m2.Unlock() + return + } + } + is.m2.Unlock() + return &IndexSnapshotTermFieldReader{ + recycle: true, + } +} + +func (is *IndexSnapshot) getFieldTFRCacheThreshold() uint64 { + if is.parent.config != nil { + if _, ok := is.parent.config["FieldTFRCacheThreshold"]; ok { + return is.parent.config["FieldTFRCacheThreshold"].(uint64) + } + } + return DefaultFieldTFRCacheThreshold +} + +func (is *IndexSnapshot) recycleTermFieldReader(tfr *IndexSnapshotTermFieldReader) { + if !tfr.recycle { + // Do not recycle an optimized unadorned term field reader (used for + // ConjunctionUnadorned or DisjunctionUnadorned), during when a fresh + // roaring.Bitmap is built by AND-ing or OR-ing individual bitmaps, + // and we'll need to release them for GC. (See MB-40916) + return + } + + is.parent.rootLock.RLock() + obsolete := is.parent.root != is + is.parent.rootLock.RUnlock() + if obsolete { + // if we're not the current root (mutations happened), don't bother recycling + return + } + + is.m2.Lock() + if is.fieldTFRs == nil { + is.fieldTFRs = map[string][]*IndexSnapshotTermFieldReader{} + } + if uint64(len(is.fieldTFRs[tfr.field])) < is.getFieldTFRCacheThreshold() { + tfr.bytesRead = 0 + is.fieldTFRs[tfr.field] = append(is.fieldTFRs[tfr.field], tfr) + } + is.m2.Unlock() +} + +func docNumberToBytes(buf []byte, in uint64) []byte { + if len(buf) != 8 { + if cap(buf) >= 8 { + buf = buf[0:8] + } else { + buf = make([]byte, 8) + } + } + binary.BigEndian.PutUint64(buf, in) + return buf +} + +func docInternalToNumber(in index.IndexInternalID) (uint64, error) { + if len(in) != 8 { + return 0, fmt.Errorf("wrong len for IndexInternalID: %q", in) + } + return binary.BigEndian.Uint64(in), nil +} + +func (is *IndexSnapshot) documentVisitFieldTermsOnSegment( + segmentIndex int, localDocNum uint64, fields []string, cFields []string, + visitor index.DocValueVisitor, dvs segment.DocVisitState) ( + cFieldsOut []string, dvsOut segment.DocVisitState, err error) { + ss := is.segment[segmentIndex] + + var vFields []string // fields that are visitable via the segment + + ssv, ssvOk := ss.segment.(segment.DocValueVisitable) + if ssvOk && ssv != nil { + vFields, err = ssv.VisitableDocValueFields() + if err != nil { + return nil, nil, err + } + } + + var errCh chan error + + // cFields represents the fields that we'll need from the + // cachedDocs, and might be optionally be provided by the caller, + // if the caller happens to know we're on the same segmentIndex + // from a previous invocation + if cFields == nil { + cFields = subtractStrings(fields, vFields) + + if !ss.cachedDocs.hasFields(cFields) { + errCh = make(chan error, 1) + + go func() { + err := ss.cachedDocs.prepareFields(cFields, ss) + if err != nil { + errCh <- err + } + close(errCh) + }() + } + } + + if ssvOk && ssv != nil && len(vFields) > 0 { + dvs, err = ssv.VisitDocValues(localDocNum, fields, visitor, dvs) + if err != nil { + return nil, nil, err + } + } + + if errCh != nil { + err = <-errCh + if err != nil { + return nil, nil, err + } + } + + if len(cFields) > 0 { + ss.cachedDocs.visitDoc(localDocNum, cFields, visitor) + } + + return cFields, dvs, nil +} + +func (is *IndexSnapshot) DocValueReader(fields []string) ( + index.DocValueReader, error) { + return &DocValueReader{i: is, fields: fields, currSegmentIndex: -1}, nil +} + +type DocValueReader struct { + i *IndexSnapshot + fields []string + dvs segment.DocVisitState + + currSegmentIndex int + currCachedFields []string + + totalBytesRead uint64 + bytesRead uint64 +} + +func (dvr *DocValueReader) BytesRead() uint64 { + return dvr.totalBytesRead + dvr.bytesRead +} + +func (dvr *DocValueReader) VisitDocValues(id index.IndexInternalID, + visitor index.DocValueVisitor) (err error) { + docNum, err := docInternalToNumber(id) + if err != nil { + return err + } + + segmentIndex, localDocNum := dvr.i.segmentIndexAndLocalDocNumFromGlobal(docNum) + if segmentIndex >= len(dvr.i.segment) { + return nil + } + + if dvr.currSegmentIndex != segmentIndex { + dvr.currSegmentIndex = segmentIndex + dvr.currCachedFields = nil + dvr.totalBytesRead += dvr.bytesRead + dvr.bytesRead = 0 + } + + dvr.currCachedFields, dvr.dvs, err = dvr.i.documentVisitFieldTermsOnSegment( + dvr.currSegmentIndex, localDocNum, dvr.fields, dvr.currCachedFields, visitor, dvr.dvs) + + if dvr.dvs != nil { + dvr.bytesRead = dvr.dvs.BytesRead() + } + return err +} + +func (is *IndexSnapshot) DumpAll() chan interface{} { + rv := make(chan interface{}) + go func() { + close(rv) + }() + return rv +} + +func (is *IndexSnapshot) DumpDoc(id string) chan interface{} { + rv := make(chan interface{}) + go func() { + close(rv) + }() + return rv +} + +func (is *IndexSnapshot) DumpFields() chan interface{} { + rv := make(chan interface{}) + go func() { + close(rv) + }() + return rv +} + +func (is *IndexSnapshot) diskSegmentsPaths() map[string]struct{} { + rv := make(map[string]struct{}, len(is.segment)) + for _, s := range is.segment { + if seg, ok := s.segment.(segment.PersistedSegment); ok { + rv[seg.Path()] = struct{}{} + } + } + return rv +} + +// reClaimableDocsRatio gives a ratio about the obsoleted or +// reclaimable documents present in a given index snapshot. +func (is *IndexSnapshot) reClaimableDocsRatio() float64 { + var totalCount, liveCount uint64 + for _, s := range is.segment { + if _, ok := s.segment.(segment.PersistedSegment); ok { + totalCount += uint64(s.FullSize()) + liveCount += uint64(s.Count()) + } + } + + if totalCount > 0 { + return float64(totalCount-liveCount) / float64(totalCount) + } + return 0 +} + +// subtractStrings returns set a minus elements of set b. +func subtractStrings(a, b []string) []string { + if len(b) == 0 { + return a + } + + rv := make([]string, 0, len(a)) +OUTER: + for _, as := range a { + for _, bs := range b { + if as == bs { + continue OUTER + } + } + rv = append(rv, as) + } + return rv +} + +func (is *IndexSnapshot) CopyTo(d index.Directory) error { + // get the root bolt file. + w, err := d.GetWriter(filepath.Join("store", "root.bolt")) + if err != nil || w == nil { + return fmt.Errorf("failed to create the root.bolt file, err: %v", err) + } + rootFile, ok := w.(*os.File) + if !ok { + return fmt.Errorf("invalid root.bolt file found") + } + + copyBolt, err := bolt.Open(rootFile.Name(), 0600, nil) + if err != nil { + return err + } + defer func() { + w.Close() + if cerr := copyBolt.Close(); cerr != nil && err == nil { + err = cerr + } + }() + + // start a write transaction + tx, err := copyBolt.Begin(true) + if err != nil { + return err + } + + _, _, err = prepareBoltSnapshot(is, tx, "", is.parent.segPlugin, d) + if err != nil { + _ = tx.Rollback() + return fmt.Errorf("error backing up index snapshot: %v", err) + } + + // commit bolt data + err = tx.Commit() + if err != nil { + return fmt.Errorf("error commit tx to backup root bolt: %v", err) + } + + return copyBolt.Sync() +} + +func (is *IndexSnapshot) UpdateIOStats(val uint64) { + atomic.AddUint64(&is.parent.stats.TotBytesReadAtQueryTime, val) +} + +func (is *IndexSnapshot) GetSpatialAnalyzerPlugin(typ string) ( + index.SpatialAnalyzerPlugin, error) { + var rv index.SpatialAnalyzerPlugin + is.m.Lock() + rv = is.parent.spatialPlugin + is.m.Unlock() + + if rv == nil { + return nil, fmt.Errorf("no spatial plugin type: %s found", typ) + } + return rv, nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_index_dict.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_index_dict.go new file mode 100644 index 0000000000..658aa8148a --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_index_dict.go @@ -0,0 +1,113 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorch + +import ( + "container/heap" + + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" +) + +type segmentDictCursor struct { + dict segment.TermDictionary + itr segment.DictionaryIterator + curr index.DictEntry +} + +type IndexSnapshotFieldDict struct { + snapshot *IndexSnapshot + cursors []*segmentDictCursor + entry index.DictEntry + bytesRead uint64 +} + +func (i *IndexSnapshotFieldDict) BytesRead() uint64 { + return i.bytesRead +} + +func (i *IndexSnapshotFieldDict) Len() int { return len(i.cursors) } +func (i *IndexSnapshotFieldDict) Less(a, b int) bool { + return i.cursors[a].curr.Term < i.cursors[b].curr.Term +} +func (i *IndexSnapshotFieldDict) Swap(a, b int) { + i.cursors[a], i.cursors[b] = i.cursors[b], i.cursors[a] +} + +func (i *IndexSnapshotFieldDict) Push(x interface{}) { + i.cursors = append(i.cursors, x.(*segmentDictCursor)) +} + +func (i *IndexSnapshotFieldDict) Pop() interface{} { + n := len(i.cursors) + x := i.cursors[n-1] + i.cursors = i.cursors[0 : n-1] + return x +} + +func (i *IndexSnapshotFieldDict) Next() (*index.DictEntry, error) { + if len(i.cursors) == 0 { + return nil, nil + } + i.entry = i.cursors[0].curr + next, err := i.cursors[0].itr.Next() + if err != nil { + return nil, err + } + if next == nil { + // at end of this cursor, remove it + heap.Pop(i) + } else { + // modified heap, fix it + i.cursors[0].curr = *next + heap.Fix(i, 0) + } + // look for any other entries with the exact same term + for len(i.cursors) > 0 && i.cursors[0].curr.Term == i.entry.Term { + i.entry.Count += i.cursors[0].curr.Count + next, err := i.cursors[0].itr.Next() + if err != nil { + return nil, err + } + if next == nil { + // at end of this cursor, remove it + heap.Pop(i) + } else { + // modified heap, fix it + i.cursors[0].curr = *next + heap.Fix(i, 0) + } + } + + return &i.entry, nil +} + +func (i *IndexSnapshotFieldDict) Close() error { + return nil +} + +func (i *IndexSnapshotFieldDict) Contains(key []byte) (bool, error) { + if len(i.cursors) == 0 { + return false, nil + } + + for _, cursor := range i.cursors { + if found, _ := cursor.dict.Contains(key); found { + return true, nil + } + } + + return false, nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_index_doc.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_index_doc.go new file mode 100644 index 0000000000..fe174e7e3e --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_index_doc.go @@ -0,0 +1,80 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorch + +import ( + "bytes" + "reflect" + + "github.com/RoaringBitmap/roaring" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeIndexSnapshotDocIDReader int + +func init() { + var isdr IndexSnapshotDocIDReader + reflectStaticSizeIndexSnapshotDocIDReader = int(reflect.TypeOf(isdr).Size()) +} + +type IndexSnapshotDocIDReader struct { + snapshot *IndexSnapshot + iterators []roaring.IntIterable + segmentOffset int +} + +func (i *IndexSnapshotDocIDReader) Size() int { + return reflectStaticSizeIndexSnapshotDocIDReader + size.SizeOfPtr +} + +func (i *IndexSnapshotDocIDReader) Next() (index.IndexInternalID, error) { + for i.segmentOffset < len(i.iterators) { + if !i.iterators[i.segmentOffset].HasNext() { + i.segmentOffset++ + continue + } + next := i.iterators[i.segmentOffset].Next() + // make segment number into global number by adding offset + globalOffset := i.snapshot.offsets[i.segmentOffset] + return docNumberToBytes(nil, uint64(next)+globalOffset), nil + } + return nil, nil +} + +func (i *IndexSnapshotDocIDReader) Advance(ID index.IndexInternalID) (index.IndexInternalID, error) { + // FIXME do something better + next, err := i.Next() + if err != nil { + return nil, err + } + if next == nil { + return nil, nil + } + for bytes.Compare(next, ID) < 0 { + next, err = i.Next() + if err != nil { + return nil, err + } + if next == nil { + break + } + } + return next, nil +} + +func (i *IndexSnapshotDocIDReader) Close() error { + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_index_tfr.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_index_tfr.go new file mode 100644 index 0000000000..349620c718 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_index_tfr.go @@ -0,0 +1,214 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorch + +import ( + "bytes" + "context" + "fmt" + "reflect" + "sync/atomic" + + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" +) + +var reflectStaticSizeIndexSnapshotTermFieldReader int + +func init() { + var istfr IndexSnapshotTermFieldReader + reflectStaticSizeIndexSnapshotTermFieldReader = int(reflect.TypeOf(istfr).Size()) +} + +type IndexSnapshotTermFieldReader struct { + term []byte + field string + snapshot *IndexSnapshot + dicts []segment.TermDictionary + postings []segment.PostingsList + iterators []segment.PostingsIterator + segmentOffset int + includeFreq bool + includeNorm bool + includeTermVectors bool + currPosting segment.Posting + currID index.IndexInternalID + recycle bool + bytesRead uint64 + ctx context.Context +} + +func (i *IndexSnapshotTermFieldReader) incrementBytesRead(val uint64) { + i.bytesRead += val +} + +func (i *IndexSnapshotTermFieldReader) Size() int { + sizeInBytes := reflectStaticSizeIndexSnapshotTermFieldReader + size.SizeOfPtr + + len(i.term) + + len(i.field) + + len(i.currID) + + for _, entry := range i.postings { + sizeInBytes += entry.Size() + } + + for _, entry := range i.iterators { + sizeInBytes += entry.Size() + } + + if i.currPosting != nil { + sizeInBytes += i.currPosting.Size() + } + + return sizeInBytes +} + +func (i *IndexSnapshotTermFieldReader) Next(preAlloced *index.TermFieldDoc) (*index.TermFieldDoc, error) { + rv := preAlloced + if rv == nil { + rv = &index.TermFieldDoc{} + } + // find the next hit + for i.segmentOffset < len(i.iterators) { + prevBytesRead := i.iterators[i.segmentOffset].BytesRead() + next, err := i.iterators[i.segmentOffset].Next() + if err != nil { + return nil, err + } + if next != nil { + // make segment number into global number by adding offset + globalOffset := i.snapshot.offsets[i.segmentOffset] + nnum := next.Number() + rv.ID = docNumberToBytes(rv.ID, nnum+globalOffset) + i.postingToTermFieldDoc(next, rv) + + i.currID = rv.ID + i.currPosting = next + // postingsIterators is maintain the bytesRead stat in a cumulative fashion. + // this is because there are chances of having a series of loadChunk calls, + // and they have to be added together before sending the bytesRead at this point + // upstream. + if delta := i.iterators[i.segmentOffset].BytesRead() - prevBytesRead; delta > 0 { + i.incrementBytesRead(delta) + } + + return rv, nil + } + i.segmentOffset++ + } + return nil, nil +} + +func (i *IndexSnapshotTermFieldReader) postingToTermFieldDoc(next segment.Posting, rv *index.TermFieldDoc) { + if i.includeFreq { + rv.Freq = next.Frequency() + } + if i.includeNorm { + rv.Norm = next.Norm() + } + if i.includeTermVectors { + locs := next.Locations() + if cap(rv.Vectors) < len(locs) { + rv.Vectors = make([]*index.TermFieldVector, len(locs)) + backing := make([]index.TermFieldVector, len(locs)) + for i := range backing { + rv.Vectors[i] = &backing[i] + } + } + rv.Vectors = rv.Vectors[:len(locs)] + for i, loc := range locs { + *rv.Vectors[i] = index.TermFieldVector{ + Start: loc.Start(), + End: loc.End(), + Pos: loc.Pos(), + ArrayPositions: loc.ArrayPositions(), + Field: loc.Field(), + } + } + } +} + +func (i *IndexSnapshotTermFieldReader) Advance(ID index.IndexInternalID, preAlloced *index.TermFieldDoc) (*index.TermFieldDoc, error) { + // FIXME do something better + // for now, if we need to seek backwards, then restart from the beginning + if i.currPosting != nil && bytes.Compare(i.currID, ID) >= 0 { + i2, err := i.snapshot.TermFieldReader(nil, i.term, i.field, + i.includeFreq, i.includeNorm, i.includeTermVectors) + if err != nil { + return nil, err + } + // close the current term field reader before replacing it with a new one + _ = i.Close() + *i = *(i2.(*IndexSnapshotTermFieldReader)) + } + num, err := docInternalToNumber(ID) + if err != nil { + return nil, fmt.Errorf("error converting to doc number % x - %v", ID, err) + } + segIndex, ldocNum := i.snapshot.segmentIndexAndLocalDocNumFromGlobal(num) + if segIndex >= len(i.snapshot.segment) { + return nil, fmt.Errorf("computed segment index %d out of bounds %d", + segIndex, len(i.snapshot.segment)) + } + // skip directly to the target segment + i.segmentOffset = segIndex + next, err := i.iterators[i.segmentOffset].Advance(ldocNum) + if err != nil { + return nil, err + } + if next == nil { + // we jumped directly to the segment that should have contained it + // but it wasn't there, so reuse Next() which should correctly + // get the next hit after it (we moved i.segmentOffset) + return i.Next(preAlloced) + } + + if preAlloced == nil { + preAlloced = &index.TermFieldDoc{} + } + preAlloced.ID = docNumberToBytes(preAlloced.ID, next.Number()+ + i.snapshot.offsets[segIndex]) + i.postingToTermFieldDoc(next, preAlloced) + i.currID = preAlloced.ID + i.currPosting = next + return preAlloced, nil +} + +func (i *IndexSnapshotTermFieldReader) Count() uint64 { + var rv uint64 + for _, posting := range i.postings { + rv += posting.Count() + } + return rv +} + +func (i *IndexSnapshotTermFieldReader) Close() error { + if i.ctx != nil { + statsCallbackFn := i.ctx.Value(search.SearchIOStatsCallbackKey) + if statsCallbackFn != nil { + // essentially before you close the TFR, you must report this + // reader's bytesRead value + statsCallbackFn.(search.SearchIOStatsCallbackFunc)(i.bytesRead) + } + } + + if i.snapshot != nil { + atomic.AddUint64(&i.snapshot.parent.stats.TotTermSearchersFinished, uint64(1)) + i.snapshot.recycleTermFieldReader(i) + } + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_segment.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_segment.go new file mode 100644 index 0000000000..0b76ec7465 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/snapshot_segment.go @@ -0,0 +1,284 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorch + +import ( + "bytes" + "sync" + "sync/atomic" + + "github.com/RoaringBitmap/roaring" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" +) + +var TermSeparator byte = 0xff + +var TermSeparatorSplitSlice = []byte{TermSeparator} + +type SegmentSnapshot struct { + // this flag is needed to identify whether this + // segment was mmaped recently, in which case + // we consider the loading cost of the metadata + // as part of IO stats. + mmaped uint32 + id uint64 + segment segment.Segment + deleted *roaring.Bitmap + creator string + + cachedDocs *cachedDocs +} + +func (s *SegmentSnapshot) Segment() segment.Segment { + return s.segment +} + +func (s *SegmentSnapshot) Deleted() *roaring.Bitmap { + return s.deleted +} + +func (s *SegmentSnapshot) Id() uint64 { + return s.id +} + +func (s *SegmentSnapshot) FullSize() int64 { + return int64(s.segment.Count()) +} + +func (s *SegmentSnapshot) LiveSize() int64 { + return int64(s.Count()) +} + +func (s *SegmentSnapshot) Close() error { + return s.segment.Close() +} + +func (s *SegmentSnapshot) VisitDocument(num uint64, visitor segment.StoredFieldValueVisitor) error { + return s.segment.VisitStoredFields(num, visitor) +} + +func (s *SegmentSnapshot) DocID(num uint64) ([]byte, error) { + return s.segment.DocID(num) +} + +func (s *SegmentSnapshot) Count() uint64 { + rv := s.segment.Count() + if s.deleted != nil { + rv -= s.deleted.GetCardinality() + } + return rv +} + +func (s *SegmentSnapshot) DocNumbers(docIDs []string) (*roaring.Bitmap, error) { + rv, err := s.segment.DocNumbers(docIDs) + if err != nil { + return nil, err + } + if s.deleted != nil { + rv.AndNot(s.deleted) + } + return rv, nil +} + +// DocNumbersLive returns a bitmap containing doc numbers for all live docs +func (s *SegmentSnapshot) DocNumbersLive() *roaring.Bitmap { + rv := roaring.NewBitmap() + rv.AddRange(0, s.segment.Count()) + if s.deleted != nil { + rv.AndNot(s.deleted) + } + return rv +} + +func (s *SegmentSnapshot) Fields() []string { + return s.segment.Fields() +} + +func (s *SegmentSnapshot) Size() (rv int) { + rv = s.segment.Size() + if s.deleted != nil { + rv += int(s.deleted.GetSizeInBytes()) + } + rv += s.cachedDocs.Size() + return +} + +type cachedFieldDocs struct { + m sync.Mutex + readyCh chan struct{} // closed when the cachedFieldDocs.docs is ready to be used. + err error // Non-nil if there was an error when preparing this cachedFieldDocs. + docs map[uint64][]byte // Keyed by localDocNum, value is a list of terms delimited by 0xFF. + size uint64 +} + +func (cfd *cachedFieldDocs) Size() int { + var rv int + cfd.m.Lock() + for _, entry := range cfd.docs { + rv += 8 /* size of uint64 */ + len(entry) + } + cfd.m.Unlock() + return rv +} + +func (cfd *cachedFieldDocs) prepareField(field string, ss *SegmentSnapshot) { + cfd.m.Lock() + defer func() { + close(cfd.readyCh) + cfd.m.Unlock() + }() + + cfd.size += uint64(size.SizeOfUint64) /* size field */ + dict, err := ss.segment.Dictionary(field) + if err != nil { + cfd.err = err + return + } + + var postings segment.PostingsList + var postingsItr segment.PostingsIterator + + dictItr := dict.AutomatonIterator(nil, nil, nil) + next, err := dictItr.Next() + for err == nil && next != nil { + var err1 error + postings, err1 = dict.PostingsList([]byte(next.Term), nil, postings) + if err1 != nil { + cfd.err = err1 + return + } + + cfd.size += uint64(size.SizeOfUint64) /* map key */ + postingsItr = postings.Iterator(false, false, false, postingsItr) + nextPosting, err2 := postingsItr.Next() + for err2 == nil && nextPosting != nil { + docNum := nextPosting.Number() + cfd.docs[docNum] = append(cfd.docs[docNum], []byte(next.Term)...) + cfd.docs[docNum] = append(cfd.docs[docNum], TermSeparator) + cfd.size += uint64(len(next.Term) + 1) // map value + nextPosting, err2 = postingsItr.Next() + } + + if err2 != nil { + cfd.err = err2 + return + } + + next, err = dictItr.Next() + } + + if err != nil { + cfd.err = err + return + } +} + +type cachedDocs struct { + size uint64 + m sync.Mutex // As the cache is asynchronously prepared, need a lock + cache map[string]*cachedFieldDocs // Keyed by field +} + +func (c *cachedDocs) prepareFields(wantedFields []string, ss *SegmentSnapshot) error { + c.m.Lock() + + if c.cache == nil { + c.cache = make(map[string]*cachedFieldDocs, len(ss.Fields())) + } + + for _, field := range wantedFields { + _, exists := c.cache[field] + if !exists { + c.cache[field] = &cachedFieldDocs{ + readyCh: make(chan struct{}), + docs: make(map[uint64][]byte), + } + + go c.cache[field].prepareField(field, ss) + } + } + + for _, field := range wantedFields { + cachedFieldDocs := c.cache[field] + c.m.Unlock() + <-cachedFieldDocs.readyCh + + if cachedFieldDocs.err != nil { + return cachedFieldDocs.err + } + c.m.Lock() + } + + c.updateSizeLOCKED() + + c.m.Unlock() + return nil +} + +// hasFields returns true if the cache has all the given fields +func (c *cachedDocs) hasFields(fields []string) bool { + c.m.Lock() + for _, field := range fields { + if _, exists := c.cache[field]; !exists { + c.m.Unlock() + return false // found a field not in cache + } + } + c.m.Unlock() + return true +} + +func (c *cachedDocs) Size() int { + return int(atomic.LoadUint64(&c.size)) +} + +func (c *cachedDocs) updateSizeLOCKED() { + sizeInBytes := 0 + for k, v := range c.cache { // cachedFieldDocs + sizeInBytes += len(k) + if v != nil { + sizeInBytes += v.Size() + } + } + atomic.StoreUint64(&c.size, uint64(sizeInBytes)) +} + +func (c *cachedDocs) visitDoc(localDocNum uint64, + fields []string, visitor index.DocValueVisitor) { + c.m.Lock() + + for _, field := range fields { + if cachedFieldDocs, exists := c.cache[field]; exists { + c.m.Unlock() + <-cachedFieldDocs.readyCh + c.m.Lock() + + if tlist, exists := cachedFieldDocs.docs[localDocNum]; exists { + for { + i := bytes.Index(tlist, TermSeparatorSplitSlice) + if i < 0 { + break + } + visitor(field, tlist[0:i]) + tlist = tlist[i+1:] + } + } + } + } + + c.m.Unlock() +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/stats.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/stats.go new file mode 100644 index 0000000000..d265e9d040 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/stats.go @@ -0,0 +1,155 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorch + +import ( + "encoding/json" + "reflect" + "sync/atomic" +) + +// Stats tracks statistics about the index, fields that are +// prefixed like CurXxxx are gauges (can go up and down), +// and fields that are prefixed like TotXxxx are monotonically +// increasing counters. +type Stats struct { + TotUpdates uint64 + TotDeletes uint64 + + TotBatches uint64 + TotBatchesEmpty uint64 + TotBatchIntroTime uint64 + MaxBatchIntroTime uint64 + + CurRootEpoch uint64 + LastPersistedEpoch uint64 + LastMergedEpoch uint64 + + TotOnErrors uint64 + + TotAnalysisTime uint64 + TotIndexTime uint64 + + TotIndexedPlainTextBytes uint64 + + TotBytesReadAtQueryTime uint64 + TotBytesWrittenAtIndexTime uint64 + + TotTermSearchersStarted uint64 + TotTermSearchersFinished uint64 + + TotEventTriggerStarted uint64 + TotEventTriggerCompleted uint64 + + TotIntroduceLoop uint64 + TotIntroduceSegmentBeg uint64 + TotIntroduceSegmentEnd uint64 + TotIntroducePersistBeg uint64 + TotIntroducePersistEnd uint64 + TotIntroduceMergeBeg uint64 + TotIntroduceMergeEnd uint64 + TotIntroduceRevertBeg uint64 + TotIntroduceRevertEnd uint64 + + TotIntroducedItems uint64 + TotIntroducedSegmentsBatch uint64 + TotIntroducedSegmentsMerge uint64 + + TotPersistLoopBeg uint64 + TotPersistLoopErr uint64 + TotPersistLoopProgress uint64 + TotPersistLoopWait uint64 + TotPersistLoopWaitNotified uint64 + TotPersistLoopEnd uint64 + + TotPersistedItems uint64 + TotItemsToPersist uint64 + TotPersistedSegments uint64 + + TotPersisterSlowMergerPause uint64 + TotPersisterSlowMergerResume uint64 + + TotPersisterNapPauseCompleted uint64 + TotPersisterMergerNapBreak uint64 + + TotFileMergeLoopBeg uint64 + TotFileMergeLoopErr uint64 + TotFileMergeLoopEnd uint64 + + TotFileMergeForceOpsStarted uint64 + TotFileMergeForceOpsCompleted uint64 + + TotFileMergePlan uint64 + TotFileMergePlanErr uint64 + TotFileMergePlanNone uint64 + TotFileMergePlanOk uint64 + + TotFileMergePlanTasks uint64 + TotFileMergePlanTasksDone uint64 + TotFileMergePlanTasksErr uint64 + TotFileMergePlanTasksSegments uint64 + TotFileMergePlanTasksSegmentsEmpty uint64 + + TotFileMergeSegmentsEmpty uint64 + TotFileMergeSegments uint64 + TotFileSegmentsAtRoot uint64 + TotFileMergeWrittenBytes uint64 + + TotFileMergeZapBeg uint64 + TotFileMergeZapEnd uint64 + TotFileMergeZapTime uint64 + MaxFileMergeZapTime uint64 + TotFileMergeZapIntroductionTime uint64 + MaxFileMergeZapIntroductionTime uint64 + + TotFileMergeIntroductions uint64 + TotFileMergeIntroductionsDone uint64 + TotFileMergeIntroductionsSkipped uint64 + TotFileMergeIntroductionsObsoleted uint64 + + CurFilesIneligibleForRemoval uint64 + TotSnapshotsRemovedFromMetaStore uint64 + + TotMemMergeBeg uint64 + TotMemMergeErr uint64 + TotMemMergeDone uint64 + TotMemMergeZapBeg uint64 + TotMemMergeZapEnd uint64 + TotMemMergeZapTime uint64 + MaxMemMergeZapTime uint64 + TotMemMergeSegments uint64 + TotMemorySegmentsAtRoot uint64 +} + +// atomically populates the returned map +func (s *Stats) ToMap() map[string]interface{} { + m := map[string]interface{}{} + sve := reflect.ValueOf(s).Elem() + svet := sve.Type() + for i := 0; i < svet.NumField(); i++ { + svef := sve.Field(i) + if svef.CanAddr() { + svefp := svef.Addr().Interface() + m[svet.Field(i).Name] = atomic.LoadUint64(svefp.(*uint64)) + } + } + return m +} + +// MarshalJSON implements json.Marshaler, and in contrast to standard +// json marshaling provides atomic safety +func (s *Stats) MarshalJSON() ([]byte, error) { + return json.Marshal(s.ToMap()) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/unadorned.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/unadorned.go new file mode 100644 index 0000000000..8221b23e3f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/scorch/unadorned.go @@ -0,0 +1,182 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorch + +import ( + "math" + "reflect" + + "github.com/RoaringBitmap/roaring" + segment "github.com/blevesearch/scorch_segment_api/v2" +) + +var reflectStaticSizeUnadornedPostingsIteratorBitmap int +var reflectStaticSizeUnadornedPostingsIterator1Hit int +var reflectStaticSizeUnadornedPosting int + +func init() { + var pib unadornedPostingsIteratorBitmap + reflectStaticSizeUnadornedPostingsIteratorBitmap = int(reflect.TypeOf(pib).Size()) + var pi1h unadornedPostingsIterator1Hit + reflectStaticSizeUnadornedPostingsIterator1Hit = int(reflect.TypeOf(pi1h).Size()) + var up UnadornedPosting + reflectStaticSizeUnadornedPosting = int(reflect.TypeOf(up).Size()) +} + +type unadornedPostingsIteratorBitmap struct { + actual roaring.IntPeekable + actualBM *roaring.Bitmap +} + +func (i *unadornedPostingsIteratorBitmap) Next() (segment.Posting, error) { + return i.nextAtOrAfter(0) +} + +func (i *unadornedPostingsIteratorBitmap) Advance(docNum uint64) (segment.Posting, error) { + return i.nextAtOrAfter(docNum) +} + +func (i *unadornedPostingsIteratorBitmap) nextAtOrAfter(atOrAfter uint64) (segment.Posting, error) { + docNum, exists := i.nextDocNumAtOrAfter(atOrAfter) + if !exists { + return nil, nil + } + return UnadornedPosting(docNum), nil +} + +func (i *unadornedPostingsIteratorBitmap) nextDocNumAtOrAfter(atOrAfter uint64) (uint64, bool) { + if i.actual == nil || !i.actual.HasNext() { + return 0, false + } + i.actual.AdvanceIfNeeded(uint32(atOrAfter)) + + if !i.actual.HasNext() { + return 0, false // couldn't find anything + } + + return uint64(i.actual.Next()), true +} + +func (i *unadornedPostingsIteratorBitmap) Size() int { + return reflectStaticSizeUnadornedPostingsIteratorBitmap +} + +func (i *unadornedPostingsIteratorBitmap) BytesRead() uint64 { + return 0 +} + +func (i *unadornedPostingsIteratorBitmap) BytesWritten() uint64 { + return 0 +} + +func (i *unadornedPostingsIteratorBitmap) ResetBytesRead(uint64) {} + +func (i *unadornedPostingsIteratorBitmap) ActualBitmap() *roaring.Bitmap { + return i.actualBM +} + +func (i *unadornedPostingsIteratorBitmap) DocNum1Hit() (uint64, bool) { + return 0, false +} + +func (i *unadornedPostingsIteratorBitmap) ReplaceActual(actual *roaring.Bitmap) { + i.actualBM = actual + i.actual = actual.Iterator() +} + +func newUnadornedPostingsIteratorFromBitmap(bm *roaring.Bitmap) segment.PostingsIterator { + return &unadornedPostingsIteratorBitmap{ + actualBM: bm, + actual: bm.Iterator(), + } +} + +const docNum1HitFinished = math.MaxUint64 + +type unadornedPostingsIterator1Hit struct { + docNum uint64 +} + +func (i *unadornedPostingsIterator1Hit) Next() (segment.Posting, error) { + return i.nextAtOrAfter(0) +} + +func (i *unadornedPostingsIterator1Hit) Advance(docNum uint64) (segment.Posting, error) { + return i.nextAtOrAfter(docNum) +} + +func (i *unadornedPostingsIterator1Hit) nextAtOrAfter(atOrAfter uint64) (segment.Posting, error) { + docNum, exists := i.nextDocNumAtOrAfter(atOrAfter) + if !exists { + return nil, nil + } + return UnadornedPosting(docNum), nil +} + +func (i *unadornedPostingsIterator1Hit) nextDocNumAtOrAfter(atOrAfter uint64) (uint64, bool) { + if i.docNum == docNum1HitFinished { + return 0, false + } + if i.docNum < atOrAfter { + // advanced past our 1-hit + i.docNum = docNum1HitFinished // consume our 1-hit docNum + return 0, false + } + docNum := i.docNum + i.docNum = docNum1HitFinished // consume our 1-hit docNum + return docNum, true +} + +func (i *unadornedPostingsIterator1Hit) Size() int { + return reflectStaticSizeUnadornedPostingsIterator1Hit +} + +func (i *unadornedPostingsIterator1Hit) BytesRead() uint64 { + return 0 +} + +func (i *unadornedPostingsIterator1Hit) BytesWritten() uint64 { + return 0 +} + +func (i *unadornedPostingsIterator1Hit) ResetBytesRead(uint64) {} + +func newUnadornedPostingsIteratorFrom1Hit(docNum1Hit uint64) segment.PostingsIterator { + return &unadornedPostingsIterator1Hit{ + docNum1Hit, + } +} + +type UnadornedPosting uint64 + +func (p UnadornedPosting) Number() uint64 { + return uint64(p) +} + +func (p UnadornedPosting) Frequency() uint64 { + return 0 +} + +func (p UnadornedPosting) Norm() float64 { + return 0 +} + +func (p UnadornedPosting) Locations() []segment.Location { + return nil +} + +func (p UnadornedPosting) Size() int { + return reflectStaticSizeUnadornedPosting +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/analysis.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/analysis.go new file mode 100644 index 0000000000..1ebd1918ee --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/analysis.go @@ -0,0 +1,129 @@ +// Copyright (c) 2015 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package upsidedown + +import ( + index "github.com/blevesearch/bleve_index_api" +) + +type IndexRow interface { + KeySize() int + KeyTo([]byte) (int, error) + Key() []byte + + ValueSize() int + ValueTo([]byte) (int, error) + Value() []byte +} + +type AnalysisResult struct { + DocID string + Rows []IndexRow +} + +func (udc *UpsideDownCouch) Analyze(d index.Document) *AnalysisResult { + return udc.analyze(d) +} + +func (udc *UpsideDownCouch) analyze(d index.Document) *AnalysisResult { + rv := &AnalysisResult{ + DocID: d.ID(), + Rows: make([]IndexRow, 0, 100), + } + + docIDBytes := []byte(d.ID()) + + // track our back index entries + backIndexStoredEntries := make([]*BackIndexStoreEntry, 0) + + // information we collate as we merge fields with same name + fieldTermFreqs := make(map[uint16]index.TokenFrequencies) + fieldLengths := make(map[uint16]int) + fieldIncludeTermVectors := make(map[uint16]bool) + fieldNames := make(map[uint16]string) + + analyzeField := func(field index.Field, storable bool) { + fieldIndex, newFieldRow := udc.fieldIndexOrNewRow(field.Name()) + if newFieldRow != nil { + rv.Rows = append(rv.Rows, newFieldRow) + } + fieldNames[fieldIndex] = field.Name() + + if field.Options().IsIndexed() { + field.Analyze() + fieldLength := field.AnalyzedLength() + tokenFreqs := field.AnalyzedTokenFrequencies() + existingFreqs := fieldTermFreqs[fieldIndex] + if existingFreqs == nil { + fieldTermFreqs[fieldIndex] = tokenFreqs + } else { + existingFreqs.MergeAll(field.Name(), tokenFreqs) + fieldTermFreqs[fieldIndex] = existingFreqs + } + fieldLengths[fieldIndex] += fieldLength + fieldIncludeTermVectors[fieldIndex] = field.Options().IncludeTermVectors() + } + + if storable && field.Options().IsStored() { + rv.Rows, backIndexStoredEntries = udc.storeField(docIDBytes, field, fieldIndex, rv.Rows, backIndexStoredEntries) + } + } + + // walk all the fields, record stored fields now + // place information about indexed fields into map + // this collates information across fields with + // same names (arrays) + d.VisitFields(func(field index.Field) { + analyzeField(field, true) + }) + + if d.HasComposite() { + for fieldIndex, tokenFreqs := range fieldTermFreqs { + // see if any of the composite fields need this + d.VisitComposite(func(field index.CompositeField) { + field.Compose(fieldNames[fieldIndex], fieldLengths[fieldIndex], tokenFreqs) + }) + } + + d.VisitComposite(func(field index.CompositeField) { + analyzeField(field, false) + }) + } + + rowsCapNeeded := len(rv.Rows) + 1 + for _, tokenFreqs := range fieldTermFreqs { + rowsCapNeeded += len(tokenFreqs) + } + + rv.Rows = append(make([]IndexRow, 0, rowsCapNeeded), rv.Rows...) + + backIndexTermsEntries := make([]*BackIndexTermsEntry, 0, len(fieldTermFreqs)) + + // walk through the collated information and process + // once for each indexed field (unique name) + for fieldIndex, tokenFreqs := range fieldTermFreqs { + fieldLength := fieldLengths[fieldIndex] + includeTermVectors := fieldIncludeTermVectors[fieldIndex] + + // encode this field + rv.Rows, backIndexTermsEntries = udc.indexField(docIDBytes, includeTermVectors, fieldIndex, fieldLength, tokenFreqs, rv.Rows, backIndexTermsEntries) + } + + // build the back index row + backIndexRow := NewBackIndexRow(docIDBytes, backIndexTermsEntries, backIndexStoredEntries) + rv.Rows = append(rv.Rows, backIndexRow) + + return rv +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/benchmark_all.sh b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/benchmark_all.sh new file mode 100644 index 0000000000..079fef1865 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/benchmark_all.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +BENCHMARKS=`grep "func Benchmark" *_test.go | sed 's/.*func //' | sed s/\(.*{//` + +for BENCHMARK in $BENCHMARKS +do + go test -v -run=xxx -bench=^$BENCHMARK$ -benchtime=10s -tags 'forestdb leveldb' | grep -v ok | grep -v PASS +done diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/dump.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/dump.go new file mode 100644 index 0000000000..64ebb1b265 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/dump.go @@ -0,0 +1,174 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package upsidedown + +import ( + "bytes" + "sort" + + "github.com/blevesearch/upsidedown_store_api" +) + +// the functions in this file are only intended to be used by +// the bleve_dump utility and the debug http handlers +// if your application relies on them, you're doing something wrong +// they may change or be removed at any time + +func dumpPrefix(kvreader store.KVReader, rv chan interface{}, prefix []byte) { + start := prefix + if start == nil { + start = []byte{0} + } + it := kvreader.PrefixIterator(start) + defer func() { + cerr := it.Close() + if cerr != nil { + rv <- cerr + } + }() + key, val, valid := it.Current() + for valid { + ck := make([]byte, len(key)) + copy(ck, key) + cv := make([]byte, len(val)) + copy(cv, val) + row, err := ParseFromKeyValue(ck, cv) + if err != nil { + rv <- err + return + } + rv <- row + + it.Next() + key, val, valid = it.Current() + } +} + +func dumpRange(kvreader store.KVReader, rv chan interface{}, start, end []byte) { + it := kvreader.RangeIterator(start, end) + defer func() { + cerr := it.Close() + if cerr != nil { + rv <- cerr + } + }() + key, val, valid := it.Current() + for valid { + ck := make([]byte, len(key)) + copy(ck, key) + cv := make([]byte, len(val)) + copy(cv, val) + row, err := ParseFromKeyValue(ck, cv) + if err != nil { + rv <- err + return + } + rv <- row + + it.Next() + key, val, valid = it.Current() + } +} + +func (i *IndexReader) DumpAll() chan interface{} { + rv := make(chan interface{}) + go func() { + defer close(rv) + dumpRange(i.kvreader, rv, nil, nil) + }() + return rv +} + +func (i *IndexReader) DumpFields() chan interface{} { + rv := make(chan interface{}) + go func() { + defer close(rv) + dumpPrefix(i.kvreader, rv, []byte{'f'}) + }() + return rv +} + +type keyset [][]byte + +func (k keyset) Len() int { return len(k) } +func (k keyset) Swap(i, j int) { k[i], k[j] = k[j], k[i] } +func (k keyset) Less(i, j int) bool { return bytes.Compare(k[i], k[j]) < 0 } + +// DumpDoc returns all rows in the index related to this doc id +func (i *IndexReader) DumpDoc(id string) chan interface{} { + idBytes := []byte(id) + + rv := make(chan interface{}) + + go func() { + defer close(rv) + + back, err := backIndexRowForDoc(i.kvreader, []byte(id)) + if err != nil { + rv <- err + return + } + + // no such doc + if back == nil { + return + } + // build sorted list of term keys + keys := make(keyset, 0) + for _, entry := range back.termsEntries { + for i := range entry.Terms { + tfr := NewTermFrequencyRow([]byte(entry.Terms[i]), uint16(*entry.Field), idBytes, 0, 0) + key := tfr.Key() + keys = append(keys, key) + } + } + sort.Sort(keys) + + // first add all the stored rows + storedRowPrefix := NewStoredRow(idBytes, 0, []uint64{}, 'x', []byte{}).ScanPrefixForDoc() + dumpPrefix(i.kvreader, rv, storedRowPrefix) + + // now walk term keys in order and add them as well + if len(keys) > 0 { + it := i.kvreader.RangeIterator(keys[0], nil) + defer func() { + cerr := it.Close() + if cerr != nil { + rv <- cerr + } + }() + + for _, key := range keys { + it.Seek(key) + rkey, rval, valid := it.Current() + if !valid { + break + } + rck := make([]byte, len(rkey)) + copy(rck, key) + rcv := make([]byte, len(rval)) + copy(rcv, rval) + row, err := ParseFromKeyValue(rck, rcv) + if err != nil { + rv <- err + return + } + rv <- row + } + } + }() + + return rv +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/field_cache.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/field_cache.go new file mode 100644 index 0000000000..1f68b71dd6 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/field_cache.go @@ -0,0 +1,88 @@ +// Copyright (c) 2015 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package upsidedown + +import ( + "sync" +) + +type FieldCache struct { + fieldIndexes map[string]uint16 + indexFields []string + lastFieldIndex int + mutex sync.RWMutex +} + +func NewFieldCache() *FieldCache { + return &FieldCache{ + fieldIndexes: make(map[string]uint16), + lastFieldIndex: -1, + } +} + +func (f *FieldCache) AddExisting(field string, index uint16) { + f.mutex.Lock() + f.addLOCKED(field, index) + f.mutex.Unlock() +} + +func (f *FieldCache) addLOCKED(field string, index uint16) uint16 { + f.fieldIndexes[field] = index + if len(f.indexFields) < int(index)+1 { + prevIndexFields := f.indexFields + f.indexFields = make([]string, int(index)+16) + copy(f.indexFields, prevIndexFields) + } + f.indexFields[int(index)] = field + if int(index) > f.lastFieldIndex { + f.lastFieldIndex = int(index) + } + return index +} + +// FieldNamed returns the index of the field, and whether or not it existed +// before this call. if createIfMissing is true, and new field index is assigned +// but the second return value will still be false +func (f *FieldCache) FieldNamed(field string, createIfMissing bool) (uint16, bool) { + f.mutex.RLock() + if index, ok := f.fieldIndexes[field]; ok { + f.mutex.RUnlock() + return index, true + } else if !createIfMissing { + f.mutex.RUnlock() + return 0, false + } + // trade read lock for write lock + f.mutex.RUnlock() + f.mutex.Lock() + // need to check again with write lock + if index, ok := f.fieldIndexes[field]; ok { + f.mutex.Unlock() + return index, true + } + // assign next field id + index := f.addLOCKED(field, uint16(f.lastFieldIndex+1)) + f.mutex.Unlock() + return index, false +} + +func (f *FieldCache) FieldIndexed(index uint16) (field string) { + f.mutex.RLock() + if int(index) < len(f.indexFields) { + field = f.indexFields[int(index)] + } + f.mutex.RUnlock() + return field +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/field_dict.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/field_dict.go new file mode 100644 index 0000000000..4875680c99 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/field_dict.go @@ -0,0 +1,82 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package upsidedown + +import ( + "fmt" + + index "github.com/blevesearch/bleve_index_api" + store "github.com/blevesearch/upsidedown_store_api" +) + +type UpsideDownCouchFieldDict struct { + indexReader *IndexReader + iterator store.KVIterator + dictRow *DictionaryRow + dictEntry *index.DictEntry + field uint16 +} + +func newUpsideDownCouchFieldDict(indexReader *IndexReader, field uint16, startTerm, endTerm []byte) (*UpsideDownCouchFieldDict, error) { + + startKey := NewDictionaryRow(startTerm, field, 0).Key() + if endTerm == nil { + endTerm = []byte{ByteSeparator} + } else { + endTerm = incrementBytes(endTerm) + } + endKey := NewDictionaryRow(endTerm, field, 0).Key() + + it := indexReader.kvreader.RangeIterator(startKey, endKey) + + return &UpsideDownCouchFieldDict{ + indexReader: indexReader, + iterator: it, + dictRow: &DictionaryRow{}, // Pre-alloced, reused row. + dictEntry: &index.DictEntry{}, // Pre-alloced, reused entry. + field: field, + }, nil + +} + +func (r *UpsideDownCouchFieldDict) BytesRead() uint64 { + return 0 +} + +func (r *UpsideDownCouchFieldDict) Next() (*index.DictEntry, error) { + key, val, valid := r.iterator.Current() + if !valid { + return nil, nil + } + + err := r.dictRow.parseDictionaryK(key) + if err != nil { + return nil, fmt.Errorf("unexpected error parsing dictionary row key: %v", err) + } + err = r.dictRow.parseDictionaryV(val) + if err != nil { + return nil, fmt.Errorf("unexpected error parsing dictionary row val: %v", err) + } + r.dictEntry.Term = string(r.dictRow.term) + r.dictEntry.Count = r.dictRow.count + // advance the iterator to the next term + r.iterator.Next() + return r.dictEntry, nil + +} + +func (r *UpsideDownCouchFieldDict) Close() error { + return r.iterator.Close() +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/index_reader.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/index_reader.go new file mode 100644 index 0000000000..5c164fc8ca --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/index_reader.go @@ -0,0 +1,228 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package upsidedown + +import ( + "context" + "reflect" + + "github.com/blevesearch/bleve/v2/document" + index "github.com/blevesearch/bleve_index_api" + "github.com/blevesearch/upsidedown_store_api" +) + +var reflectStaticSizeIndexReader int + +func init() { + var ir IndexReader + reflectStaticSizeIndexReader = int(reflect.TypeOf(ir).Size()) +} + +type IndexReader struct { + index *UpsideDownCouch + kvreader store.KVReader + docCount uint64 +} + +func (i *IndexReader) TermFieldReader(ctx context.Context, term []byte, fieldName string, includeFreq, includeNorm, includeTermVectors bool) (index.TermFieldReader, error) { + fieldIndex, fieldExists := i.index.fieldCache.FieldNamed(fieldName, false) + if fieldExists { + return newUpsideDownCouchTermFieldReader(i, term, uint16(fieldIndex), includeFreq, includeNorm, includeTermVectors) + } + return newUpsideDownCouchTermFieldReader(i, []byte{ByteSeparator}, ^uint16(0), includeFreq, includeNorm, includeTermVectors) +} + +func (i *IndexReader) FieldDict(fieldName string) (index.FieldDict, error) { + return i.FieldDictRange(fieldName, nil, nil) +} + +func (i *IndexReader) FieldDictRange(fieldName string, startTerm []byte, endTerm []byte) (index.FieldDict, error) { + fieldIndex, fieldExists := i.index.fieldCache.FieldNamed(fieldName, false) + if fieldExists { + return newUpsideDownCouchFieldDict(i, uint16(fieldIndex), startTerm, endTerm) + } + return newUpsideDownCouchFieldDict(i, ^uint16(0), []byte{ByteSeparator}, []byte{}) +} + +func (i *IndexReader) FieldDictPrefix(fieldName string, termPrefix []byte) (index.FieldDict, error) { + return i.FieldDictRange(fieldName, termPrefix, termPrefix) +} + +func (i *IndexReader) DocIDReaderAll() (index.DocIDReader, error) { + return newUpsideDownCouchDocIDReader(i) +} + +func (i *IndexReader) DocIDReaderOnly(ids []string) (index.DocIDReader, error) { + return newUpsideDownCouchDocIDReaderOnly(i, ids) +} + +func (i *IndexReader) Document(id string) (doc index.Document, err error) { + // first hit the back index to confirm doc exists + var backIndexRow *BackIndexRow + backIndexRow, err = backIndexRowForDoc(i.kvreader, []byte(id)) + if err != nil { + return + } + if backIndexRow == nil { + return + } + rvd := document.NewDocument(id) + storedRow := NewStoredRow([]byte(id), 0, []uint64{}, 'x', nil) + storedRowScanPrefix := storedRow.ScanPrefixForDoc() + it := i.kvreader.PrefixIterator(storedRowScanPrefix) + defer func() { + if cerr := it.Close(); err == nil && cerr != nil { + err = cerr + } + }() + key, val, valid := it.Current() + for valid { + safeVal := make([]byte, len(val)) + copy(safeVal, val) + var row *StoredRow + row, err = NewStoredRowKV(key, safeVal) + if err != nil { + return nil, err + } + if row != nil { + fieldName := i.index.fieldCache.FieldIndexed(row.field) + field := decodeFieldType(row.typ, fieldName, row.arrayPositions, row.value) + if field != nil { + rvd.AddField(field) + } + } + + it.Next() + key, val, valid = it.Current() + } + return rvd, nil +} + +func (i *IndexReader) documentVisitFieldTerms(id index.IndexInternalID, fields []string, visitor index.DocValueVisitor) error { + fieldsMap := make(map[uint16]string, len(fields)) + for _, f := range fields { + id, ok := i.index.fieldCache.FieldNamed(f, false) + if ok { + fieldsMap[id] = f + } + } + + tempRow := BackIndexRow{ + doc: id, + } + + keyBuf := GetRowBuffer() + if tempRow.KeySize() > len(keyBuf) { + keyBuf = make([]byte, 2*tempRow.KeySize()) + } + defer PutRowBuffer(keyBuf) + keySize, err := tempRow.KeyTo(keyBuf) + if err != nil { + return err + } + + value, err := i.kvreader.Get(keyBuf[:keySize]) + if err != nil { + return err + } + if value == nil { + return nil + } + + return visitBackIndexRow(value, func(field uint32, term []byte) { + if field, ok := fieldsMap[uint16(field)]; ok { + visitor(field, term) + } + }) +} + +func (i *IndexReader) Fields() (fields []string, err error) { + fields = make([]string, 0) + it := i.kvreader.PrefixIterator([]byte{'f'}) + defer func() { + if cerr := it.Close(); err == nil && cerr != nil { + err = cerr + } + }() + key, val, valid := it.Current() + for valid { + var row UpsideDownCouchRow + row, err = ParseFromKeyValue(key, val) + if err != nil { + fields = nil + return + } + if row != nil { + fieldRow, ok := row.(*FieldRow) + if ok { + fields = append(fields, fieldRow.name) + } + } + + it.Next() + key, val, valid = it.Current() + } + return +} + +func (i *IndexReader) GetInternal(key []byte) ([]byte, error) { + internalRow := NewInternalRow(key, nil) + return i.kvreader.Get(internalRow.Key()) +} + +func (i *IndexReader) DocCount() (uint64, error) { + return i.docCount, nil +} + +func (i *IndexReader) Close() error { + return i.kvreader.Close() +} + +func (i *IndexReader) ExternalID(id index.IndexInternalID) (string, error) { + return string(id), nil +} + +func (i *IndexReader) InternalID(id string) (index.IndexInternalID, error) { + return index.IndexInternalID(id), nil +} + +func incrementBytes(in []byte) []byte { + rv := make([]byte, len(in)) + copy(rv, in) + for i := len(rv) - 1; i >= 0; i-- { + rv[i] = rv[i] + 1 + if rv[i] != 0 { + // didn't overflow, so stop + break + } + } + return rv +} + +func (i *IndexReader) DocValueReader(fields []string) (index.DocValueReader, error) { + return &DocValueReader{i: i, fields: fields}, nil +} + +type DocValueReader struct { + i *IndexReader + fields []string +} + +func (dvr *DocValueReader) VisitDocValues(id index.IndexInternalID, + visitor index.DocValueVisitor) error { + return dvr.i.documentVisitFieldTerms(id, dvr.fields, visitor) +} + +func (dvr *DocValueReader) BytesRead() uint64 { return 0 } diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/reader.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/reader.go new file mode 100644 index 0000000000..68b15318e1 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/reader.go @@ -0,0 +1,376 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package upsidedown + +import ( + "bytes" + "reflect" + "sort" + "sync/atomic" + + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" + "github.com/blevesearch/upsidedown_store_api" +) + +var reflectStaticSizeUpsideDownCouchTermFieldReader int +var reflectStaticSizeUpsideDownCouchDocIDReader int + +func init() { + var tfr UpsideDownCouchTermFieldReader + reflectStaticSizeUpsideDownCouchTermFieldReader = + int(reflect.TypeOf(tfr).Size()) + var cdr UpsideDownCouchDocIDReader + reflectStaticSizeUpsideDownCouchDocIDReader = + int(reflect.TypeOf(cdr).Size()) +} + +type UpsideDownCouchTermFieldReader struct { + count uint64 + indexReader *IndexReader + iterator store.KVIterator + term []byte + tfrNext *TermFrequencyRow + tfrPrealloc TermFrequencyRow + keyBuf []byte + field uint16 + includeTermVectors bool +} + +func (r *UpsideDownCouchTermFieldReader) Size() int { + sizeInBytes := reflectStaticSizeUpsideDownCouchTermFieldReader + size.SizeOfPtr + + len(r.term) + + r.tfrPrealloc.Size() + + len(r.keyBuf) + + if r.tfrNext != nil { + sizeInBytes += r.tfrNext.Size() + } + + return sizeInBytes +} + +func newUpsideDownCouchTermFieldReader(indexReader *IndexReader, term []byte, field uint16, includeFreq, includeNorm, includeTermVectors bool) (*UpsideDownCouchTermFieldReader, error) { + bufNeeded := termFrequencyRowKeySize(term, nil) + if bufNeeded < dictionaryRowKeySize(term) { + bufNeeded = dictionaryRowKeySize(term) + } + buf := make([]byte, bufNeeded) + + bufUsed := dictionaryRowKeyTo(buf, field, term) + val, err := indexReader.kvreader.Get(buf[:bufUsed]) + if err != nil { + return nil, err + } + if val == nil { + atomic.AddUint64(&indexReader.index.stats.termSearchersStarted, uint64(1)) + rv := &UpsideDownCouchTermFieldReader{ + count: 0, + term: term, + field: field, + includeTermVectors: includeTermVectors, + } + rv.tfrNext = &rv.tfrPrealloc + return rv, nil + } + + count, err := dictionaryRowParseV(val) + if err != nil { + return nil, err + } + + bufUsed = termFrequencyRowKeyTo(buf, field, term, nil) + it := indexReader.kvreader.PrefixIterator(buf[:bufUsed]) + + atomic.AddUint64(&indexReader.index.stats.termSearchersStarted, uint64(1)) + return &UpsideDownCouchTermFieldReader{ + indexReader: indexReader, + iterator: it, + count: count, + term: term, + field: field, + includeTermVectors: includeTermVectors, + }, nil +} + +func (r *UpsideDownCouchTermFieldReader) Count() uint64 { + return r.count +} + +func (r *UpsideDownCouchTermFieldReader) Next(preAlloced *index.TermFieldDoc) (*index.TermFieldDoc, error) { + if r.iterator != nil { + // We treat tfrNext also like an initialization flag, which + // tells us whether we need to invoke the underlying + // iterator.Next(). The first time, don't call iterator.Next(). + if r.tfrNext != nil { + r.iterator.Next() + } else { + r.tfrNext = &r.tfrPrealloc + } + key, val, valid := r.iterator.Current() + if valid { + tfr := r.tfrNext + err := tfr.parseKDoc(key, r.term) + if err != nil { + return nil, err + } + err = tfr.parseV(val, r.includeTermVectors) + if err != nil { + return nil, err + } + rv := preAlloced + if rv == nil { + rv = &index.TermFieldDoc{} + } + rv.ID = append(rv.ID, tfr.doc...) + rv.Freq = tfr.freq + rv.Norm = float64(tfr.norm) + if tfr.vectors != nil { + rv.Vectors = r.indexReader.index.termFieldVectorsFromTermVectors(tfr.vectors) + } + return rv, nil + } + } + return nil, nil +} + +func (r *UpsideDownCouchTermFieldReader) Advance(docID index.IndexInternalID, preAlloced *index.TermFieldDoc) (rv *index.TermFieldDoc, err error) { + if r.iterator != nil { + if r.tfrNext == nil { + r.tfrNext = &TermFrequencyRow{} + } + tfr := InitTermFrequencyRow(r.tfrNext, r.term, r.field, docID, 0, 0) + r.keyBuf, err = tfr.KeyAppendTo(r.keyBuf[:0]) + if err != nil { + return nil, err + } + r.iterator.Seek(r.keyBuf) + key, val, valid := r.iterator.Current() + if valid { + err := tfr.parseKDoc(key, r.term) + if err != nil { + return nil, err + } + err = tfr.parseV(val, r.includeTermVectors) + if err != nil { + return nil, err + } + rv = preAlloced + if rv == nil { + rv = &index.TermFieldDoc{} + } + rv.ID = append(rv.ID, tfr.doc...) + rv.Freq = tfr.freq + rv.Norm = float64(tfr.norm) + if tfr.vectors != nil { + rv.Vectors = r.indexReader.index.termFieldVectorsFromTermVectors(tfr.vectors) + } + return rv, nil + } + } + return nil, nil +} + +func (r *UpsideDownCouchTermFieldReader) Close() error { + if r.indexReader != nil { + atomic.AddUint64(&r.indexReader.index.stats.termSearchersFinished, uint64(1)) + } + if r.iterator != nil { + return r.iterator.Close() + } + return nil +} + +type UpsideDownCouchDocIDReader struct { + indexReader *IndexReader + iterator store.KVIterator + only []string + onlyPos int + onlyMode bool +} + +func (r *UpsideDownCouchDocIDReader) Size() int { + sizeInBytes := reflectStaticSizeUpsideDownCouchDocIDReader + + reflectStaticSizeIndexReader + size.SizeOfPtr + + for _, entry := range r.only { + sizeInBytes += size.SizeOfString + len(entry) + } + + return sizeInBytes +} + +func newUpsideDownCouchDocIDReader(indexReader *IndexReader) (*UpsideDownCouchDocIDReader, error) { + startBytes := []byte{0x0} + endBytes := []byte{0xff} + + bisr := NewBackIndexRow(startBytes, nil, nil) + bier := NewBackIndexRow(endBytes, nil, nil) + it := indexReader.kvreader.RangeIterator(bisr.Key(), bier.Key()) + + return &UpsideDownCouchDocIDReader{ + indexReader: indexReader, + iterator: it, + }, nil +} + +func newUpsideDownCouchDocIDReaderOnly(indexReader *IndexReader, ids []string) (*UpsideDownCouchDocIDReader, error) { + // we don't actually own the list of ids, so if before we sort we must copy + idsCopy := make([]string, len(ids)) + copy(idsCopy, ids) + // ensure ids are sorted + sort.Strings(idsCopy) + startBytes := []byte{0x0} + if len(idsCopy) > 0 { + startBytes = []byte(idsCopy[0]) + } + endBytes := []byte{0xff} + if len(idsCopy) > 0 { + endBytes = incrementBytes([]byte(idsCopy[len(idsCopy)-1])) + } + bisr := NewBackIndexRow(startBytes, nil, nil) + bier := NewBackIndexRow(endBytes, nil, nil) + it := indexReader.kvreader.RangeIterator(bisr.Key(), bier.Key()) + + return &UpsideDownCouchDocIDReader{ + indexReader: indexReader, + iterator: it, + only: idsCopy, + onlyMode: true, + }, nil +} + +func (r *UpsideDownCouchDocIDReader) Next() (index.IndexInternalID, error) { + key, val, valid := r.iterator.Current() + + if r.onlyMode { + var rv index.IndexInternalID + for valid && r.onlyPos < len(r.only) { + br, err := NewBackIndexRowKV(key, val) + if err != nil { + return nil, err + } + if !bytes.Equal(br.doc, []byte(r.only[r.onlyPos])) { + ok := r.nextOnly() + if !ok { + return nil, nil + } + r.iterator.Seek(NewBackIndexRow([]byte(r.only[r.onlyPos]), nil, nil).Key()) + key, val, valid = r.iterator.Current() + continue + } else { + rv = append([]byte(nil), br.doc...) + break + } + } + if valid && r.onlyPos < len(r.only) { + ok := r.nextOnly() + if ok { + r.iterator.Seek(NewBackIndexRow([]byte(r.only[r.onlyPos]), nil, nil).Key()) + } + return rv, nil + } + + } else { + if valid { + br, err := NewBackIndexRowKV(key, val) + if err != nil { + return nil, err + } + rv := append([]byte(nil), br.doc...) + r.iterator.Next() + return rv, nil + } + } + return nil, nil +} + +func (r *UpsideDownCouchDocIDReader) Advance(docID index.IndexInternalID) (index.IndexInternalID, error) { + + if r.onlyMode { + r.onlyPos = sort.SearchStrings(r.only, string(docID)) + if r.onlyPos >= len(r.only) { + // advanced to key after our last only key + return nil, nil + } + r.iterator.Seek(NewBackIndexRow([]byte(r.only[r.onlyPos]), nil, nil).Key()) + key, val, valid := r.iterator.Current() + + var rv index.IndexInternalID + for valid && r.onlyPos < len(r.only) { + br, err := NewBackIndexRowKV(key, val) + if err != nil { + return nil, err + } + if !bytes.Equal(br.doc, []byte(r.only[r.onlyPos])) { + // the only key we seek'd to didn't exist + // now look for the closest key that did exist in only + r.onlyPos = sort.SearchStrings(r.only, string(br.doc)) + if r.onlyPos >= len(r.only) { + // advanced to key after our last only key + return nil, nil + } + // now seek to this new only key + r.iterator.Seek(NewBackIndexRow([]byte(r.only[r.onlyPos]), nil, nil).Key()) + key, val, valid = r.iterator.Current() + continue + } else { + rv = append([]byte(nil), br.doc...) + break + } + } + if valid && r.onlyPos < len(r.only) { + ok := r.nextOnly() + if ok { + r.iterator.Seek(NewBackIndexRow([]byte(r.only[r.onlyPos]), nil, nil).Key()) + } + return rv, nil + } + } else { + bir := NewBackIndexRow(docID, nil, nil) + r.iterator.Seek(bir.Key()) + key, val, valid := r.iterator.Current() + if valid { + br, err := NewBackIndexRowKV(key, val) + if err != nil { + return nil, err + } + rv := append([]byte(nil), br.doc...) + r.iterator.Next() + return rv, nil + } + } + return nil, nil +} + +func (r *UpsideDownCouchDocIDReader) Close() error { + return r.iterator.Close() +} + +// move the r.only pos forward one, skipping duplicates +// return true if there is more data, or false if we got to the end of the list +func (r *UpsideDownCouchDocIDReader) nextOnly() bool { + + // advance 1 position, until we see a different key + // it's already sorted, so this skips duplicates + start := r.onlyPos + r.onlyPos++ + for r.onlyPos < len(r.only) && r.only[r.onlyPos] == r.only[start] { + start = r.onlyPos + r.onlyPos++ + } + // inidicate if we got to the end of the list + return r.onlyPos < len(r.only) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/row.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/row.go new file mode 100644 index 0000000000..901a4bcb06 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/row.go @@ -0,0 +1,1141 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package upsidedown + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" + "math" + "reflect" + + "github.com/blevesearch/bleve/v2/size" + "github.com/golang/protobuf/proto" +) + +var reflectStaticSizeTermFrequencyRow int +var reflectStaticSizeTermVector int + +func init() { + var tfr TermFrequencyRow + reflectStaticSizeTermFrequencyRow = int(reflect.TypeOf(tfr).Size()) + var tv TermVector + reflectStaticSizeTermVector = int(reflect.TypeOf(tv).Size()) +} + +const ByteSeparator byte = 0xff + +type UpsideDownCouchRowStream chan UpsideDownCouchRow + +type UpsideDownCouchRow interface { + KeySize() int + KeyTo([]byte) (int, error) + Key() []byte + Value() []byte + ValueSize() int + ValueTo([]byte) (int, error) +} + +func ParseFromKeyValue(key, value []byte) (UpsideDownCouchRow, error) { + if len(key) > 0 { + switch key[0] { + case 'v': + return NewVersionRowKV(key, value) + case 'f': + return NewFieldRowKV(key, value) + case 'd': + return NewDictionaryRowKV(key, value) + case 't': + return NewTermFrequencyRowKV(key, value) + case 'b': + return NewBackIndexRowKV(key, value) + case 's': + return NewStoredRowKV(key, value) + case 'i': + return NewInternalRowKV(key, value) + } + return nil, fmt.Errorf("Unknown field type '%s'", string(key[0])) + } + return nil, fmt.Errorf("Invalid empty key") +} + +// VERSION + +type VersionRow struct { + version uint8 +} + +func (v *VersionRow) Key() []byte { + return []byte{'v'} +} + +func (v *VersionRow) KeySize() int { + return 1 +} + +func (v *VersionRow) KeyTo(buf []byte) (int, error) { + buf[0] = 'v' + return 1, nil +} + +func (v *VersionRow) Value() []byte { + return []byte{byte(v.version)} +} + +func (v *VersionRow) ValueSize() int { + return 1 +} + +func (v *VersionRow) ValueTo(buf []byte) (int, error) { + buf[0] = v.version + return 1, nil +} + +func (v *VersionRow) String() string { + return fmt.Sprintf("Version: %d", v.version) +} + +func NewVersionRow(version uint8) *VersionRow { + return &VersionRow{ + version: version, + } +} + +func NewVersionRowKV(key, value []byte) (*VersionRow, error) { + rv := VersionRow{} + buf := bytes.NewBuffer(value) + err := binary.Read(buf, binary.LittleEndian, &rv.version) + if err != nil { + return nil, err + } + return &rv, nil +} + +// INTERNAL STORAGE + +type InternalRow struct { + key []byte + val []byte +} + +func (i *InternalRow) Key() []byte { + buf := make([]byte, i.KeySize()) + size, _ := i.KeyTo(buf) + return buf[:size] +} + +func (i *InternalRow) KeySize() int { + return len(i.key) + 1 +} + +func (i *InternalRow) KeyTo(buf []byte) (int, error) { + buf[0] = 'i' + actual := copy(buf[1:], i.key) + return 1 + actual, nil +} + +func (i *InternalRow) Value() []byte { + return i.val +} + +func (i *InternalRow) ValueSize() int { + return len(i.val) +} + +func (i *InternalRow) ValueTo(buf []byte) (int, error) { + actual := copy(buf, i.val) + return actual, nil +} + +func (i *InternalRow) String() string { + return fmt.Sprintf("InternalStore - Key: %s (% x) Val: %s (% x)", i.key, i.key, i.val, i.val) +} + +func NewInternalRow(key, val []byte) *InternalRow { + return &InternalRow{ + key: key, + val: val, + } +} + +func NewInternalRowKV(key, value []byte) (*InternalRow, error) { + rv := InternalRow{} + rv.key = key[1:] + rv.val = value + return &rv, nil +} + +// FIELD definition + +type FieldRow struct { + index uint16 + name string +} + +func (f *FieldRow) Key() []byte { + buf := make([]byte, f.KeySize()) + size, _ := f.KeyTo(buf) + return buf[:size] +} + +func (f *FieldRow) KeySize() int { + return 3 +} + +func (f *FieldRow) KeyTo(buf []byte) (int, error) { + buf[0] = 'f' + binary.LittleEndian.PutUint16(buf[1:3], f.index) + return 3, nil +} + +func (f *FieldRow) Value() []byte { + return append([]byte(f.name), ByteSeparator) +} + +func (f *FieldRow) ValueSize() int { + return len(f.name) + 1 +} + +func (f *FieldRow) ValueTo(buf []byte) (int, error) { + size := copy(buf, f.name) + buf[size] = ByteSeparator + return size + 1, nil +} + +func (f *FieldRow) String() string { + return fmt.Sprintf("Field: %d Name: %s", f.index, f.name) +} + +func NewFieldRow(index uint16, name string) *FieldRow { + return &FieldRow{ + index: index, + name: name, + } +} + +func NewFieldRowKV(key, value []byte) (*FieldRow, error) { + rv := FieldRow{} + + buf := bytes.NewBuffer(key) + _, err := buf.ReadByte() // type + if err != nil { + return nil, err + } + err = binary.Read(buf, binary.LittleEndian, &rv.index) + if err != nil { + return nil, err + } + + buf = bytes.NewBuffer(value) + rv.name, err = buf.ReadString(ByteSeparator) + if err != nil { + return nil, err + } + rv.name = rv.name[:len(rv.name)-1] // trim off separator byte + + return &rv, nil +} + +// DICTIONARY + +const DictionaryRowMaxValueSize = binary.MaxVarintLen64 + +type DictionaryRow struct { + term []byte + count uint64 + field uint16 +} + +func (dr *DictionaryRow) Key() []byte { + buf := make([]byte, dr.KeySize()) + size, _ := dr.KeyTo(buf) + return buf[:size] +} + +func (dr *DictionaryRow) KeySize() int { + return dictionaryRowKeySize(dr.term) +} + +func dictionaryRowKeySize(term []byte) int { + return len(term) + 3 +} + +func (dr *DictionaryRow) KeyTo(buf []byte) (int, error) { + return dictionaryRowKeyTo(buf, dr.field, dr.term), nil +} + +func dictionaryRowKeyTo(buf []byte, field uint16, term []byte) int { + buf[0] = 'd' + binary.LittleEndian.PutUint16(buf[1:3], field) + size := copy(buf[3:], term) + return size + 3 +} + +func (dr *DictionaryRow) Value() []byte { + buf := make([]byte, dr.ValueSize()) + size, _ := dr.ValueTo(buf) + return buf[:size] +} + +func (dr *DictionaryRow) ValueSize() int { + return DictionaryRowMaxValueSize +} + +func (dr *DictionaryRow) ValueTo(buf []byte) (int, error) { + used := binary.PutUvarint(buf, dr.count) + return used, nil +} + +func (dr *DictionaryRow) String() string { + return fmt.Sprintf("Dictionary Term: `%s` Field: %d Count: %d ", string(dr.term), dr.field, dr.count) +} + +func NewDictionaryRow(term []byte, field uint16, count uint64) *DictionaryRow { + return &DictionaryRow{ + term: term, + field: field, + count: count, + } +} + +func NewDictionaryRowKV(key, value []byte) (*DictionaryRow, error) { + rv, err := NewDictionaryRowK(key) + if err != nil { + return nil, err + } + + err = rv.parseDictionaryV(value) + if err != nil { + return nil, err + } + return rv, nil + +} + +func NewDictionaryRowK(key []byte) (*DictionaryRow, error) { + rv := &DictionaryRow{} + err := rv.parseDictionaryK(key) + if err != nil { + return nil, err + } + return rv, nil +} + +func (dr *DictionaryRow) parseDictionaryK(key []byte) error { + dr.field = binary.LittleEndian.Uint16(key[1:3]) + if dr.term != nil { + dr.term = dr.term[:0] + } + dr.term = append(dr.term, key[3:]...) + return nil +} + +func (dr *DictionaryRow) parseDictionaryV(value []byte) error { + count, err := dictionaryRowParseV(value) + if err != nil { + return err + } + dr.count = count + return nil +} + +func dictionaryRowParseV(value []byte) (uint64, error) { + count, nread := binary.Uvarint(value) + if nread <= 0 { + return 0, fmt.Errorf("DictionaryRow parse Uvarint error, nread: %d", nread) + } + return count, nil +} + +// TERM FIELD FREQUENCY + +type TermVector struct { + field uint16 + arrayPositions []uint64 + pos uint64 + start uint64 + end uint64 +} + +func (tv *TermVector) Size() int { + return reflectStaticSizeTermVector + size.SizeOfPtr + + len(tv.arrayPositions)*size.SizeOfUint64 +} + +func (tv *TermVector) String() string { + return fmt.Sprintf("Field: %d Pos: %d Start: %d End %d ArrayPositions: %#v", tv.field, tv.pos, tv.start, tv.end, tv.arrayPositions) +} + +type TermFrequencyRow struct { + term []byte + doc []byte + freq uint64 + vectors []*TermVector + norm float32 + field uint16 +} + +func (tfr *TermFrequencyRow) Size() int { + sizeInBytes := reflectStaticSizeTermFrequencyRow + + len(tfr.term) + + len(tfr.doc) + + for _, entry := range tfr.vectors { + sizeInBytes += entry.Size() + } + + return sizeInBytes +} + +func (tfr *TermFrequencyRow) Term() []byte { + return tfr.term +} + +func (tfr *TermFrequencyRow) Freq() uint64 { + return tfr.freq +} + +func (tfr *TermFrequencyRow) ScanPrefixForField() []byte { + buf := make([]byte, 3) + buf[0] = 't' + binary.LittleEndian.PutUint16(buf[1:3], tfr.field) + return buf +} + +func (tfr *TermFrequencyRow) ScanPrefixForFieldTermPrefix() []byte { + buf := make([]byte, 3+len(tfr.term)) + buf[0] = 't' + binary.LittleEndian.PutUint16(buf[1:3], tfr.field) + copy(buf[3:], tfr.term) + return buf +} + +func (tfr *TermFrequencyRow) ScanPrefixForFieldTerm() []byte { + buf := make([]byte, 3+len(tfr.term)+1) + buf[0] = 't' + binary.LittleEndian.PutUint16(buf[1:3], tfr.field) + termLen := copy(buf[3:], tfr.term) + buf[3+termLen] = ByteSeparator + return buf +} + +func (tfr *TermFrequencyRow) Key() []byte { + buf := make([]byte, tfr.KeySize()) + size, _ := tfr.KeyTo(buf) + return buf[:size] +} + +func (tfr *TermFrequencyRow) KeySize() int { + return termFrequencyRowKeySize(tfr.term, tfr.doc) +} + +func termFrequencyRowKeySize(term, doc []byte) int { + return 3 + len(term) + 1 + len(doc) +} + +func (tfr *TermFrequencyRow) KeyTo(buf []byte) (int, error) { + return termFrequencyRowKeyTo(buf, tfr.field, tfr.term, tfr.doc), nil +} + +func termFrequencyRowKeyTo(buf []byte, field uint16, term, doc []byte) int { + buf[0] = 't' + binary.LittleEndian.PutUint16(buf[1:3], field) + termLen := copy(buf[3:], term) + buf[3+termLen] = ByteSeparator + docLen := copy(buf[3+termLen+1:], doc) + return 3 + termLen + 1 + docLen +} + +func (tfr *TermFrequencyRow) KeyAppendTo(buf []byte) ([]byte, error) { + keySize := tfr.KeySize() + if cap(buf) < keySize { + buf = make([]byte, keySize) + } + actualSize, err := tfr.KeyTo(buf[0:keySize]) + return buf[0:actualSize], err +} + +func (tfr *TermFrequencyRow) DictionaryRowKey() []byte { + dr := NewDictionaryRow(tfr.term, tfr.field, 0) + return dr.Key() +} + +func (tfr *TermFrequencyRow) DictionaryRowKeySize() int { + dr := NewDictionaryRow(tfr.term, tfr.field, 0) + return dr.KeySize() +} + +func (tfr *TermFrequencyRow) DictionaryRowKeyTo(buf []byte) (int, error) { + dr := NewDictionaryRow(tfr.term, tfr.field, 0) + return dr.KeyTo(buf) +} + +func (tfr *TermFrequencyRow) Value() []byte { + buf := make([]byte, tfr.ValueSize()) + size, _ := tfr.ValueTo(buf) + return buf[:size] +} + +func (tfr *TermFrequencyRow) ValueSize() int { + bufLen := binary.MaxVarintLen64 + binary.MaxVarintLen64 + for _, vector := range tfr.vectors { + bufLen += (binary.MaxVarintLen64 * 4) + (1+len(vector.arrayPositions))*binary.MaxVarintLen64 + } + return bufLen +} + +func (tfr *TermFrequencyRow) ValueTo(buf []byte) (int, error) { + used := binary.PutUvarint(buf[:binary.MaxVarintLen64], tfr.freq) + + normuint32 := math.Float32bits(tfr.norm) + newbuf := buf[used : used+binary.MaxVarintLen64] + used += binary.PutUvarint(newbuf, uint64(normuint32)) + + for _, vector := range tfr.vectors { + used += binary.PutUvarint(buf[used:used+binary.MaxVarintLen64], uint64(vector.field)) + used += binary.PutUvarint(buf[used:used+binary.MaxVarintLen64], vector.pos) + used += binary.PutUvarint(buf[used:used+binary.MaxVarintLen64], vector.start) + used += binary.PutUvarint(buf[used:used+binary.MaxVarintLen64], vector.end) + used += binary.PutUvarint(buf[used:used+binary.MaxVarintLen64], uint64(len(vector.arrayPositions))) + for _, arrayPosition := range vector.arrayPositions { + used += binary.PutUvarint(buf[used:used+binary.MaxVarintLen64], arrayPosition) + } + } + return used, nil +} + +func (tfr *TermFrequencyRow) String() string { + return fmt.Sprintf("Term: `%s` Field: %d DocId: `%s` Frequency: %d Norm: %f Vectors: %v", string(tfr.term), tfr.field, string(tfr.doc), tfr.freq, tfr.norm, tfr.vectors) +} + +func InitTermFrequencyRow(tfr *TermFrequencyRow, term []byte, field uint16, docID []byte, freq uint64, norm float32) *TermFrequencyRow { + tfr.term = term + tfr.field = field + tfr.doc = docID + tfr.freq = freq + tfr.norm = norm + return tfr +} + +func NewTermFrequencyRow(term []byte, field uint16, docID []byte, freq uint64, norm float32) *TermFrequencyRow { + return &TermFrequencyRow{ + term: term, + field: field, + doc: docID, + freq: freq, + norm: norm, + } +} + +func NewTermFrequencyRowWithTermVectors(term []byte, field uint16, docID []byte, freq uint64, norm float32, vectors []*TermVector) *TermFrequencyRow { + return &TermFrequencyRow{ + term: term, + field: field, + doc: docID, + freq: freq, + norm: norm, + vectors: vectors, + } +} + +func NewTermFrequencyRowK(key []byte) (*TermFrequencyRow, error) { + rv := &TermFrequencyRow{} + err := rv.parseK(key) + if err != nil { + return nil, err + } + return rv, nil +} + +func (tfr *TermFrequencyRow) parseK(key []byte) error { + keyLen := len(key) + if keyLen < 3 { + return fmt.Errorf("invalid term frequency key, no valid field") + } + tfr.field = binary.LittleEndian.Uint16(key[1:3]) + + termEndPos := bytes.IndexByte(key[3:], ByteSeparator) + if termEndPos < 0 { + return fmt.Errorf("invalid term frequency key, no byte separator terminating term") + } + tfr.term = key[3 : 3+termEndPos] + + docLen := keyLen - (3 + termEndPos + 1) + if docLen < 1 { + return fmt.Errorf("invalid term frequency key, empty docid") + } + tfr.doc = key[3+termEndPos+1:] + + return nil +} + +func (tfr *TermFrequencyRow) parseKDoc(key []byte, term []byte) error { + tfr.doc = key[3+len(term)+1:] + if len(tfr.doc) == 0 { + return fmt.Errorf("invalid term frequency key, empty docid") + } + + return nil +} + +func (tfr *TermFrequencyRow) parseV(value []byte, includeTermVectors bool) error { + var bytesRead int + tfr.freq, bytesRead = binary.Uvarint(value) + if bytesRead <= 0 { + return fmt.Errorf("invalid term frequency value, invalid frequency") + } + currOffset := bytesRead + + var norm uint64 + norm, bytesRead = binary.Uvarint(value[currOffset:]) + if bytesRead <= 0 { + return fmt.Errorf("invalid term frequency value, no norm") + } + currOffset += bytesRead + + tfr.norm = math.Float32frombits(uint32(norm)) + + tfr.vectors = nil + if !includeTermVectors { + return nil + } + + var field uint64 + field, bytesRead = binary.Uvarint(value[currOffset:]) + for bytesRead > 0 { + currOffset += bytesRead + tv := TermVector{} + tv.field = uint16(field) + // at this point we expect at least one term vector + if tfr.vectors == nil { + tfr.vectors = make([]*TermVector, 0) + } + + tv.pos, bytesRead = binary.Uvarint(value[currOffset:]) + if bytesRead <= 0 { + return fmt.Errorf("invalid term frequency value, vector contains no position") + } + currOffset += bytesRead + + tv.start, bytesRead = binary.Uvarint(value[currOffset:]) + if bytesRead <= 0 { + return fmt.Errorf("invalid term frequency value, vector contains no start") + } + currOffset += bytesRead + + tv.end, bytesRead = binary.Uvarint(value[currOffset:]) + if bytesRead <= 0 { + return fmt.Errorf("invalid term frequency value, vector contains no end") + } + currOffset += bytesRead + + var arrayPositionsLen uint64 = 0 + arrayPositionsLen, bytesRead = binary.Uvarint(value[currOffset:]) + if bytesRead <= 0 { + return fmt.Errorf("invalid term frequency value, vector contains no arrayPositionLen") + } + currOffset += bytesRead + + if arrayPositionsLen > 0 { + tv.arrayPositions = make([]uint64, arrayPositionsLen) + for i := 0; uint64(i) < arrayPositionsLen; i++ { + tv.arrayPositions[i], bytesRead = binary.Uvarint(value[currOffset:]) + if bytesRead <= 0 { + return fmt.Errorf("invalid term frequency value, vector contains no arrayPosition of index %d", i) + } + currOffset += bytesRead + } + } + + tfr.vectors = append(tfr.vectors, &tv) + // try to read next record (may not exist) + field, bytesRead = binary.Uvarint(value[currOffset:]) + } + if len(value[currOffset:]) > 0 && bytesRead <= 0 { + return fmt.Errorf("invalid term frequency value, vector field invalid") + } + + return nil +} + +func NewTermFrequencyRowKV(key, value []byte) (*TermFrequencyRow, error) { + rv, err := NewTermFrequencyRowK(key) + if err != nil { + return nil, err + } + + err = rv.parseV(value, true) + if err != nil { + return nil, err + } + return rv, nil + +} + +type BackIndexRow struct { + doc []byte + termsEntries []*BackIndexTermsEntry + storedEntries []*BackIndexStoreEntry +} + +func (br *BackIndexRow) AllTermKeys() [][]byte { + if br == nil { + return nil + } + rv := make([][]byte, 0, len(br.termsEntries)) // FIXME this underestimates severely + for _, termsEntry := range br.termsEntries { + for i := range termsEntry.Terms { + termRow := NewTermFrequencyRow([]byte(termsEntry.Terms[i]), uint16(termsEntry.GetField()), br.doc, 0, 0) + rv = append(rv, termRow.Key()) + } + } + return rv +} + +func (br *BackIndexRow) AllStoredKeys() [][]byte { + if br == nil { + return nil + } + rv := make([][]byte, len(br.storedEntries)) + for i, storedEntry := range br.storedEntries { + storedRow := NewStoredRow(br.doc, uint16(storedEntry.GetField()), storedEntry.GetArrayPositions(), 'x', []byte{}) + rv[i] = storedRow.Key() + } + return rv +} + +func (br *BackIndexRow) Key() []byte { + buf := make([]byte, br.KeySize()) + size, _ := br.KeyTo(buf) + return buf[:size] +} + +func (br *BackIndexRow) KeySize() int { + return len(br.doc) + 1 +} + +func (br *BackIndexRow) KeyTo(buf []byte) (int, error) { + buf[0] = 'b' + used := copy(buf[1:], br.doc) + return used + 1, nil +} + +func (br *BackIndexRow) Value() []byte { + buf := make([]byte, br.ValueSize()) + size, _ := br.ValueTo(buf) + return buf[:size] +} + +func (br *BackIndexRow) ValueSize() int { + birv := &BackIndexRowValue{ + TermsEntries: br.termsEntries, + StoredEntries: br.storedEntries, + } + return birv.Size() +} + +func (br *BackIndexRow) ValueTo(buf []byte) (int, error) { + birv := &BackIndexRowValue{ + TermsEntries: br.termsEntries, + StoredEntries: br.storedEntries, + } + return birv.MarshalTo(buf) +} + +func (br *BackIndexRow) String() string { + return fmt.Sprintf("Backindex DocId: `%s` Terms Entries: %v, Stored Entries: %v", string(br.doc), br.termsEntries, br.storedEntries) +} + +func NewBackIndexRow(docID []byte, entries []*BackIndexTermsEntry, storedFields []*BackIndexStoreEntry) *BackIndexRow { + return &BackIndexRow{ + doc: docID, + termsEntries: entries, + storedEntries: storedFields, + } +} + +func NewBackIndexRowKV(key, value []byte) (*BackIndexRow, error) { + rv := BackIndexRow{} + + buf := bytes.NewBuffer(key) + _, err := buf.ReadByte() // type + if err != nil { + return nil, err + } + + rv.doc, err = buf.ReadBytes(ByteSeparator) + if err == io.EOF && len(rv.doc) < 1 { + err = fmt.Errorf("invalid doc length 0 - % x", key) + } + if err != nil && err != io.EOF { + return nil, err + } else if err == nil { + rv.doc = rv.doc[:len(rv.doc)-1] // trim off separator byte + } + + var birv BackIndexRowValue + err = proto.Unmarshal(value, &birv) + if err != nil { + return nil, err + } + rv.termsEntries = birv.TermsEntries + rv.storedEntries = birv.StoredEntries + + return &rv, nil +} + +// STORED + +type StoredRow struct { + doc []byte + field uint16 + arrayPositions []uint64 + typ byte + value []byte +} + +func (s *StoredRow) Key() []byte { + buf := make([]byte, s.KeySize()) + size, _ := s.KeyTo(buf) + return buf[0:size] +} + +func (s *StoredRow) KeySize() int { + return 1 + len(s.doc) + 1 + 2 + (binary.MaxVarintLen64 * len(s.arrayPositions)) +} + +func (s *StoredRow) KeyTo(buf []byte) (int, error) { + docLen := len(s.doc) + buf[0] = 's' + copy(buf[1:], s.doc) + buf[1+docLen] = ByteSeparator + binary.LittleEndian.PutUint16(buf[1+docLen+1:], s.field) + bytesUsed := 1 + docLen + 1 + 2 + for _, arrayPosition := range s.arrayPositions { + varbytes := binary.PutUvarint(buf[bytesUsed:], arrayPosition) + bytesUsed += varbytes + } + return bytesUsed, nil +} + +func (s *StoredRow) Value() []byte { + buf := make([]byte, s.ValueSize()) + size, _ := s.ValueTo(buf) + return buf[:size] +} + +func (s *StoredRow) ValueSize() int { + return len(s.value) + 1 +} + +func (s *StoredRow) ValueTo(buf []byte) (int, error) { + buf[0] = s.typ + used := copy(buf[1:], s.value) + return used + 1, nil +} + +func (s *StoredRow) String() string { + return fmt.Sprintf("Document: %s Field %d, Array Positions: %v, Type: %s Value: %s", s.doc, s.field, s.arrayPositions, string(s.typ), s.value) +} + +func (s *StoredRow) ScanPrefixForDoc() []byte { + docLen := len(s.doc) + buf := make([]byte, 1+docLen+1) + buf[0] = 's' + copy(buf[1:], s.doc) + buf[1+docLen] = ByteSeparator + return buf +} + +func NewStoredRow(docID []byte, field uint16, arrayPositions []uint64, typ byte, value []byte) *StoredRow { + return &StoredRow{ + doc: docID, + field: field, + arrayPositions: arrayPositions, + typ: typ, + value: value, + } +} + +func NewStoredRowK(key []byte) (*StoredRow, error) { + rv := StoredRow{} + + buf := bytes.NewBuffer(key) + _, err := buf.ReadByte() // type + if err != nil { + return nil, err + } + + rv.doc, err = buf.ReadBytes(ByteSeparator) + if len(rv.doc) < 2 { // 1 for min doc id length, 1 for separator + err = fmt.Errorf("invalid doc length 0") + return nil, err + } + + rv.doc = rv.doc[:len(rv.doc)-1] // trim off separator byte + + err = binary.Read(buf, binary.LittleEndian, &rv.field) + if err != nil { + return nil, err + } + + rv.arrayPositions = make([]uint64, 0) + nextArrayPos, err := binary.ReadUvarint(buf) + for err == nil { + rv.arrayPositions = append(rv.arrayPositions, nextArrayPos) + nextArrayPos, err = binary.ReadUvarint(buf) + } + return &rv, nil +} + +func NewStoredRowKV(key, value []byte) (*StoredRow, error) { + rv, err := NewStoredRowK(key) + if err != nil { + return nil, err + } + rv.typ = value[0] + rv.value = value[1:] + return rv, nil +} + +type backIndexFieldTermVisitor func(field uint32, term []byte) + +// visitBackIndexRow is designed to process a protobuf encoded +// value, without creating unnecessary garbage. Instead values are passed +// to a callback, inspected first, and only copied if necessary. +// Due to the fact that this borrows from generated code, it must be marnually +// updated if the protobuf definition changes. +// +// This code originates from: +// func (m *BackIndexRowValue) Unmarshal(data []byte) error +// the sections which create garbage or parse unintersting sections +// have been commented out. This was done by design to allow for easier +// merging in the future if that original function is regenerated +func visitBackIndexRow(data []byte, callback backIndexFieldTermVisitor) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TermsEntries", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + postIndex := iNdEx + msglen + if msglen < 0 { + return ErrInvalidLengthUpsidedown + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + // dont parse term entries + // m.TermsEntries = append(m.TermsEntries, &BackIndexTermsEntry{}) + // if err := m.TermsEntries[len(m.TermsEntries)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + // return err + // } + // instead, inspect them + if err := visitBackIndexRowFieldTerms(data[iNdEx:postIndex], callback); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StoredEntries", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + postIndex := iNdEx + msglen + if msglen < 0 { + return ErrInvalidLengthUpsidedown + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + // don't parse stored entries + // m.StoredEntries = append(m.StoredEntries, &BackIndexStoreEntry{}) + // if err := m.StoredEntries[len(m.StoredEntries)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + // return err + // } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipUpsidedown(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthUpsidedown + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + // don't track unrecognized data + //m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + return nil +} + +// visitBackIndexRowFieldTerms is designed to process a protobuf encoded +// sub-value within the BackIndexRowValue, without creating unnecessary garbage. +// Instead values are passed to a callback, inspected first, and only copied if +// necessary. Due to the fact that this borrows from generated code, it must +// be marnually updated if the protobuf definition changes. +// +// This code originates from: +// func (m *BackIndexTermsEntry) Unmarshal(data []byte) error { +// the sections which create garbage or parse uninteresting sections +// have been commented out. This was done by design to allow for easier +// merging in the future if that original function is regenerated +func visitBackIndexRowFieldTerms(data []byte, callback backIndexFieldTermVisitor) error { + var theField uint32 + + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Field", wireType) + } + var v uint32 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + // m.Field = &v + theField = v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Terms", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + postIndex := iNdEx + int(stringLen) + if postIndex > l { + return io.ErrUnexpectedEOF + } + //m.Terms = append(m.Terms, string(data[iNdEx:postIndex])) + callback(theField, data[iNdEx:postIndex]) + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipUpsidedown(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthUpsidedown + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + //m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + // if hasFields[0]&uint64(0x00000001) == 0 { + // return new(github_com_golang_protobuf_proto.RequiredNotSetError) + // } + + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/row_merge.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/row_merge.go new file mode 100644 index 0000000000..39172ade66 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/row_merge.go @@ -0,0 +1,76 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package upsidedown + +import ( + "encoding/binary" +) + +var mergeOperator upsideDownMerge + +var dictionaryTermIncr []byte +var dictionaryTermDecr []byte + +func init() { + dictionaryTermIncr = make([]byte, 8) + binary.LittleEndian.PutUint64(dictionaryTermIncr, uint64(1)) + dictionaryTermDecr = make([]byte, 8) + var negOne = int64(-1) + binary.LittleEndian.PutUint64(dictionaryTermDecr, uint64(negOne)) +} + +type upsideDownMerge struct{} + +func (m *upsideDownMerge) FullMerge(key, existingValue []byte, operands [][]byte) ([]byte, bool) { + // set up record based on key + dr, err := NewDictionaryRowK(key) + if err != nil { + return nil, false + } + if len(existingValue) > 0 { + // if existing value, parse it + err = dr.parseDictionaryV(existingValue) + if err != nil { + return nil, false + } + } + + // now process operands + for _, operand := range operands { + next := int64(binary.LittleEndian.Uint64(operand)) + if next < 0 && uint64(-next) > dr.count { + // subtracting next from existing would overflow + dr.count = 0 + } else if next < 0 { + dr.count -= uint64(-next) + } else { + dr.count += uint64(next) + } + } + + return dr.Value(), true +} + +func (m *upsideDownMerge) PartialMerge(key, leftOperand, rightOperand []byte) ([]byte, bool) { + left := int64(binary.LittleEndian.Uint64(leftOperand)) + right := int64(binary.LittleEndian.Uint64(rightOperand)) + rv := make([]byte, 8) + binary.LittleEndian.PutUint64(rv, uint64(left+right)) + return rv, true +} + +func (m *upsideDownMerge) Name() string { + return "upsideDownMerge" +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/stats.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/stats.go new file mode 100644 index 0000000000..c1b4ddc018 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/stats.go @@ -0,0 +1,55 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package upsidedown + +import ( + "encoding/json" + "sync/atomic" + + "github.com/blevesearch/upsidedown_store_api" +) + +type indexStat struct { + updates, deletes, batches, errors uint64 + analysisTime, indexTime uint64 + termSearchersStarted uint64 + termSearchersFinished uint64 + numPlainTextBytesIndexed uint64 + i *UpsideDownCouch +} + +func (i *indexStat) statsMap() map[string]interface{} { + m := map[string]interface{}{} + m["updates"] = atomic.LoadUint64(&i.updates) + m["deletes"] = atomic.LoadUint64(&i.deletes) + m["batches"] = atomic.LoadUint64(&i.batches) + m["errors"] = atomic.LoadUint64(&i.errors) + m["analysis_time"] = atomic.LoadUint64(&i.analysisTime) + m["index_time"] = atomic.LoadUint64(&i.indexTime) + m["term_searchers_started"] = atomic.LoadUint64(&i.termSearchersStarted) + m["term_searchers_finished"] = atomic.LoadUint64(&i.termSearchersFinished) + m["num_plain_text_bytes_indexed"] = atomic.LoadUint64(&i.numPlainTextBytesIndexed) + + if o, ok := i.i.store.(store.KVStoreStats); ok { + m["kv"] = o.StatsMap() + } + + return m +} + +func (i *indexStat) MarshalJSON() ([]byte, error) { + m := i.statsMap() + return json.Marshal(m) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/iterator.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/iterator.go new file mode 100644 index 0000000000..cf4da87c35 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/iterator.go @@ -0,0 +1,85 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package boltdb + +import ( + "bytes" + + bolt "go.etcd.io/bbolt" +) + +type Iterator struct { + store *Store + tx *bolt.Tx + cursor *bolt.Cursor + prefix []byte + start []byte + end []byte + valid bool + key []byte + val []byte +} + +func (i *Iterator) updateValid() { + i.valid = (i.key != nil) + if i.valid { + if i.prefix != nil { + i.valid = bytes.HasPrefix(i.key, i.prefix) + } else if i.end != nil { + i.valid = bytes.Compare(i.key, i.end) < 0 + } + } +} + +func (i *Iterator) Seek(k []byte) { + if i.start != nil && bytes.Compare(k, i.start) < 0 { + k = i.start + } + if i.prefix != nil && !bytes.HasPrefix(k, i.prefix) { + if bytes.Compare(k, i.prefix) < 0 { + k = i.prefix + } else { + i.valid = false + return + } + } + i.key, i.val = i.cursor.Seek(k) + i.updateValid() +} + +func (i *Iterator) Next() { + i.key, i.val = i.cursor.Next() + i.updateValid() +} + +func (i *Iterator) Current() ([]byte, []byte, bool) { + return i.key, i.val, i.valid +} + +func (i *Iterator) Key() []byte { + return i.key +} + +func (i *Iterator) Value() []byte { + return i.val +} + +func (i *Iterator) Valid() bool { + return i.valid +} + +func (i *Iterator) Close() error { + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/reader.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/reader.go new file mode 100644 index 0000000000..79513f600c --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/reader.go @@ -0,0 +1,73 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package boltdb + +import ( + store "github.com/blevesearch/upsidedown_store_api" + bolt "go.etcd.io/bbolt" +) + +type Reader struct { + store *Store + tx *bolt.Tx + bucket *bolt.Bucket +} + +func (r *Reader) Get(key []byte) ([]byte, error) { + var rv []byte + v := r.bucket.Get(key) + if v != nil { + rv = make([]byte, len(v)) + copy(rv, v) + } + return rv, nil +} + +func (r *Reader) MultiGet(keys [][]byte) ([][]byte, error) { + return store.MultiGet(r, keys) +} + +func (r *Reader) PrefixIterator(prefix []byte) store.KVIterator { + cursor := r.bucket.Cursor() + + rv := &Iterator{ + store: r.store, + tx: r.tx, + cursor: cursor, + prefix: prefix, + } + + rv.Seek(prefix) + return rv +} + +func (r *Reader) RangeIterator(start, end []byte) store.KVIterator { + cursor := r.bucket.Cursor() + + rv := &Iterator{ + store: r.store, + tx: r.tx, + cursor: cursor, + start: start, + end: end, + } + + rv.Seek(start) + return rv +} + +func (r *Reader) Close() error { + return r.tx.Rollback() +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/stats.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/stats.go new file mode 100644 index 0000000000..e50e552745 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/stats.go @@ -0,0 +1,26 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package boltdb + +import "encoding/json" + +type stats struct { + s *Store +} + +func (s *stats) MarshalJSON() ([]byte, error) { + bs := s.s.db.Stats() + return json.Marshal(bs) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/store.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/store.go new file mode 100644 index 0000000000..bc99275e17 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/store.go @@ -0,0 +1,181 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package boltdb implements a store.KVStore on top of BoltDB. It supports the +// following options: +// +// "bucket" (string): the name of BoltDB bucket to use, defaults to "bleve". +// +// "nosync" (bool): if true, set boltdb.DB.NoSync to true. It speeds up index +// operations in exchange of losing integrity guarantees if indexation aborts +// without closing the index. Use it when rebuilding indexes from zero. +package boltdb + +import ( + "bytes" + "encoding/json" + "fmt" + "os" + + "github.com/blevesearch/bleve/v2/registry" + store "github.com/blevesearch/upsidedown_store_api" + bolt "go.etcd.io/bbolt" +) + +const ( + Name = "boltdb" + defaultCompactBatchSize = 100 +) + +type Store struct { + path string + bucket string + db *bolt.DB + noSync bool + fillPercent float64 + mo store.MergeOperator +} + +func New(mo store.MergeOperator, config map[string]interface{}) (store.KVStore, error) { + path, ok := config["path"].(string) + if !ok { + return nil, fmt.Errorf("must specify path") + } + if path == "" { + return nil, os.ErrInvalid + } + + bucket, ok := config["bucket"].(string) + if !ok { + bucket = "bleve" + } + + noSync, _ := config["nosync"].(bool) + + fillPercent, ok := config["fillPercent"].(float64) + if !ok { + fillPercent = bolt.DefaultFillPercent + } + + bo := &bolt.Options{} + ro, ok := config["read_only"].(bool) + if ok { + bo.ReadOnly = ro + } + + if initialMmapSize, ok := config["initialMmapSize"].(int); ok { + bo.InitialMmapSize = initialMmapSize + } else if initialMmapSize, ok := config["initialMmapSize"].(float64); ok { + bo.InitialMmapSize = int(initialMmapSize) + } + + db, err := bolt.Open(path, 0600, bo) + if err != nil { + return nil, err + } + db.NoSync = noSync + + if !bo.ReadOnly { + err = db.Update(func(tx *bolt.Tx) error { + _, err := tx.CreateBucketIfNotExists([]byte(bucket)) + + return err + }) + if err != nil { + return nil, err + } + } + + rv := Store{ + path: path, + bucket: bucket, + db: db, + mo: mo, + noSync: noSync, + fillPercent: fillPercent, + } + return &rv, nil +} + +func (bs *Store) Close() error { + return bs.db.Close() +} + +func (bs *Store) Reader() (store.KVReader, error) { + tx, err := bs.db.Begin(false) + if err != nil { + return nil, err + } + return &Reader{ + store: bs, + tx: tx, + bucket: tx.Bucket([]byte(bs.bucket)), + }, nil +} + +func (bs *Store) Writer() (store.KVWriter, error) { + return &Writer{ + store: bs, + }, nil +} + +func (bs *Store) Stats() json.Marshaler { + return &stats{ + s: bs, + } +} + +// CompactWithBatchSize removes DictionaryTerm entries with a count of zero (in batchSize batches) +// Removing entries is a workaround for github issue #374. +func (bs *Store) CompactWithBatchSize(batchSize int) error { + for { + cnt := 0 + err := bs.db.Batch(func(tx *bolt.Tx) error { + c := tx.Bucket([]byte(bs.bucket)).Cursor() + prefix := []byte("d") + + for k, v := c.Seek(prefix); bytes.HasPrefix(k, prefix); k, v = c.Next() { + if bytes.Equal(v, []byte{0}) { + cnt++ + if err := c.Delete(); err != nil { + return err + } + if cnt == batchSize { + break + } + } + + } + return nil + }) + if err != nil { + return err + } + + if cnt == 0 { + break + } + } + return nil +} + +// Compact calls CompactWithBatchSize with a default batch size of 100. This is a workaround +// for github issue #374. +func (bs *Store) Compact() error { + return bs.CompactWithBatchSize(defaultCompactBatchSize) +} + +func init() { + registry.RegisterKVStore(Name, New) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/writer.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/writer.go new file mode 100644 index 0000000000..c25583cab7 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb/writer.go @@ -0,0 +1,95 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package boltdb + +import ( + "fmt" + + store "github.com/blevesearch/upsidedown_store_api" +) + +type Writer struct { + store *Store +} + +func (w *Writer) NewBatch() store.KVBatch { + return store.NewEmulatedBatch(w.store.mo) +} + +func (w *Writer) NewBatchEx(options store.KVBatchOptions) ([]byte, store.KVBatch, error) { + return make([]byte, options.TotalBytes), w.NewBatch(), nil +} + +func (w *Writer) ExecuteBatch(batch store.KVBatch) (err error) { + + emulatedBatch, ok := batch.(*store.EmulatedBatch) + if !ok { + return fmt.Errorf("wrong type of batch") + } + + tx, err := w.store.db.Begin(true) + if err != nil { + return + } + // defer function to ensure that once started, + // we either Commit tx or Rollback + defer func() { + // if nothing went wrong, commit + if err == nil { + // careful to catch error here too + err = tx.Commit() + } else { + // caller should see error that caused abort, + // not success or failure of Rollback itself + _ = tx.Rollback() + } + }() + + bucket := tx.Bucket([]byte(w.store.bucket)) + bucket.FillPercent = w.store.fillPercent + + for k, mergeOps := range emulatedBatch.Merger.Merges { + kb := []byte(k) + existingVal := bucket.Get(kb) + mergedVal, fullMergeOk := w.store.mo.FullMerge(kb, existingVal, mergeOps) + if !fullMergeOk { + err = fmt.Errorf("merge operator returned failure") + return + } + err = bucket.Put(kb, mergedVal) + if err != nil { + return + } + } + + for _, op := range emulatedBatch.Ops { + if op.V != nil { + err = bucket.Put(op.K, op.V) + if err != nil { + return + } + } else { + err = bucket.Delete(op.K) + if err != nil { + return + } + } + } + return +} + +func (w *Writer) Close() error { + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap/iterator.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap/iterator.go new file mode 100644 index 0000000000..c03f75c72a --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap/iterator.go @@ -0,0 +1,152 @@ +// Copyright (c) 2015 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package gtreap provides an in-memory implementation of the +// KVStore interfaces using the gtreap balanced-binary treap, +// copy-on-write data structure. +package gtreap + +import ( + "bytes" + "sync" + + "github.com/blevesearch/gtreap" +) + +type Iterator struct { + t *gtreap.Treap + + m sync.Mutex + cancelCh chan struct{} + nextCh chan *Item + curr *Item + currOk bool + + prefix []byte + start []byte + end []byte +} + +func (w *Iterator) Seek(k []byte) { + if w.start != nil && bytes.Compare(k, w.start) < 0 { + k = w.start + } + if w.prefix != nil && !bytes.HasPrefix(k, w.prefix) { + if bytes.Compare(k, w.prefix) < 0 { + k = w.prefix + } else { + var end []byte + for i := len(w.prefix) - 1; i >= 0; i-- { + c := w.prefix[i] + if c < 0xff { + end = make([]byte, i+1) + copy(end, w.prefix) + end[i] = c + 1 + break + } + } + k = end + } + } + w.restart(&Item{k: k}) +} + +func (w *Iterator) restart(start *Item) *Iterator { + cancelCh := make(chan struct{}) + nextCh := make(chan *Item, 1) + + w.m.Lock() + if w.cancelCh != nil { + close(w.cancelCh) + } + w.cancelCh = cancelCh + w.nextCh = nextCh + w.curr = nil + w.currOk = false + w.m.Unlock() + + go func() { + if start != nil { + w.t.VisitAscend(start, func(itm gtreap.Item) bool { + select { + case <-cancelCh: + return false + case nextCh <- itm.(*Item): + return true + } + }) + } + close(nextCh) + }() + + w.Next() + + return w +} + +func (w *Iterator) Next() { + w.m.Lock() + nextCh := w.nextCh + w.m.Unlock() + w.curr, w.currOk = <-nextCh +} + +func (w *Iterator) Current() ([]byte, []byte, bool) { + w.m.Lock() + defer w.m.Unlock() + if !w.currOk || w.curr == nil { + return nil, nil, false + } + if w.prefix != nil && !bytes.HasPrefix(w.curr.k, w.prefix) { + return nil, nil, false + } else if w.end != nil && bytes.Compare(w.curr.k, w.end) >= 0 { + return nil, nil, false + } + return w.curr.k, w.curr.v, w.currOk +} + +func (w *Iterator) Key() []byte { + k, _, ok := w.Current() + if !ok { + return nil + } + return k +} + +func (w *Iterator) Value() []byte { + _, v, ok := w.Current() + if !ok { + return nil + } + return v +} + +func (w *Iterator) Valid() bool { + _, _, ok := w.Current() + return ok +} + +func (w *Iterator) Close() error { + w.m.Lock() + if w.cancelCh != nil { + close(w.cancelCh) + } + w.cancelCh = nil + w.nextCh = nil + w.curr = nil + w.currOk = false + w.m.Unlock() + + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap/reader.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap/reader.go new file mode 100644 index 0000000000..52b05d788e --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap/reader.go @@ -0,0 +1,66 @@ +// Copyright (c) 2015 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package gtreap provides an in-memory implementation of the +// KVStore interfaces using the gtreap balanced-binary treap, +// copy-on-write data structure. +package gtreap + +import ( + "github.com/blevesearch/upsidedown_store_api" + + "github.com/blevesearch/gtreap" +) + +type Reader struct { + t *gtreap.Treap +} + +func (w *Reader) Get(k []byte) (v []byte, err error) { + var rv []byte + itm := w.t.Get(&Item{k: k}) + if itm != nil { + rv = make([]byte, len(itm.(*Item).v)) + copy(rv, itm.(*Item).v) + return rv, nil + } + return nil, nil +} + +func (r *Reader) MultiGet(keys [][]byte) ([][]byte, error) { + return store.MultiGet(r, keys) +} + +func (w *Reader) PrefixIterator(k []byte) store.KVIterator { + rv := Iterator{ + t: w.t, + prefix: k, + } + rv.restart(&Item{k: k}) + return &rv +} + +func (w *Reader) RangeIterator(start, end []byte) store.KVIterator { + rv := Iterator{ + t: w.t, + start: start, + end: end, + } + rv.restart(&Item{k: start}) + return &rv +} + +func (w *Reader) Close() error { + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap/store.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap/store.go new file mode 100644 index 0000000000..3cc7eb9ae1 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap/store.go @@ -0,0 +1,82 @@ +// Copyright (c) 2015 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package gtreap provides an in-memory implementation of the +// KVStore interfaces using the gtreap balanced-binary treap, +// copy-on-write data structure. + +package gtreap + +import ( + "bytes" + "fmt" + "os" + "sync" + + "github.com/blevesearch/bleve/v2/registry" + "github.com/blevesearch/gtreap" + "github.com/blevesearch/upsidedown_store_api" +) + +const Name = "gtreap" + +type Store struct { + m sync.Mutex + t *gtreap.Treap + mo store.MergeOperator +} + +type Item struct { + k []byte + v []byte +} + +func itemCompare(a, b interface{}) int { + return bytes.Compare(a.(*Item).k, b.(*Item).k) +} + +func New(mo store.MergeOperator, config map[string]interface{}) (store.KVStore, error) { + path, ok := config["path"].(string) + if !ok { + return nil, fmt.Errorf("must specify path") + } + if path != "" { + return nil, os.ErrInvalid + } + + rv := Store{ + t: gtreap.NewTreap(itemCompare), + mo: mo, + } + return &rv, nil +} + +func (s *Store) Close() error { + return nil +} + +func (s *Store) Reader() (store.KVReader, error) { + s.m.Lock() + t := s.t + s.m.Unlock() + return &Reader{t: t}, nil +} + +func (s *Store) Writer() (store.KVWriter, error) { + return &Writer{s: s}, nil +} + +func init() { + registry.RegisterKVStore(Name, New) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap/writer.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap/writer.go new file mode 100644 index 0000000000..80aa15b193 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap/writer.go @@ -0,0 +1,76 @@ +// Copyright (c) 2015 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package gtreap provides an in-memory implementation of the +// KVStore interfaces using the gtreap balanced-binary treap, +// copy-on-write data structure. +package gtreap + +import ( + "fmt" + "math/rand" + + "github.com/blevesearch/upsidedown_store_api" +) + +type Writer struct { + s *Store +} + +func (w *Writer) NewBatch() store.KVBatch { + return store.NewEmulatedBatch(w.s.mo) +} + +func (w *Writer) NewBatchEx(options store.KVBatchOptions) ([]byte, store.KVBatch, error) { + return make([]byte, options.TotalBytes), w.NewBatch(), nil +} + +func (w *Writer) ExecuteBatch(batch store.KVBatch) error { + + emulatedBatch, ok := batch.(*store.EmulatedBatch) + if !ok { + return fmt.Errorf("wrong type of batch") + } + + w.s.m.Lock() + for k, mergeOps := range emulatedBatch.Merger.Merges { + kb := []byte(k) + var existingVal []byte + existingItem := w.s.t.Get(&Item{k: kb}) + if existingItem != nil { + existingVal = w.s.t.Get(&Item{k: kb}).(*Item).v + } + mergedVal, fullMergeOk := w.s.mo.FullMerge(kb, existingVal, mergeOps) + if !fullMergeOk { + return fmt.Errorf("merge operator returned failure") + } + w.s.t = w.s.t.Upsert(&Item{k: kb, v: mergedVal}, rand.Int()) + } + + for _, op := range emulatedBatch.Ops { + if op.V != nil { + w.s.t = w.s.t.Upsert(&Item{k: op.K, v: op.V}, rand.Int()) + } else { + w.s.t = w.s.t.Delete(&Item{k: op.K}) + } + } + w.s.m.Unlock() + + return nil +} + +func (w *Writer) Close() error { + w.s = nil + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/upsidedown.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/upsidedown.go new file mode 100644 index 0000000000..34c331942b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/upsidedown.go @@ -0,0 +1,1071 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:generate protoc --gofast_out=. upsidedown.proto + +package upsidedown + +import ( + "encoding/binary" + "encoding/json" + "fmt" + "math" + "sync" + "sync/atomic" + "time" + + "github.com/blevesearch/bleve/v2/document" + "github.com/blevesearch/bleve/v2/registry" + index "github.com/blevesearch/bleve_index_api" + store "github.com/blevesearch/upsidedown_store_api" + + "github.com/golang/protobuf/proto" +) + +const Name = "upside_down" + +// RowBufferSize should ideally this is sized to be the smallest +// size that can contain an index row key and its corresponding +// value. It is not a limit, if need be a larger buffer is +// allocated, but performance will be more optimal if *most* +// rows fit this size. +const RowBufferSize = 4 * 1024 + +var VersionKey = []byte{'v'} + +const Version uint8 = 7 + +var IncompatibleVersion = fmt.Errorf("incompatible version, %d is supported", Version) + +var ErrorUnknownStorageType = fmt.Errorf("unknown storage type") + +type UpsideDownCouch struct { + version uint8 + path string + storeName string + storeConfig map[string]interface{} + store store.KVStore + fieldCache *FieldCache + analysisQueue *index.AnalysisQueue + stats *indexStat + + m sync.RWMutex + // fields protected by m + docCount uint64 + + writeMutex sync.Mutex +} + +type docBackIndexRow struct { + docID string + doc index.Document // If deletion, doc will be nil. + backIndexRow *BackIndexRow +} + +func NewUpsideDownCouch(storeName string, storeConfig map[string]interface{}, analysisQueue *index.AnalysisQueue) (index.Index, error) { + rv := &UpsideDownCouch{ + version: Version, + fieldCache: NewFieldCache(), + storeName: storeName, + storeConfig: storeConfig, + analysisQueue: analysisQueue, + } + rv.stats = &indexStat{i: rv} + return rv, nil +} + +func (udc *UpsideDownCouch) init(kvwriter store.KVWriter) (err error) { + // version marker + rowsAll := [][]UpsideDownCouchRow{ + {NewVersionRow(udc.version)}, + } + + err = udc.batchRows(kvwriter, nil, rowsAll, nil) + return +} + +func (udc *UpsideDownCouch) loadSchema(kvreader store.KVReader) (err error) { + + it := kvreader.PrefixIterator([]byte{'f'}) + defer func() { + if cerr := it.Close(); err == nil && cerr != nil { + err = cerr + } + }() + + key, val, valid := it.Current() + for valid { + var fieldRow *FieldRow + fieldRow, err = NewFieldRowKV(key, val) + if err != nil { + return + } + udc.fieldCache.AddExisting(fieldRow.name, fieldRow.index) + + it.Next() + key, val, valid = it.Current() + } + + val, err = kvreader.Get([]byte{'v'}) + if err != nil { + return + } + var vr *VersionRow + vr, err = NewVersionRowKV([]byte{'v'}, val) + if err != nil { + return + } + if vr.version != Version { + err = IncompatibleVersion + return + } + + return +} + +var rowBufferPool sync.Pool + +func GetRowBuffer() []byte { + if rb, ok := rowBufferPool.Get().([]byte); ok { + return rb + } else { + return make([]byte, RowBufferSize) + } +} + +func PutRowBuffer(buf []byte) { + rowBufferPool.Put(buf) +} + +func (udc *UpsideDownCouch) batchRows(writer store.KVWriter, addRowsAll [][]UpsideDownCouchRow, updateRowsAll [][]UpsideDownCouchRow, deleteRowsAll [][]UpsideDownCouchRow) (err error) { + dictionaryDeltas := make(map[string]int64) + + // count up bytes needed for buffering. + addNum := 0 + addKeyBytes := 0 + addValBytes := 0 + + updateNum := 0 + updateKeyBytes := 0 + updateValBytes := 0 + + deleteNum := 0 + deleteKeyBytes := 0 + + rowBuf := GetRowBuffer() + + for _, addRows := range addRowsAll { + for _, row := range addRows { + tfr, ok := row.(*TermFrequencyRow) + if ok { + if tfr.DictionaryRowKeySize() > len(rowBuf) { + rowBuf = make([]byte, tfr.DictionaryRowKeySize()) + } + dictKeySize, err := tfr.DictionaryRowKeyTo(rowBuf) + if err != nil { + return err + } + dictionaryDeltas[string(rowBuf[:dictKeySize])] += 1 + } + addKeyBytes += row.KeySize() + addValBytes += row.ValueSize() + } + addNum += len(addRows) + } + + for _, updateRows := range updateRowsAll { + for _, row := range updateRows { + updateKeyBytes += row.KeySize() + updateValBytes += row.ValueSize() + } + updateNum += len(updateRows) + } + + for _, deleteRows := range deleteRowsAll { + for _, row := range deleteRows { + tfr, ok := row.(*TermFrequencyRow) + if ok { + // need to decrement counter + if tfr.DictionaryRowKeySize() > len(rowBuf) { + rowBuf = make([]byte, tfr.DictionaryRowKeySize()) + } + dictKeySize, err := tfr.DictionaryRowKeyTo(rowBuf) + if err != nil { + return err + } + dictionaryDeltas[string(rowBuf[:dictKeySize])] -= 1 + } + deleteKeyBytes += row.KeySize() + } + deleteNum += len(deleteRows) + } + + PutRowBuffer(rowBuf) + + mergeNum := len(dictionaryDeltas) + mergeKeyBytes := 0 + mergeValBytes := mergeNum * DictionaryRowMaxValueSize + + for dictRowKey := range dictionaryDeltas { + mergeKeyBytes += len(dictRowKey) + } + + // prepare batch + totBytes := addKeyBytes + addValBytes + + updateKeyBytes + updateValBytes + + deleteKeyBytes + + 2*(mergeKeyBytes+mergeValBytes) + + buf, wb, err := writer.NewBatchEx(store.KVBatchOptions{ + TotalBytes: totBytes, + NumSets: addNum + updateNum, + NumDeletes: deleteNum, + NumMerges: mergeNum, + }) + if err != nil { + return err + } + defer func() { + _ = wb.Close() + }() + + // fill the batch + for _, addRows := range addRowsAll { + for _, row := range addRows { + keySize, err := row.KeyTo(buf) + if err != nil { + return err + } + valSize, err := row.ValueTo(buf[keySize:]) + if err != nil { + return err + } + wb.Set(buf[:keySize], buf[keySize:keySize+valSize]) + buf = buf[keySize+valSize:] + } + } + + for _, updateRows := range updateRowsAll { + for _, row := range updateRows { + keySize, err := row.KeyTo(buf) + if err != nil { + return err + } + valSize, err := row.ValueTo(buf[keySize:]) + if err != nil { + return err + } + wb.Set(buf[:keySize], buf[keySize:keySize+valSize]) + buf = buf[keySize+valSize:] + } + } + + for _, deleteRows := range deleteRowsAll { + for _, row := range deleteRows { + keySize, err := row.KeyTo(buf) + if err != nil { + return err + } + wb.Delete(buf[:keySize]) + buf = buf[keySize:] + } + } + + for dictRowKey, delta := range dictionaryDeltas { + dictRowKeyLen := copy(buf, dictRowKey) + binary.LittleEndian.PutUint64(buf[dictRowKeyLen:], uint64(delta)) + wb.Merge(buf[:dictRowKeyLen], buf[dictRowKeyLen:dictRowKeyLen+DictionaryRowMaxValueSize]) + buf = buf[dictRowKeyLen+DictionaryRowMaxValueSize:] + } + + // write out the batch + return writer.ExecuteBatch(wb) +} + +func (udc *UpsideDownCouch) Open() (err error) { + // acquire the write mutex for the duration of Open() + udc.writeMutex.Lock() + defer udc.writeMutex.Unlock() + + // open the kv store + storeConstructor := registry.KVStoreConstructorByName(udc.storeName) + if storeConstructor == nil { + err = ErrorUnknownStorageType + return + } + + // now open the store + udc.store, err = storeConstructor(&mergeOperator, udc.storeConfig) + if err != nil { + return + } + + // start a reader to look at the index + var kvreader store.KVReader + kvreader, err = udc.store.Reader() + if err != nil { + return + } + + var value []byte + value, err = kvreader.Get(VersionKey) + if err != nil { + _ = kvreader.Close() + return + } + + if value != nil { + err = udc.loadSchema(kvreader) + if err != nil { + _ = kvreader.Close() + return + } + + // set doc count + udc.m.Lock() + udc.docCount, err = udc.countDocs(kvreader) + udc.m.Unlock() + + err = kvreader.Close() + } else { + // new index, close the reader and open writer to init + err = kvreader.Close() + if err != nil { + return + } + + var kvwriter store.KVWriter + kvwriter, err = udc.store.Writer() + if err != nil { + return + } + defer func() { + if cerr := kvwriter.Close(); err == nil && cerr != nil { + err = cerr + } + }() + + // init the index + err = udc.init(kvwriter) + } + + return +} + +func (udc *UpsideDownCouch) countDocs(kvreader store.KVReader) (count uint64, err error) { + it := kvreader.PrefixIterator([]byte{'b'}) + defer func() { + if cerr := it.Close(); err == nil && cerr != nil { + err = cerr + } + }() + + _, _, valid := it.Current() + for valid { + count++ + it.Next() + _, _, valid = it.Current() + } + + return +} + +func (udc *UpsideDownCouch) rowCount() (count uint64, err error) { + // start an isolated reader for use during the rowcount + kvreader, err := udc.store.Reader() + if err != nil { + return + } + defer func() { + if cerr := kvreader.Close(); err == nil && cerr != nil { + err = cerr + } + }() + it := kvreader.RangeIterator(nil, nil) + defer func() { + if cerr := it.Close(); err == nil && cerr != nil { + err = cerr + } + }() + + _, _, valid := it.Current() + for valid { + count++ + it.Next() + _, _, valid = it.Current() + } + + return +} + +func (udc *UpsideDownCouch) Close() error { + return udc.store.Close() +} + +func (udc *UpsideDownCouch) Update(doc index.Document) (err error) { + // do analysis before acquiring write lock + analysisStart := time.Now() + resultChan := make(chan *AnalysisResult) + + // put the work on the queue + udc.analysisQueue.Queue(func() { + ar := udc.analyze(doc) + resultChan <- ar + }) + + // wait for the result + result := <-resultChan + close(resultChan) + atomic.AddUint64(&udc.stats.analysisTime, uint64(time.Since(analysisStart))) + + udc.writeMutex.Lock() + defer udc.writeMutex.Unlock() + + // open a reader for backindex lookup + var kvreader store.KVReader + kvreader, err = udc.store.Reader() + if err != nil { + return + } + + // first we lookup the backindex row for the doc id if it exists + // lookup the back index row + var backIndexRow *BackIndexRow + backIndexRow, err = backIndexRowForDoc(kvreader, index.IndexInternalID(doc.ID())) + if err != nil { + _ = kvreader.Close() + atomic.AddUint64(&udc.stats.errors, 1) + return + } + + err = kvreader.Close() + if err != nil { + return + } + + return udc.UpdateWithAnalysis(doc, result, backIndexRow) +} + +func (udc *UpsideDownCouch) UpdateWithAnalysis(doc index.Document, + result *AnalysisResult, backIndexRow *BackIndexRow) (err error) { + // start a writer for this update + indexStart := time.Now() + var kvwriter store.KVWriter + kvwriter, err = udc.store.Writer() + if err != nil { + return + } + defer func() { + if cerr := kvwriter.Close(); err == nil && cerr != nil { + err = cerr + } + }() + + // prepare a list of rows + var addRowsAll [][]UpsideDownCouchRow + var updateRowsAll [][]UpsideDownCouchRow + var deleteRowsAll [][]UpsideDownCouchRow + + addRows, updateRows, deleteRows := udc.mergeOldAndNew(backIndexRow, result.Rows) + if len(addRows) > 0 { + addRowsAll = append(addRowsAll, addRows) + } + if len(updateRows) > 0 { + updateRowsAll = append(updateRowsAll, updateRows) + } + if len(deleteRows) > 0 { + deleteRowsAll = append(deleteRowsAll, deleteRows) + } + + err = udc.batchRows(kvwriter, addRowsAll, updateRowsAll, deleteRowsAll) + if err == nil && backIndexRow == nil { + udc.m.Lock() + udc.docCount++ + udc.m.Unlock() + } + atomic.AddUint64(&udc.stats.indexTime, uint64(time.Since(indexStart))) + if err == nil { + atomic.AddUint64(&udc.stats.updates, 1) + atomic.AddUint64(&udc.stats.numPlainTextBytesIndexed, doc.NumPlainTextBytes()) + } else { + atomic.AddUint64(&udc.stats.errors, 1) + } + return +} + +func (udc *UpsideDownCouch) mergeOldAndNew(backIndexRow *BackIndexRow, rows []IndexRow) (addRows []UpsideDownCouchRow, updateRows []UpsideDownCouchRow, deleteRows []UpsideDownCouchRow) { + addRows = make([]UpsideDownCouchRow, 0, len(rows)) + + if backIndexRow == nil { + addRows = addRows[0:len(rows)] + for i, row := range rows { + addRows[i] = row + } + return addRows, nil, nil + } + + updateRows = make([]UpsideDownCouchRow, 0, len(rows)) + deleteRows = make([]UpsideDownCouchRow, 0, len(rows)) + + var existingTermKeys map[string]struct{} + backIndexTermKeys := backIndexRow.AllTermKeys() + if len(backIndexTermKeys) > 0 { + existingTermKeys = make(map[string]struct{}, len(backIndexTermKeys)) + for _, key := range backIndexTermKeys { + existingTermKeys[string(key)] = struct{}{} + } + } + + var existingStoredKeys map[string]struct{} + backIndexStoredKeys := backIndexRow.AllStoredKeys() + if len(backIndexStoredKeys) > 0 { + existingStoredKeys = make(map[string]struct{}, len(backIndexStoredKeys)) + for _, key := range backIndexStoredKeys { + existingStoredKeys[string(key)] = struct{}{} + } + } + + keyBuf := GetRowBuffer() + for _, row := range rows { + switch row := row.(type) { + case *TermFrequencyRow: + if existingTermKeys != nil { + if row.KeySize() > len(keyBuf) { + keyBuf = make([]byte, row.KeySize()) + } + keySize, _ := row.KeyTo(keyBuf) + if _, ok := existingTermKeys[string(keyBuf[:keySize])]; ok { + updateRows = append(updateRows, row) + delete(existingTermKeys, string(keyBuf[:keySize])) + continue + } + } + addRows = append(addRows, row) + case *StoredRow: + if existingStoredKeys != nil { + if row.KeySize() > len(keyBuf) { + keyBuf = make([]byte, row.KeySize()) + } + keySize, _ := row.KeyTo(keyBuf) + if _, ok := existingStoredKeys[string(keyBuf[:keySize])]; ok { + updateRows = append(updateRows, row) + delete(existingStoredKeys, string(keyBuf[:keySize])) + continue + } + } + addRows = append(addRows, row) + default: + updateRows = append(updateRows, row) + } + } + PutRowBuffer(keyBuf) + + // any of the existing rows that weren't updated need to be deleted + for existingTermKey := range existingTermKeys { + termFreqRow, err := NewTermFrequencyRowK([]byte(existingTermKey)) + if err == nil { + deleteRows = append(deleteRows, termFreqRow) + } + } + + // any of the existing stored fields that weren't updated need to be deleted + for existingStoredKey := range existingStoredKeys { + storedRow, err := NewStoredRowK([]byte(existingStoredKey)) + if err == nil { + deleteRows = append(deleteRows, storedRow) + } + } + + return addRows, updateRows, deleteRows +} + +func (udc *UpsideDownCouch) storeField(docID []byte, field index.Field, fieldIndex uint16, rows []IndexRow, backIndexStoredEntries []*BackIndexStoreEntry) ([]IndexRow, []*BackIndexStoreEntry) { + fieldType := field.EncodedFieldType() + storedRow := NewStoredRow(docID, fieldIndex, field.ArrayPositions(), fieldType, field.Value()) + + // record the back index entry + backIndexStoredEntry := BackIndexStoreEntry{Field: proto.Uint32(uint32(fieldIndex)), ArrayPositions: field.ArrayPositions()} + + return append(rows, storedRow), append(backIndexStoredEntries, &backIndexStoredEntry) +} + +func (udc *UpsideDownCouch) indexField(docID []byte, includeTermVectors bool, fieldIndex uint16, fieldLength int, tokenFreqs index.TokenFrequencies, rows []IndexRow, backIndexTermsEntries []*BackIndexTermsEntry) ([]IndexRow, []*BackIndexTermsEntry) { + fieldNorm := float32(1.0 / math.Sqrt(float64(fieldLength))) + + termFreqRows := make([]TermFrequencyRow, len(tokenFreqs)) + termFreqRowsUsed := 0 + + terms := make([]string, 0, len(tokenFreqs)) + for k, tf := range tokenFreqs { + termFreqRow := &termFreqRows[termFreqRowsUsed] + termFreqRowsUsed++ + + InitTermFrequencyRow(termFreqRow, tf.Term, fieldIndex, docID, + uint64(frequencyFromTokenFreq(tf)), fieldNorm) + + if includeTermVectors { + termFreqRow.vectors, rows = udc.termVectorsFromTokenFreq(fieldIndex, tf, rows) + } + + // record the back index entry + terms = append(terms, k) + + rows = append(rows, termFreqRow) + } + backIndexTermsEntry := BackIndexTermsEntry{Field: proto.Uint32(uint32(fieldIndex)), Terms: terms} + backIndexTermsEntries = append(backIndexTermsEntries, &backIndexTermsEntry) + + return rows, backIndexTermsEntries +} + +func (udc *UpsideDownCouch) Delete(id string) (err error) { + indexStart := time.Now() + + udc.writeMutex.Lock() + defer udc.writeMutex.Unlock() + + // open a reader for backindex lookup + var kvreader store.KVReader + kvreader, err = udc.store.Reader() + if err != nil { + return + } + + // first we lookup the backindex row for the doc id if it exists + // lookup the back index row + var backIndexRow *BackIndexRow + backIndexRow, err = backIndexRowForDoc(kvreader, index.IndexInternalID(id)) + if err != nil { + _ = kvreader.Close() + atomic.AddUint64(&udc.stats.errors, 1) + return + } + + err = kvreader.Close() + if err != nil { + return + } + + if backIndexRow == nil { + atomic.AddUint64(&udc.stats.deletes, 1) + return + } + + // start a writer for this delete + var kvwriter store.KVWriter + kvwriter, err = udc.store.Writer() + if err != nil { + return + } + defer func() { + if cerr := kvwriter.Close(); err == nil && cerr != nil { + err = cerr + } + }() + + var deleteRowsAll [][]UpsideDownCouchRow + + deleteRows := udc.deleteSingle(id, backIndexRow, nil) + if len(deleteRows) > 0 { + deleteRowsAll = append(deleteRowsAll, deleteRows) + } + + err = udc.batchRows(kvwriter, nil, nil, deleteRowsAll) + if err == nil { + udc.m.Lock() + udc.docCount-- + udc.m.Unlock() + } + atomic.AddUint64(&udc.stats.indexTime, uint64(time.Since(indexStart))) + if err == nil { + atomic.AddUint64(&udc.stats.deletes, 1) + } else { + atomic.AddUint64(&udc.stats.errors, 1) + } + return +} + +func (udc *UpsideDownCouch) deleteSingle(id string, backIndexRow *BackIndexRow, deleteRows []UpsideDownCouchRow) []UpsideDownCouchRow { + idBytes := []byte(id) + + for _, backIndexEntry := range backIndexRow.termsEntries { + for i := range backIndexEntry.Terms { + tfr := NewTermFrequencyRow([]byte(backIndexEntry.Terms[i]), uint16(*backIndexEntry.Field), idBytes, 0, 0) + deleteRows = append(deleteRows, tfr) + } + } + for _, se := range backIndexRow.storedEntries { + sf := NewStoredRow(idBytes, uint16(*se.Field), se.ArrayPositions, 'x', nil) + deleteRows = append(deleteRows, sf) + } + + // also delete the back entry itself + deleteRows = append(deleteRows, backIndexRow) + return deleteRows +} + +func decodeFieldType(typ byte, name string, pos []uint64, value []byte) document.Field { + switch typ { + case 't': + return document.NewTextField(name, pos, value) + case 'n': + return document.NewNumericFieldFromBytes(name, pos, value) + case 'd': + return document.NewDateTimeFieldFromBytes(name, pos, value) + case 'b': + return document.NewBooleanFieldFromBytes(name, pos, value) + case 'g': + return document.NewGeoPointFieldFromBytes(name, pos, value) + case 'i': + return document.NewIPFieldFromBytes(name, pos, value) + } + return nil +} + +func frequencyFromTokenFreq(tf *index.TokenFreq) int { + return tf.Frequency() +} + +func (udc *UpsideDownCouch) termVectorsFromTokenFreq(field uint16, tf *index.TokenFreq, rows []IndexRow) ([]*TermVector, []IndexRow) { + a := make([]TermVector, len(tf.Locations)) + rv := make([]*TermVector, len(tf.Locations)) + + for i, l := range tf.Locations { + var newFieldRow *FieldRow + fieldIndex := field + if l.Field != "" { + // lookup correct field + fieldIndex, newFieldRow = udc.fieldIndexOrNewRow(l.Field) + if newFieldRow != nil { + rows = append(rows, newFieldRow) + } + } + a[i] = TermVector{ + field: fieldIndex, + arrayPositions: l.ArrayPositions, + pos: uint64(l.Position), + start: uint64(l.Start), + end: uint64(l.End), + } + rv[i] = &a[i] + } + + return rv, rows +} + +func (udc *UpsideDownCouch) termFieldVectorsFromTermVectors(in []*TermVector) []*index.TermFieldVector { + if len(in) == 0 { + return nil + } + + a := make([]index.TermFieldVector, len(in)) + rv := make([]*index.TermFieldVector, len(in)) + + for i, tv := range in { + fieldName := udc.fieldCache.FieldIndexed(tv.field) + a[i] = index.TermFieldVector{ + Field: fieldName, + ArrayPositions: tv.arrayPositions, + Pos: tv.pos, + Start: tv.start, + End: tv.end, + } + rv[i] = &a[i] + } + return rv +} + +func (udc *UpsideDownCouch) Batch(batch *index.Batch) (err error) { + persistedCallback := batch.PersistedCallback() + if persistedCallback != nil { + defer persistedCallback(err) + } + analysisStart := time.Now() + + resultChan := make(chan *AnalysisResult, len(batch.IndexOps)) + + var numUpdates uint64 + var numPlainTextBytes uint64 + for _, doc := range batch.IndexOps { + if doc != nil { + numUpdates++ + numPlainTextBytes += doc.NumPlainTextBytes() + } + } + + if numUpdates > 0 { + go func() { + for k := range batch.IndexOps { + doc := batch.IndexOps[k] + if doc != nil { + // put the work on the queue + udc.analysisQueue.Queue(func() { + ar := udc.analyze(doc) + resultChan <- ar + }) + } + } + }() + } + + // retrieve back index rows concurrent with analysis + docBackIndexRowErr := error(nil) + docBackIndexRowCh := make(chan *docBackIndexRow, len(batch.IndexOps)) + + udc.writeMutex.Lock() + defer udc.writeMutex.Unlock() + + go func() { + defer close(docBackIndexRowCh) + + // open a reader for backindex lookup + var kvreader store.KVReader + kvreader, err = udc.store.Reader() + if err != nil { + docBackIndexRowErr = err + return + } + defer func() { + if cerr := kvreader.Close(); err == nil && cerr != nil { + docBackIndexRowErr = cerr + } + }() + + for docID, doc := range batch.IndexOps { + backIndexRow, err := backIndexRowForDoc(kvreader, index.IndexInternalID(docID)) + if err != nil { + docBackIndexRowErr = err + return + } + + docBackIndexRowCh <- &docBackIndexRow{docID, doc, backIndexRow} + } + }() + + // wait for analysis result + newRowsMap := make(map[string][]IndexRow) + var itemsDeQueued uint64 + for itemsDeQueued < numUpdates { + result := <-resultChan + newRowsMap[result.DocID] = result.Rows + itemsDeQueued++ + } + close(resultChan) + + atomic.AddUint64(&udc.stats.analysisTime, uint64(time.Since(analysisStart))) + + docsAdded := uint64(0) + docsDeleted := uint64(0) + + indexStart := time.Now() + + // prepare a list of rows + var addRowsAll [][]UpsideDownCouchRow + var updateRowsAll [][]UpsideDownCouchRow + var deleteRowsAll [][]UpsideDownCouchRow + + // add the internal ops + var updateRows []UpsideDownCouchRow + var deleteRows []UpsideDownCouchRow + + for internalKey, internalValue := range batch.InternalOps { + if internalValue == nil { + // delete + deleteInternalRow := NewInternalRow([]byte(internalKey), nil) + deleteRows = append(deleteRows, deleteInternalRow) + } else { + updateInternalRow := NewInternalRow([]byte(internalKey), internalValue) + updateRows = append(updateRows, updateInternalRow) + } + } + + if len(updateRows) > 0 { + updateRowsAll = append(updateRowsAll, updateRows) + } + if len(deleteRows) > 0 { + deleteRowsAll = append(deleteRowsAll, deleteRows) + } + + // process back index rows as they arrive + for dbir := range docBackIndexRowCh { + if dbir.doc == nil && dbir.backIndexRow != nil { + // delete + deleteRows := udc.deleteSingle(dbir.docID, dbir.backIndexRow, nil) + if len(deleteRows) > 0 { + deleteRowsAll = append(deleteRowsAll, deleteRows) + } + docsDeleted++ + } else if dbir.doc != nil { + addRows, updateRows, deleteRows := udc.mergeOldAndNew(dbir.backIndexRow, newRowsMap[dbir.docID]) + if len(addRows) > 0 { + addRowsAll = append(addRowsAll, addRows) + } + if len(updateRows) > 0 { + updateRowsAll = append(updateRowsAll, updateRows) + } + if len(deleteRows) > 0 { + deleteRowsAll = append(deleteRowsAll, deleteRows) + } + if dbir.backIndexRow == nil { + docsAdded++ + } + } + } + + if docBackIndexRowErr != nil { + return docBackIndexRowErr + } + + // start a writer for this batch + var kvwriter store.KVWriter + kvwriter, err = udc.store.Writer() + if err != nil { + return + } + + err = udc.batchRows(kvwriter, addRowsAll, updateRowsAll, deleteRowsAll) + if err != nil { + _ = kvwriter.Close() + atomic.AddUint64(&udc.stats.errors, 1) + return + } + + err = kvwriter.Close() + + atomic.AddUint64(&udc.stats.indexTime, uint64(time.Since(indexStart))) + + if err == nil { + udc.m.Lock() + udc.docCount += docsAdded + udc.docCount -= docsDeleted + udc.m.Unlock() + atomic.AddUint64(&udc.stats.updates, numUpdates) + atomic.AddUint64(&udc.stats.deletes, docsDeleted) + atomic.AddUint64(&udc.stats.batches, 1) + atomic.AddUint64(&udc.stats.numPlainTextBytesIndexed, numPlainTextBytes) + } else { + atomic.AddUint64(&udc.stats.errors, 1) + } + + return +} + +func (udc *UpsideDownCouch) SetInternal(key, val []byte) (err error) { + internalRow := NewInternalRow(key, val) + udc.writeMutex.Lock() + defer udc.writeMutex.Unlock() + var writer store.KVWriter + writer, err = udc.store.Writer() + if err != nil { + return + } + defer func() { + if cerr := writer.Close(); err == nil && cerr != nil { + err = cerr + } + }() + + batch := writer.NewBatch() + batch.Set(internalRow.Key(), internalRow.Value()) + + return writer.ExecuteBatch(batch) +} + +func (udc *UpsideDownCouch) DeleteInternal(key []byte) (err error) { + internalRow := NewInternalRow(key, nil) + udc.writeMutex.Lock() + defer udc.writeMutex.Unlock() + var writer store.KVWriter + writer, err = udc.store.Writer() + if err != nil { + return + } + defer func() { + if cerr := writer.Close(); err == nil && cerr != nil { + err = cerr + } + }() + + batch := writer.NewBatch() + batch.Delete(internalRow.Key()) + return writer.ExecuteBatch(batch) +} + +func (udc *UpsideDownCouch) Reader() (index.IndexReader, error) { + kvr, err := udc.store.Reader() + if err != nil { + return nil, fmt.Errorf("error opening store reader: %v", err) + } + udc.m.RLock() + defer udc.m.RUnlock() + return &IndexReader{ + index: udc, + kvreader: kvr, + docCount: udc.docCount, + }, nil +} + +func (udc *UpsideDownCouch) Stats() json.Marshaler { + return udc.stats +} + +func (udc *UpsideDownCouch) StatsMap() map[string]interface{} { + return udc.stats.statsMap() +} + +func (udc *UpsideDownCouch) Advanced() (store.KVStore, error) { + return udc.store, nil +} + +func (udc *UpsideDownCouch) fieldIndexOrNewRow(name string) (uint16, *FieldRow) { + index, existed := udc.fieldCache.FieldNamed(name, true) + if !existed { + return index, NewFieldRow(index, name) + } + return index, nil +} + +func init() { + registry.RegisterIndexType(Name, NewUpsideDownCouch) +} + +func backIndexRowForDoc(kvreader store.KVReader, docID index.IndexInternalID) (*BackIndexRow, error) { + // use a temporary row structure to build key + tempRow := BackIndexRow{ + doc: docID, + } + + keyBuf := GetRowBuffer() + if tempRow.KeySize() > len(keyBuf) { + keyBuf = make([]byte, 2*tempRow.KeySize()) + } + defer PutRowBuffer(keyBuf) + keySize, err := tempRow.KeyTo(keyBuf) + if err != nil { + return nil, err + } + + value, err := kvreader.Get(keyBuf[:keySize]) + if err != nil { + return nil, err + } + if value == nil { + return nil, nil + } + backIndexRow, err := NewBackIndexRowKV(keyBuf[:keySize], value) + if err != nil { + return nil, err + } + return backIndexRow, nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/upsidedown.pb.go b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/upsidedown.pb.go new file mode 100644 index 0000000000..f2080c9b40 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/upsidedown.pb.go @@ -0,0 +1,690 @@ +// Code generated by protoc-gen-gogo. +// source: upsidedown.proto +// DO NOT EDIT! + +/* +Package upsidedown is a generated protocol buffer package. + +It is generated from these files: + + upsidedown.proto + +It has these top-level messages: + + BackIndexTermsEntry + BackIndexStoreEntry + BackIndexRowValue +*/ +package upsidedown + +import proto "github.com/golang/protobuf/proto" +import math "math" + +import io "io" +import fmt "fmt" +import github_com_golang_protobuf_proto "github.com/golang/protobuf/proto" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = math.Inf + +type BackIndexTermsEntry struct { + Field *uint32 `protobuf:"varint,1,req,name=field" json:"field,omitempty"` + Terms []string `protobuf:"bytes,2,rep,name=terms" json:"terms,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *BackIndexTermsEntry) Reset() { *m = BackIndexTermsEntry{} } +func (m *BackIndexTermsEntry) String() string { return proto.CompactTextString(m) } +func (*BackIndexTermsEntry) ProtoMessage() {} + +func (m *BackIndexTermsEntry) GetField() uint32 { + if m != nil && m.Field != nil { + return *m.Field + } + return 0 +} + +func (m *BackIndexTermsEntry) GetTerms() []string { + if m != nil { + return m.Terms + } + return nil +} + +type BackIndexStoreEntry struct { + Field *uint32 `protobuf:"varint,1,req,name=field" json:"field,omitempty"` + ArrayPositions []uint64 `protobuf:"varint,2,rep,name=arrayPositions" json:"arrayPositions,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *BackIndexStoreEntry) Reset() { *m = BackIndexStoreEntry{} } +func (m *BackIndexStoreEntry) String() string { return proto.CompactTextString(m) } +func (*BackIndexStoreEntry) ProtoMessage() {} + +func (m *BackIndexStoreEntry) GetField() uint32 { + if m != nil && m.Field != nil { + return *m.Field + } + return 0 +} + +func (m *BackIndexStoreEntry) GetArrayPositions() []uint64 { + if m != nil { + return m.ArrayPositions + } + return nil +} + +type BackIndexRowValue struct { + TermsEntries []*BackIndexTermsEntry `protobuf:"bytes,1,rep,name=termsEntries" json:"termsEntries,omitempty"` + StoredEntries []*BackIndexStoreEntry `protobuf:"bytes,2,rep,name=storedEntries" json:"storedEntries,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *BackIndexRowValue) Reset() { *m = BackIndexRowValue{} } +func (m *BackIndexRowValue) String() string { return proto.CompactTextString(m) } +func (*BackIndexRowValue) ProtoMessage() {} + +func (m *BackIndexRowValue) GetTermsEntries() []*BackIndexTermsEntry { + if m != nil { + return m.TermsEntries + } + return nil +} + +func (m *BackIndexRowValue) GetStoredEntries() []*BackIndexStoreEntry { + if m != nil { + return m.StoredEntries + } + return nil +} + +func (m *BackIndexTermsEntry) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Field", wireType) + } + var v uint32 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Field = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Terms", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + postIndex := iNdEx + int(stringLen) + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Terms = append(m.Terms, string(data[iNdEx:postIndex])) + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipUpsidedown(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthUpsidedown + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return new(github_com_golang_protobuf_proto.RequiredNotSetError) + } + + return nil +} +func (m *BackIndexStoreEntry) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Field", wireType) + } + var v uint32 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Field = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ArrayPositions", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.ArrayPositions = append(m.ArrayPositions, v) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipUpsidedown(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthUpsidedown + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return new(github_com_golang_protobuf_proto.RequiredNotSetError) + } + + return nil +} +func (m *BackIndexRowValue) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TermsEntries", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + postIndex := iNdEx + msglen + if msglen < 0 { + return ErrInvalidLengthUpsidedown + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TermsEntries = append(m.TermsEntries, &BackIndexTermsEntry{}) + if err := m.TermsEntries[len(m.TermsEntries)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StoredEntries", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + postIndex := iNdEx + msglen + if msglen < 0 { + return ErrInvalidLengthUpsidedown + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StoredEntries = append(m.StoredEntries, &BackIndexStoreEntry{}) + if err := m.StoredEntries[len(m.StoredEntries)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipUpsidedown(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthUpsidedown + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + return nil +} +func skipUpsidedown(data []byte) (n int, err error) { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for { + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if data[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthUpsidedown + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipUpsidedown(data[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthUpsidedown = fmt.Errorf("proto: negative length found during unmarshaling") +) + +func (m *BackIndexTermsEntry) Size() (n int) { + var l int + _ = l + if m.Field != nil { + n += 1 + sovUpsidedown(uint64(*m.Field)) + } + if len(m.Terms) > 0 { + for _, s := range m.Terms { + l = len(s) + n += 1 + l + sovUpsidedown(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *BackIndexStoreEntry) Size() (n int) { + var l int + _ = l + if m.Field != nil { + n += 1 + sovUpsidedown(uint64(*m.Field)) + } + if len(m.ArrayPositions) > 0 { + for _, e := range m.ArrayPositions { + n += 1 + sovUpsidedown(uint64(e)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *BackIndexRowValue) Size() (n int) { + var l int + _ = l + if len(m.TermsEntries) > 0 { + for _, e := range m.TermsEntries { + l = e.Size() + n += 1 + l + sovUpsidedown(uint64(l)) + } + } + if len(m.StoredEntries) > 0 { + for _, e := range m.StoredEntries { + l = e.Size() + n += 1 + l + sovUpsidedown(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovUpsidedown(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozUpsidedown(x uint64) (n int) { + return sovUpsidedown(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *BackIndexTermsEntry) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *BackIndexTermsEntry) MarshalTo(data []byte) (n int, err error) { + var i int + _ = i + var l int + _ = l + if m.Field == nil { + return 0, new(github_com_golang_protobuf_proto.RequiredNotSetError) + } else { + data[i] = 0x8 + i++ + i = encodeVarintUpsidedown(data, i, uint64(*m.Field)) + } + if len(m.Terms) > 0 { + for _, s := range m.Terms { + data[i] = 0x12 + i++ + l = len(s) + for l >= 1<<7 { + data[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + data[i] = uint8(l) + i++ + i += copy(data[i:], s) + } + } + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *BackIndexStoreEntry) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *BackIndexStoreEntry) MarshalTo(data []byte) (n int, err error) { + var i int + _ = i + var l int + _ = l + if m.Field == nil { + return 0, new(github_com_golang_protobuf_proto.RequiredNotSetError) + } else { + data[i] = 0x8 + i++ + i = encodeVarintUpsidedown(data, i, uint64(*m.Field)) + } + if len(m.ArrayPositions) > 0 { + for _, num := range m.ArrayPositions { + data[i] = 0x10 + i++ + i = encodeVarintUpsidedown(data, i, uint64(num)) + } + } + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *BackIndexRowValue) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *BackIndexRowValue) MarshalTo(data []byte) (n int, err error) { + var i int + _ = i + var l int + _ = l + if len(m.TermsEntries) > 0 { + for _, msg := range m.TermsEntries { + data[i] = 0xa + i++ + i = encodeVarintUpsidedown(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if len(m.StoredEntries) > 0 { + for _, msg := range m.StoredEntries { + data[i] = 0x12 + i++ + i = encodeVarintUpsidedown(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) + } + return i, nil +} + +func encodeFixed64Upsidedown(data []byte, offset int, v uint64) int { + data[offset] = uint8(v) + data[offset+1] = uint8(v >> 8) + data[offset+2] = uint8(v >> 16) + data[offset+3] = uint8(v >> 24) + data[offset+4] = uint8(v >> 32) + data[offset+5] = uint8(v >> 40) + data[offset+6] = uint8(v >> 48) + data[offset+7] = uint8(v >> 56) + return offset + 8 +} +func encodeFixed32Upsidedown(data []byte, offset int, v uint32) int { + data[offset] = uint8(v) + data[offset+1] = uint8(v >> 8) + data[offset+2] = uint8(v >> 16) + data[offset+3] = uint8(v >> 24) + return offset + 4 +} +func encodeVarintUpsidedown(data []byte, offset int, v uint64) int { + for v >= 1<<7 { + data[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + data[offset] = uint8(v) + return offset + 1 +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/upsidedown.proto b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/upsidedown.proto new file mode 100644 index 0000000000..cf0492a2db --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index/upsidedown/upsidedown.proto @@ -0,0 +1,14 @@ +message BackIndexTermsEntry { + required uint32 field = 1; + repeated string terms = 2; +} + +message BackIndexStoreEntry { + required uint32 field = 1; + repeated uint64 arrayPositions = 2; +} + +message BackIndexRowValue { + repeated BackIndexTermsEntry termsEntries = 1; + repeated BackIndexStoreEntry storedEntries = 2; +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index_alias.go b/backend/vendor/github.com/blevesearch/bleve/v2/index_alias.go new file mode 100644 index 0000000000..7a85d72131 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index_alias.go @@ -0,0 +1,37 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bleve + +// An IndexAlias is a wrapper around one or more +// Index objects. It has two distinct modes of +// operation. +// 1. When it points to a single index, ALL index +// operations are valid and will be passed through +// to the underlying index. +// 2. When it points to more than one index, the only +// valid operation is Search. In this case the +// search will be performed across all the +// underlying indexes and the results merged. +// Calls to Add/Remove/Swap the underlying indexes +// are atomic, so you can safely change the +// underlying Index objects while other components +// are performing operations. +type IndexAlias interface { + Index + + Add(i ...Index) + Remove(i ...Index) + Swap(in, out []Index) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index_alias_impl.go b/backend/vendor/github.com/blevesearch/bleve/v2/index_alias_impl.go new file mode 100644 index 0000000000..a73dd6b8fe --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index_alias_impl.go @@ -0,0 +1,616 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bleve + +import ( + "context" + "sync" + "time" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + index "github.com/blevesearch/bleve_index_api" +) + +type indexAliasImpl struct { + name string + indexes []Index + mutex sync.RWMutex + open bool +} + +// NewIndexAlias creates a new IndexAlias over the provided +// Index objects. +func NewIndexAlias(indexes ...Index) *indexAliasImpl { + return &indexAliasImpl{ + name: "alias", + indexes: indexes, + open: true, + } +} + +// VisitIndexes invokes the visit callback on every +// indexes included in the index alias. +func (i *indexAliasImpl) VisitIndexes(visit func(Index)) { + i.mutex.RLock() + for _, idx := range i.indexes { + visit(idx) + } + i.mutex.RUnlock() +} + +func (i *indexAliasImpl) isAliasToSingleIndex() error { + if len(i.indexes) < 1 { + return ErrorAliasEmpty + } else if len(i.indexes) > 1 { + return ErrorAliasMulti + } + return nil +} + +func (i *indexAliasImpl) Index(id string, data interface{}) error { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return ErrorIndexClosed + } + + err := i.isAliasToSingleIndex() + if err != nil { + return err + } + + return i.indexes[0].Index(id, data) +} + +func (i *indexAliasImpl) Delete(id string) error { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return ErrorIndexClosed + } + + err := i.isAliasToSingleIndex() + if err != nil { + return err + } + + return i.indexes[0].Delete(id) +} + +func (i *indexAliasImpl) Batch(b *Batch) error { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return ErrorIndexClosed + } + + err := i.isAliasToSingleIndex() + if err != nil { + return err + } + + return i.indexes[0].Batch(b) +} + +func (i *indexAliasImpl) Document(id string) (index.Document, error) { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return nil, ErrorIndexClosed + } + + err := i.isAliasToSingleIndex() + if err != nil { + return nil, err + } + + return i.indexes[0].Document(id) +} + +func (i *indexAliasImpl) DocCount() (uint64, error) { + i.mutex.RLock() + defer i.mutex.RUnlock() + + rv := uint64(0) + + if !i.open { + return 0, ErrorIndexClosed + } + + for _, index := range i.indexes { + otherCount, err := index.DocCount() + if err == nil { + rv += otherCount + } + // tolerate errors to produce partial counts + } + + return rv, nil +} + +func (i *indexAliasImpl) Search(req *SearchRequest) (*SearchResult, error) { + return i.SearchInContext(context.Background(), req) +} + +func (i *indexAliasImpl) SearchInContext(ctx context.Context, req *SearchRequest) (*SearchResult, error) { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return nil, ErrorIndexClosed + } + + if len(i.indexes) < 1 { + return nil, ErrorAliasEmpty + } + + // short circuit the simple case + if len(i.indexes) == 1 { + return i.indexes[0].SearchInContext(ctx, req) + } + + return MultiSearch(ctx, req, i.indexes...) +} + +func (i *indexAliasImpl) Fields() ([]string, error) { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return nil, ErrorIndexClosed + } + + err := i.isAliasToSingleIndex() + if err != nil { + return nil, err + } + + return i.indexes[0].Fields() +} + +func (i *indexAliasImpl) FieldDict(field string) (index.FieldDict, error) { + i.mutex.RLock() + + if !i.open { + i.mutex.RUnlock() + return nil, ErrorIndexClosed + } + + err := i.isAliasToSingleIndex() + if err != nil { + i.mutex.RUnlock() + return nil, err + } + + fieldDict, err := i.indexes[0].FieldDict(field) + if err != nil { + i.mutex.RUnlock() + return nil, err + } + + return &indexAliasImplFieldDict{ + index: i, + fieldDict: fieldDict, + }, nil +} + +func (i *indexAliasImpl) FieldDictRange(field string, startTerm []byte, endTerm []byte) (index.FieldDict, error) { + i.mutex.RLock() + + if !i.open { + i.mutex.RUnlock() + return nil, ErrorIndexClosed + } + + err := i.isAliasToSingleIndex() + if err != nil { + i.mutex.RUnlock() + return nil, err + } + + fieldDict, err := i.indexes[0].FieldDictRange(field, startTerm, endTerm) + if err != nil { + i.mutex.RUnlock() + return nil, err + } + + return &indexAliasImplFieldDict{ + index: i, + fieldDict: fieldDict, + }, nil +} + +func (i *indexAliasImpl) FieldDictPrefix(field string, termPrefix []byte) (index.FieldDict, error) { + i.mutex.RLock() + + if !i.open { + i.mutex.RUnlock() + return nil, ErrorIndexClosed + } + + err := i.isAliasToSingleIndex() + if err != nil { + i.mutex.RUnlock() + return nil, err + } + + fieldDict, err := i.indexes[0].FieldDictPrefix(field, termPrefix) + if err != nil { + i.mutex.RUnlock() + return nil, err + } + + return &indexAliasImplFieldDict{ + index: i, + fieldDict: fieldDict, + }, nil +} + +func (i *indexAliasImpl) Close() error { + i.mutex.Lock() + defer i.mutex.Unlock() + + i.open = false + return nil +} + +func (i *indexAliasImpl) Mapping() mapping.IndexMapping { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return nil + } + + err := i.isAliasToSingleIndex() + if err != nil { + return nil + } + + return i.indexes[0].Mapping() +} + +func (i *indexAliasImpl) Stats() *IndexStat { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return nil + } + + err := i.isAliasToSingleIndex() + if err != nil { + return nil + } + + return i.indexes[0].Stats() +} + +func (i *indexAliasImpl) StatsMap() map[string]interface{} { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return nil + } + + err := i.isAliasToSingleIndex() + if err != nil { + return nil + } + + return i.indexes[0].StatsMap() +} + +func (i *indexAliasImpl) GetInternal(key []byte) ([]byte, error) { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return nil, ErrorIndexClosed + } + + err := i.isAliasToSingleIndex() + if err != nil { + return nil, err + } + + return i.indexes[0].GetInternal(key) +} + +func (i *indexAliasImpl) SetInternal(key, val []byte) error { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return ErrorIndexClosed + } + + err := i.isAliasToSingleIndex() + if err != nil { + return err + } + + return i.indexes[0].SetInternal(key, val) +} + +func (i *indexAliasImpl) DeleteInternal(key []byte) error { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return ErrorIndexClosed + } + + err := i.isAliasToSingleIndex() + if err != nil { + return err + } + + return i.indexes[0].DeleteInternal(key) +} + +func (i *indexAliasImpl) Advanced() (index.Index, error) { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return nil, ErrorIndexClosed + } + + err := i.isAliasToSingleIndex() + if err != nil { + return nil, err + } + + return i.indexes[0].Advanced() +} + +func (i *indexAliasImpl) Add(indexes ...Index) { + i.mutex.Lock() + defer i.mutex.Unlock() + + i.indexes = append(i.indexes, indexes...) +} + +func (i *indexAliasImpl) removeSingle(index Index) { + for pos, in := range i.indexes { + if in == index { + i.indexes = append(i.indexes[:pos], i.indexes[pos+1:]...) + break + } + } +} + +func (i *indexAliasImpl) Remove(indexes ...Index) { + i.mutex.Lock() + defer i.mutex.Unlock() + + for _, in := range indexes { + i.removeSingle(in) + } +} + +func (i *indexAliasImpl) Swap(in, out []Index) { + i.mutex.Lock() + defer i.mutex.Unlock() + + // add + i.indexes = append(i.indexes, in...) + + // delete + for _, ind := range out { + i.removeSingle(ind) + } +} + +// createChildSearchRequest creates a separate +// request from the original +// For now, avoid data race on req structure. +// TODO disable highlight/field load on child +// requests, and add code to do this only on +// the actual final results. +// Perhaps that part needs to be optional, +// could be slower in remote usages. +func createChildSearchRequest(req *SearchRequest) *SearchRequest { + rv := SearchRequest{ + Query: req.Query, + Size: req.Size + req.From, + From: 0, + Highlight: req.Highlight, + Fields: req.Fields, + Facets: req.Facets, + Explain: req.Explain, + Sort: req.Sort.Copy(), + IncludeLocations: req.IncludeLocations, + Score: req.Score, + SearchAfter: req.SearchAfter, + SearchBefore: req.SearchBefore, + } + return &rv +} + +type asyncSearchResult struct { + Name string + Result *SearchResult + Err error +} + +// MultiSearch executes a SearchRequest across multiple Index objects, +// then merges the results. The indexes must honor any ctx deadline. +func MultiSearch(ctx context.Context, req *SearchRequest, indexes ...Index) (*SearchResult, error) { + + searchStart := time.Now() + asyncResults := make(chan *asyncSearchResult, len(indexes)) + + var reverseQueryExecution bool + if req.SearchBefore != nil { + reverseQueryExecution = true + req.Sort.Reverse() + req.SearchAfter = req.SearchBefore + req.SearchBefore = nil + } + + // run search on each index in separate go routine + var waitGroup sync.WaitGroup + + var searchChildIndex = func(in Index, childReq *SearchRequest) { + rv := asyncSearchResult{Name: in.Name()} + rv.Result, rv.Err = in.SearchInContext(ctx, childReq) + asyncResults <- &rv + waitGroup.Done() + } + + waitGroup.Add(len(indexes)) + for _, in := range indexes { + go searchChildIndex(in, createChildSearchRequest(req)) + } + + // on another go routine, close after finished + go func() { + waitGroup.Wait() + close(asyncResults) + }() + + var sr *SearchResult + indexErrors := make(map[string]error) + + for asr := range asyncResults { + if asr.Err == nil { + if sr == nil { + // first result + sr = asr.Result + } else { + // merge with previous + sr.Merge(asr.Result) + } + } else { + indexErrors[asr.Name] = asr.Err + } + } + + // merge just concatenated all the hits + // now lets clean it up + + // handle case where no results were successful + if sr == nil { + sr = &SearchResult{ + Status: &SearchStatus{ + Errors: make(map[string]error), + }, + } + } + + sortFunc := req.SortFunc() + // sort all hits with the requested order + if len(req.Sort) > 0 { + sorter := newSearchHitSorter(req.Sort, sr.Hits) + sortFunc(sorter) + } + + // now skip over the correct From + if req.From > 0 && len(sr.Hits) > req.From { + sr.Hits = sr.Hits[req.From:] + } else if req.From > 0 { + sr.Hits = search.DocumentMatchCollection{} + } + + // now trim to the correct size + if req.Size > 0 && len(sr.Hits) > req.Size { + sr.Hits = sr.Hits[0:req.Size] + } + + // fix up facets + for name, fr := range req.Facets { + sr.Facets.Fixup(name, fr.Size) + } + + if reverseQueryExecution { + // reverse the sort back to the original + req.Sort.Reverse() + // resort using the original order + mhs := newSearchHitSorter(req.Sort, sr.Hits) + sortFunc(mhs) + // reset request + req.SearchBefore = req.SearchAfter + req.SearchAfter = nil + } + + // fix up original request + sr.Request = req + searchDuration := time.Since(searchStart) + sr.Took = searchDuration + + // fix up errors + if len(indexErrors) > 0 { + if sr.Status.Errors == nil { + sr.Status.Errors = make(map[string]error) + } + for indexName, indexErr := range indexErrors { + sr.Status.Errors[indexName] = indexErr + sr.Status.Total++ + sr.Status.Failed++ + } + } + + return sr, nil +} + +func (i *indexAliasImpl) NewBatch() *Batch { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return nil + } + + err := i.isAliasToSingleIndex() + if err != nil { + return nil + } + + return i.indexes[0].NewBatch() +} + +func (i *indexAliasImpl) Name() string { + return i.name +} + +func (i *indexAliasImpl) SetName(name string) { + i.name = name +} + +type indexAliasImplFieldDict struct { + index *indexAliasImpl + fieldDict index.FieldDict +} + +func (f *indexAliasImplFieldDict) BytesRead() uint64 { + return f.fieldDict.BytesRead() +} + +func (f *indexAliasImplFieldDict) Next() (*index.DictEntry, error) { + return f.fieldDict.Next() +} + +func (f *indexAliasImplFieldDict) Close() error { + defer f.index.mutex.RUnlock() + return f.fieldDict.Close() +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index_impl.go b/backend/vendor/github.com/blevesearch/bleve/v2/index_impl.go new file mode 100644 index 0000000000..c5a0c46f44 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index_impl.go @@ -0,0 +1,993 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bleve + +import ( + "context" + "encoding/json" + "fmt" + "io" + "os" + "path/filepath" + "sync" + "sync/atomic" + "time" + + "github.com/blevesearch/bleve/v2/document" + "github.com/blevesearch/bleve/v2/index/scorch" + "github.com/blevesearch/bleve/v2/index/upsidedown" + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/registry" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/collector" + "github.com/blevesearch/bleve/v2/search/facet" + "github.com/blevesearch/bleve/v2/search/highlight" + index "github.com/blevesearch/bleve_index_api" +) + +type indexImpl struct { + path string + name string + meta *indexMeta + i index.Index + m mapping.IndexMapping + mutex sync.RWMutex + open bool + stats *IndexStat +} + +const storePath = "store" + +var mappingInternalKey = []byte("_mapping") + +const SearchQueryStartCallbackKey = "_search_query_start_callback_key" +const SearchQueryEndCallbackKey = "_search_query_end_callback_key" + +type SearchQueryStartCallbackFn func(size uint64) error +type SearchQueryEndCallbackFn func(size uint64) error + +func indexStorePath(path string) string { + return path + string(os.PathSeparator) + storePath +} + +func newIndexUsing(path string, mapping mapping.IndexMapping, indexType string, kvstore string, kvconfig map[string]interface{}) (*indexImpl, error) { + // first validate the mapping + err := mapping.Validate() + if err != nil { + return nil, err + } + + if kvconfig == nil { + kvconfig = map[string]interface{}{} + } + + if kvstore == "" { + return nil, fmt.Errorf("bleve not configured for file based indexing") + } + + rv := indexImpl{ + path: path, + name: path, + m: mapping, + meta: newIndexMeta(indexType, kvstore, kvconfig), + } + rv.stats = &IndexStat{i: &rv} + // at this point there is hope that we can be successful, so save index meta + if path != "" { + err = rv.meta.Save(path) + if err != nil { + return nil, err + } + kvconfig["create_if_missing"] = true + kvconfig["error_if_exists"] = true + kvconfig["path"] = indexStorePath(path) + } else { + kvconfig["path"] = "" + } + + // open the index + indexTypeConstructor := registry.IndexTypeConstructorByName(rv.meta.IndexType) + if indexTypeConstructor == nil { + return nil, ErrorUnknownIndexType + } + + rv.i, err = indexTypeConstructor(rv.meta.Storage, kvconfig, Config.analysisQueue) + if err != nil { + return nil, err + } + err = rv.i.Open() + if err != nil { + return nil, err + } + defer func(rv *indexImpl) { + if !rv.open { + rv.i.Close() + } + }(&rv) + + // now persist the mapping + mappingBytes, err := json.Marshal(mapping) + if err != nil { + return nil, err + } + err = rv.i.SetInternal(mappingInternalKey, mappingBytes) + if err != nil { + return nil, err + } + + // mark the index as open + rv.mutex.Lock() + defer rv.mutex.Unlock() + rv.open = true + indexStats.Register(&rv) + return &rv, nil +} + +func openIndexUsing(path string, runtimeConfig map[string]interface{}) (rv *indexImpl, err error) { + rv = &indexImpl{ + path: path, + name: path, + } + rv.stats = &IndexStat{i: rv} + + rv.meta, err = openIndexMeta(path) + if err != nil { + return nil, err + } + + // backwards compatibility if index type is missing + if rv.meta.IndexType == "" { + rv.meta.IndexType = upsidedown.Name + } + + storeConfig := rv.meta.Config + if storeConfig == nil { + storeConfig = map[string]interface{}{} + } + + storeConfig["path"] = indexStorePath(path) + storeConfig["create_if_missing"] = false + storeConfig["error_if_exists"] = false + for rck, rcv := range runtimeConfig { + storeConfig[rck] = rcv + } + + // open the index + indexTypeConstructor := registry.IndexTypeConstructorByName(rv.meta.IndexType) + if indexTypeConstructor == nil { + return nil, ErrorUnknownIndexType + } + + rv.i, err = indexTypeConstructor(rv.meta.Storage, storeConfig, Config.analysisQueue) + if err != nil { + return nil, err + } + err = rv.i.Open() + if err != nil { + return nil, err + } + defer func(rv *indexImpl) { + if !rv.open { + rv.i.Close() + } + }(rv) + + // now load the mapping + indexReader, err := rv.i.Reader() + if err != nil { + return nil, err + } + defer func() { + if cerr := indexReader.Close(); cerr != nil && err == nil { + err = cerr + } + }() + + mappingBytes, err := indexReader.GetInternal(mappingInternalKey) + if err != nil { + return nil, err + } + + var im *mapping.IndexMappingImpl + err = json.Unmarshal(mappingBytes, &im) + if err != nil { + return nil, fmt.Errorf("error parsing mapping JSON: %v\nmapping contents:\n%s", err, string(mappingBytes)) + } + + // mark the index as open + rv.mutex.Lock() + defer rv.mutex.Unlock() + rv.open = true + + // validate the mapping + err = im.Validate() + if err != nil { + // note even if the mapping is invalid + // we still return an open usable index + return rv, err + } + + rv.m = im + indexStats.Register(rv) + return rv, err +} + +// Advanced returns internal index implementation +func (i *indexImpl) Advanced() (index.Index, error) { + return i.i, nil +} + +// Mapping returns the IndexMapping in use by this +// Index. +func (i *indexImpl) Mapping() mapping.IndexMapping { + return i.m +} + +// Index the object with the specified identifier. +// The IndexMapping for this index will determine +// how the object is indexed. +func (i *indexImpl) Index(id string, data interface{}) (err error) { + if id == "" { + return ErrorEmptyID + } + + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return ErrorIndexClosed + } + + doc := document.NewDocument(id) + err = i.m.MapDocument(doc, data) + if err != nil { + return + } + err = i.i.Update(doc) + return +} + +// IndexAdvanced takes a document.Document object +// skips the mapping and indexes it. +func (i *indexImpl) IndexAdvanced(doc *document.Document) (err error) { + if doc.ID() == "" { + return ErrorEmptyID + } + + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return ErrorIndexClosed + } + + err = i.i.Update(doc) + return +} + +// Delete entries for the specified identifier from +// the index. +func (i *indexImpl) Delete(id string) (err error) { + if id == "" { + return ErrorEmptyID + } + + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return ErrorIndexClosed + } + + err = i.i.Delete(id) + return +} + +// Batch executes multiple Index and Delete +// operations at the same time. There are often +// significant performance benefits when performing +// operations in a batch. +func (i *indexImpl) Batch(b *Batch) error { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return ErrorIndexClosed + } + + return i.i.Batch(b.internal) +} + +// Document is used to find the values of all the +// stored fields for a document in the index. These +// stored fields are put back into a Document object +// and returned. +func (i *indexImpl) Document(id string) (doc index.Document, err error) { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return nil, ErrorIndexClosed + } + indexReader, err := i.i.Reader() + if err != nil { + return nil, err + } + defer func() { + if cerr := indexReader.Close(); err == nil && cerr != nil { + err = cerr + } + }() + + doc, err = indexReader.Document(id) + if err != nil { + return nil, err + } + return doc, nil +} + +// DocCount returns the number of documents in the +// index. +func (i *indexImpl) DocCount() (count uint64, err error) { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return 0, ErrorIndexClosed + } + + // open a reader for this search + indexReader, err := i.i.Reader() + if err != nil { + return 0, fmt.Errorf("error opening index reader %v", err) + } + defer func() { + if cerr := indexReader.Close(); err == nil && cerr != nil { + err = cerr + } + }() + + count, err = indexReader.DocCount() + return +} + +// Search executes a search request operation. +// Returns a SearchResult object or an error. +func (i *indexImpl) Search(req *SearchRequest) (sr *SearchResult, err error) { + return i.SearchInContext(context.Background(), req) +} + +var documentMatchEmptySize int +var searchContextEmptySize int +var facetResultEmptySize int +var documentEmptySize int + +func init() { + var dm search.DocumentMatch + documentMatchEmptySize = dm.Size() + + var sc search.SearchContext + searchContextEmptySize = sc.Size() + + var fr search.FacetResult + facetResultEmptySize = fr.Size() + + var d document.Document + documentEmptySize = d.Size() +} + +// memNeededForSearch is a helper function that returns an estimate of RAM +// needed to execute a search request. +func memNeededForSearch(req *SearchRequest, + searcher search.Searcher, + topnCollector *collector.TopNCollector) uint64 { + + backingSize := req.Size + req.From + 1 + if req.Size+req.From > collector.PreAllocSizeSkipCap { + backingSize = collector.PreAllocSizeSkipCap + 1 + } + numDocMatches := backingSize + searcher.DocumentMatchPoolSize() + + estimate := 0 + + // overhead, size in bytes from collector + estimate += topnCollector.Size() + + // pre-allocing DocumentMatchPool + estimate += searchContextEmptySize + numDocMatches*documentMatchEmptySize + + // searcher overhead + estimate += searcher.Size() + + // overhead from results, lowestMatchOutsideResults + estimate += (numDocMatches + 1) * documentMatchEmptySize + + // additional overhead from SearchResult + estimate += reflectStaticSizeSearchResult + reflectStaticSizeSearchStatus + + // overhead from facet results + if req.Facets != nil { + estimate += len(req.Facets) * facetResultEmptySize + } + + // highlighting, store + if len(req.Fields) > 0 || req.Highlight != nil { + // Size + From => number of hits + estimate += (req.Size + req.From) * documentEmptySize + } + + return uint64(estimate) +} + +// SearchInContext executes a search request operation within the provided +// Context. Returns a SearchResult object or an error. +func (i *indexImpl) SearchInContext(ctx context.Context, req *SearchRequest) (sr *SearchResult, err error) { + i.mutex.RLock() + defer i.mutex.RUnlock() + + searchStart := time.Now() + + if !i.open { + return nil, ErrorIndexClosed + } + + var reverseQueryExecution bool + if req.SearchBefore != nil { + reverseQueryExecution = true + req.Sort.Reverse() + req.SearchAfter = req.SearchBefore + req.SearchBefore = nil + } + + var coll *collector.TopNCollector + if req.SearchAfter != nil { + coll = collector.NewTopNCollectorAfter(req.Size, req.Sort, req.SearchAfter) + } else { + coll = collector.NewTopNCollector(req.Size, req.From, req.Sort) + } + + // open a reader for this search + indexReader, err := i.i.Reader() + if err != nil { + return nil, fmt.Errorf("error opening index reader %v", err) + } + defer func() { + if cerr := indexReader.Close(); err == nil && cerr != nil { + err = cerr + } + }() + + // This callback and variable handles the tracking of bytes read + // 1. as part of creation of tfr and its Next() calls which is + // accounted by invoking this callback when the TFR is closed. + // 2. the docvalues portion (accounted in collector) and the retrieval + // of stored fields bytes (by LoadAndHighlightFields) + var totalBytesRead uint64 + sendBytesRead := func(bytesRead uint64) { + totalBytesRead += bytesRead + } + + ctx = context.WithValue(ctx, search.SearchIOStatsCallbackKey, + search.SearchIOStatsCallbackFunc(sendBytesRead)) + + searcher, err := req.Query.Searcher(ctx, indexReader, i.m, search.SearcherOptions{ + Explain: req.Explain, + IncludeTermVectors: req.IncludeLocations || req.Highlight != nil, + Score: req.Score, + }) + if err != nil { + return nil, err + } + defer func() { + if serr := searcher.Close(); err == nil && serr != nil { + err = serr + } + if sr != nil { + sr.BytesRead = totalBytesRead + } + if sr, ok := indexReader.(*scorch.IndexSnapshot); ok { + sr.UpdateIOStats(totalBytesRead) + } + }() + + if req.Facets != nil { + facetsBuilder := search.NewFacetsBuilder(indexReader) + for facetName, facetRequest := range req.Facets { + if facetRequest.NumericRanges != nil { + // build numeric range facet + facetBuilder := facet.NewNumericFacetBuilder(facetRequest.Field, facetRequest.Size) + for _, nr := range facetRequest.NumericRanges { + facetBuilder.AddRange(nr.Name, nr.Min, nr.Max) + } + facetsBuilder.Add(facetName, facetBuilder) + } else if facetRequest.DateTimeRanges != nil { + // build date range facet + facetBuilder := facet.NewDateTimeFacetBuilder(facetRequest.Field, facetRequest.Size) + dateTimeParser := i.m.DateTimeParserNamed("") + for _, dr := range facetRequest.DateTimeRanges { + start, end := dr.ParseDates(dateTimeParser) + facetBuilder.AddRange(dr.Name, start, end) + } + facetsBuilder.Add(facetName, facetBuilder) + } else { + // build terms facet + facetBuilder := facet.NewTermsFacetBuilder(facetRequest.Field, facetRequest.Size) + facetsBuilder.Add(facetName, facetBuilder) + } + } + coll.SetFacetsBuilder(facetsBuilder) + } + + memNeeded := memNeededForSearch(req, searcher, coll) + if cb := ctx.Value(SearchQueryStartCallbackKey); cb != nil { + if cbF, ok := cb.(SearchQueryStartCallbackFn); ok { + err = cbF(memNeeded) + } + } + if err != nil { + return nil, err + } + + if cb := ctx.Value(SearchQueryEndCallbackKey); cb != nil { + if cbF, ok := cb.(SearchQueryEndCallbackFn); ok { + defer func() { + _ = cbF(memNeeded) + }() + } + } + + err = coll.Collect(ctx, searcher, indexReader) + if err != nil { + return nil, err + } + + hits := coll.Results() + + var highlighter highlight.Highlighter + + if req.Highlight != nil { + // get the right highlighter + highlighter, err = Config.Cache.HighlighterNamed(Config.DefaultHighlighter) + if err != nil { + return nil, err + } + if req.Highlight.Style != nil { + highlighter, err = Config.Cache.HighlighterNamed(*req.Highlight.Style) + if err != nil { + return nil, err + } + } + if highlighter == nil { + return nil, fmt.Errorf("no highlighter named `%s` registered", *req.Highlight.Style) + } + } + + for _, hit := range hits { + if i.name != "" { + hit.Index = i.name + } + err, storedFieldsBytes := LoadAndHighlightFields(hit, req, i.name, indexReader, highlighter) + if err != nil { + return nil, err + } + totalBytesRead += storedFieldsBytes + } + + atomic.AddUint64(&i.stats.searches, 1) + searchDuration := time.Since(searchStart) + atomic.AddUint64(&i.stats.searchTime, uint64(searchDuration)) + + if Config.SlowSearchLogThreshold > 0 && + searchDuration > Config.SlowSearchLogThreshold { + logger.Printf("slow search took %s - %v", searchDuration, req) + } + + if reverseQueryExecution { + // reverse the sort back to the original + req.Sort.Reverse() + // resort using the original order + mhs := newSearchHitSorter(req.Sort, hits) + req.SortFunc()(mhs) + // reset request + req.SearchBefore = req.SearchAfter + req.SearchAfter = nil + } + + return &SearchResult{ + Status: &SearchStatus{ + Total: 1, + Successful: 1, + }, + Request: req, + Hits: hits, + Total: coll.Total(), + MaxScore: coll.MaxScore(), + Took: searchDuration, + Facets: coll.FacetResults(), + }, nil +} + +func LoadAndHighlightFields(hit *search.DocumentMatch, req *SearchRequest, + indexName string, r index.IndexReader, + highlighter highlight.Highlighter) (error, uint64) { + var totalStoredFieldsBytes uint64 + if len(req.Fields) > 0 || highlighter != nil { + doc, err := r.Document(hit.ID) + totalStoredFieldsBytes = doc.StoredFieldsBytes() + if err == nil && doc != nil { + if len(req.Fields) > 0 { + fieldsToLoad := deDuplicate(req.Fields) + for _, f := range fieldsToLoad { + doc.VisitFields(func(docF index.Field) { + if f == "*" || docF.Name() == f { + var value interface{} + switch docF := docF.(type) { + case index.TextField: + value = docF.Text() + case index.NumericField: + num, err := docF.Number() + if err == nil { + value = num + } + case index.DateTimeField: + datetime, err := docF.DateTime() + if err == nil { + value = datetime.Format(time.RFC3339) + } + case index.BooleanField: + boolean, err := docF.Boolean() + if err == nil { + value = boolean + } + case index.GeoPointField: + lon, err := docF.Lon() + if err == nil { + lat, err := docF.Lat() + if err == nil { + value = []float64{lon, lat} + } + } + case index.GeoShapeField: + v, err := docF.GeoShape() + if err == nil { + value = v + } + } + + if value != nil { + hit.AddFieldValue(docF.Name(), value) + } + } + }) + } + } + if highlighter != nil { + highlightFields := req.Highlight.Fields + if highlightFields == nil { + // add all fields with matches + highlightFields = make([]string, 0, len(hit.Locations)) + for k := range hit.Locations { + highlightFields = append(highlightFields, k) + } + } + for _, hf := range highlightFields { + highlighter.BestFragmentsInField(hit, doc, hf, 1) + } + } + } else if doc == nil { + // unexpected case, a doc ID that was found as a search hit + // was unable to be found during document lookup + return ErrorIndexReadInconsistency, 0 + } + } + + return nil, totalStoredFieldsBytes +} + +// Fields returns the name of all the fields this +// Index has operated on. +func (i *indexImpl) Fields() (fields []string, err error) { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return nil, ErrorIndexClosed + } + + indexReader, err := i.i.Reader() + if err != nil { + return nil, err + } + defer func() { + if cerr := indexReader.Close(); err == nil && cerr != nil { + err = cerr + } + }() + + fields, err = indexReader.Fields() + if err != nil { + return nil, err + } + return fields, nil +} + +func (i *indexImpl) FieldDict(field string) (index.FieldDict, error) { + i.mutex.RLock() + + if !i.open { + i.mutex.RUnlock() + return nil, ErrorIndexClosed + } + + indexReader, err := i.i.Reader() + if err != nil { + i.mutex.RUnlock() + return nil, err + } + + fieldDict, err := indexReader.FieldDict(field) + if err != nil { + i.mutex.RUnlock() + return nil, err + } + + return &indexImplFieldDict{ + index: i, + indexReader: indexReader, + fieldDict: fieldDict, + }, nil +} + +func (i *indexImpl) FieldDictRange(field string, startTerm []byte, endTerm []byte) (index.FieldDict, error) { + i.mutex.RLock() + + if !i.open { + i.mutex.RUnlock() + return nil, ErrorIndexClosed + } + + indexReader, err := i.i.Reader() + if err != nil { + i.mutex.RUnlock() + return nil, err + } + + fieldDict, err := indexReader.FieldDictRange(field, startTerm, endTerm) + if err != nil { + i.mutex.RUnlock() + return nil, err + } + + return &indexImplFieldDict{ + index: i, + indexReader: indexReader, + fieldDict: fieldDict, + }, nil +} + +func (i *indexImpl) FieldDictPrefix(field string, termPrefix []byte) (index.FieldDict, error) { + i.mutex.RLock() + + if !i.open { + i.mutex.RUnlock() + return nil, ErrorIndexClosed + } + + indexReader, err := i.i.Reader() + if err != nil { + i.mutex.RUnlock() + return nil, err + } + + fieldDict, err := indexReader.FieldDictPrefix(field, termPrefix) + if err != nil { + i.mutex.RUnlock() + return nil, err + } + + return &indexImplFieldDict{ + index: i, + indexReader: indexReader, + fieldDict: fieldDict, + }, nil +} + +func (i *indexImpl) Close() error { + i.mutex.Lock() + defer i.mutex.Unlock() + + indexStats.UnRegister(i) + + i.open = false + return i.i.Close() +} + +func (i *indexImpl) Stats() *IndexStat { + return i.stats +} + +func (i *indexImpl) StatsMap() map[string]interface{} { + return i.stats.statsMap() +} + +func (i *indexImpl) GetInternal(key []byte) (val []byte, err error) { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return nil, ErrorIndexClosed + } + + reader, err := i.i.Reader() + if err != nil { + return nil, err + } + defer func() { + if cerr := reader.Close(); err == nil && cerr != nil { + err = cerr + } + }() + + val, err = reader.GetInternal(key) + if err != nil { + return nil, err + } + return val, nil +} + +func (i *indexImpl) SetInternal(key, val []byte) error { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return ErrorIndexClosed + } + + return i.i.SetInternal(key, val) +} + +func (i *indexImpl) DeleteInternal(key []byte) error { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return ErrorIndexClosed + } + + return i.i.DeleteInternal(key) +} + +// NewBatch creates a new empty batch. +func (i *indexImpl) NewBatch() *Batch { + return &Batch{ + index: i, + internal: index.NewBatch(), + } +} + +func (i *indexImpl) Name() string { + return i.name +} + +func (i *indexImpl) SetName(name string) { + indexStats.UnRegister(i) + i.name = name + indexStats.Register(i) +} + +type indexImplFieldDict struct { + index *indexImpl + indexReader index.IndexReader + fieldDict index.FieldDict +} + +func (f *indexImplFieldDict) BytesRead() uint64 { + return f.fieldDict.BytesRead() +} + +func (f *indexImplFieldDict) Next() (*index.DictEntry, error) { + return f.fieldDict.Next() +} + +func (f *indexImplFieldDict) Close() error { + defer f.index.mutex.RUnlock() + err := f.fieldDict.Close() + if err != nil { + return err + } + return f.indexReader.Close() +} + +// helper function to remove duplicate entries from slice of strings +func deDuplicate(fields []string) []string { + entries := make(map[string]struct{}) + ret := []string{} + for _, entry := range fields { + if _, exists := entries[entry]; !exists { + entries[entry] = struct{}{} + ret = append(ret, entry) + } + } + return ret +} + +type searchHitSorter struct { + hits search.DocumentMatchCollection + sort search.SortOrder + cachedScoring []bool + cachedDesc []bool +} + +func newSearchHitSorter(sort search.SortOrder, hits search.DocumentMatchCollection) *searchHitSorter { + return &searchHitSorter{ + sort: sort, + hits: hits, + cachedScoring: sort.CacheIsScore(), + cachedDesc: sort.CacheDescending(), + } +} + +func (m *searchHitSorter) Len() int { return len(m.hits) } +func (m *searchHitSorter) Swap(i, j int) { m.hits[i], m.hits[j] = m.hits[j], m.hits[i] } +func (m *searchHitSorter) Less(i, j int) bool { + c := m.sort.Compare(m.cachedScoring, m.cachedDesc, m.hits[i], m.hits[j]) + return c < 0 +} + +func (i *indexImpl) CopyTo(d index.Directory) (err error) { + i.mutex.RLock() + defer i.mutex.RUnlock() + + if !i.open { + return ErrorIndexClosed + } + + indexReader, err := i.i.Reader() + if err != nil { + return err + } + defer func() { + if cerr := indexReader.Close(); err == nil && cerr != nil { + err = cerr + } + }() + + irc, ok := indexReader.(IndexCopyable) + if !ok { + return fmt.Errorf("index implementation does not support copy") + } + + err = irc.CopyTo(d) + if err != nil { + return fmt.Errorf("error copying index metadata: %v", err) + } + + // copy the metadata + return i.meta.CopyTo(d) +} + +func (f FileSystemDirectory) GetWriter(filePath string) (io.WriteCloser, + error) { + dir, file := filepath.Split(filePath) + if dir != "" { + err := os.MkdirAll(filepath.Join(string(f), dir), os.ModePerm) + if err != nil { + return nil, err + } + } + + return os.OpenFile(filepath.Join(string(f), dir, file), + os.O_RDWR|os.O_CREATE, 0600) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index_meta.go b/backend/vendor/github.com/blevesearch/bleve/v2/index_meta.go new file mode 100644 index 0000000000..90c7fffac8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index_meta.go @@ -0,0 +1,115 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bleve + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + + "github.com/blevesearch/bleve/v2/index/upsidedown" + index "github.com/blevesearch/bleve_index_api" +) + +const metaFilename = "index_meta.json" + +type indexMeta struct { + Storage string `json:"storage"` + IndexType string `json:"index_type"` + Config map[string]interface{} `json:"config,omitempty"` +} + +func newIndexMeta(indexType string, storage string, config map[string]interface{}) *indexMeta { + return &indexMeta{ + IndexType: indexType, + Storage: storage, + Config: config, + } +} + +func openIndexMeta(path string) (*indexMeta, error) { + if _, err := os.Stat(path); os.IsNotExist(err) { + return nil, ErrorIndexPathDoesNotExist + } + indexMetaPath := indexMetaPath(path) + metaBytes, err := os.ReadFile(indexMetaPath) + if err != nil { + return nil, ErrorIndexMetaMissing + } + var im indexMeta + err = json.Unmarshal(metaBytes, &im) + if err != nil { + return nil, ErrorIndexMetaCorrupt + } + if im.IndexType == "" { + im.IndexType = upsidedown.Name + } + return &im, nil +} + +func (i *indexMeta) Save(path string) (err error) { + indexMetaPath := indexMetaPath(path) + // ensure any necessary parent directories exist + err = os.MkdirAll(path, 0700) + if err != nil { + if os.IsExist(err) { + return ErrorIndexPathExists + } + return err + } + metaBytes, err := json.Marshal(i) + if err != nil { + return err + } + indexMetaFile, err := os.OpenFile(indexMetaPath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666) + if err != nil { + if os.IsExist(err) { + return ErrorIndexPathExists + } + return err + } + defer func() { + if ierr := indexMetaFile.Close(); err == nil && ierr != nil { + err = ierr + } + }() + _, err = indexMetaFile.Write(metaBytes) + if err != nil { + return err + } + return nil +} + +func (i *indexMeta) CopyTo(d index.Directory) (err error) { + metaBytes, err := json.Marshal(i) + if err != nil { + return err + } + + w, err := d.GetWriter(metaFilename) + if w == nil || err != nil { + return fmt.Errorf("invalid writer for file: %s, err: %v", + metaFilename, err) + } + defer w.Close() + + _, err = w.Write(metaBytes) + return err +} + +func indexMetaPath(path string) string { + return filepath.Join(path, metaFilename) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/index_stats.go b/backend/vendor/github.com/blevesearch/bleve/v2/index_stats.go new file mode 100644 index 0000000000..2d303f6ebf --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/index_stats.go @@ -0,0 +1,75 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bleve + +import ( + "encoding/json" + "sync" + "sync/atomic" +) + +type IndexStat struct { + searches uint64 + searchTime uint64 + i *indexImpl +} + +func (is *IndexStat) statsMap() map[string]interface{} { + m := map[string]interface{}{} + m["index"] = is.i.i.StatsMap() + m["searches"] = atomic.LoadUint64(&is.searches) + m["search_time"] = atomic.LoadUint64(&is.searchTime) + return m +} + +func (is *IndexStat) MarshalJSON() ([]byte, error) { + m := is.statsMap() + return json.Marshal(m) +} + +type IndexStats struct { + indexes map[string]*IndexStat + mutex sync.RWMutex +} + +func NewIndexStats() *IndexStats { + return &IndexStats{ + indexes: make(map[string]*IndexStat), + } +} + +func (i *IndexStats) Register(index Index) { + i.mutex.Lock() + defer i.mutex.Unlock() + i.indexes[index.Name()] = index.Stats() +} + +func (i *IndexStats) UnRegister(index Index) { + i.mutex.Lock() + defer i.mutex.Unlock() + delete(i.indexes, index.Name()) +} + +func (i *IndexStats) String() string { + i.mutex.RLock() + defer i.mutex.RUnlock() + bytes, err := json.Marshal(i.indexes) + if err != nil { + return "error marshaling stats" + } + return string(bytes) +} + +var indexStats *IndexStats diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/mapping.go b/backend/vendor/github.com/blevesearch/bleve/v2/mapping.go new file mode 100644 index 0000000000..723105a294 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/mapping.go @@ -0,0 +1,79 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bleve + +import "github.com/blevesearch/bleve/v2/mapping" + +// NewIndexMapping creates a new IndexMapping that will use all the default indexing rules +func NewIndexMapping() *mapping.IndexMappingImpl { + return mapping.NewIndexMapping() +} + +// NewDocumentMapping returns a new document mapping +// with all the default values. +func NewDocumentMapping() *mapping.DocumentMapping { + return mapping.NewDocumentMapping() +} + +// NewDocumentStaticMapping returns a new document +// mapping that will not automatically index parts +// of a document without an explicit mapping. +func NewDocumentStaticMapping() *mapping.DocumentMapping { + return mapping.NewDocumentStaticMapping() +} + +// NewDocumentDisabledMapping returns a new document +// mapping that will not perform any indexing. +func NewDocumentDisabledMapping() *mapping.DocumentMapping { + return mapping.NewDocumentDisabledMapping() +} + +// NewTextFieldMapping returns a default field mapping for text +func NewTextFieldMapping() *mapping.FieldMapping { + return mapping.NewTextFieldMapping() +} + +// NewKeywordFieldMapping returns a field mapping for text using the keyword +// analyzer, which essentially doesn't apply any specific text analysis. +func NewKeywordFieldMapping() *mapping.FieldMapping { + return mapping.NewKeywordFieldMapping() +} + +// NewNumericFieldMapping returns a default field mapping for numbers +func NewNumericFieldMapping() *mapping.FieldMapping { + return mapping.NewNumericFieldMapping() +} + +// NewDateTimeFieldMapping returns a default field mapping for dates +func NewDateTimeFieldMapping() *mapping.FieldMapping { + return mapping.NewDateTimeFieldMapping() +} + +// NewBooleanFieldMapping returns a default field mapping for booleans +func NewBooleanFieldMapping() *mapping.FieldMapping { + return mapping.NewBooleanFieldMapping() +} + +func NewGeoPointFieldMapping() *mapping.FieldMapping { + return mapping.NewGeoPointFieldMapping() +} + +func NewGeoShapeFieldMapping() *mapping.FieldMapping { + return mapping.NewGeoShapeFieldMapping() +} + +func NewIPFieldMapping() *mapping.FieldMapping { + return mapping.NewIPFieldMapping() +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/mapping/analysis.go b/backend/vendor/github.com/blevesearch/bleve/v2/mapping/analysis.go new file mode 100644 index 0000000000..03e3cd01be --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/mapping/analysis.go @@ -0,0 +1,99 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mapping + +type customAnalysis struct { + CharFilters map[string]map[string]interface{} `json:"char_filters,omitempty"` + Tokenizers map[string]map[string]interface{} `json:"tokenizers,omitempty"` + TokenMaps map[string]map[string]interface{} `json:"token_maps,omitempty"` + TokenFilters map[string]map[string]interface{} `json:"token_filters,omitempty"` + Analyzers map[string]map[string]interface{} `json:"analyzers,omitempty"` + DateTimeParsers map[string]map[string]interface{} `json:"date_time_parsers,omitempty"` +} + +func (c *customAnalysis) registerAll(i *IndexMappingImpl) error { + for name, config := range c.CharFilters { + _, err := i.cache.DefineCharFilter(name, config) + if err != nil { + return err + } + } + + if len(c.Tokenizers) > 0 { + // put all the names in map tracking work to do + todo := map[string]struct{}{} + for name := range c.Tokenizers { + todo[name] = struct{}{} + } + registered := 1 + errs := []error{} + // as long as we keep making progress, keep going + for len(todo) > 0 && registered > 0 { + registered = 0 + errs = []error{} + for name := range todo { + config := c.Tokenizers[name] + _, err := i.cache.DefineTokenizer(name, config) + if err != nil { + errs = append(errs, err) + } else { + delete(todo, name) + registered++ + } + } + } + + if len(errs) > 0 { + return errs[0] + } + } + for name, config := range c.TokenMaps { + _, err := i.cache.DefineTokenMap(name, config) + if err != nil { + return err + } + } + for name, config := range c.TokenFilters { + _, err := i.cache.DefineTokenFilter(name, config) + if err != nil { + return err + } + } + for name, config := range c.Analyzers { + _, err := i.cache.DefineAnalyzer(name, config) + if err != nil { + return err + } + } + for name, config := range c.DateTimeParsers { + _, err := i.cache.DefineDateTimeParser(name, config) + if err != nil { + return err + } + } + return nil +} + +func newCustomAnalysis() *customAnalysis { + rv := customAnalysis{ + CharFilters: make(map[string]map[string]interface{}), + Tokenizers: make(map[string]map[string]interface{}), + TokenMaps: make(map[string]map[string]interface{}), + TokenFilters: make(map[string]map[string]interface{}), + Analyzers: make(map[string]map[string]interface{}), + DateTimeParsers: make(map[string]map[string]interface{}), + } + return &rv +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/mapping/document.go b/backend/vendor/github.com/blevesearch/bleve/v2/mapping/document.go new file mode 100644 index 0000000000..3f3bbfd38d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/mapping/document.go @@ -0,0 +1,572 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mapping + +import ( + "encoding" + "encoding/json" + "fmt" + "net" + "reflect" + "time" + + "github.com/blevesearch/bleve/v2/registry" +) + +// A DocumentMapping describes how a type of document +// should be indexed. +// As documents can be hierarchical, named sub-sections +// of documents are mapped using the same structure in +// the Properties field. +// Each value inside a document can be indexed 0 or more +// ways. These index entries are called fields and +// are stored in the Fields field. +// Entire sections of a document can be ignored or +// excluded by setting Enabled to false. +// If not explicitly mapped, default mapping operations +// are used. To disable this automatic handling, set +// Dynamic to false. +type DocumentMapping struct { + Enabled bool `json:"enabled"` + Dynamic bool `json:"dynamic"` + Properties map[string]*DocumentMapping `json:"properties,omitempty"` + Fields []*FieldMapping `json:"fields,omitempty"` + DefaultAnalyzer string `json:"default_analyzer,omitempty"` + + // StructTagKey overrides "json" when looking for field names in struct tags + StructTagKey string `json:"struct_tag_key,omitempty"` +} + +func (dm *DocumentMapping) Validate(cache *registry.Cache) error { + var err error + if dm.DefaultAnalyzer != "" { + _, err := cache.AnalyzerNamed(dm.DefaultAnalyzer) + if err != nil { + return err + } + } + for _, property := range dm.Properties { + err = property.Validate(cache) + if err != nil { + return err + } + } + for _, field := range dm.Fields { + if field.Analyzer != "" { + _, err = cache.AnalyzerNamed(field.Analyzer) + if err != nil { + return err + } + } + if field.DateFormat != "" { + _, err = cache.DateTimeParserNamed(field.DateFormat) + if err != nil { + return err + } + } + switch field.Type { + case "text", "datetime", "number", "boolean", "geopoint", "geoshape", "IP": + default: + return fmt.Errorf("unknown field type: '%s'", field.Type) + } + } + return nil +} + +// analyzerNameForPath attempts to first find the field +// described by this path, then returns the analyzer +// configured for that field +func (dm *DocumentMapping) analyzerNameForPath(path string) string { + field := dm.fieldDescribedByPath(path) + if field != nil { + return field.Analyzer + } + return "" +} + +func (dm *DocumentMapping) fieldDescribedByPath(path string) *FieldMapping { + pathElements := decodePath(path) + if len(pathElements) > 1 { + // easy case, there is more than 1 path element remaining + // the next path element must match a property name + // at this level + for propName, subDocMapping := range dm.Properties { + if propName == pathElements[0] { + return subDocMapping.fieldDescribedByPath(encodePath(pathElements[1:])) + } + } + } + + // either the path just had one element + // or it had multiple, but no match for the first element at this level + // look for match with full path + + // first look for property name with empty field + for propName, subDocMapping := range dm.Properties { + if propName == path { + // found property name match, now look at its fields + for _, field := range subDocMapping.Fields { + if field.Name == "" || field.Name == path { + // match + return field + } + } + } + } + // next, walk the properties again, looking for field overriding the name + for propName, subDocMapping := range dm.Properties { + if propName != path { + // property name isn't a match, but field name could override it + for _, field := range subDocMapping.Fields { + if field.Name == path { + return field + } + } + } + } + + return nil +} + +// documentMappingForPath only returns EXACT matches for a sub document +// or for an explicitly mapped field, if you want to find the +// closest document mapping to a field not explicitly mapped +// use closestDocMapping +func (dm *DocumentMapping) documentMappingForPath(path string) *DocumentMapping { + pathElements := decodePath(path) + current := dm +OUTER: + for i, pathElement := range pathElements { + for name, subDocMapping := range current.Properties { + if name == pathElement { + current = subDocMapping + continue OUTER + } + } + // no subDocMapping matches this pathElement + // only if this is the last element check for field name + if i == len(pathElements)-1 { + for _, field := range current.Fields { + if field.Name == pathElement { + break + } + } + } + + return nil + } + return current +} + +// closestDocMapping findest the most specific document mapping that matches +// part of the provided path +func (dm *DocumentMapping) closestDocMapping(path string) *DocumentMapping { + pathElements := decodePath(path) + current := dm +OUTER: + for _, pathElement := range pathElements { + for name, subDocMapping := range current.Properties { + if name == pathElement { + current = subDocMapping + continue OUTER + } + } + break + } + return current +} + +// NewDocumentMapping returns a new document mapping +// with all the default values. +func NewDocumentMapping() *DocumentMapping { + return &DocumentMapping{ + Enabled: true, + Dynamic: true, + } +} + +// NewDocumentStaticMapping returns a new document +// mapping that will not automatically index parts +// of a document without an explicit mapping. +func NewDocumentStaticMapping() *DocumentMapping { + return &DocumentMapping{ + Enabled: true, + } +} + +// NewDocumentDisabledMapping returns a new document +// mapping that will not perform any indexing. +func NewDocumentDisabledMapping() *DocumentMapping { + return &DocumentMapping{} +} + +// AddSubDocumentMapping adds the provided DocumentMapping as a sub-mapping +// for the specified named subsection. +func (dm *DocumentMapping) AddSubDocumentMapping(property string, sdm *DocumentMapping) { + if dm.Properties == nil { + dm.Properties = make(map[string]*DocumentMapping) + } + dm.Properties[property] = sdm +} + +// AddFieldMappingsAt adds one or more FieldMappings +// at the named sub-document. If the named sub-document +// doesn't yet exist it is created for you. +// This is a convenience function to make most common +// mappings more concise. +// Otherwise, you would: +// +// subMapping := NewDocumentMapping() +// subMapping.AddFieldMapping(fieldMapping) +// parentMapping.AddSubDocumentMapping(property, subMapping) +func (dm *DocumentMapping) AddFieldMappingsAt(property string, fms ...*FieldMapping) { + if dm.Properties == nil { + dm.Properties = make(map[string]*DocumentMapping) + } + sdm, ok := dm.Properties[property] + if !ok { + sdm = NewDocumentMapping() + } + for _, fm := range fms { + sdm.AddFieldMapping(fm) + } + dm.Properties[property] = sdm +} + +// AddFieldMapping adds the provided FieldMapping for this section +// of the document. +func (dm *DocumentMapping) AddFieldMapping(fm *FieldMapping) { + if dm.Fields == nil { + dm.Fields = make([]*FieldMapping, 0) + } + dm.Fields = append(dm.Fields, fm) +} + +// UnmarshalJSON offers custom unmarshaling with optional strict validation +func (dm *DocumentMapping) UnmarshalJSON(data []byte) error { + var tmp map[string]json.RawMessage + err := json.Unmarshal(data, &tmp) + if err != nil { + return err + } + + // set defaults for fields which might have been omitted + dm.Enabled = true + dm.Dynamic = true + + var invalidKeys []string + for k, v := range tmp { + switch k { + case "enabled": + err := json.Unmarshal(v, &dm.Enabled) + if err != nil { + return err + } + case "dynamic": + err := json.Unmarshal(v, &dm.Dynamic) + if err != nil { + return err + } + case "default_analyzer": + err := json.Unmarshal(v, &dm.DefaultAnalyzer) + if err != nil { + return err + } + case "properties": + err := json.Unmarshal(v, &dm.Properties) + if err != nil { + return err + } + case "fields": + err := json.Unmarshal(v, &dm.Fields) + if err != nil { + return err + } + case "struct_tag_key": + err := json.Unmarshal(v, &dm.StructTagKey) + if err != nil { + return err + } + default: + invalidKeys = append(invalidKeys, k) + } + } + + if MappingJSONStrict && len(invalidKeys) > 0 { + return fmt.Errorf("document mapping contains invalid keys: %v", invalidKeys) + } + + return nil +} + +func (dm *DocumentMapping) defaultAnalyzerName(path []string) string { + current := dm + rv := current.DefaultAnalyzer + for _, pathElement := range path { + var ok bool + current, ok = current.Properties[pathElement] + if !ok { + break + } + if current.DefaultAnalyzer != "" { + rv = current.DefaultAnalyzer + } + } + return rv +} + +func (dm *DocumentMapping) walkDocument(data interface{}, path []string, indexes []uint64, context *walkContext) { + // allow default "json" tag to be overridden + structTagKey := dm.StructTagKey + if structTagKey == "" { + structTagKey = "json" + } + + val := reflect.ValueOf(data) + if !val.IsValid() { + return + } + + typ := val.Type() + switch typ.Kind() { + case reflect.Map: + // FIXME can add support for other map keys in the future + if typ.Key().Kind() == reflect.String { + for _, key := range val.MapKeys() { + fieldName := key.String() + fieldVal := val.MapIndex(key).Interface() + dm.processProperty(fieldVal, append(path, fieldName), indexes, context) + } + } + case reflect.Struct: + for i := 0; i < val.NumField(); i++ { + field := typ.Field(i) + fieldName := field.Name + // anonymous fields of type struct can elide the type name + if field.Anonymous && field.Type.Kind() == reflect.Struct { + fieldName = "" + } + + // if the field has a name under the specified tag, prefer that + tag := field.Tag.Get(structTagKey) + tagFieldName := parseTagName(tag) + if tagFieldName == "-" { + continue + } + // allow tag to set field name to empty, only if anonymous + if field.Tag != "" && (tagFieldName != "" || field.Anonymous) { + fieldName = tagFieldName + } + + if val.Field(i).CanInterface() { + fieldVal := val.Field(i).Interface() + newpath := path + if fieldName != "" { + newpath = append(path, fieldName) + } + dm.processProperty(fieldVal, newpath, indexes, context) + } + } + case reflect.Slice, reflect.Array: + for i := 0; i < val.Len(); i++ { + if val.Index(i).CanInterface() { + fieldVal := val.Index(i).Interface() + dm.processProperty(fieldVal, path, append(indexes, uint64(i)), context) + } + } + case reflect.Ptr: + ptrElem := val.Elem() + if ptrElem.IsValid() && ptrElem.CanInterface() { + dm.processProperty(ptrElem.Interface(), path, indexes, context) + } + case reflect.String: + dm.processProperty(val.String(), path, indexes, context) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + dm.processProperty(float64(val.Int()), path, indexes, context) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + dm.processProperty(float64(val.Uint()), path, indexes, context) + case reflect.Float32, reflect.Float64: + dm.processProperty(float64(val.Float()), path, indexes, context) + case reflect.Bool: + dm.processProperty(val.Bool(), path, indexes, context) + } + +} + +func (dm *DocumentMapping) processProperty(property interface{}, path []string, indexes []uint64, context *walkContext) { + pathString := encodePath(path) + // look to see if there is a mapping for this field + subDocMapping := dm.documentMappingForPath(pathString) + closestDocMapping := dm.closestDocMapping(pathString) + + // check to see if we even need to do further processing + if subDocMapping != nil && !subDocMapping.Enabled { + return + } + + propertyValue := reflect.ValueOf(property) + if !propertyValue.IsValid() { + // cannot do anything with the zero value + return + } + propertyType := propertyValue.Type() + switch propertyType.Kind() { + case reflect.String: + propertyValueString := propertyValue.String() + if subDocMapping != nil { + // index by explicit mapping + for _, fieldMapping := range subDocMapping.Fields { + if fieldMapping.Type == "geoshape" { + fieldMapping.processGeoShape(property, pathString, path, indexes, context) + } else if fieldMapping.Type == "geopoint" { + fieldMapping.processGeoPoint(property, pathString, path, indexes, context) + } else { + fieldMapping.processString(propertyValueString, pathString, path, indexes, context) + } + } + } else if closestDocMapping.Dynamic { + // automatic indexing behavior + + // first see if it can be parsed by the default date parser + dateTimeParser := context.im.DateTimeParserNamed(context.im.DefaultDateTimeParser) + if dateTimeParser != nil { + parsedDateTime, err := dateTimeParser.ParseDateTime(propertyValueString) + if err != nil { + // index as text + fieldMapping := newTextFieldMappingDynamic(context.im) + fieldMapping.processString(propertyValueString, pathString, path, indexes, context) + } else { + // index as datetime + fieldMapping := newDateTimeFieldMappingDynamic(context.im) + fieldMapping.processTime(parsedDateTime, pathString, path, indexes, context) + } + } + } + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + dm.processProperty(float64(propertyValue.Int()), path, indexes, context) + return + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + dm.processProperty(float64(propertyValue.Uint()), path, indexes, context) + return + case reflect.Float64, reflect.Float32: + propertyValFloat := propertyValue.Float() + if subDocMapping != nil { + // index by explicit mapping + for _, fieldMapping := range subDocMapping.Fields { + fieldMapping.processFloat64(propertyValFloat, pathString, path, indexes, context) + } + } else if closestDocMapping.Dynamic { + // automatic indexing behavior + fieldMapping := newNumericFieldMappingDynamic(context.im) + fieldMapping.processFloat64(propertyValFloat, pathString, path, indexes, context) + } + case reflect.Bool: + propertyValBool := propertyValue.Bool() + if subDocMapping != nil { + // index by explicit mapping + for _, fieldMapping := range subDocMapping.Fields { + fieldMapping.processBoolean(propertyValBool, pathString, path, indexes, context) + } + } else if closestDocMapping.Dynamic { + // automatic indexing behavior + fieldMapping := newBooleanFieldMappingDynamic(context.im) + fieldMapping.processBoolean(propertyValBool, pathString, path, indexes, context) + } + case reflect.Struct: + switch property := property.(type) { + case time.Time: + // don't descend into the time struct + if subDocMapping != nil { + // index by explicit mapping + for _, fieldMapping := range subDocMapping.Fields { + fieldMapping.processTime(property, pathString, path, indexes, context) + } + } else if closestDocMapping.Dynamic { + fieldMapping := newDateTimeFieldMappingDynamic(context.im) + fieldMapping.processTime(property, pathString, path, indexes, context) + } + case encoding.TextMarshaler: + txt, err := property.MarshalText() + if err == nil && subDocMapping != nil { + // index by explicit mapping + for _, fieldMapping := range subDocMapping.Fields { + if fieldMapping.Type == "text" { + fieldMapping.processString(string(txt), pathString, path, indexes, context) + } + } + } + dm.walkDocument(property, path, indexes, context) + default: + if subDocMapping != nil { + for _, fieldMapping := range subDocMapping.Fields { + if fieldMapping.Type == "geopoint" { + fieldMapping.processGeoPoint(property, pathString, path, indexes, context) + } else if fieldMapping.Type == "geoshape" { + fieldMapping.processGeoShape(property, pathString, path, indexes, context) + } + } + } + dm.walkDocument(property, path, indexes, context) + } + case reflect.Map, reflect.Slice: + if subDocMapping != nil { + for _, fieldMapping := range subDocMapping.Fields { + switch fieldMapping.Type { + case "geopoint": + fieldMapping.processGeoPoint(property, pathString, path, indexes, context) + case "IP": + ip, ok := property.(net.IP) + if ok { + fieldMapping.processIP(ip, pathString, path, indexes, context) + } + case "geoshape": + fieldMapping.processGeoShape(property, pathString, path, indexes, context) + } + } + } + dm.walkDocument(property, path, indexes, context) + case reflect.Ptr: + if !propertyValue.IsNil() { + switch property := property.(type) { + case encoding.TextMarshaler: + // ONLY process TextMarshaler if there is an explicit mapping + // AND all of the fields are of type text + // OTHERWISE process field without TextMarshaler + if subDocMapping != nil { + allFieldsText := true + for _, fieldMapping := range subDocMapping.Fields { + if fieldMapping.Type != "text" { + allFieldsText = false + break + } + } + txt, err := property.MarshalText() + if err == nil && allFieldsText { + txtStr := string(txt) + for _, fieldMapping := range subDocMapping.Fields { + fieldMapping.processString(txtStr, pathString, path, indexes, context) + } + return + } + } + dm.walkDocument(property, path, indexes, context) + default: + dm.walkDocument(property, path, indexes, context) + } + } + default: + dm.walkDocument(property, path, indexes, context) + } +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/mapping/field.go b/backend/vendor/github.com/blevesearch/bleve/v2/mapping/field.go new file mode 100644 index 0000000000..511782acc4 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/mapping/field.go @@ -0,0 +1,461 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mapping + +import ( + "encoding/json" + "fmt" + "net" + "time" + + "github.com/blevesearch/bleve/v2/analysis/analyzer/keyword" + index "github.com/blevesearch/bleve_index_api" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/document" + "github.com/blevesearch/bleve/v2/geo" +) + +// control the default behavior for dynamic fields (those not explicitly mapped) +var ( + IndexDynamic = true + StoreDynamic = true + DocValuesDynamic = true // TODO revisit default? +) + +// A FieldMapping describes how a specific item +// should be put into the index. +type FieldMapping struct { + Name string `json:"name,omitempty"` + Type string `json:"type,omitempty"` + + // Analyzer specifies the name of the analyzer to use for this field. If + // Analyzer is empty, traverse the DocumentMapping tree toward the root and + // pick the first non-empty DefaultAnalyzer found. If there is none, use + // the IndexMapping.DefaultAnalyzer. + Analyzer string `json:"analyzer,omitempty"` + + // Store indicates whether to store field values in the index. Stored + // values can be retrieved from search results using SearchRequest.Fields. + Store bool `json:"store,omitempty"` + Index bool `json:"index,omitempty"` + + // IncludeTermVectors, if true, makes terms occurrences to be recorded for + // this field. It includes the term position within the terms sequence and + // the term offsets in the source document field. Term vectors are required + // to perform phrase queries or terms highlighting in source documents. + IncludeTermVectors bool `json:"include_term_vectors,omitempty"` + IncludeInAll bool `json:"include_in_all,omitempty"` + DateFormat string `json:"date_format,omitempty"` + + // DocValues, if true makes the index uninverting possible for this field + // It is useful for faceting and sorting queries. + DocValues bool `json:"docvalues,omitempty"` + + // SkipFreqNorm, if true, avoids the indexing of frequency and norm values + // of the tokens for this field. This option would be useful for saving + // the processing of freq/norm details when the default score based relevancy + // isn't needed. + SkipFreqNorm bool `json:"skip_freq_norm,omitempty"` +} + +// NewTextFieldMapping returns a default field mapping for text +func NewTextFieldMapping() *FieldMapping { + return &FieldMapping{ + Type: "text", + Store: true, + Index: true, + IncludeTermVectors: true, + IncludeInAll: true, + DocValues: true, + } +} + +func newTextFieldMappingDynamic(im *IndexMappingImpl) *FieldMapping { + rv := NewTextFieldMapping() + rv.Store = im.StoreDynamic + rv.Index = im.IndexDynamic + rv.DocValues = im.DocValuesDynamic + return rv +} + +// NewKeyworFieldMapping returns a default field mapping for text with analyzer "keyword". +func NewKeywordFieldMapping() *FieldMapping { + return &FieldMapping{ + Type: "text", + Analyzer: keyword.Name, + Store: true, + Index: true, + IncludeTermVectors: true, + IncludeInAll: true, + DocValues: true, + } +} + +// NewNumericFieldMapping returns a default field mapping for numbers +func NewNumericFieldMapping() *FieldMapping { + return &FieldMapping{ + Type: "number", + Store: true, + Index: true, + IncludeInAll: true, + DocValues: true, + } +} + +func newNumericFieldMappingDynamic(im *IndexMappingImpl) *FieldMapping { + rv := NewNumericFieldMapping() + rv.Store = im.StoreDynamic + rv.Index = im.IndexDynamic + rv.DocValues = im.DocValuesDynamic + return rv +} + +// NewDateTimeFieldMapping returns a default field mapping for dates +func NewDateTimeFieldMapping() *FieldMapping { + return &FieldMapping{ + Type: "datetime", + Store: true, + Index: true, + IncludeInAll: true, + DocValues: true, + } +} + +func newDateTimeFieldMappingDynamic(im *IndexMappingImpl) *FieldMapping { + rv := NewDateTimeFieldMapping() + rv.Store = im.StoreDynamic + rv.Index = im.IndexDynamic + rv.DocValues = im.DocValuesDynamic + return rv +} + +// NewBooleanFieldMapping returns a default field mapping for booleans +func NewBooleanFieldMapping() *FieldMapping { + return &FieldMapping{ + Type: "boolean", + Store: true, + Index: true, + IncludeInAll: true, + DocValues: true, + } +} + +func newBooleanFieldMappingDynamic(im *IndexMappingImpl) *FieldMapping { + rv := NewBooleanFieldMapping() + rv.Store = im.StoreDynamic + rv.Index = im.IndexDynamic + rv.DocValues = im.DocValuesDynamic + return rv +} + +// NewGeoPointFieldMapping returns a default field mapping for geo points +func NewGeoPointFieldMapping() *FieldMapping { + return &FieldMapping{ + Type: "geopoint", + Store: true, + Index: true, + IncludeInAll: true, + DocValues: true, + } +} + +// NewGeoShapeFieldMapping returns a default field mapping +// for geoshapes +func NewGeoShapeFieldMapping() *FieldMapping { + return &FieldMapping{ + Type: "geoshape", + Store: true, + Index: true, + IncludeInAll: true, + DocValues: true, + } +} + +// NewIPFieldMapping returns a default field mapping for IP points +func NewIPFieldMapping() *FieldMapping { + return &FieldMapping{ + Type: "IP", + Store: true, + Index: true, + IncludeInAll: true, + } +} + +// Options returns the indexing options for this field. +func (fm *FieldMapping) Options() index.FieldIndexingOptions { + var rv index.FieldIndexingOptions + if fm.Store { + rv |= index.StoreField + } + if fm.Index { + rv |= index.IndexField + } + if fm.IncludeTermVectors { + rv |= index.IncludeTermVectors + } + if fm.DocValues { + rv |= index.DocValues + } + if fm.SkipFreqNorm { + rv |= index.SkipFreqNorm + } + return rv +} + +func (fm *FieldMapping) processString(propertyValueString string, pathString string, path []string, indexes []uint64, context *walkContext) { + fieldName := getFieldName(pathString, path, fm) + options := fm.Options() + if fm.Type == "text" { + analyzer := fm.analyzerForField(path, context) + field := document.NewTextFieldCustom(fieldName, indexes, []byte(propertyValueString), options, analyzer) + context.doc.AddField(field) + + if !fm.IncludeInAll { + context.excludedFromAll = append(context.excludedFromAll, fieldName) + } + } else if fm.Type == "datetime" { + dateTimeFormat := context.im.DefaultDateTimeParser + if fm.DateFormat != "" { + dateTimeFormat = fm.DateFormat + } + dateTimeParser := context.im.DateTimeParserNamed(dateTimeFormat) + if dateTimeParser != nil { + parsedDateTime, err := dateTimeParser.ParseDateTime(propertyValueString) + if err == nil { + fm.processTime(parsedDateTime, pathString, path, indexes, context) + } + } + } else if fm.Type == "IP" { + ip := net.ParseIP(propertyValueString) + if ip != nil { + fm.processIP(ip, pathString, path, indexes, context) + } + } +} + +func (fm *FieldMapping) processFloat64(propertyValFloat float64, pathString string, path []string, indexes []uint64, context *walkContext) { + fieldName := getFieldName(pathString, path, fm) + if fm.Type == "number" { + options := fm.Options() + field := document.NewNumericFieldWithIndexingOptions(fieldName, indexes, propertyValFloat, options) + context.doc.AddField(field) + + if !fm.IncludeInAll { + context.excludedFromAll = append(context.excludedFromAll, fieldName) + } + } +} + +func (fm *FieldMapping) processTime(propertyValueTime time.Time, pathString string, path []string, indexes []uint64, context *walkContext) { + fieldName := getFieldName(pathString, path, fm) + if fm.Type == "datetime" { + options := fm.Options() + field, err := document.NewDateTimeFieldWithIndexingOptions(fieldName, indexes, propertyValueTime, options) + if err == nil { + context.doc.AddField(field) + } else { + logger.Printf("could not build date %v", err) + } + + if !fm.IncludeInAll { + context.excludedFromAll = append(context.excludedFromAll, fieldName) + } + } +} + +func (fm *FieldMapping) processBoolean(propertyValueBool bool, pathString string, path []string, indexes []uint64, context *walkContext) { + fieldName := getFieldName(pathString, path, fm) + if fm.Type == "boolean" { + options := fm.Options() + field := document.NewBooleanFieldWithIndexingOptions(fieldName, indexes, propertyValueBool, options) + context.doc.AddField(field) + + if !fm.IncludeInAll { + context.excludedFromAll = append(context.excludedFromAll, fieldName) + } + } +} + +func (fm *FieldMapping) processGeoPoint(propertyMightBeGeoPoint interface{}, pathString string, path []string, indexes []uint64, context *walkContext) { + lon, lat, found := geo.ExtractGeoPoint(propertyMightBeGeoPoint) + if found { + fieldName := getFieldName(pathString, path, fm) + options := fm.Options() + field := document.NewGeoPointFieldWithIndexingOptions(fieldName, indexes, lon, lat, options) + context.doc.AddField(field) + + if !fm.IncludeInAll { + context.excludedFromAll = append(context.excludedFromAll, fieldName) + } + } +} + +func (fm *FieldMapping) processIP(ip net.IP, pathString string, path []string, indexes []uint64, context *walkContext) { + fieldName := getFieldName(pathString, path, fm) + options := fm.Options() + field := document.NewIPFieldWithIndexingOptions(fieldName, indexes, ip, options) + context.doc.AddField(field) + + if !fm.IncludeInAll { + context.excludedFromAll = append(context.excludedFromAll, fieldName) + } +} + +func (fm *FieldMapping) processGeoShape(propertyMightBeGeoShape interface{}, + pathString string, path []string, indexes []uint64, context *walkContext) { + coordValue, shape, err := geo.ParseGeoShapeField(propertyMightBeGeoShape) + if err != nil { + return + } + + if shape == geo.CircleType { + center, radius, found := geo.ExtractCircle(propertyMightBeGeoShape) + if found { + fieldName := getFieldName(pathString, path, fm) + options := fm.Options() + field := document.NewGeoCircleFieldWithIndexingOptions(fieldName, + indexes, center, radius, options) + context.doc.AddField(field) + + if !fm.IncludeInAll { + context.excludedFromAll = append(context.excludedFromAll, fieldName) + } + } + } else if shape == geo.GeometryCollectionType { + coordinates, shapes, found := geo.ExtractGeometryCollection(propertyMightBeGeoShape) + if found { + fieldName := getFieldName(pathString, path, fm) + options := fm.Options() + field := document.NewGeometryCollectionFieldWithIndexingOptions(fieldName, + indexes, coordinates, shapes, options) + context.doc.AddField(field) + + if !fm.IncludeInAll { + context.excludedFromAll = append(context.excludedFromAll, fieldName) + } + } + } else { + coordinates, shape, found := geo.ExtractGeoShapeCoordinates(coordValue, shape) + if found { + fieldName := getFieldName(pathString, path, fm) + options := fm.Options() + field := document.NewGeoShapeFieldWithIndexingOptions(fieldName, + indexes, coordinates, shape, options) + context.doc.AddField(field) + + if !fm.IncludeInAll { + context.excludedFromAll = append(context.excludedFromAll, fieldName) + } + } + } +} + +func (fm *FieldMapping) analyzerForField(path []string, context *walkContext) analysis.Analyzer { + analyzerName := fm.Analyzer + if analyzerName == "" { + analyzerName = context.dm.defaultAnalyzerName(path) + if analyzerName == "" { + analyzerName = context.im.DefaultAnalyzer + } + } + return context.im.AnalyzerNamed(analyzerName) +} + +func getFieldName(pathString string, path []string, fieldMapping *FieldMapping) string { + fieldName := pathString + if fieldMapping.Name != "" { + parentName := "" + if len(path) > 1 { + parentName = encodePath(path[:len(path)-1]) + pathSeparator + } + fieldName = parentName + fieldMapping.Name + } + return fieldName +} + +// UnmarshalJSON offers custom unmarshaling with optional strict validation +func (fm *FieldMapping) UnmarshalJSON(data []byte) error { + + var tmp map[string]json.RawMessage + err := json.Unmarshal(data, &tmp) + if err != nil { + return err + } + + var invalidKeys []string + for k, v := range tmp { + switch k { + case "name": + err := json.Unmarshal(v, &fm.Name) + if err != nil { + return err + } + case "type": + err := json.Unmarshal(v, &fm.Type) + if err != nil { + return err + } + case "analyzer": + err := json.Unmarshal(v, &fm.Analyzer) + if err != nil { + return err + } + case "store": + err := json.Unmarshal(v, &fm.Store) + if err != nil { + return err + } + case "index": + err := json.Unmarshal(v, &fm.Index) + if err != nil { + return err + } + case "include_term_vectors": + err := json.Unmarshal(v, &fm.IncludeTermVectors) + if err != nil { + return err + } + case "include_in_all": + err := json.Unmarshal(v, &fm.IncludeInAll) + if err != nil { + return err + } + case "date_format": + err := json.Unmarshal(v, &fm.DateFormat) + if err != nil { + return err + } + case "docvalues": + err := json.Unmarshal(v, &fm.DocValues) + if err != nil { + return err + } + case "skip_freq_norm": + err := json.Unmarshal(v, &fm.SkipFreqNorm) + if err != nil { + return err + } + default: + invalidKeys = append(invalidKeys, k) + } + } + + if MappingJSONStrict && len(invalidKeys) > 0 { + return fmt.Errorf("field mapping contains invalid keys: %v", invalidKeys) + } + + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/mapping/index.go b/backend/vendor/github.com/blevesearch/bleve/v2/mapping/index.go new file mode 100644 index 0000000000..1d982dd414 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/mapping/index.go @@ -0,0 +1,444 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mapping + +import ( + "encoding/json" + "fmt" + index "github.com/blevesearch/bleve_index_api" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/analysis/analyzer/standard" + "github.com/blevesearch/bleve/v2/analysis/datetime/optional" + "github.com/blevesearch/bleve/v2/document" + "github.com/blevesearch/bleve/v2/registry" +) + +var MappingJSONStrict = false + +const defaultTypeField = "_type" +const defaultType = "_default" +const defaultField = "_all" +const defaultAnalyzer = standard.Name +const defaultDateTimeParser = optional.Name + +// An IndexMappingImpl controls how objects are placed +// into an index. +// First the type of the object is determined. +// Once the type is know, the appropriate +// DocumentMapping is selected by the type. +// If no mapping was determined for that type, +// a DefaultMapping will be used. +type IndexMappingImpl struct { + TypeMapping map[string]*DocumentMapping `json:"types,omitempty"` + DefaultMapping *DocumentMapping `json:"default_mapping"` + TypeField string `json:"type_field"` + DefaultType string `json:"default_type"` + DefaultAnalyzer string `json:"default_analyzer"` + DefaultDateTimeParser string `json:"default_datetime_parser"` + DefaultField string `json:"default_field"` + StoreDynamic bool `json:"store_dynamic"` + IndexDynamic bool `json:"index_dynamic"` + DocValuesDynamic bool `json:"docvalues_dynamic"` + CustomAnalysis *customAnalysis `json:"analysis,omitempty"` + cache *registry.Cache +} + +// AddCustomCharFilter defines a custom char filter for use in this mapping +func (im *IndexMappingImpl) AddCustomCharFilter(name string, config map[string]interface{}) error { + _, err := im.cache.DefineCharFilter(name, config) + if err != nil { + return err + } + im.CustomAnalysis.CharFilters[name] = config + return nil +} + +// AddCustomTokenizer defines a custom tokenizer for use in this mapping +func (im *IndexMappingImpl) AddCustomTokenizer(name string, config map[string]interface{}) error { + _, err := im.cache.DefineTokenizer(name, config) + if err != nil { + return err + } + im.CustomAnalysis.Tokenizers[name] = config + return nil +} + +// AddCustomTokenMap defines a custom token map for use in this mapping +func (im *IndexMappingImpl) AddCustomTokenMap(name string, config map[string]interface{}) error { + _, err := im.cache.DefineTokenMap(name, config) + if err != nil { + return err + } + im.CustomAnalysis.TokenMaps[name] = config + return nil +} + +// AddCustomTokenFilter defines a custom token filter for use in this mapping +func (im *IndexMappingImpl) AddCustomTokenFilter(name string, config map[string]interface{}) error { + _, err := im.cache.DefineTokenFilter(name, config) + if err != nil { + return err + } + im.CustomAnalysis.TokenFilters[name] = config + return nil +} + +// AddCustomAnalyzer defines a custom analyzer for use in this mapping. The +// config map must have a "type" string entry to resolve the analyzer +// constructor. The constructor is invoked with the remaining entries and +// returned analyzer is registered in the IndexMapping. +// +// bleve comes with predefined analyzers, like +// github.com/blevesearch/bleve/analysis/analyzer/custom. They are +// available only if their package is imported by client code. To achieve this, +// use their metadata to fill configuration entries: +// +// import ( +// "github.com/blevesearch/bleve/v2/analysis/analyzer/custom" +// "github.com/blevesearch/bleve/v2/analysis/char/html" +// "github.com/blevesearch/bleve/v2/analysis/token/lowercase" +// "github.com/blevesearch/bleve/v2/analysis/tokenizer/unicode" +// ) +// +// m := bleve.NewIndexMapping() +// err := m.AddCustomAnalyzer("html", map[string]interface{}{ +// "type": custom.Name, +// "char_filters": []string{ +// html.Name, +// }, +// "tokenizer": unicode.Name, +// "token_filters": []string{ +// lowercase.Name, +// ... +// }, +// }) +func (im *IndexMappingImpl) AddCustomAnalyzer(name string, config map[string]interface{}) error { + _, err := im.cache.DefineAnalyzer(name, config) + if err != nil { + return err + } + im.CustomAnalysis.Analyzers[name] = config + return nil +} + +// AddCustomDateTimeParser defines a custom date time parser for use in this mapping +func (im *IndexMappingImpl) AddCustomDateTimeParser(name string, config map[string]interface{}) error { + _, err := im.cache.DefineDateTimeParser(name, config) + if err != nil { + return err + } + im.CustomAnalysis.DateTimeParsers[name] = config + return nil +} + +// NewIndexMapping creates a new IndexMapping that will use all the default indexing rules +func NewIndexMapping() *IndexMappingImpl { + return &IndexMappingImpl{ + TypeMapping: make(map[string]*DocumentMapping), + DefaultMapping: NewDocumentMapping(), + TypeField: defaultTypeField, + DefaultType: defaultType, + DefaultAnalyzer: defaultAnalyzer, + DefaultDateTimeParser: defaultDateTimeParser, + DefaultField: defaultField, + IndexDynamic: IndexDynamic, + StoreDynamic: StoreDynamic, + DocValuesDynamic: DocValuesDynamic, + CustomAnalysis: newCustomAnalysis(), + cache: registry.NewCache(), + } +} + +// Validate will walk the entire structure ensuring the following +// explicitly named and default analyzers can be built +func (im *IndexMappingImpl) Validate() error { + _, err := im.cache.AnalyzerNamed(im.DefaultAnalyzer) + if err != nil { + return err + } + _, err = im.cache.DateTimeParserNamed(im.DefaultDateTimeParser) + if err != nil { + return err + } + err = im.DefaultMapping.Validate(im.cache) + if err != nil { + return err + } + for _, docMapping := range im.TypeMapping { + err = docMapping.Validate(im.cache) + if err != nil { + return err + } + } + return nil +} + +// AddDocumentMapping sets a custom document mapping for the specified type +func (im *IndexMappingImpl) AddDocumentMapping(doctype string, dm *DocumentMapping) { + im.TypeMapping[doctype] = dm +} + +func (im *IndexMappingImpl) mappingForType(docType string) *DocumentMapping { + docMapping := im.TypeMapping[docType] + if docMapping == nil { + docMapping = im.DefaultMapping + } + return docMapping +} + +// UnmarshalJSON offers custom unmarshaling with optional strict validation +func (im *IndexMappingImpl) UnmarshalJSON(data []byte) error { + + var tmp map[string]json.RawMessage + err := json.Unmarshal(data, &tmp) + if err != nil { + return err + } + + // set defaults for fields which might have been omitted + im.cache = registry.NewCache() + im.CustomAnalysis = newCustomAnalysis() + im.TypeField = defaultTypeField + im.DefaultType = defaultType + im.DefaultAnalyzer = defaultAnalyzer + im.DefaultDateTimeParser = defaultDateTimeParser + im.DefaultField = defaultField + im.DefaultMapping = NewDocumentMapping() + im.TypeMapping = make(map[string]*DocumentMapping) + im.StoreDynamic = StoreDynamic + im.IndexDynamic = IndexDynamic + im.DocValuesDynamic = DocValuesDynamic + + var invalidKeys []string + for k, v := range tmp { + switch k { + case "analysis": + err := json.Unmarshal(v, &im.CustomAnalysis) + if err != nil { + return err + } + case "type_field": + err := json.Unmarshal(v, &im.TypeField) + if err != nil { + return err + } + case "default_type": + err := json.Unmarshal(v, &im.DefaultType) + if err != nil { + return err + } + case "default_analyzer": + err := json.Unmarshal(v, &im.DefaultAnalyzer) + if err != nil { + return err + } + case "default_datetime_parser": + err := json.Unmarshal(v, &im.DefaultDateTimeParser) + if err != nil { + return err + } + case "default_field": + err := json.Unmarshal(v, &im.DefaultField) + if err != nil { + return err + } + case "default_mapping": + err := json.Unmarshal(v, &im.DefaultMapping) + if err != nil { + return err + } + case "types": + err := json.Unmarshal(v, &im.TypeMapping) + if err != nil { + return err + } + case "store_dynamic": + err := json.Unmarshal(v, &im.StoreDynamic) + if err != nil { + return err + } + case "index_dynamic": + err := json.Unmarshal(v, &im.IndexDynamic) + if err != nil { + return err + } + case "docvalues_dynamic": + err := json.Unmarshal(v, &im.DocValuesDynamic) + if err != nil { + return err + } + default: + invalidKeys = append(invalidKeys, k) + } + } + + if MappingJSONStrict && len(invalidKeys) > 0 { + return fmt.Errorf("index mapping contains invalid keys: %v", invalidKeys) + } + + err = im.CustomAnalysis.registerAll(im) + if err != nil { + return err + } + + return nil +} + +func (im *IndexMappingImpl) determineType(data interface{}) string { + // first see if the object implements bleveClassifier + bleveClassifier, ok := data.(bleveClassifier) + if ok { + return bleveClassifier.BleveType() + } + // next see if the object implements Classifier + classifier, ok := data.(Classifier) + if ok { + return classifier.Type() + } + + // now see if we can find a type using the mapping + typ, ok := mustString(lookupPropertyPath(data, im.TypeField)) + if ok { + return typ + } + + return im.DefaultType +} + +func (im *IndexMappingImpl) MapDocument(doc *document.Document, data interface{}) error { + docType := im.determineType(data) + docMapping := im.mappingForType(docType) + if docMapping.Enabled { + walkContext := im.newWalkContext(doc, docMapping) + docMapping.walkDocument(data, []string{}, []uint64{}, walkContext) + + // see if the _all field was disabled + allMapping := docMapping.documentMappingForPath("_all") + if allMapping == nil || allMapping.Enabled { + field := document.NewCompositeFieldWithIndexingOptions("_all", true, []string{}, walkContext.excludedFromAll, index.IndexField|index.IncludeTermVectors) + doc.AddField(field) + } + } + + return nil +} + +type walkContext struct { + doc *document.Document + im *IndexMappingImpl + dm *DocumentMapping + excludedFromAll []string +} + +func (im *IndexMappingImpl) newWalkContext(doc *document.Document, dm *DocumentMapping) *walkContext { + return &walkContext{ + doc: doc, + im: im, + dm: dm, + excludedFromAll: []string{"_id"}, + } +} + +// AnalyzerNameForPath attempts to find the best analyzer to use with only a +// field name will walk all the document types, look for field mappings at the +// provided path, if one exists and it has an explicit analyzer that is +// returned. +func (im *IndexMappingImpl) AnalyzerNameForPath(path string) string { + // first we look for explicit mapping on the field + for _, docMapping := range im.TypeMapping { + analyzerName := docMapping.analyzerNameForPath(path) + if analyzerName != "" { + return analyzerName + } + } + // now try the default mapping + pathMapping := im.DefaultMapping.documentMappingForPath(path) + if pathMapping != nil { + if len(pathMapping.Fields) > 0 { + if pathMapping.Fields[0].Analyzer != "" { + return pathMapping.Fields[0].Analyzer + } + } + } + + // next we will try default analyzers for the path + pathDecoded := decodePath(path) + for _, docMapping := range im.TypeMapping { + rv := docMapping.defaultAnalyzerName(pathDecoded) + if rv != "" { + return rv + } + } + + return im.DefaultAnalyzer +} + +func (im *IndexMappingImpl) AnalyzerNamed(name string) analysis.Analyzer { + analyzer, err := im.cache.AnalyzerNamed(name) + if err != nil { + logger.Printf("error using analyzer named: %s", name) + return nil + } + return analyzer +} + +func (im *IndexMappingImpl) DateTimeParserNamed(name string) analysis.DateTimeParser { + if name == "" { + name = im.DefaultDateTimeParser + } + dateTimeParser, err := im.cache.DateTimeParserNamed(name) + if err != nil { + logger.Printf("error using datetime parser named: %s", name) + return nil + } + return dateTimeParser +} + +func (im *IndexMappingImpl) datetimeParserNameForPath(path string) string { + + // first we look for explicit mapping on the field + for _, docMapping := range im.TypeMapping { + pathMapping := docMapping.documentMappingForPath(path) + if pathMapping != nil { + if len(pathMapping.Fields) > 0 { + if pathMapping.Fields[0].Analyzer != "" { + return pathMapping.Fields[0].Analyzer + } + } + } + } + + return im.DefaultDateTimeParser +} + +func (im *IndexMappingImpl) AnalyzeText(analyzerName string, text []byte) (analysis.TokenStream, error) { + analyzer, err := im.cache.AnalyzerNamed(analyzerName) + if err != nil { + return nil, err + } + return analyzer.Analyze(text), nil +} + +// FieldAnalyzer returns the name of the analyzer used on a field. +func (im *IndexMappingImpl) FieldAnalyzer(field string) string { + return im.AnalyzerNameForPath(field) +} + +// wrapper to satisfy new interface + +func (im *IndexMappingImpl) DefaultSearchField() string { + return im.DefaultField +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/mapping/mapping.go b/backend/vendor/github.com/blevesearch/bleve/v2/mapping/mapping.go new file mode 100644 index 0000000000..2506352e0f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/mapping/mapping.go @@ -0,0 +1,58 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mapping + +import ( + "io/ioutil" + "log" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/document" +) + +// A Classifier is an interface describing any object which knows how to +// identify its own type. Alternatively, if a struct already has a Type +// field or method in conflict, one can use BleveType instead. +type Classifier interface { + Type() string +} + +// A bleveClassifier is an interface describing any object which knows how +// to identify its own type. This is introduced as an alternative to the +// Classifier interface which often has naming conflicts with existing +// structures. +type bleveClassifier interface { + BleveType() string +} + +var logger = log.New(ioutil.Discard, "bleve mapping ", log.LstdFlags) + +// SetLog sets the logger used for logging +// by default log messages are sent to ioutil.Discard +func SetLog(l *log.Logger) { + logger = l +} + +type IndexMapping interface { + MapDocument(doc *document.Document, data interface{}) error + Validate() error + + DateTimeParserNamed(name string) analysis.DateTimeParser + + DefaultSearchField() string + + AnalyzerNameForPath(path string) string + AnalyzerNamed(name string) analysis.Analyzer +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/mapping/reflect.go b/backend/vendor/github.com/blevesearch/bleve/v2/mapping/reflect.go new file mode 100644 index 0000000000..6500a70592 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/mapping/reflect.go @@ -0,0 +1,92 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mapping + +import ( + "reflect" + "strings" +) + +func lookupPropertyPath(data interface{}, path string) interface{} { + pathParts := decodePath(path) + + current := data + for _, part := range pathParts { + current = lookupPropertyPathPart(current, part) + if current == nil { + break + } + } + + return current +} + +func lookupPropertyPathPart(data interface{}, part string) interface{} { + val := reflect.ValueOf(data) + if !val.IsValid() { + return nil + } + typ := val.Type() + switch typ.Kind() { + case reflect.Map: + // FIXME can add support for other map keys in the future + if typ.Key().Kind() == reflect.String { + key := reflect.ValueOf(part) + entry := val.MapIndex(key) + if entry.IsValid() { + return entry.Interface() + } + } + case reflect.Struct: + field := val.FieldByName(part) + if field.IsValid() && field.CanInterface() { + return field.Interface() + } + case reflect.Ptr: + ptrElem := val.Elem() + if ptrElem.IsValid() && ptrElem.CanInterface() { + return lookupPropertyPathPart(ptrElem.Interface(), part) + } + } + return nil +} + +const pathSeparator = "." + +func decodePath(path string) []string { + return strings.Split(path, pathSeparator) +} + +func encodePath(pathElements []string) string { + return strings.Join(pathElements, pathSeparator) +} + +func mustString(data interface{}) (string, bool) { + if data != nil { + str, ok := data.(string) + if ok { + return str, true + } + } + return "", false +} + +// parseTagName extracts the field name from a struct tag +func parseTagName(tag string) string { + if idx := strings.Index(tag, ","); idx != -1 { + return tag[:idx] + } + return tag +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/numeric/bin.go b/backend/vendor/github.com/blevesearch/bleve/v2/numeric/bin.go new file mode 100644 index 0000000000..368952a2cb --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/numeric/bin.go @@ -0,0 +1,43 @@ +package numeric + +var interleaveMagic = []uint64{ + 0x5555555555555555, + 0x3333333333333333, + 0x0F0F0F0F0F0F0F0F, + 0x00FF00FF00FF00FF, + 0x0000FFFF0000FFFF, + 0x00000000FFFFFFFF, + 0xAAAAAAAAAAAAAAAA, +} + +var interleaveShift = []uint{1, 2, 4, 8, 16} + +// Interleave the first 32 bits of each uint64 +// apdated from org.apache.lucene.util.BitUtil +// which was adapted from: +// http://graphics.stanford.edu/~seander/bithacks.html#InterleaveBMN +func Interleave(v1, v2 uint64) uint64 { + v1 = (v1 | (v1 << interleaveShift[4])) & interleaveMagic[4] + v1 = (v1 | (v1 << interleaveShift[3])) & interleaveMagic[3] + v1 = (v1 | (v1 << interleaveShift[2])) & interleaveMagic[2] + v1 = (v1 | (v1 << interleaveShift[1])) & interleaveMagic[1] + v1 = (v1 | (v1 << interleaveShift[0])) & interleaveMagic[0] + v2 = (v2 | (v2 << interleaveShift[4])) & interleaveMagic[4] + v2 = (v2 | (v2 << interleaveShift[3])) & interleaveMagic[3] + v2 = (v2 | (v2 << interleaveShift[2])) & interleaveMagic[2] + v2 = (v2 | (v2 << interleaveShift[1])) & interleaveMagic[1] + v2 = (v2 | (v2 << interleaveShift[0])) & interleaveMagic[0] + return (v2 << 1) | v1 +} + +// Deinterleave the 32-bit value starting at position 0 +// to get the other 32-bit value, shift it by 1 first +func Deinterleave(b uint64) uint64 { + b &= interleaveMagic[0] + b = (b ^ (b >> interleaveShift[0])) & interleaveMagic[1] + b = (b ^ (b >> interleaveShift[1])) & interleaveMagic[2] + b = (b ^ (b >> interleaveShift[2])) & interleaveMagic[3] + b = (b ^ (b >> interleaveShift[3])) & interleaveMagic[4] + b = (b ^ (b >> interleaveShift[4])) & interleaveMagic[5] + return b +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/numeric/float.go b/backend/vendor/github.com/blevesearch/bleve/v2/numeric/float.go new file mode 100644 index 0000000000..2bb14d7e8f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/numeric/float.go @@ -0,0 +1,34 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package numeric + +import ( + "math" +) + +func Float64ToInt64(f float64) int64 { + fasint := int64(math.Float64bits(f)) + if fasint < 0 { + fasint = fasint ^ 0x7fffffffffffffff + } + return fasint +} + +func Int64ToFloat64(i int64) float64 { + if i < 0 { + i ^= 0x7fffffffffffffff + } + return math.Float64frombits(uint64(i)) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/numeric/prefix_coded.go b/backend/vendor/github.com/blevesearch/bleve/v2/numeric/prefix_coded.go new file mode 100644 index 0000000000..29bd0fc5c1 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/numeric/prefix_coded.go @@ -0,0 +1,111 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package numeric + +import "fmt" + +const ShiftStartInt64 byte = 0x20 + +// PrefixCoded is a byte array encoding of +// 64-bit numeric values shifted by 0-63 bits +type PrefixCoded []byte + +func NewPrefixCodedInt64(in int64, shift uint) (PrefixCoded, error) { + rv, _, err := NewPrefixCodedInt64Prealloc(in, shift, nil) + return rv, err +} + +func NewPrefixCodedInt64Prealloc(in int64, shift uint, prealloc []byte) ( + rv PrefixCoded, preallocRest []byte, err error) { + if shift > 63 { + return nil, prealloc, fmt.Errorf("cannot shift %d, must be between 0 and 63", shift) + } + + nChars := ((63 - shift) / 7) + 1 + + size := int(nChars + 1) + if len(prealloc) >= size { + rv = PrefixCoded(prealloc[0:size]) + preallocRest = prealloc[size:] + } else { + rv = make(PrefixCoded, size) + } + + rv[0] = ShiftStartInt64 + byte(shift) + + sortableBits := int64(uint64(in) ^ 0x8000000000000000) + sortableBits = int64(uint64(sortableBits) >> shift) + for nChars > 0 { + // Store 7 bits per byte for compatibility + // with UTF-8 encoding of terms + rv[nChars] = byte(sortableBits & 0x7f) + nChars-- + sortableBits = int64(uint64(sortableBits) >> 7) + } + + return rv, preallocRest, nil +} + +func MustNewPrefixCodedInt64(in int64, shift uint) PrefixCoded { + rv, err := NewPrefixCodedInt64(in, shift) + if err != nil { + panic(err) + } + return rv +} + +// Shift returns the number of bits shifted +// returns 0 if in uninitialized state +func (p PrefixCoded) Shift() (uint, error) { + if len(p) > 0 { + shift := p[0] - ShiftStartInt64 + if shift < 0 || shift < 63 { + return uint(shift), nil + } + } + return 0, fmt.Errorf("invalid prefix coded value") +} + +func (p PrefixCoded) Int64() (int64, error) { + shift, err := p.Shift() + if err != nil { + return 0, err + } + var sortableBits int64 + for _, inbyte := range p[1:] { + sortableBits <<= 7 + sortableBits |= int64(inbyte) + } + return int64(uint64((sortableBits << shift)) ^ 0x8000000000000000), nil +} + +func ValidPrefixCodedTerm(p string) (bool, int) { + return ValidPrefixCodedTermBytes([]byte(p)) +} + +func ValidPrefixCodedTermBytes(p []byte) (bool, int) { + if len(p) > 0 { + if p[0] < ShiftStartInt64 || p[0] > ShiftStartInt64+63 { + return false, 0 + } + shift := p[0] - ShiftStartInt64 + nChars := ((63 - int(shift)) / 7) + 1 + if len(p) != nChars+1 { + return false, 0 + } + return true, int(shift) + } + return false, 0 +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/query.go b/backend/vendor/github.com/blevesearch/bleve/v2/query.go new file mode 100644 index 0000000000..4f1f136ce3 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/query.go @@ -0,0 +1,227 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bleve + +import ( + "time" + + "github.com/blevesearch/bleve/v2/search/query" +) + +// NewBoolFieldQuery creates a new Query for boolean fields +func NewBoolFieldQuery(val bool) *query.BoolFieldQuery { + return query.NewBoolFieldQuery(val) +} + +// NewBooleanQuery creates a compound Query composed +// of several other Query objects. +// These other query objects are added using the +// AddMust() AddShould() and AddMustNot() methods. +// Result documents must satisfy ALL of the +// must Queries. +// Result documents must satisfy NONE of the must not +// Queries. +// Result documents that ALSO satisfy any of the should +// Queries will score higher. +func NewBooleanQuery() *query.BooleanQuery { + return query.NewBooleanQuery(nil, nil, nil) +} + +// NewConjunctionQuery creates a new compound Query. +// Result documents must satisfy all of the queries. +func NewConjunctionQuery(conjuncts ...query.Query) *query.ConjunctionQuery { + return query.NewConjunctionQuery(conjuncts) +} + +// NewDateRangeQuery creates a new Query for ranges +// of date values. +// Date strings are parsed using the DateTimeParser configured in the +// top-level config.QueryDateTimeParser +// Either, but not both endpoints can be nil. +func NewDateRangeQuery(start, end time.Time) *query.DateRangeQuery { + return query.NewDateRangeQuery(start, end) +} + +// NewDateRangeInclusiveQuery creates a new Query for ranges +// of date values. +// Date strings are parsed using the DateTimeParser configured in the +// top-level config.QueryDateTimeParser +// Either, but not both endpoints can be nil. +// startInclusive and endInclusive control inclusion of the endpoints. +func NewDateRangeInclusiveQuery(start, end time.Time, startInclusive, endInclusive *bool) *query.DateRangeQuery { + return query.NewDateRangeInclusiveQuery(start, end, startInclusive, endInclusive) +} + +// NewDisjunctionQuery creates a new compound Query. +// Result documents satisfy at least one Query. +func NewDisjunctionQuery(disjuncts ...query.Query) *query.DisjunctionQuery { + return query.NewDisjunctionQuery(disjuncts) +} + +// NewDocIDQuery creates a new Query object returning indexed documents among +// the specified set. Combine it with ConjunctionQuery to restrict the scope of +// other queries output. +func NewDocIDQuery(ids []string) *query.DocIDQuery { + return query.NewDocIDQuery(ids) +} + +// NewFuzzyQuery creates a new Query which finds +// documents containing terms within a specific +// fuzziness of the specified term. +// The default fuzziness is 1. +// +// The current implementation uses Levenshtein edit +// distance as the fuzziness metric. +func NewFuzzyQuery(term string) *query.FuzzyQuery { + return query.NewFuzzyQuery(term) +} + +// NewMatchAllQuery creates a Query which will +// match all documents in the index. +func NewMatchAllQuery() *query.MatchAllQuery { + return query.NewMatchAllQuery() +} + +// NewMatchNoneQuery creates a Query which will not +// match any documents in the index. +func NewMatchNoneQuery() *query.MatchNoneQuery { + return query.NewMatchNoneQuery() +} + +// NewMatchPhraseQuery creates a new Query object +// for matching phrases in the index. +// An Analyzer is chosen based on the field. +// Input text is analyzed using this analyzer. +// Token terms resulting from this analysis are +// used to build a search phrase. Result documents +// must match this phrase. Queried field must have been indexed with +// IncludeTermVectors set to true. +func NewMatchPhraseQuery(matchPhrase string) *query.MatchPhraseQuery { + return query.NewMatchPhraseQuery(matchPhrase) +} + +// NewMatchQuery creates a Query for matching text. +// An Analyzer is chosen based on the field. +// Input text is analyzed using this analyzer. +// Token terms resulting from this analysis are +// used to perform term searches. Result documents +// must satisfy at least one of these term searches. +func NewMatchQuery(match string) *query.MatchQuery { + return query.NewMatchQuery(match) +} + +// NewNumericRangeQuery creates a new Query for ranges +// of numeric values. +// Either, but not both endpoints can be nil. +// The minimum value is inclusive. +// The maximum value is exclusive. +func NewNumericRangeQuery(min, max *float64) *query.NumericRangeQuery { + return query.NewNumericRangeQuery(min, max) +} + +// NewNumericRangeInclusiveQuery creates a new Query for ranges +// of numeric values. +// Either, but not both endpoints can be nil. +// Control endpoint inclusion with inclusiveMin, inclusiveMax. +func NewNumericRangeInclusiveQuery(min, max *float64, minInclusive, maxInclusive *bool) *query.NumericRangeQuery { + return query.NewNumericRangeInclusiveQuery(min, max, minInclusive, maxInclusive) +} + +// NewTermRangeQuery creates a new Query for ranges +// of text terms. +// Either, but not both endpoints can be "". +// The minimum value is inclusive. +// The maximum value is exclusive. +func NewTermRangeQuery(min, max string) *query.TermRangeQuery { + return query.NewTermRangeQuery(min, max) +} + +// NewTermRangeInclusiveQuery creates a new Query for ranges +// of text terms. +// Either, but not both endpoints can be "". +// Control endpoint inclusion with inclusiveMin, inclusiveMax. +func NewTermRangeInclusiveQuery(min, max string, minInclusive, maxInclusive *bool) *query.TermRangeQuery { + return query.NewTermRangeInclusiveQuery(min, max, minInclusive, maxInclusive) +} + +// NewPhraseQuery creates a new Query for finding +// exact term phrases in the index. +// The provided terms must exist in the correct +// order, at the correct index offsets, in the +// specified field. Queried field must have been indexed with +// IncludeTermVectors set to true. +func NewPhraseQuery(terms []string, field string) *query.PhraseQuery { + return query.NewPhraseQuery(terms, field) +} + +// NewPrefixQuery creates a new Query which finds +// documents containing terms that start with the +// specified prefix. +func NewPrefixQuery(prefix string) *query.PrefixQuery { + return query.NewPrefixQuery(prefix) +} + +// NewRegexpQuery creates a new Query which finds +// documents containing terms that match the +// specified regular expression. +func NewRegexpQuery(regexp string) *query.RegexpQuery { + return query.NewRegexpQuery(regexp) +} + +// NewQueryStringQuery creates a new Query used for +// finding documents that satisfy a query string. The +// query string is a small query language for humans. +func NewQueryStringQuery(q string) *query.QueryStringQuery { + return query.NewQueryStringQuery(q) +} + +// NewTermQuery creates a new Query for finding an +// exact term match in the index. +func NewTermQuery(term string) *query.TermQuery { + return query.NewTermQuery(term) +} + +// NewWildcardQuery creates a new Query which finds +// documents containing terms that match the +// specified wildcard. In the wildcard pattern '*' +// will match any sequence of 0 or more characters, +// and '?' will match any single character. +func NewWildcardQuery(wildcard string) *query.WildcardQuery { + return query.NewWildcardQuery(wildcard) +} + +// NewGeoBoundingBoxQuery creates a new Query for performing geo bounding +// box searches. The arguments describe the position of the box and documents +// which have an indexed geo point inside the box will be returned. +func NewGeoBoundingBoxQuery(topLeftLon, topLeftLat, bottomRightLon, bottomRightLat float64) *query.GeoBoundingBoxQuery { + return query.NewGeoBoundingBoxQuery(topLeftLon, topLeftLat, bottomRightLon, bottomRightLat) +} + +// NewGeoDistanceQuery creates a new Query for performing geo distance +// searches. The arguments describe a position and a distance. Documents +// which have an indexed geo point which is less than or equal to the provided +// distance from the given position will be returned. +func NewGeoDistanceQuery(lon, lat float64, distance string) *query.GeoDistanceQuery { + return query.NewGeoDistanceQuery(lon, lat, distance) +} + +// NewIPRangeQuery creates a new Query for matching IP addresses. +// If the argument is in CIDR format, then the query will match all +// IP addresses in the network specified. If the argument is an IP address, +// then the query will return documents which contain that IP. +// Both ipv4 and ipv6 are supported. +func NewIPRangeQuery(cidr string) *query.IPRangeQuery { + return query.NewIPRangeQuery(cidr) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/registry/analyzer.go b/backend/vendor/github.com/blevesearch/bleve/v2/registry/analyzer.go new file mode 100644 index 0000000000..f4753bc1c2 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/registry/analyzer.go @@ -0,0 +1,89 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package registry + +import ( + "fmt" + + "github.com/blevesearch/bleve/v2/analysis" +) + +func RegisterAnalyzer(name string, constructor AnalyzerConstructor) { + _, exists := analyzers[name] + if exists { + panic(fmt.Errorf("attempted to register duplicate analyzer named '%s'", name)) + } + analyzers[name] = constructor +} + +type AnalyzerConstructor func(config map[string]interface{}, cache *Cache) (analysis.Analyzer, error) +type AnalyzerRegistry map[string]AnalyzerConstructor + +type AnalyzerCache struct { + *ConcurrentCache +} + +func NewAnalyzerCache() *AnalyzerCache { + return &AnalyzerCache{ + NewConcurrentCache(), + } +} + +func AnalyzerBuild(name string, config map[string]interface{}, cache *Cache) (interface{}, error) { + cons, registered := analyzers[name] + if !registered { + return nil, fmt.Errorf("no analyzer with name or type '%s' registered", name) + } + analyzer, err := cons(config, cache) + if err != nil { + return nil, fmt.Errorf("error building analyzer: %v", err) + } + return analyzer, nil +} + +func (c *AnalyzerCache) AnalyzerNamed(name string, cache *Cache) (analysis.Analyzer, error) { + item, err := c.ItemNamed(name, cache, AnalyzerBuild) + if err != nil { + return nil, err + } + return item.(analysis.Analyzer), nil +} + +func (c *AnalyzerCache) DefineAnalyzer(name string, typ string, config map[string]interface{}, cache *Cache) (analysis.Analyzer, error) { + item, err := c.DefineItem(name, typ, config, cache, AnalyzerBuild) + if err != nil { + if err == ErrAlreadyDefined { + return nil, fmt.Errorf("analyzer named '%s' already defined", name) + } + return nil, err + } + return item.(analysis.Analyzer), nil +} + +func AnalyzerTypesAndInstances() ([]string, []string) { + emptyConfig := map[string]interface{}{} + emptyCache := NewCache() + var types []string + var instances []string + for name, cons := range analyzers { + _, err := cons(emptyConfig, emptyCache) + if err == nil { + instances = append(instances, name) + } else { + types = append(types, name) + } + } + return types, instances +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/registry/cache.go b/backend/vendor/github.com/blevesearch/bleve/v2/registry/cache.go new file mode 100644 index 0000000000..b0ce852a20 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/registry/cache.go @@ -0,0 +1,87 @@ +// Copyright (c) 2016 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package registry + +import ( + "fmt" + "sync" +) + +var ErrAlreadyDefined = fmt.Errorf("item already defined") + +type CacheBuild func(name string, config map[string]interface{}, cache *Cache) (interface{}, error) + +type ConcurrentCache struct { + mutex sync.RWMutex + data map[string]interface{} +} + +func NewConcurrentCache() *ConcurrentCache { + return &ConcurrentCache{ + data: make(map[string]interface{}), + } +} + +func (c *ConcurrentCache) ItemNamed(name string, cache *Cache, build CacheBuild) (interface{}, error) { + c.mutex.RLock() + item, cached := c.data[name] + if cached { + c.mutex.RUnlock() + return item, nil + } + // give up read lock + c.mutex.RUnlock() + // try to build it + newItem, err := build(name, nil, cache) + if err != nil { + return nil, err + } + // acquire write lock + c.mutex.Lock() + defer c.mutex.Unlock() + // check again because it could have been created while trading locks + item, cached = c.data[name] + if cached { + return item, nil + } + c.data[name] = newItem + return newItem, nil +} + +func (c *ConcurrentCache) DefineItem(name string, typ string, config map[string]interface{}, cache *Cache, build CacheBuild) (interface{}, error) { + c.mutex.RLock() + _, cached := c.data[name] + if cached { + c.mutex.RUnlock() + return nil, ErrAlreadyDefined + } + // give up read lock so others lookups can proceed + c.mutex.RUnlock() + // really not there, try to build it + newItem, err := build(typ, config, cache) + if err != nil { + return nil, err + } + // now we've built it, acquire lock + c.mutex.Lock() + defer c.mutex.Unlock() + // check again because it could have been created while trading locks + _, cached = c.data[name] + if cached { + return nil, ErrAlreadyDefined + } + c.data[name] = newItem + return newItem, nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/registry/char_filter.go b/backend/vendor/github.com/blevesearch/bleve/v2/registry/char_filter.go new file mode 100644 index 0000000000..aa400be682 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/registry/char_filter.go @@ -0,0 +1,89 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package registry + +import ( + "fmt" + + "github.com/blevesearch/bleve/v2/analysis" +) + +func RegisterCharFilter(name string, constructor CharFilterConstructor) { + _, exists := charFilters[name] + if exists { + panic(fmt.Errorf("attempted to register duplicate char filter named '%s'", name)) + } + charFilters[name] = constructor +} + +type CharFilterConstructor func(config map[string]interface{}, cache *Cache) (analysis.CharFilter, error) +type CharFilterRegistry map[string]CharFilterConstructor + +type CharFilterCache struct { + *ConcurrentCache +} + +func NewCharFilterCache() *CharFilterCache { + return &CharFilterCache{ + NewConcurrentCache(), + } +} + +func CharFilterBuild(name string, config map[string]interface{}, cache *Cache) (interface{}, error) { + cons, registered := charFilters[name] + if !registered { + return nil, fmt.Errorf("no char filter with name or type '%s' registered", name) + } + charFilter, err := cons(config, cache) + if err != nil { + return nil, fmt.Errorf("error building char filter: %v", err) + } + return charFilter, nil +} + +func (c *CharFilterCache) CharFilterNamed(name string, cache *Cache) (analysis.CharFilter, error) { + item, err := c.ItemNamed(name, cache, CharFilterBuild) + if err != nil { + return nil, err + } + return item.(analysis.CharFilter), nil +} + +func (c *CharFilterCache) DefineCharFilter(name string, typ string, config map[string]interface{}, cache *Cache) (analysis.CharFilter, error) { + item, err := c.DefineItem(name, typ, config, cache, CharFilterBuild) + if err != nil { + if err == ErrAlreadyDefined { + return nil, fmt.Errorf("char filter named '%s' already defined", name) + } + return nil, err + } + return item.(analysis.CharFilter), nil +} + +func CharFilterTypesAndInstances() ([]string, []string) { + emptyConfig := map[string]interface{}{} + emptyCache := NewCache() + var types []string + var instances []string + for name, cons := range charFilters { + _, err := cons(emptyConfig, emptyCache) + if err == nil { + instances = append(instances, name) + } else { + types = append(types, name) + } + } + return types, instances +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/registry/datetime_parser.go b/backend/vendor/github.com/blevesearch/bleve/v2/registry/datetime_parser.go new file mode 100644 index 0000000000..a2d8ac24ab --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/registry/datetime_parser.go @@ -0,0 +1,89 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package registry + +import ( + "fmt" + + "github.com/blevesearch/bleve/v2/analysis" +) + +func RegisterDateTimeParser(name string, constructor DateTimeParserConstructor) { + _, exists := dateTimeParsers[name] + if exists { + panic(fmt.Errorf("attempted to register duplicate date time parser named '%s'", name)) + } + dateTimeParsers[name] = constructor +} + +type DateTimeParserConstructor func(config map[string]interface{}, cache *Cache) (analysis.DateTimeParser, error) +type DateTimeParserRegistry map[string]DateTimeParserConstructor + +type DateTimeParserCache struct { + *ConcurrentCache +} + +func NewDateTimeParserCache() *DateTimeParserCache { + return &DateTimeParserCache{ + NewConcurrentCache(), + } +} + +func DateTimeParserBuild(name string, config map[string]interface{}, cache *Cache) (interface{}, error) { + cons, registered := dateTimeParsers[name] + if !registered { + return nil, fmt.Errorf("no date time parser with name or type '%s' registered", name) + } + dateTimeParser, err := cons(config, cache) + if err != nil { + return nil, fmt.Errorf("error building date time parser: %v", err) + } + return dateTimeParser, nil +} + +func (c *DateTimeParserCache) DateTimeParserNamed(name string, cache *Cache) (analysis.DateTimeParser, error) { + item, err := c.ItemNamed(name, cache, DateTimeParserBuild) + if err != nil { + return nil, err + } + return item.(analysis.DateTimeParser), nil +} + +func (c *DateTimeParserCache) DefineDateTimeParser(name string, typ string, config map[string]interface{}, cache *Cache) (analysis.DateTimeParser, error) { + item, err := c.DefineItem(name, typ, config, cache, DateTimeParserBuild) + if err != nil { + if err == ErrAlreadyDefined { + return nil, fmt.Errorf("date time parser named '%s' already defined", name) + } + return nil, err + } + return item.(analysis.DateTimeParser), nil +} + +func DateTimeParserTypesAndInstances() ([]string, []string) { + emptyConfig := map[string]interface{}{} + emptyCache := NewCache() + var types []string + var instances []string + for name, cons := range dateTimeParsers { + _, err := cons(emptyConfig, emptyCache) + if err == nil { + instances = append(instances, name) + } else { + types = append(types, name) + } + } + return types, instances +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/registry/fragment_formatter.go b/backend/vendor/github.com/blevesearch/bleve/v2/registry/fragment_formatter.go new file mode 100644 index 0000000000..6699f53bab --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/registry/fragment_formatter.go @@ -0,0 +1,89 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package registry + +import ( + "fmt" + + "github.com/blevesearch/bleve/v2/search/highlight" +) + +func RegisterFragmentFormatter(name string, constructor FragmentFormatterConstructor) { + _, exists := fragmentFormatters[name] + if exists { + panic(fmt.Errorf("attempted to register duplicate fragment formatter named '%s'", name)) + } + fragmentFormatters[name] = constructor +} + +type FragmentFormatterConstructor func(config map[string]interface{}, cache *Cache) (highlight.FragmentFormatter, error) +type FragmentFormatterRegistry map[string]FragmentFormatterConstructor + +type FragmentFormatterCache struct { + *ConcurrentCache +} + +func NewFragmentFormatterCache() *FragmentFormatterCache { + return &FragmentFormatterCache{ + NewConcurrentCache(), + } +} + +func FragmentFormatterBuild(name string, config map[string]interface{}, cache *Cache) (interface{}, error) { + cons, registered := fragmentFormatters[name] + if !registered { + return nil, fmt.Errorf("no fragment formatter with name or type '%s' registered", name) + } + fragmentFormatter, err := cons(config, cache) + if err != nil { + return nil, fmt.Errorf("error building fragment formatter: %v", err) + } + return fragmentFormatter, nil +} + +func (c *FragmentFormatterCache) FragmentFormatterNamed(name string, cache *Cache) (highlight.FragmentFormatter, error) { + item, err := c.ItemNamed(name, cache, FragmentFormatterBuild) + if err != nil { + return nil, err + } + return item.(highlight.FragmentFormatter), nil +} + +func (c *FragmentFormatterCache) DefineFragmentFormatter(name string, typ string, config map[string]interface{}, cache *Cache) (highlight.FragmentFormatter, error) { + item, err := c.DefineItem(name, typ, config, cache, FragmentFormatterBuild) + if err != nil { + if err == ErrAlreadyDefined { + return nil, fmt.Errorf("fragment formatter named '%s' already defined", name) + } + return nil, err + } + return item.(highlight.FragmentFormatter), nil +} + +func FragmentFormatterTypesAndInstances() ([]string, []string) { + emptyConfig := map[string]interface{}{} + emptyCache := NewCache() + var types []string + var instances []string + for name, cons := range fragmentFormatters { + _, err := cons(emptyConfig, emptyCache) + if err == nil { + instances = append(instances, name) + } else { + types = append(types, name) + } + } + return types, instances +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/registry/fragmenter.go b/backend/vendor/github.com/blevesearch/bleve/v2/registry/fragmenter.go new file mode 100644 index 0000000000..cd1e32d28d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/registry/fragmenter.go @@ -0,0 +1,89 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package registry + +import ( + "fmt" + + "github.com/blevesearch/bleve/v2/search/highlight" +) + +func RegisterFragmenter(name string, constructor FragmenterConstructor) { + _, exists := fragmenters[name] + if exists { + panic(fmt.Errorf("attempted to register duplicate fragmenter named '%s'", name)) + } + fragmenters[name] = constructor +} + +type FragmenterConstructor func(config map[string]interface{}, cache *Cache) (highlight.Fragmenter, error) +type FragmenterRegistry map[string]FragmenterConstructor + +type FragmenterCache struct { + *ConcurrentCache +} + +func NewFragmenterCache() *FragmenterCache { + return &FragmenterCache{ + NewConcurrentCache(), + } +} + +func FragmenterBuild(name string, config map[string]interface{}, cache *Cache) (interface{}, error) { + cons, registered := fragmenters[name] + if !registered { + return nil, fmt.Errorf("no fragmenter with name or type '%s' registered", name) + } + fragmenter, err := cons(config, cache) + if err != nil { + return nil, fmt.Errorf("error building fragmenter: %v", err) + } + return fragmenter, nil +} + +func (c *FragmenterCache) FragmenterNamed(name string, cache *Cache) (highlight.Fragmenter, error) { + item, err := c.ItemNamed(name, cache, FragmenterBuild) + if err != nil { + return nil, err + } + return item.(highlight.Fragmenter), nil +} + +func (c *FragmenterCache) DefineFragmenter(name string, typ string, config map[string]interface{}, cache *Cache) (highlight.Fragmenter, error) { + item, err := c.DefineItem(name, typ, config, cache, FragmenterBuild) + if err != nil { + if err == ErrAlreadyDefined { + return nil, fmt.Errorf("fragmenter named '%s' already defined", name) + } + return nil, err + } + return item.(highlight.Fragmenter), nil +} + +func FragmenterTypesAndInstances() ([]string, []string) { + emptyConfig := map[string]interface{}{} + emptyCache := NewCache() + var types []string + var instances []string + for name, cons := range fragmenters { + _, err := cons(emptyConfig, emptyCache) + if err == nil { + instances = append(instances, name) + } else { + types = append(types, name) + } + } + return types, instances +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/registry/highlighter.go b/backend/vendor/github.com/blevesearch/bleve/v2/registry/highlighter.go new file mode 100644 index 0000000000..8eb210fb3c --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/registry/highlighter.go @@ -0,0 +1,89 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package registry + +import ( + "fmt" + + "github.com/blevesearch/bleve/v2/search/highlight" +) + +func RegisterHighlighter(name string, constructor HighlighterConstructor) { + _, exists := highlighters[name] + if exists { + panic(fmt.Errorf("attempted to register duplicate highlighter named '%s'", name)) + } + highlighters[name] = constructor +} + +type HighlighterConstructor func(config map[string]interface{}, cache *Cache) (highlight.Highlighter, error) +type HighlighterRegistry map[string]HighlighterConstructor + +type HighlighterCache struct { + *ConcurrentCache +} + +func NewHighlighterCache() *HighlighterCache { + return &HighlighterCache{ + NewConcurrentCache(), + } +} + +func HighlighterBuild(name string, config map[string]interface{}, cache *Cache) (interface{}, error) { + cons, registered := highlighters[name] + if !registered { + return nil, fmt.Errorf("no highlighter with name or type '%s' registered", name) + } + highlighter, err := cons(config, cache) + if err != nil { + return nil, fmt.Errorf("error building highlighter: %v", err) + } + return highlighter, nil +} + +func (c *HighlighterCache) HighlighterNamed(name string, cache *Cache) (highlight.Highlighter, error) { + item, err := c.ItemNamed(name, cache, HighlighterBuild) + if err != nil { + return nil, err + } + return item.(highlight.Highlighter), nil +} + +func (c *HighlighterCache) DefineHighlighter(name string, typ string, config map[string]interface{}, cache *Cache) (highlight.Highlighter, error) { + item, err := c.DefineItem(name, typ, config, cache, HighlighterBuild) + if err != nil { + if err == ErrAlreadyDefined { + return nil, fmt.Errorf("highlighter named '%s' already defined", name) + } + return nil, err + } + return item.(highlight.Highlighter), nil +} + +func HighlighterTypesAndInstances() ([]string, []string) { + emptyConfig := map[string]interface{}{} + emptyCache := NewCache() + var types []string + var instances []string + for name, cons := range highlighters { + _, err := cons(emptyConfig, emptyCache) + if err == nil { + instances = append(instances, name) + } else { + types = append(types, name) + } + } + return types, instances +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/registry/index_type.go b/backend/vendor/github.com/blevesearch/bleve/v2/registry/index_type.go new file mode 100644 index 0000000000..67938c4afa --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/registry/index_type.go @@ -0,0 +1,45 @@ +// Copyright (c) 2015 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package registry + +import ( + "fmt" + + index "github.com/blevesearch/bleve_index_api" +) + +func RegisterIndexType(name string, constructor IndexTypeConstructor) { + _, exists := indexTypes[name] + if exists { + panic(fmt.Errorf("attempted to register duplicate index encoding named '%s'", name)) + } + indexTypes[name] = constructor +} + +type IndexTypeConstructor func(storeName string, storeConfig map[string]interface{}, analysisQueue *index.AnalysisQueue) (index.Index, error) +type IndexTypeRegistry map[string]IndexTypeConstructor + +func IndexTypeConstructorByName(name string) IndexTypeConstructor { + return indexTypes[name] +} + +func IndexTypesAndInstances() ([]string, []string) { + var types []string + var instances []string + for name := range stores { + types = append(types, name) + } + return types, instances +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/registry/registry.go b/backend/vendor/github.com/blevesearch/bleve/v2/registry/registry.go new file mode 100644 index 0000000000..1954d08963 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/registry/registry.go @@ -0,0 +1,184 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package registry + +import ( + "fmt" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/search/highlight" +) + +var stores = make(KVStoreRegistry, 0) +var indexTypes = make(IndexTypeRegistry, 0) + +// highlight +var fragmentFormatters = make(FragmentFormatterRegistry, 0) +var fragmenters = make(FragmenterRegistry, 0) +var highlighters = make(HighlighterRegistry, 0) + +// analysis +var charFilters = make(CharFilterRegistry, 0) +var tokenizers = make(TokenizerRegistry, 0) +var tokenMaps = make(TokenMapRegistry, 0) +var tokenFilters = make(TokenFilterRegistry, 0) +var analyzers = make(AnalyzerRegistry, 0) +var dateTimeParsers = make(DateTimeParserRegistry, 0) + +type Cache struct { + CharFilters *CharFilterCache + Tokenizers *TokenizerCache + TokenMaps *TokenMapCache + TokenFilters *TokenFilterCache + Analyzers *AnalyzerCache + DateTimeParsers *DateTimeParserCache + FragmentFormatters *FragmentFormatterCache + Fragmenters *FragmenterCache + Highlighters *HighlighterCache +} + +func NewCache() *Cache { + return &Cache{ + CharFilters: NewCharFilterCache(), + Tokenizers: NewTokenizerCache(), + TokenMaps: NewTokenMapCache(), + TokenFilters: NewTokenFilterCache(), + Analyzers: NewAnalyzerCache(), + DateTimeParsers: NewDateTimeParserCache(), + FragmentFormatters: NewFragmentFormatterCache(), + Fragmenters: NewFragmenterCache(), + Highlighters: NewHighlighterCache(), + } +} + +func typeFromConfig(config map[string]interface{}) (string, error) { + prop, ok := config["type"] + if !ok { + return "", fmt.Errorf("'type' property is not defined") + } + typ, ok := prop.(string) + if !ok { + return "", fmt.Errorf("'type' property must be a string, not %T", prop) + } + return typ, nil +} + +func (c *Cache) CharFilterNamed(name string) (analysis.CharFilter, error) { + return c.CharFilters.CharFilterNamed(name, c) +} + +func (c *Cache) DefineCharFilter(name string, config map[string]interface{}) (analysis.CharFilter, error) { + typ, err := typeFromConfig(config) + if err != nil { + return nil, err + } + return c.CharFilters.DefineCharFilter(name, typ, config, c) +} + +func (c *Cache) TokenizerNamed(name string) (analysis.Tokenizer, error) { + return c.Tokenizers.TokenizerNamed(name, c) +} + +func (c *Cache) DefineTokenizer(name string, config map[string]interface{}) (analysis.Tokenizer, error) { + typ, err := typeFromConfig(config) + if err != nil { + return nil, fmt.Errorf("cannot resolve '%s' tokenizer type: %s", name, err) + } + return c.Tokenizers.DefineTokenizer(name, typ, config, c) +} + +func (c *Cache) TokenMapNamed(name string) (analysis.TokenMap, error) { + return c.TokenMaps.TokenMapNamed(name, c) +} + +func (c *Cache) DefineTokenMap(name string, config map[string]interface{}) (analysis.TokenMap, error) { + typ, err := typeFromConfig(config) + if err != nil { + return nil, err + } + return c.TokenMaps.DefineTokenMap(name, typ, config, c) +} + +func (c *Cache) TokenFilterNamed(name string) (analysis.TokenFilter, error) { + return c.TokenFilters.TokenFilterNamed(name, c) +} + +func (c *Cache) DefineTokenFilter(name string, config map[string]interface{}) (analysis.TokenFilter, error) { + typ, err := typeFromConfig(config) + if err != nil { + return nil, err + } + return c.TokenFilters.DefineTokenFilter(name, typ, config, c) +} + +func (c *Cache) AnalyzerNamed(name string) (analysis.Analyzer, error) { + return c.Analyzers.AnalyzerNamed(name, c) +} + +func (c *Cache) DefineAnalyzer(name string, config map[string]interface{}) (analysis.Analyzer, error) { + typ, err := typeFromConfig(config) + if err != nil { + return nil, err + } + return c.Analyzers.DefineAnalyzer(name, typ, config, c) +} + +func (c *Cache) DateTimeParserNamed(name string) (analysis.DateTimeParser, error) { + return c.DateTimeParsers.DateTimeParserNamed(name, c) +} + +func (c *Cache) DefineDateTimeParser(name string, config map[string]interface{}) (analysis.DateTimeParser, error) { + typ, err := typeFromConfig(config) + if err != nil { + return nil, err + } + return c.DateTimeParsers.DefineDateTimeParser(name, typ, config, c) +} + +func (c *Cache) FragmentFormatterNamed(name string) (highlight.FragmentFormatter, error) { + return c.FragmentFormatters.FragmentFormatterNamed(name, c) +} + +func (c *Cache) DefineFragmentFormatter(name string, config map[string]interface{}) (highlight.FragmentFormatter, error) { + typ, err := typeFromConfig(config) + if err != nil { + return nil, err + } + return c.FragmentFormatters.DefineFragmentFormatter(name, typ, config, c) +} + +func (c *Cache) FragmenterNamed(name string) (highlight.Fragmenter, error) { + return c.Fragmenters.FragmenterNamed(name, c) +} + +func (c *Cache) DefineFragmenter(name string, config map[string]interface{}) (highlight.Fragmenter, error) { + typ, err := typeFromConfig(config) + if err != nil { + return nil, err + } + return c.Fragmenters.DefineFragmenter(name, typ, config, c) +} + +func (c *Cache) HighlighterNamed(name string) (highlight.Highlighter, error) { + return c.Highlighters.HighlighterNamed(name, c) +} + +func (c *Cache) DefineHighlighter(name string, config map[string]interface{}) (highlight.Highlighter, error) { + typ, err := typeFromConfig(config) + if err != nil { + return nil, err + } + return c.Highlighters.DefineHighlighter(name, typ, config, c) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/registry/store.go b/backend/vendor/github.com/blevesearch/bleve/v2/registry/store.go new file mode 100644 index 0000000000..02ebd888cc --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/registry/store.go @@ -0,0 +1,51 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package registry + +import ( + "fmt" + + "github.com/blevesearch/upsidedown_store_api" +) + +func RegisterKVStore(name string, constructor KVStoreConstructor) { + _, exists := stores[name] + if exists { + panic(fmt.Errorf("attempted to register duplicate store named '%s'", name)) + } + stores[name] = constructor +} + +// KVStoreConstructor is used to build a KVStore of a specific type when +// specificied by the index configuration. In addition to meeting the +// store.KVStore interface, KVStores must also support this constructor. +// Note that currently the values of config must +// be able to be marshaled and unmarshaled using the encoding/json library (used +// when reading/writing the index metadata file). +type KVStoreConstructor func(mo store.MergeOperator, config map[string]interface{}) (store.KVStore, error) +type KVStoreRegistry map[string]KVStoreConstructor + +func KVStoreConstructorByName(name string) KVStoreConstructor { + return stores[name] +} + +func KVStoreTypesAndInstances() ([]string, []string) { + var types []string + var instances []string + for name := range stores { + types = append(types, name) + } + return types, instances +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/registry/token_filter.go b/backend/vendor/github.com/blevesearch/bleve/v2/registry/token_filter.go new file mode 100644 index 0000000000..df39411ae3 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/registry/token_filter.go @@ -0,0 +1,89 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package registry + +import ( + "fmt" + + "github.com/blevesearch/bleve/v2/analysis" +) + +func RegisterTokenFilter(name string, constructor TokenFilterConstructor) { + _, exists := tokenFilters[name] + if exists { + panic(fmt.Errorf("attempted to register duplicate token filter named '%s'", name)) + } + tokenFilters[name] = constructor +} + +type TokenFilterConstructor func(config map[string]interface{}, cache *Cache) (analysis.TokenFilter, error) +type TokenFilterRegistry map[string]TokenFilterConstructor + +type TokenFilterCache struct { + *ConcurrentCache +} + +func NewTokenFilterCache() *TokenFilterCache { + return &TokenFilterCache{ + NewConcurrentCache(), + } +} + +func TokenFilterBuild(name string, config map[string]interface{}, cache *Cache) (interface{}, error) { + cons, registered := tokenFilters[name] + if !registered { + return nil, fmt.Errorf("no token filter with name or type '%s' registered", name) + } + tokenFilter, err := cons(config, cache) + if err != nil { + return nil, fmt.Errorf("error building token filter: %v", err) + } + return tokenFilter, nil +} + +func (c *TokenFilterCache) TokenFilterNamed(name string, cache *Cache) (analysis.TokenFilter, error) { + item, err := c.ItemNamed(name, cache, TokenFilterBuild) + if err != nil { + return nil, err + } + return item.(analysis.TokenFilter), nil +} + +func (c *TokenFilterCache) DefineTokenFilter(name string, typ string, config map[string]interface{}, cache *Cache) (analysis.TokenFilter, error) { + item, err := c.DefineItem(name, typ, config, cache, TokenFilterBuild) + if err != nil { + if err == ErrAlreadyDefined { + return nil, fmt.Errorf("token filter named '%s' already defined", name) + } + return nil, err + } + return item.(analysis.TokenFilter), nil +} + +func TokenFilterTypesAndInstances() ([]string, []string) { + emptyConfig := map[string]interface{}{} + emptyCache := NewCache() + var types []string + var instances []string + for name, cons := range tokenFilters { + _, err := cons(emptyConfig, emptyCache) + if err == nil { + instances = append(instances, name) + } else { + types = append(types, name) + } + } + return types, instances +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/registry/token_maps.go b/backend/vendor/github.com/blevesearch/bleve/v2/registry/token_maps.go new file mode 100644 index 0000000000..08c9956eb1 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/registry/token_maps.go @@ -0,0 +1,89 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package registry + +import ( + "fmt" + + "github.com/blevesearch/bleve/v2/analysis" +) + +func RegisterTokenMap(name string, constructor TokenMapConstructor) { + _, exists := tokenMaps[name] + if exists { + panic(fmt.Errorf("attempted to register duplicate token map named '%s'", name)) + } + tokenMaps[name] = constructor +} + +type TokenMapConstructor func(config map[string]interface{}, cache *Cache) (analysis.TokenMap, error) +type TokenMapRegistry map[string]TokenMapConstructor + +type TokenMapCache struct { + *ConcurrentCache +} + +func NewTokenMapCache() *TokenMapCache { + return &TokenMapCache{ + NewConcurrentCache(), + } +} + +func TokenMapBuild(name string, config map[string]interface{}, cache *Cache) (interface{}, error) { + cons, registered := tokenMaps[name] + if !registered { + return nil, fmt.Errorf("no token map with name or type '%s' registered", name) + } + tokenMap, err := cons(config, cache) + if err != nil { + return nil, fmt.Errorf("error building token map: %v", err) + } + return tokenMap, nil +} + +func (c *TokenMapCache) TokenMapNamed(name string, cache *Cache) (analysis.TokenMap, error) { + item, err := c.ItemNamed(name, cache, TokenMapBuild) + if err != nil { + return nil, err + } + return item.(analysis.TokenMap), nil +} + +func (c *TokenMapCache) DefineTokenMap(name string, typ string, config map[string]interface{}, cache *Cache) (analysis.TokenMap, error) { + item, err := c.DefineItem(name, typ, config, cache, TokenMapBuild) + if err != nil { + if err == ErrAlreadyDefined { + return nil, fmt.Errorf("token map named '%s' already defined", name) + } + return nil, err + } + return item.(analysis.TokenMap), nil +} + +func TokenMapTypesAndInstances() ([]string, []string) { + emptyConfig := map[string]interface{}{} + emptyCache := NewCache() + var types []string + var instances []string + for name, cons := range tokenMaps { + _, err := cons(emptyConfig, emptyCache) + if err == nil { + instances = append(instances, name) + } else { + types = append(types, name) + } + } + return types, instances +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/registry/tokenizer.go b/backend/vendor/github.com/blevesearch/bleve/v2/registry/tokenizer.go new file mode 100644 index 0000000000..eb954287c3 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/registry/tokenizer.go @@ -0,0 +1,89 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package registry + +import ( + "fmt" + + "github.com/blevesearch/bleve/v2/analysis" +) + +func RegisterTokenizer(name string, constructor TokenizerConstructor) { + _, exists := tokenizers[name] + if exists { + panic(fmt.Errorf("attempted to register duplicate tokenizer named '%s'", name)) + } + tokenizers[name] = constructor +} + +type TokenizerConstructor func(config map[string]interface{}, cache *Cache) (analysis.Tokenizer, error) +type TokenizerRegistry map[string]TokenizerConstructor + +type TokenizerCache struct { + *ConcurrentCache +} + +func NewTokenizerCache() *TokenizerCache { + return &TokenizerCache{ + NewConcurrentCache(), + } +} + +func TokenizerBuild(name string, config map[string]interface{}, cache *Cache) (interface{}, error) { + cons, registered := tokenizers[name] + if !registered { + return nil, fmt.Errorf("no tokenizer with name or type '%s' registered", name) + } + tokenizer, err := cons(config, cache) + if err != nil { + return nil, fmt.Errorf("error building tokenizer: %v", err) + } + return tokenizer, nil +} + +func (c *TokenizerCache) TokenizerNamed(name string, cache *Cache) (analysis.Tokenizer, error) { + item, err := c.ItemNamed(name, cache, TokenizerBuild) + if err != nil { + return nil, err + } + return item.(analysis.Tokenizer), nil +} + +func (c *TokenizerCache) DefineTokenizer(name string, typ string, config map[string]interface{}, cache *Cache) (analysis.Tokenizer, error) { + item, err := c.DefineItem(name, typ, config, cache, TokenizerBuild) + if err != nil { + if err == ErrAlreadyDefined { + return nil, fmt.Errorf("tokenizer named '%s' already defined", name) + } + return nil, err + } + return item.(analysis.Tokenizer), nil +} + +func TokenizerTypesAndInstances() ([]string, []string) { + emptyConfig := map[string]interface{}{} + emptyCache := NewCache() + var types []string + var instances []string + for name, cons := range tokenizers { + _, err := cons(emptyConfig, emptyCache) + if err == nil { + instances = append(instances, name) + } else { + types = append(types, name) + } + } + return types, instances +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search.go b/backend/vendor/github.com/blevesearch/bleve/v2/search.go new file mode 100644 index 0000000000..acb812adaa --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search.go @@ -0,0 +1,641 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bleve + +import ( + "encoding/json" + "fmt" + "reflect" + "sort" + "time" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/analysis/datetime/optional" + "github.com/blevesearch/bleve/v2/document" + "github.com/blevesearch/bleve/v2/registry" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/collector" + "github.com/blevesearch/bleve/v2/search/query" + "github.com/blevesearch/bleve/v2/size" +) + +var reflectStaticSizeSearchResult int +var reflectStaticSizeSearchStatus int + +func init() { + var sr SearchResult + reflectStaticSizeSearchResult = int(reflect.TypeOf(sr).Size()) + var ss SearchStatus + reflectStaticSizeSearchStatus = int(reflect.TypeOf(ss).Size()) +} + +var cache = registry.NewCache() + +const defaultDateTimeParser = optional.Name + +type numericRange struct { + Name string `json:"name,omitempty"` + Min *float64 `json:"min,omitempty"` + Max *float64 `json:"max,omitempty"` +} + +type dateTimeRange struct { + Name string `json:"name,omitempty"` + Start time.Time `json:"start,omitempty"` + End time.Time `json:"end,omitempty"` + startString *string + endString *string +} + +func (dr *dateTimeRange) ParseDates(dateTimeParser analysis.DateTimeParser) (start, end time.Time) { + start = dr.Start + if dr.Start.IsZero() && dr.startString != nil { + s, err := dateTimeParser.ParseDateTime(*dr.startString) + if err == nil { + start = s + } + } + end = dr.End + if dr.End.IsZero() && dr.endString != nil { + e, err := dateTimeParser.ParseDateTime(*dr.endString) + if err == nil { + end = e + } + } + return start, end +} + +func (dr *dateTimeRange) UnmarshalJSON(input []byte) error { + var temp struct { + Name string `json:"name,omitempty"` + Start *string `json:"start,omitempty"` + End *string `json:"end,omitempty"` + } + + err := json.Unmarshal(input, &temp) + if err != nil { + return err + } + + dr.Name = temp.Name + if temp.Start != nil { + dr.startString = temp.Start + } + if temp.End != nil { + dr.endString = temp.End + } + + return nil +} + +func (dr *dateTimeRange) MarshalJSON() ([]byte, error) { + rv := map[string]interface{}{ + "name": dr.Name, + "start": dr.Start, + "end": dr.End, + } + if dr.Start.IsZero() && dr.startString != nil { + rv["start"] = dr.startString + } + if dr.End.IsZero() && dr.endString != nil { + rv["end"] = dr.endString + } + return json.Marshal(rv) +} + +// A FacetRequest describes a facet or aggregation +// of the result document set you would like to be +// built. +type FacetRequest struct { + Size int `json:"size"` + Field string `json:"field"` + NumericRanges []*numericRange `json:"numeric_ranges,omitempty"` + DateTimeRanges []*dateTimeRange `json:"date_ranges,omitempty"` +} + +func (fr *FacetRequest) Validate() error { + nrCount := len(fr.NumericRanges) + drCount := len(fr.DateTimeRanges) + if nrCount > 0 && drCount > 0 { + return fmt.Errorf("facet can only conain numeric ranges or date ranges, not both") + } + + if nrCount > 0 { + nrNames := map[string]interface{}{} + for _, nr := range fr.NumericRanges { + if _, ok := nrNames[nr.Name]; ok { + return fmt.Errorf("numeric ranges contains duplicate name '%s'", nr.Name) + } + nrNames[nr.Name] = struct{}{} + if nr.Min == nil && nr.Max == nil { + return fmt.Errorf("numeric range query must specify either min, max or both for range name '%s'", nr.Name) + } + } + + } else { + dateTimeParser, err := cache.DateTimeParserNamed(defaultDateTimeParser) + if err != nil { + return err + } + drNames := map[string]interface{}{} + for _, dr := range fr.DateTimeRanges { + if _, ok := drNames[dr.Name]; ok { + return fmt.Errorf("date ranges contains duplicate name '%s'", dr.Name) + } + drNames[dr.Name] = struct{}{} + start, end := dr.ParseDates(dateTimeParser) + if start.IsZero() && end.IsZero() { + return fmt.Errorf("date range query must specify either start, end or both for range name '%s'", dr.Name) + } + } + } + return nil +} + +// NewFacetRequest creates a facet on the specified +// field that limits the number of entries to the +// specified size. +func NewFacetRequest(field string, size int) *FacetRequest { + return &FacetRequest{ + Field: field, + Size: size, + } +} + +// AddDateTimeRange adds a bucket to a field +// containing date values. Documents with a +// date value falling into this range are tabulated +// as part of this bucket/range. +func (fr *FacetRequest) AddDateTimeRange(name string, start, end time.Time) { + if fr.DateTimeRanges == nil { + fr.DateTimeRanges = make([]*dateTimeRange, 0, 1) + } + fr.DateTimeRanges = append(fr.DateTimeRanges, &dateTimeRange{Name: name, Start: start, End: end}) +} + +// AddDateTimeRangeString adds a bucket to a field +// containing date values. +func (fr *FacetRequest) AddDateTimeRangeString(name string, start, end *string) { + if fr.DateTimeRanges == nil { + fr.DateTimeRanges = make([]*dateTimeRange, 0, 1) + } + fr.DateTimeRanges = append(fr.DateTimeRanges, + &dateTimeRange{Name: name, startString: start, endString: end}) +} + +// AddNumericRange adds a bucket to a field +// containing numeric values. Documents with a +// numeric value falling into this range are +// tabulated as part of this bucket/range. +func (fr *FacetRequest) AddNumericRange(name string, min, max *float64) { + if fr.NumericRanges == nil { + fr.NumericRanges = make([]*numericRange, 0, 1) + } + fr.NumericRanges = append(fr.NumericRanges, &numericRange{Name: name, Min: min, Max: max}) +} + +// FacetsRequest groups together all the +// FacetRequest objects for a single query. +type FacetsRequest map[string]*FacetRequest + +func (fr FacetsRequest) Validate() error { + for _, v := range fr { + err := v.Validate() + if err != nil { + return err + } + } + return nil +} + +// HighlightRequest describes how field matches +// should be highlighted. +type HighlightRequest struct { + Style *string `json:"style"` + Fields []string `json:"fields"` +} + +// NewHighlight creates a default +// HighlightRequest. +func NewHighlight() *HighlightRequest { + return &HighlightRequest{} +} + +// NewHighlightWithStyle creates a HighlightRequest +// with an alternate style. +func NewHighlightWithStyle(style string) *HighlightRequest { + return &HighlightRequest{ + Style: &style, + } +} + +func (h *HighlightRequest) AddField(field string) { + if h.Fields == nil { + h.Fields = make([]string, 0, 1) + } + h.Fields = append(h.Fields, field) +} + +// A SearchRequest describes all the parameters +// needed to search the index. +// Query is required. +// Size/From describe how much and which part of the +// result set to return. +// Highlight describes optional search result +// highlighting. +// Fields describes a list of field values which +// should be retrieved for result documents, provided they +// were stored while indexing. +// Facets describe the set of facets to be computed. +// Explain triggers inclusion of additional search +// result score explanations. +// Sort describes the desired order for the results to be returned. +// Score controls the kind of scoring performed +// SearchAfter supports deep paging by providing a minimum sort key +// SearchBefore supports deep paging by providing a maximum sort key +// sortFunc specifies the sort implementation to use for sorting results. +// +// A special field named "*" can be used to return all fields. +type SearchRequest struct { + Query query.Query `json:"query"` + Size int `json:"size"` + From int `json:"from"` + Highlight *HighlightRequest `json:"highlight"` + Fields []string `json:"fields"` + Facets FacetsRequest `json:"facets"` + Explain bool `json:"explain"` + Sort search.SortOrder `json:"sort"` + IncludeLocations bool `json:"includeLocations"` + Score string `json:"score,omitempty"` + SearchAfter []string `json:"search_after"` + SearchBefore []string `json:"search_before"` + + sortFunc func(sort.Interface) +} + +func (r *SearchRequest) Validate() error { + if srq, ok := r.Query.(query.ValidatableQuery); ok { + err := srq.Validate() + if err != nil { + return err + } + } + + if r.SearchAfter != nil && r.SearchBefore != nil { + return fmt.Errorf("cannot use search after and search before together") + } + + if r.SearchAfter != nil { + if r.From != 0 { + return fmt.Errorf("cannot use search after with from !=0") + } + if len(r.SearchAfter) != len(r.Sort) { + return fmt.Errorf("search after must have same size as sort order") + } + } + if r.SearchBefore != nil { + if r.From != 0 { + return fmt.Errorf("cannot use search before with from !=0") + } + if len(r.SearchBefore) != len(r.Sort) { + return fmt.Errorf("search before must have same size as sort order") + } + } + + return r.Facets.Validate() +} + +// AddFacet adds a FacetRequest to this SearchRequest +func (r *SearchRequest) AddFacet(facetName string, f *FacetRequest) { + if r.Facets == nil { + r.Facets = make(FacetsRequest, 1) + } + r.Facets[facetName] = f +} + +// SortBy changes the request to use the requested sort order +// this form uses the simplified syntax with an array of strings +// each string can either be a field name +// or the magic value _id and _score which refer to the doc id and search score +// any of these values can optionally be prefixed with - to reverse the order +func (r *SearchRequest) SortBy(order []string) { + so := search.ParseSortOrderStrings(order) + r.Sort = so +} + +// SortByCustom changes the request to use the requested sort order +func (r *SearchRequest) SortByCustom(order search.SortOrder) { + r.Sort = order +} + +// SetSearchAfter sets the request to skip over hits with a sort +// value less than the provided sort after key +func (r *SearchRequest) SetSearchAfter(after []string) { + r.SearchAfter = after +} + +// SetSearchBefore sets the request to skip over hits with a sort +// value greater than the provided sort before key +func (r *SearchRequest) SetSearchBefore(before []string) { + r.SearchBefore = before +} + +// UnmarshalJSON deserializes a JSON representation of +// a SearchRequest +func (r *SearchRequest) UnmarshalJSON(input []byte) error { + var temp struct { + Q json.RawMessage `json:"query"` + Size *int `json:"size"` + From int `json:"from"` + Highlight *HighlightRequest `json:"highlight"` + Fields []string `json:"fields"` + Facets FacetsRequest `json:"facets"` + Explain bool `json:"explain"` + Sort []json.RawMessage `json:"sort"` + IncludeLocations bool `json:"includeLocations"` + Score string `json:"score"` + SearchAfter []string `json:"search_after"` + SearchBefore []string `json:"search_before"` + } + + err := json.Unmarshal(input, &temp) + if err != nil { + return err + } + + if temp.Size == nil { + r.Size = 10 + } else { + r.Size = *temp.Size + } + if temp.Sort == nil { + r.Sort = search.SortOrder{&search.SortScore{Desc: true}} + } else { + r.Sort, err = search.ParseSortOrderJSON(temp.Sort) + if err != nil { + return err + } + } + r.From = temp.From + r.Explain = temp.Explain + r.Highlight = temp.Highlight + r.Fields = temp.Fields + r.Facets = temp.Facets + r.IncludeLocations = temp.IncludeLocations + r.Score = temp.Score + r.SearchAfter = temp.SearchAfter + r.SearchBefore = temp.SearchBefore + r.Query, err = query.ParseQuery(temp.Q) + if err != nil { + return err + } + + if r.Size < 0 { + r.Size = 10 + } + if r.From < 0 { + r.From = 0 + } + + return nil + +} + +// NewSearchRequest creates a new SearchRequest +// for the Query, using default values for all +// other search parameters. +func NewSearchRequest(q query.Query) *SearchRequest { + return NewSearchRequestOptions(q, 10, 0, false) +} + +// NewSearchRequestOptions creates a new SearchRequest +// for the Query, with the requested size, from +// and explanation search parameters. +// By default results are ordered by score, descending. +func NewSearchRequestOptions(q query.Query, size, from int, explain bool) *SearchRequest { + return &SearchRequest{ + Query: q, + Size: size, + From: from, + Explain: explain, + Sort: search.SortOrder{&search.SortScore{Desc: true}}, + } +} + +// IndexErrMap tracks errors with the name of the index where it occurred +type IndexErrMap map[string]error + +// MarshalJSON seralizes the error into a string for JSON consumption +func (iem IndexErrMap) MarshalJSON() ([]byte, error) { + tmp := make(map[string]string, len(iem)) + for k, v := range iem { + tmp[k] = v.Error() + } + return json.Marshal(tmp) +} + +func (iem IndexErrMap) UnmarshalJSON(data []byte) error { + var tmp map[string]string + err := json.Unmarshal(data, &tmp) + if err != nil { + return err + } + for k, v := range tmp { + iem[k] = fmt.Errorf("%s", v) + } + return nil +} + +// SearchStatus is a secion in the SearchResult reporting how many +// underlying indexes were queried, how many were successful/failed +// and a map of any errors that were encountered +type SearchStatus struct { + Total int `json:"total"` + Failed int `json:"failed"` + Successful int `json:"successful"` + Errors IndexErrMap `json:"errors,omitempty"` +} + +// Merge will merge together multiple SearchStatuses during a MultiSearch +func (ss *SearchStatus) Merge(other *SearchStatus) { + ss.Total += other.Total + ss.Failed += other.Failed + ss.Successful += other.Successful + if len(other.Errors) > 0 { + if ss.Errors == nil { + ss.Errors = make(map[string]error) + } + for otherIndex, otherError := range other.Errors { + ss.Errors[otherIndex] = otherError + } + } +} + +// A SearchResult describes the results of executing +// a SearchRequest. +type SearchResult struct { + Status *SearchStatus `json:"status"` + Request *SearchRequest `json:"request"` + Hits search.DocumentMatchCollection `json:"hits"` + Total uint64 `json:"total_hits"` + BytesRead uint64 `json:"bytesRead"` + MaxScore float64 `json:"max_score"` + Took time.Duration `json:"took"` + Facets search.FacetResults `json:"facets"` +} + +func (sr *SearchResult) Size() int { + sizeInBytes := reflectStaticSizeSearchResult + size.SizeOfPtr + + reflectStaticSizeSearchStatus + + for _, entry := range sr.Hits { + if entry != nil { + sizeInBytes += entry.Size() + } + } + + for k, v := range sr.Facets { + sizeInBytes += size.SizeOfString + len(k) + + v.Size() + } + + return sizeInBytes +} + +func (sr *SearchResult) String() string { + rv := "" + if sr.Total > 0 { + if sr.Request.Size > 0 { + rv = fmt.Sprintf("%d matches, showing %d through %d, took %s\n", sr.Total, sr.Request.From+1, sr.Request.From+len(sr.Hits), sr.Took) + for i, hit := range sr.Hits { + rv += fmt.Sprintf("%5d. %s (%f)\n", i+sr.Request.From+1, hit.ID, hit.Score) + for fragmentField, fragments := range hit.Fragments { + rv += fmt.Sprintf("\t%s\n", fragmentField) + for _, fragment := range fragments { + rv += fmt.Sprintf("\t\t%s\n", fragment) + } + } + for otherFieldName, otherFieldValue := range hit.Fields { + if _, ok := hit.Fragments[otherFieldName]; !ok { + rv += fmt.Sprintf("\t%s\n", otherFieldName) + rv += fmt.Sprintf("\t\t%v\n", otherFieldValue) + } + } + } + } else { + rv = fmt.Sprintf("%d matches, took %s\n", sr.Total, sr.Took) + } + } else { + rv = "No matches" + } + if len(sr.Facets) > 0 { + rv += fmt.Sprintf("Facets:\n") + for fn, f := range sr.Facets { + rv += fmt.Sprintf("%s(%d)\n", fn, f.Total) + for _, t := range f.Terms.Terms() { + rv += fmt.Sprintf("\t%s(%d)\n", t.Term, t.Count) + } + for _, n := range f.NumericRanges { + rv += fmt.Sprintf("\t%s(%d)\n", n.Name, n.Count) + } + for _, d := range f.DateRanges { + rv += fmt.Sprintf("\t%s(%d)\n", d.Name, d.Count) + } + if f.Other != 0 { + rv += fmt.Sprintf("\tOther(%d)\n", f.Other) + } + } + } + return rv +} + +// Merge will merge together multiple SearchResults during a MultiSearch +func (sr *SearchResult) Merge(other *SearchResult) { + sr.Status.Merge(other.Status) + sr.Hits = append(sr.Hits, other.Hits...) + sr.Total += other.Total + sr.BytesRead += other.BytesRead + if other.MaxScore > sr.MaxScore { + sr.MaxScore = other.MaxScore + } + if sr.Facets == nil && len(other.Facets) != 0 { + sr.Facets = other.Facets + return + } + + sr.Facets.Merge(other.Facets) +} + +// MemoryNeededForSearchResult is an exported helper function to determine the RAM +// needed to accommodate the results for a given search request. +func MemoryNeededForSearchResult(req *SearchRequest) uint64 { + if req == nil { + return 0 + } + + numDocMatches := req.Size + req.From + if req.Size+req.From > collector.PreAllocSizeSkipCap { + numDocMatches = collector.PreAllocSizeSkipCap + } + + estimate := 0 + + // overhead from the SearchResult structure + var sr SearchResult + estimate += sr.Size() + + var dm search.DocumentMatch + sizeOfDocumentMatch := dm.Size() + + // overhead from results + estimate += numDocMatches * sizeOfDocumentMatch + + // overhead from facet results + if req.Facets != nil { + var fr search.FacetResult + estimate += len(req.Facets) * fr.Size() + } + + // overhead from fields, highlighting + var d document.Document + if len(req.Fields) > 0 || req.Highlight != nil { + numDocsApplicable := req.Size + if numDocsApplicable > collector.PreAllocSizeSkipCap { + numDocsApplicable = collector.PreAllocSizeSkipCap + } + estimate += numDocsApplicable * d.Size() + } + + return uint64(estimate) +} + +// SetSortFunc sets the sort implementation to use when sorting hits. +// +// SearchRequests can specify a custom sort implementation to meet +// their needs. For instance, by specifying a parallel sort +// that uses all available cores. +func (r *SearchRequest) SetSortFunc(s func(sort.Interface)) { + r.sortFunc = s +} + +// SortFunc returns the sort implementation to use when sorting hits. +// Defaults to sort.Sort. +func (r *SearchRequest) SortFunc() func(data sort.Interface) { + if r.sortFunc != nil { + return r.sortFunc + } + + return sort.Sort +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/collector.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/collector.go new file mode 100644 index 0000000000..38e34fe7c0 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/collector.go @@ -0,0 +1,52 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package search + +import ( + "context" + "time" + + index "github.com/blevesearch/bleve_index_api" +) + +type Collector interface { + Collect(ctx context.Context, searcher Searcher, reader index.IndexReader) error + Results() DocumentMatchCollection + Total() uint64 + MaxScore() float64 + Took() time.Duration + SetFacetsBuilder(facetsBuilder *FacetsBuilder) + FacetResults() FacetResults +} + +// DocumentMatchHandler is the type of document match callback +// bleve will invoke during the search. +// Eventually, bleve will indicate the completion of an ongoing search, +// by passing a nil value for the document match callback. +// The application should take a copy of the hit/documentMatch +// if it wish to own it or need prolonged access to it. +type DocumentMatchHandler func(hit *DocumentMatch) error + +type MakeDocumentMatchHandlerKeyType string + +var MakeDocumentMatchHandlerKey = MakeDocumentMatchHandlerKeyType( + "MakeDocumentMatchHandlerKey") + +// MakeDocumentMatchHandler is an optional DocumentMatchHandler +// builder function which the applications can pass to bleve. +// These builder methods gives a DocumentMatchHandler function +// to bleve, which it will invoke on every document matches. +type MakeDocumentMatchHandler func(ctx *SearchContext) ( + callback DocumentMatchHandler, loadID bool, err error) diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/collector/heap.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/collector/heap.go new file mode 100644 index 0000000000..9503f00603 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/collector/heap.go @@ -0,0 +1,95 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "container/heap" + + "github.com/blevesearch/bleve/v2/search" +) + +type collectStoreHeap struct { + heap search.DocumentMatchCollection + compare collectorCompare +} + +func newStoreHeap(capacity int, compare collectorCompare) *collectStoreHeap { + rv := &collectStoreHeap{ + heap: make(search.DocumentMatchCollection, 0, capacity), + compare: compare, + } + heap.Init(rv) + return rv +} + +func (c *collectStoreHeap) AddNotExceedingSize(doc *search.DocumentMatch, + size int) *search.DocumentMatch { + c.add(doc) + if c.Len() > size { + return c.removeLast() + } + return nil +} + +func (c *collectStoreHeap) add(doc *search.DocumentMatch) { + heap.Push(c, doc) +} + +func (c *collectStoreHeap) removeLast() *search.DocumentMatch { + return heap.Pop(c).(*search.DocumentMatch) +} + +func (c *collectStoreHeap) Final(skip int, fixup collectorFixup) (search.DocumentMatchCollection, error) { + count := c.Len() + size := count - skip + if size <= 0 { + return make(search.DocumentMatchCollection, 0), nil + } + rv := make(search.DocumentMatchCollection, size) + for i := size - 1; i >= 0; i-- { + doc := heap.Pop(c).(*search.DocumentMatch) + rv[i] = doc + err := fixup(doc) + if err != nil { + return nil, err + } + } + return rv, nil +} + +// heap interface implementation + +func (c *collectStoreHeap) Len() int { + return len(c.heap) +} + +func (c *collectStoreHeap) Less(i, j int) bool { + so := c.compare(c.heap[i], c.heap[j]) + return -so < 0 +} + +func (c *collectStoreHeap) Swap(i, j int) { + c.heap[i], c.heap[j] = c.heap[j], c.heap[i] +} + +func (c *collectStoreHeap) Push(x interface{}) { + c.heap = append(c.heap, x.(*search.DocumentMatch)) +} + +func (c *collectStoreHeap) Pop() interface{} { + var rv *search.DocumentMatch + rv, c.heap = c.heap[len(c.heap)-1], c.heap[:len(c.heap)-1] + return rv +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/collector/list.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/collector/list.go new file mode 100644 index 0000000000..20d4c9d01b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/collector/list.go @@ -0,0 +1,86 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "container/list" + + "github.com/blevesearch/bleve/v2/search" +) + +type collectStoreList struct { + results *list.List + compare collectorCompare +} + +func newStoreList(capacity int, compare collectorCompare) *collectStoreList { + rv := &collectStoreList{ + results: list.New(), + compare: compare, + } + + return rv +} + +func (c *collectStoreList) AddNotExceedingSize(doc *search.DocumentMatch, size int) *search.DocumentMatch { + c.add(doc) + if c.len() > size { + return c.removeLast() + } + return nil +} + +func (c *collectStoreList) add(doc *search.DocumentMatch) { + for e := c.results.Front(); e != nil; e = e.Next() { + curr := e.Value.(*search.DocumentMatch) + if c.compare(doc, curr) >= 0 { + c.results.InsertBefore(doc, e) + return + } + } + // if we got to the end, we still have to add it + c.results.PushBack(doc) +} + +func (c *collectStoreList) removeLast() *search.DocumentMatch { + return c.results.Remove(c.results.Front()).(*search.DocumentMatch) +} + +func (c *collectStoreList) Final(skip int, fixup collectorFixup) (search.DocumentMatchCollection, error) { + if c.results.Len()-skip > 0 { + rv := make(search.DocumentMatchCollection, c.results.Len()-skip) + i := 0 + skipped := 0 + for e := c.results.Back(); e != nil; e = e.Prev() { + if skipped < skip { + skipped++ + continue + } + + rv[i] = e.Value.(*search.DocumentMatch) + err := fixup(rv[i]) + if err != nil { + return nil, err + } + i++ + } + return rv, nil + } + return search.DocumentMatchCollection{}, nil +} + +func (c *collectStoreList) len() int { + return c.results.Len() +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/collector/slice.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/collector/slice.go new file mode 100644 index 0000000000..b38d9abc4f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/collector/slice.go @@ -0,0 +1,77 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import "github.com/blevesearch/bleve/v2/search" + +type collectStoreSlice struct { + slice search.DocumentMatchCollection + compare collectorCompare +} + +func newStoreSlice(capacity int, compare collectorCompare) *collectStoreSlice { + rv := &collectStoreSlice{ + slice: make(search.DocumentMatchCollection, 0, capacity), + compare: compare, + } + return rv +} + +func (c *collectStoreSlice) AddNotExceedingSize(doc *search.DocumentMatch, + size int) *search.DocumentMatch { + c.add(doc) + if c.len() > size { + return c.removeLast() + } + return nil +} + +func (c *collectStoreSlice) add(doc *search.DocumentMatch) { + // find where to insert, starting at end (lowest) + i := len(c.slice) + for ; i > 0; i-- { + cmp := c.compare(doc, c.slice[i-1]) + if cmp >= 0 { + break + } + } + // insert at i + c.slice = append(c.slice, nil) + copy(c.slice[i+1:], c.slice[i:]) + c.slice[i] = doc +} + +func (c *collectStoreSlice) removeLast() *search.DocumentMatch { + var rv *search.DocumentMatch + rv, c.slice = c.slice[len(c.slice)-1], c.slice[:len(c.slice)-1] + return rv +} + +func (c *collectStoreSlice) Final(skip int, fixup collectorFixup) (search.DocumentMatchCollection, error) { + for i := skip; i < len(c.slice); i++ { + err := fixup(c.slice[i]) + if err != nil { + return nil, err + } + } + if skip <= len(c.slice) { + return c.slice[skip:], nil + } + return search.DocumentMatchCollection{}, nil +} + +func (c *collectStoreSlice) len() int { + return len(c.slice) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/collector/topn.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/collector/topn.go new file mode 100644 index 0000000000..4d19cd4559 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/collector/topn.go @@ -0,0 +1,420 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "context" + "reflect" + "strconv" + "time" + + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeTopNCollector int + +func init() { + var coll TopNCollector + reflectStaticSizeTopNCollector = int(reflect.TypeOf(coll).Size()) +} + +type collectorStore interface { + // Add the document, and if the new store size exceeds the provided size + // the last element is removed and returned. If the size has not been + // exceeded, nil is returned. + AddNotExceedingSize(doc *search.DocumentMatch, size int) *search.DocumentMatch + + Final(skip int, fixup collectorFixup) (search.DocumentMatchCollection, error) +} + +// PreAllocSizeSkipCap will cap preallocation to this amount when +// size+skip exceeds this value +var PreAllocSizeSkipCap = 1000 + +type collectorCompare func(i, j *search.DocumentMatch) int + +type collectorFixup func(d *search.DocumentMatch) error + +// TopNCollector collects the top N hits, optionally skipping some results +type TopNCollector struct { + size int + skip int + total uint64 + bytesRead uint64 + maxScore float64 + took time.Duration + sort search.SortOrder + results search.DocumentMatchCollection + facetsBuilder *search.FacetsBuilder + + store collectorStore + + needDocIds bool + neededFields []string + cachedScoring []bool + cachedDesc []bool + + lowestMatchOutsideResults *search.DocumentMatch + updateFieldVisitor index.DocValueVisitor + dvReader index.DocValueReader + searchAfter *search.DocumentMatch +} + +// CheckDoneEvery controls how frequently we check the context deadline +const CheckDoneEvery = uint64(1024) + +// NewTopNCollector builds a collector to find the top 'size' hits +// skipping over the first 'skip' hits +// ordering hits by the provided sort order +func NewTopNCollector(size int, skip int, sort search.SortOrder) *TopNCollector { + return newTopNCollector(size, skip, sort) +} + +// NewTopNCollectorAfter builds a collector to find the top 'size' hits +// skipping over the first 'skip' hits +// ordering hits by the provided sort order +func NewTopNCollectorAfter(size int, sort search.SortOrder, after []string) *TopNCollector { + rv := newTopNCollector(size, 0, sort) + rv.searchAfter = &search.DocumentMatch{ + Sort: after, + } + + for pos, ss := range sort { + if ss.RequiresDocID() { + rv.searchAfter.ID = after[pos] + } + if ss.RequiresScoring() { + if score, err := strconv.ParseFloat(after[pos], 64); err == nil { + rv.searchAfter.Score = score + } + } + } + + return rv +} + +func newTopNCollector(size int, skip int, sort search.SortOrder) *TopNCollector { + hc := &TopNCollector{size: size, skip: skip, sort: sort} + + // pre-allocate space on the store to avoid reslicing + // unless the size + skip is too large, then cap it + // everything should still work, just reslices as necessary + backingSize := size + skip + 1 + if size+skip > PreAllocSizeSkipCap { + backingSize = PreAllocSizeSkipCap + 1 + } + + if size+skip > 10 { + hc.store = newStoreHeap(backingSize, func(i, j *search.DocumentMatch) int { + return hc.sort.Compare(hc.cachedScoring, hc.cachedDesc, i, j) + }) + } else { + hc.store = newStoreSlice(backingSize, func(i, j *search.DocumentMatch) int { + return hc.sort.Compare(hc.cachedScoring, hc.cachedDesc, i, j) + }) + } + + // these lookups traverse an interface, so do once up-front + if sort.RequiresDocID() { + hc.needDocIds = true + } + hc.neededFields = sort.RequiredFields() + hc.cachedScoring = sort.CacheIsScore() + hc.cachedDesc = sort.CacheDescending() + + return hc +} + +func (hc *TopNCollector) Size() int { + sizeInBytes := reflectStaticSizeTopNCollector + size.SizeOfPtr + + if hc.facetsBuilder != nil { + sizeInBytes += hc.facetsBuilder.Size() + } + + for _, entry := range hc.neededFields { + sizeInBytes += len(entry) + size.SizeOfString + } + + sizeInBytes += len(hc.cachedScoring) + len(hc.cachedDesc) + + return sizeInBytes +} + +// Collect goes to the index to find the matching documents +func (hc *TopNCollector) Collect(ctx context.Context, searcher search.Searcher, reader index.IndexReader) error { + startTime := time.Now() + var err error + var next *search.DocumentMatch + + // pre-allocate enough space in the DocumentMatchPool + // unless the size + skip is too large, then cap it + // everything should still work, just allocates DocumentMatches on demand + backingSize := hc.size + hc.skip + 1 + if hc.size+hc.skip > PreAllocSizeSkipCap { + backingSize = PreAllocSizeSkipCap + 1 + } + searchContext := &search.SearchContext{ + DocumentMatchPool: search.NewDocumentMatchPool(backingSize+searcher.DocumentMatchPoolSize(), len(hc.sort)), + Collector: hc, + IndexReader: reader, + } + + hc.dvReader, err = reader.DocValueReader(hc.neededFields) + if err != nil { + return err + } + + hc.updateFieldVisitor = func(field string, term []byte) { + if hc.facetsBuilder != nil { + hc.facetsBuilder.UpdateVisitor(field, term) + } + hc.sort.UpdateVisitor(field, term) + } + + dmHandlerMaker := MakeTopNDocumentMatchHandler + if cv := ctx.Value(search.MakeDocumentMatchHandlerKey); cv != nil { + dmHandlerMaker = cv.(search.MakeDocumentMatchHandler) + } + // use the application given builder for making the custom document match + // handler and perform callbacks/invocations on the newly made handler. + dmHandler, loadID, err := dmHandlerMaker(searchContext) + if err != nil { + return err + } + + hc.needDocIds = hc.needDocIds || loadID + select { + case <-ctx.Done(): + return ctx.Err() + default: + next, err = searcher.Next(searchContext) + } + for err == nil && next != nil { + if hc.total%CheckDoneEvery == 0 { + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + } + + err = hc.prepareDocumentMatch(searchContext, reader, next) + if err != nil { + break + } + + err = dmHandler(next) + if err != nil { + break + } + + next, err = searcher.Next(searchContext) + } + + statsCallbackFn := ctx.Value(search.SearchIOStatsCallbackKey) + if statsCallbackFn != nil { + // hc.bytesRead corresponds to the + // total bytes read as part of docValues being read every hit + // which must be accounted by invoking the callback. + statsCallbackFn.(search.SearchIOStatsCallbackFunc)(hc.bytesRead) + } + + // help finalize/flush the results in case + // of custom document match handlers. + err = dmHandler(nil) + if err != nil { + return err + } + + // compute search duration + hc.took = time.Since(startTime) + + // finalize actual results + err = hc.finalizeResults(reader) + if err != nil { + return err + } + return nil +} + +var sortByScoreOpt = []string{"_score"} + +func (hc *TopNCollector) prepareDocumentMatch(ctx *search.SearchContext, + reader index.IndexReader, d *search.DocumentMatch) (err error) { + + // visit field terms for features that require it (sort, facets) + if len(hc.neededFields) > 0 { + err = hc.visitFieldTerms(reader, d) + if err != nil { + return err + } + } + + // increment total hits + hc.total++ + d.HitNumber = hc.total + + // update max score + if d.Score > hc.maxScore { + hc.maxScore = d.Score + } + + // see if we need to load ID (at this early stage, for example to sort on it) + if hc.needDocIds { + d.ID, err = reader.ExternalID(d.IndexInternalID) + if err != nil { + return err + } + } + + // compute this hits sort value + if len(hc.sort) == 1 && hc.cachedScoring[0] { + d.Sort = sortByScoreOpt + } else { + hc.sort.Value(d) + } + + return nil +} + +func MakeTopNDocumentMatchHandler( + ctx *search.SearchContext) (search.DocumentMatchHandler, bool, error) { + var hc *TopNCollector + var ok bool + if hc, ok = ctx.Collector.(*TopNCollector); ok { + return func(d *search.DocumentMatch) error { + if d == nil { + return nil + } + + // support search after based pagination, + // if this hit is <= the search after sort key + // we should skip it + if hc.searchAfter != nil { + // exact sort order matches use hit number to break tie + // but we want to allow for exact match, so we pretend + hc.searchAfter.HitNumber = d.HitNumber + if hc.sort.Compare(hc.cachedScoring, hc.cachedDesc, d, hc.searchAfter) <= 0 { + return nil + } + } + + // optimization, we track lowest sorting hit already removed from heap + // with this one comparison, we can avoid all heap operations if + // this hit would have been added and then immediately removed + if hc.lowestMatchOutsideResults != nil { + cmp := hc.sort.Compare(hc.cachedScoring, hc.cachedDesc, d, + hc.lowestMatchOutsideResults) + if cmp >= 0 { + // this hit can't possibly be in the result set, so avoid heap ops + ctx.DocumentMatchPool.Put(d) + return nil + } + } + + removed := hc.store.AddNotExceedingSize(d, hc.size+hc.skip) + if removed != nil { + if hc.lowestMatchOutsideResults == nil { + hc.lowestMatchOutsideResults = removed + } else { + cmp := hc.sort.Compare(hc.cachedScoring, hc.cachedDesc, + removed, hc.lowestMatchOutsideResults) + if cmp < 0 { + tmp := hc.lowestMatchOutsideResults + hc.lowestMatchOutsideResults = removed + ctx.DocumentMatchPool.Put(tmp) + } + } + } + return nil + }, false, nil + } + return nil, false, nil +} + +// visitFieldTerms is responsible for visiting the field terms of the +// search hit, and passing visited terms to the sort and facet builder +func (hc *TopNCollector) visitFieldTerms(reader index.IndexReader, d *search.DocumentMatch) error { + if hc.facetsBuilder != nil { + hc.facetsBuilder.StartDoc() + } + + err := hc.dvReader.VisitDocValues(d.IndexInternalID, hc.updateFieldVisitor) + if hc.facetsBuilder != nil { + hc.facetsBuilder.EndDoc() + } + + hc.bytesRead += hc.dvReader.BytesRead() + + return err +} + +// SetFacetsBuilder registers a facet builder for this collector +func (hc *TopNCollector) SetFacetsBuilder(facetsBuilder *search.FacetsBuilder) { + hc.facetsBuilder = facetsBuilder + hc.neededFields = append(hc.neededFields, hc.facetsBuilder.RequiredFields()...) +} + +// finalizeResults starts with the heap containing the final top size+skip +// it now throws away the results to be skipped +// and does final doc id lookup (if necessary) +func (hc *TopNCollector) finalizeResults(r index.IndexReader) error { + var err error + hc.results, err = hc.store.Final(hc.skip, func(doc *search.DocumentMatch) error { + if doc.ID == "" { + // look up the id since we need it for lookup + var err error + doc.ID, err = r.ExternalID(doc.IndexInternalID) + if err != nil { + return err + } + } + doc.Complete(nil) + return nil + }) + + return err +} + +// Results returns the collected hits +func (hc *TopNCollector) Results() search.DocumentMatchCollection { + return hc.results +} + +// Total returns the total number of hits +func (hc *TopNCollector) Total() uint64 { + return hc.total +} + +// MaxScore returns the maximum score seen across all the hits +func (hc *TopNCollector) MaxScore() float64 { + return hc.maxScore +} + +// Took returns the time spent collecting hits +func (hc *TopNCollector) Took() time.Duration { + return hc.took +} + +// FacetResults returns the computed facets results +func (hc *TopNCollector) FacetResults() search.FacetResults { + if hc.facetsBuilder != nil { + return hc.facetsBuilder.Results() + } + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/explanation.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/explanation.go new file mode 100644 index 0000000000..b1ac29aa84 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/explanation.go @@ -0,0 +1,55 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package search + +import ( + "encoding/json" + "fmt" + "reflect" + + "github.com/blevesearch/bleve/v2/size" +) + +var reflectStaticSizeExplanation int + +func init() { + var e Explanation + reflectStaticSizeExplanation = int(reflect.TypeOf(e).Size()) +} + +type Explanation struct { + Value float64 `json:"value"` + Message string `json:"message"` + Children []*Explanation `json:"children,omitempty"` +} + +func (expl *Explanation) String() string { + js, err := json.MarshalIndent(expl, "", " ") + if err != nil { + return fmt.Sprintf("error serializing explanation to json: %v", err) + } + return string(js) +} + +func (expl *Explanation) Size() int { + sizeInBytes := reflectStaticSizeExplanation + size.SizeOfPtr + + len(expl.Message) + + for _, entry := range expl.Children { + sizeInBytes += entry.Size() + } + + return sizeInBytes +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/facet/benchmark_data.txt b/backend/vendor/github.com/blevesearch/bleve/v2/search/facet/benchmark_data.txt new file mode 100644 index 0000000000..b012f78ce5 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/facet/benchmark_data.txt @@ -0,0 +1,2909 @@ +Boiling liquid expanding vapor explosion +From Wikipedia, the free encyclopedia +See also: Boiler explosion and Steam explosion + +Flames subsequent to a flammable liquid BLEVE from a tanker. BLEVEs do not necessarily involve fire. + +This article's tone or style may not reflect the encyclopedic tone used on Wikipedia. See Wikipedia's guide to writing better articles for suggestions. (July 2013) +A boiling liquid expanding vapor explosion (BLEVE, /ˈblɛviː/ blev-ee) is an explosion caused by the rupture of a vessel containing a pressurized liquid above its boiling point.[1] +Contents [hide] +1 Mechanism +1.1 Water example +1.2 BLEVEs without chemical reactions +2 Fires +3 Incidents +4 Safety measures +5 See also +6 References +7 External links +Mechanism[edit] + +This section needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed. (July 2013) +There are three characteristics of liquids which are relevant to the discussion of a BLEVE: +If a liquid in a sealed container is boiled, the pressure inside the container increases. As the liquid changes to a gas it expands - this expansion in a vented container would cause the gas and liquid to take up more space. In a sealed container the gas and liquid are not able to take up more space and so the pressure rises. Pressurized vessels containing liquids can reach an equilibrium where the liquid stops boiling and the pressure stops rising. This occurs when no more heat is being added to the system (either because it has reached ambient temperature or has had a heat source removed). +The boiling temperature of a liquid is dependent on pressure - high pressures will yield high boiling temperatures, and low pressures will yield low boiling temperatures. A common simple experiment is to place a cup of water in a vacuum chamber, and then reduce the pressure in the chamber until the water boils. By reducing the pressure the water will boil even at room temperature. This works both ways - if the pressure is increased beyond normal atmospheric pressures, the boiling of hot water could be suppressed far beyond normal temperatures. The cooling system of a modern internal combustion engine is a real-world example. +When a liquid boils it turns into a gas. The resulting gas takes up far more space than the liquid did. +Typically, a BLEVE starts with a container of liquid which is held above its normal, atmospheric-pressure boiling temperature. Many substances normally stored as liquids, such as CO2, oxygen, and other similar industrial gases have boiling temperatures, at atmospheric pressure, far below room temperature. In the case of water, a BLEVE could occur if a pressurized chamber of water is heated far beyond the standard 100 °C (212 °F). That container, because the boiling water pressurizes it, is capable of holding liquid water at very high temperatures. +If the pressurized vessel, containing liquid at high temperature (which may be room temperature, depending on the substance) ruptures, the pressure which prevents the liquid from boiling is lost. If the rupture is catastrophic, where the vessel is immediately incapable of holding any pressure at all, then there suddenly exists a large mass of liquid which is at very high temperature and very low pressure. This causes the entire volume of liquid to instantaneously boil, which in turn causes an extremely rapid expansion. Depending on temperatures, pressures and the substance involved, that expansion may be so rapid that it can be classified as an explosion, fully capable of inflicting severe damage on its surroundings. +Water example[edit] +Imagine, for example, a tank of pressurized liquid water held at 204.4 °C (400 °F). This vessel would normally be pressurized to 1.7 MPa (250 psi) above atmospheric ("gauge") pressure. Were the tank containing the water to split open, there would momentarily exist a volume of liquid water which is +at atmospheric pressure, and +204.4 °C (400 °F). +At atmospheric pressure the boiling point of water is 100 °C (212 °F) - liquid water at atmospheric pressure cannot exist at temperatures higher than 100 °C (212 °F). It is obvious, then, that 204.4 °C (400 °F) liquid water at atmospheric pressure must immediately flash to gas causing an explosion. +BLEVEs without chemical reactions[edit] +It is important to note that a BLEVE need not be a chemical explosion - nor does there need to be a fire - however if a flammable substance is subject to a BLEVE it may also be subject to intense heating, either from an external source of heat which may have caused the vessel to rupture in the first place or from an internal source of localized heating such as skin friction. This heating can cause a flammable substance to ignite, adding a secondary explosion caused by the primary BLEVE. While blast effects of any BLEVE can be devastating, a flammable substance such as propane can add significantly to the danger. +Bleve explosion.svg +While the term BLEVE is most often used to describe the results of a container of flammable liquid rupturing due to fire, a BLEVE can occur even with a non-flammable substance such as water,[2] liquid nitrogen,[3] liquid helium or other refrigerants or cryogens, and therefore is not usually considered a type of chemical explosion. +Fires[edit] +BLEVEs can be caused by an external fire near the storage vessel causing heating of the contents and pressure build-up. While tanks are often designed to withstand great pressure, constant heating can cause the metal to weaken and eventually fail. If the tank is being heated in an area where there is no liquid, it may rupture faster without the liquid to absorb the heat. Gas containers are usually equipped with relief valves that vent off excess pressure, but the tank can still fail if the pressure is not released quickly enough.[1] Relief valves are sized to release pressure fast enough to prevent the pressure from increasing beyond the strength of the vessel, but not so fast as to be the cause of an explosion. An appropriately sized relief valve will allow the liquid inside to boil slowly, maintaining a constant pressure in the vessel until all the liquid has boiled and the vessel empties. +If the substance involved is flammable, it is likely that the resulting cloud of the substance will ignite after the BLEVE has occurred, forming a fireball and possibly a fuel-air explosion, also termed a vapor cloud explosion (VCE). If the materials are toxic, a large area will be contaminated.[4] +Incidents[edit] +The term "BLEVE" was coined by three researchers at Factory Mutual, in the analysis of an accident there in 1957 involving a chemical reactor vessel.[5] +In August 1959 the Kansas City Fire Department suffered its largest ever loss of life in the line of duty, when a 25,000 gallon (95,000 litre) gas tank exploded during a fire on Southwest Boulevard killing five firefighters. This was the first time BLEVE was used to describe a burning fuel tank.[citation needed] +Later incidents included the Cheapside Street Whisky Bond Fire in Glasgow, Scotland in 1960; Feyzin, France in 1966; Crescent City, Illinois in 1970; Kingman, Arizona in 1973; a liquid nitrogen tank rupture[6] at Air Products and Chemicals and Mobay Chemical Company at New Martinsville, West Virginia on January 31, 1978 [1];Texas City, Texas in 1978; Murdock, Illinois in 1983; San Juan Ixhuatepec, Mexico City in 1984; and Toronto, Ontario in 2008. +Safety measures[edit] +[icon] This section requires expansion. (July 2013) +Some fire mitigation measures are listed under liquefied petroleum gas. +See also[edit] +Boiler explosion +Expansion ratio +Explosive boiling or phase explosion +Rapid phase transition +Viareggio train derailment +2008 Toronto explosions +Gas carriers +Los Alfaques Disaster +Lac-Mégantic derailment +References[edit] +^ Jump up to: a b Kletz, Trevor (March 1990). Critical Aspects of Safety and Loss Prevention. London: Butterworth–Heinemann. pp. 43–45. ISBN 0-408-04429-2. +Jump up ^ "Temperature Pressure Relief Valves on Water Heaters: test, inspect, replace, repair guide". Inspect-ny.com. Retrieved 2011-07-12. +Jump up ^ Liquid nitrogen BLEVE demo +Jump up ^ "Chemical Process Safety" (PDF). Retrieved 2011-07-12. +Jump up ^ David F. Peterson, BLEVE: Facts, Risk Factors, and Fallacies, Fire Engineering magazine (2002). +Jump up ^ "STATE EX REL. VAPOR CORP. v. NARICK". Supreme Court of Appeals of West Virginia. 1984-07-12. Retrieved 2014-03-16. +External links[edit] + Look up boiling liquid expanding vapor explosion in Wiktionary, the free dictionary. + Wikimedia Commons has media related to BLEVE. +BLEVE Demo on YouTube — video of a controlled BLEVE demo +huge explosions on YouTube — video of propane and isobutane BLEVEs from a train derailment at Murdock, Illinois (3 September 1983) +Propane BLEVE on YouTube — video of BLEVE from the Toronto propane depot fire +Moscow Ring Road Accident on YouTube - Dozens of LPG tank BLEVEs after a road accident in Moscow +Kingman, AZ BLEVE — An account of the 5 July 1973 explosion in Kingman, with photographs +Propane Tank Explosions — Description of circumstances required to cause a propane tank BLEVE. +Analysis of BLEVE Events at DOE Sites - Details physics and mathematics of BLEVEs. +HID - SAFETY REPORT ASSESSMENT GUIDE: Whisky Maturation Warehouses - The liquor is aged in wooden barrels that can suffer BLEVE. +Categories: ExplosivesFirefightingFireTypes of fireGas technologiesIndustrial fires and explosions +Navigation menu +Create accountLog inArticleTalkReadEditView history + +Main page +Contents +Featured content +Current events +Random article +Donate to Wikipedia +Wikimedia Shop +Interaction +Help +About Wikipedia +Community portal +Recent changes +Contact page +Tools +What links here +Related changes +Upload file +Special pages +Permanent link +Page information +Wikidata item +Cite this page +Print/export +Create a book +Download as PDF +Printable version +Languages +Català +Deutsch +Español +Français +Italiano +עברית +Nederlands +日本語 +Norsk bokmål +Polski +Português +Русский +Suomi +Edit links +This page was last modified on 18 November 2014 at 01:35. +Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Terms of Use and Privacy Policy. Wikipedia® is a registered trademark of the Wikimedia Foundation, Inc., a non-profit organization. +Privacy policyAbout WikipediaDisclaimersContact WikipediaDevelopersMobile viewWikimedia Foundation Powered by MediaWiki + + +Thermobaric weapon +From Wikipedia, the free encyclopedia + +Blast from a US Navy fuel air explosive used against a decommissioned ship, USS McNulty, 1972. +A thermobaric weapon is a type of explosive that utilizes oxygen from the surrounding air to generate an intense, high-temperature explosion, and in practice the blast wave such a weapon produces is typically significantly longer in duration than a conventional condensed explosive. The fuel-air bomb is one of the most well-known types of thermobaric weapons. +Most conventional explosives consist of a fuel-oxidizer premix (gunpowder, for example, contains 25% fuel and 75% oxidizer), whereas thermobaric weapons are almost 100% fuel, so thermobaric weapons are significantly more energetic than conventional condensed explosives of equal weight. Their reliance on atmospheric oxygen makes them unsuitable for use underwater, at high altitude, and in adverse weather. They do, however, cause considerably more destruction when used inside confined environments such as tunnels, caves, and bunkers - partly due to the sustained blast wave, and partly by consuming the available oxygen inside those confined spaces. +There are many different types of thermobaric weapons rounds that can be fitted to hand-held launchers.[1] +Contents [hide] +1 Terminology +2 Mechanism +2.1 Fuel-air explosive +2.1.1 Effect +3 Development history +3.1 Soviet and Russian developments +3.2 US developments +4 History +4.1 Military use +4.2 Non-military use +5 See also +6 References +7 External links +Terminology[edit] +The term thermobaric is derived from the Greek words for "heat" and "pressure": thermobarikos (θερμοβαρικός), from thermos (θερμός), hot + baros (βάρος), weight, pressure + suffix -ikos (-ικός), suffix -ic. +Other terms used for this family of weapons are high-impulse thermobaric weapons (HITs), heat and pressure weapons, vacuum bombs, or fuel-air explosives (FAE or FAX). +Mechanism[edit] +In contrast to condensed explosive, where oxidation in a confined region produces a blast front from essentially a point source, a flame front accelerates to a large volume producing pressure fronts both within the mixture of fuel and oxidant and then in the surrounding air.[2] +Thermobaric explosives apply the principles underlying accidental unconfined vapor cloud explosions, which include those from dispersions of flammable dusts and droplets.[3] Previously, such explosions were most often encountered in flour mills and their storage containers, and later in coal mines; but, now, most commonly in discharged oil tankers and refineries, including an incident at Buncefield in the UK in 2005 where the blast wave woke people 150 kilometres (93 mi) from its centre.[4] +A typical weapon consists of a container packed with a fuel substance, in the center of which is a small conventional-explosive "scatter charge". Fuels are chosen on the basis of the exothermicity of their oxidation, ranging from powdered metals, such as aluminium or magnesium, to organic materials, possibly with a self-contained partial oxidant. The most recent development involves the use of nanofuels.[5][6] +A thermobaric bomb's effective yield requires the most appropriate combination of a number of factors; among these are how well the fuel is dispersed, how rapidly it mixes with the surrounding atmosphere, and the initiation of the igniter and its position relative to the container of fuel. In some designs, strong munitions cases allow the blast pressure to be contained long enough for the fuel to be heated up well above its auto-ignition temperature, so that once the container bursts the super-heated fuel will auto-ignite progressively as it comes into contact with atmospheric oxygen.[7][8][9][10][11][12][13][14][15][16][17] +Conventional upper and lower limits of flammability apply to such weapons. Close in, blast from the dispersal charge, compressing and heating the surrounding atmosphere, will have some influence on the lower limit. The upper limit has been demonstrated strongly to influence the ignition of fogs above pools of oil.[18] This weakness may be eliminated by designs where the fuel is preheated well above its ignition temperature, so that its cooling during its dispersion still results in a minimal ignition delay on mixing. The continual combustion of the outer layer of fuel molecules as they come into contact with the air, generates additional heat which maintains the temperature of the interior of the fireball, and thus sustains the detonation.[19][20][21] +In confinement, a series of reflective shock waves are generated,[22][23] which maintain the fireball and can extend its duration to between 10 and 50 ms as exothermic recombination reactions occur.[24] Further damage can result as the gases cool and pressure drops sharply, leading to a partial vacuum. This effect has given rise to the misnomer "vacuum bomb". Piston-type afterburning is also believed to occur in such structures, as flame-fronts accelerate through it.[25][26] +Fuel-air explosive[edit] +A fuel-air explosive (FAE) device consists of a container of fuel and two separate explosive charges. After the munition is dropped or fired, the first explosive charge bursts open the container at a predetermined height and disperses the fuel in a cloud that mixes with atmospheric oxygen (the size of the cloud varies with the size of the munition). The cloud of fuel flows around objects and into structures. The second charge then detonates the cloud, creating a massive blast wave. The blast wave destroys unreinforced buildings and equipment and kills and injures people. The antipersonnel effect of the blast wave is more severe in foxholes, on people with body armor, and in enclosed spaces such as caves, buildings, and bunkers. +Fuel-air explosives were first developed, and used in Vietnam, by the United States. Soviet scientists, however, quickly developed their own FAE weapons, which were reportedly used against China in the Sino-Soviet border conflict and in Afghanistan. Since then, research and development has continued and currently Russian forces field a wide array of third-generation FAE warheads. +Effect[edit] +A Human Rights Watch report of 1 February 2000[27] quotes a study made by the US Defense Intelligence Agency: +The [blast] kill mechanism against living targets is unique–and unpleasant.... What kills is the pressure wave, and more importantly, the subsequent rarefaction [vacuum], which ruptures the lungs.... If the fuel deflagrates but does not detonate, victims will be severely burned and will probably also inhale the burning fuel. Since the most common FAE fuels, ethylene oxide and propylene oxide, are highly toxic, undetonated FAE should prove as lethal to personnel caught within the cloud as most chemical agents. +According to a U.S. Central Intelligence Agency study,[27] "the effect of an FAE explosion within confined spaces is immense. Those near the ignition point are obliterated. Those at the fringe are likely to suffer many internal, and thus invisible injuries, including burst eardrums and crushed inner ear organs, severe concussions, ruptured lungs and internal organs, and possibly blindness." Another Defense Intelligence Agency document speculates that because the "shock and pressure waves cause minimal damage to brain tissue…it is possible that victims of FAEs are not rendered unconscious by the blast, but instead suffer for several seconds or minutes while they suffocate."[28] +Development history[edit] +Soviet and Russian developments[edit] + +A RPO-A rocket and launcher. +The Soviet armed forces extensively developed FAE weapons,[29] such as the RPO-A, and used them in Chechnya.[30] +The Russian armed forces have developed thermobaric ammunition variants for several of their weapons, such as the TGB-7V thermobaric grenade with a lethality radius of 10 metres (33 ft), which can be launched from a RPG-7. The GM-94 is a 43 mm pump-action grenade launcher which is designed mainly to fire thermobaric grenades for close quarters combat. With the grenade weighing 250 grams (8.8 oz) and holding a 160 grams (5.6 oz) explosive mixture, its lethality radius is 3 metres (9.8 ft); however, due to the deliberate "fragmentation-free" design of the grenade, 4 metres (13 ft) is already considered a safe distance.[31] The RPO-A and upgraded RPO-M are infantry-portable RPGs designed to fire thermobaric rockets. The RPO-M, for instance, has a thermobaric warhead with a TNT equivalence of 5.5 kilograms (12 lb) of TNT and destructive capabilities similar to a 152 mm High explosive fragmentation artillery shell.[32][33] The RShG-1 and the RShG-2 are thermobaric variants of the RPG-27 and RPG-26 respectively. The RShG-1 is the more powerful variant, with its warhead having a 10 metres (33 ft) lethality radius and producing about the same effect as 6 kg (13 lb) of TNT.[34] The RMG is a further derivative of the RPG-26 that uses a tandem-charge warhead, whereby the precursor HEAT warhead blasts an opening for the main thermobaric charge to enter and detonate inside.[35] The RMG's precursor HEAT warhead can penetrate 300 mm of reinforced concrete or over 100 mm of Rolled homogeneous armour, thus allowing the 105 millimetres (4.1 in) diameter thermobaric warhead to detonate inside.[36] +The other examples include the SACLOS or millimeter wave radar-guided thermobaric variants of the 9M123 Khrizantema, the 9M133F-1 thermobaric warhead variant of the 9M133 Kornet, and the 9M131F thermobaric warhead variant of the 9K115-2 Metis-M, all of which are anti-tank missiles. The Kornet has since been upgraded to the Kornet-EM, and its thermobaric variant has a maximum range of 10 kilometres (6.2 mi) and has the TNT equivalent of 7 kilograms (15 lb) of TNT.[37] The 300 mm 9M55S thermobaric cluster warhead rocket was built to be fired from the BM-30 Smerch MLRS. A dedicated carrier of thermobaric weapons is the purpose-built TOS-1, a 24-tube MLRS designed to fire 220 mm caliber thermobaric rockets. A full salvo from the TOS-1 will cover a rectangle 200x400 metres.[38] The Iskander-M theatre ballistic missile can also carry a 700 kilograms (1,500 lb) thermobaric warhead.[39] + +The fireball blast from the Russian Air Force's FOAB, the largest Thermobaric device to be detonated. +Many Russian Air Force munitions also have thermobaric variants. The 80 mm S-8 rocket has the S-8DM and S-8DF thermobaric variants. The S-8's larger 122 mm brother, the S-13 rocket, has the S-13D and S-13DF thermobaric variants. The S-13DF's warhead weighs only 32 kg (71 lb) but its power is equivalent to 40 kg (88 lb) of TNT. The KAB-500-OD variant of the KAB-500KR has a 250 kg (550 lb) thermobaric warhead. The ODAB-500PM and ODAB-500PMV unguided bombs carry a 190 kg (420 lb) fuel-air explosive each. The KAB-1500S GLONASS/GPS guided 1,500 kg (3,300 lb) bomb also has a thermobaric variant. Its fireball will cover over a 150-metre (490 ft) radius and its lethality zone is a 500-metre (1,600 ft) radius.[40] The 9M120 Ataka-V and the 9K114 Shturm ATGMs both have thermobaric variants. +In September 2007 Russia exploded the largest thermobaric weapon ever made. The weapon's yield was reportedly greater than that of the smallest dial-a-yield nuclear weapons at their lowest settings.[41][42] Russia named this particular ordnance the "Father of All Bombs" in response to the United States developed "Massive Ordnance Air Blast" (MOAB) bomb whose backronym is the "Mother of All Bombs", and which previously held the accolade of the most powerful non-nuclear weapon in history.[43] The bomb contains an about 7 tons charge of a liquid fuel such as ethylene oxide, mixed with an energetic nanoparticle such as aluminium, surrounding a high explosive burster[44] that when detonated created an explosion equivalent to 44 metric tons of TNT. +US developments[edit] + +A BLU-72/B bomb on a USAF A-1E taking off from Nakhon Phanom, in September 1968. +Current US FAE munitions include: +BLU-73 FAE I +BLU-95 500-lb (FAE-II) +BLU-96 2,000-lb (FAE-II) +CBU-55 FAE I +CBU-72 FAE I +The XM1060 40-mm grenade is a small-arms thermobaric device, which was delivered to U.S. forces in April 2003.[45] Since the 2003 Invasion of Iraq, the US Marine Corps has introduced a thermobaric 'Novel Explosive' (SMAW-NE) round for the Mk 153 SMAW rocket launcher. One team of Marines reported that they had destroyed a large one-story masonry type building with one round from 100 yards (91 m).[46] +The AGM-114N Hellfire II, first used by U.S. forces in 2003 in Iraq, uses a Metal Augmented Charge (MAC) warhead that contains a thermobaric explosive fill using fluoridated aluminium layered between the charge casing and a PBXN-112 explosive mixture. When the PBXN-112 detonates, the aluminium mixture is dispersed and rapidly burns. The resultant sustained high pressure is extremely effective against people and structures.[47] +History[edit] +Military use[edit] + +US Navy BLU-118B being prepared for shipping for use in Afghanistan, 5 March 2002. +The first experiments with thermobaric weapon were conducted in Germany during World War II and were led by Mario Zippermayr. The German bombs used coal dust as fuel and were extensively tested in 1943 and 1944, but did not reach mass production before the war ended. +The TOS-1 system was test fired in Panjshir valley during Soviet war in Afghanistan in the early 1980s.[48] +Unconfirmed reports suggest that Russian military forces used ground delivered thermobaric weapons in the storming of the Russian parliament during the 1993 Russian constitutional crisis and also during the Battle for Grozny (first and second Chechen wars) to attack dug in Chechen fighters. The use of both TOS-1 heavy MLRS and "RPO-A Shmel" shoulder-fired rocket system in the Chechen wars is reported to have occurred.[48][49] +It is theorized that a multitude of hand-held thermobaric weapons were used by the Russian Armed Forces in their efforts to retake the school during the 2004 Beslan school hostage crisis. The RPO-A and either the TGB-7V thermobaric rocket from the RPG-7 or rockets from either the RShG-1 or the RShG-2 is claimed to have been used by the Spetsnaz during the initial storming of the school.[50][51][52] At least 3 and as many as 9 RPO-A casings were later found at the positions of the Spetsnaz.[53][54] The Russian Government later admitted to the use of the RPO-A during the crisis.[55] +According to UK Ministry of Defence, British military forces have also used thermobaric weapons in their AGM-114N Hellfire missiles (carried by Apache helicopters and UAVs) against the Taliban in the War in Afghanistan.[56] +The US military also used thermobaric weapons in Afghanistan. On 3 March 2002, a single 2,000 lb (910 kg) laser guided thermobaric bomb was used by the United States Army against cave complexes in which Al-Qaeda and Taliban fighters had taken refuge in the Gardez region of Afghanistan.[57][58] The SMAW-NE was used by the US Marines during the First Battle of Fallujah and Second Battle of Fallujah. +Reports by the rebel fighters of the Free Syrian Army claim the Syrian Air Force used such weapons against residential area targets occupied by the rebel fighters, as for instance in the Battle for Aleppo[59] and also in Kafar Batna.[60] A United Nations panel of human rights investigators reported that the Syrian government used thermobaric bombs against the rebellious town of Qusayr in March 2013.[61] +Non-military use[edit] +Thermobaric and fuel-air explosives have been used in guerrilla warfare since the 1983 Beirut barracks bombing in Lebanon, which used a gas-enhanced explosive mechanism, probably propane, butane or acetylene.[62] The explosive used by the bombers in the 1993 World Trade Center bombing incorporated the FAE principle, using three tanks of bottled hydrogen gas to enhance the blast.[63][64] Jemaah Islamiyah bombers used a shock-dispersed solid fuel charge,[65] based on the thermobaric principle,[66] to attack the Sari nightclub in the 2002 Bali bombings.[67] +See also[edit] +Bunker buster +Dust explosion +FOAB +Flame fougasse +MOAB +RPO-A +SMAW +References[edit] +Jump up ^ Algeria Isp (2011-10-18). "Libye – l'Otan utilise une bombe FAE | Politique, Algérie". Algeria ISP. Retrieved 2013-04-23. +Jump up ^ Nettleton, J. Occ. Accidents, 1, 149 (1976). +Jump up ^ Strehlow, 14th. Symp. (Int.) Comb. 1189, Comb. Inst. (1973). +Jump up ^ Health and Safety Environmental Agency, 5th. and final report, 2008. +Jump up ^ See Nanofuel/Oxidizers For Energetic Compositions – John D. Sullivan and Charles N. Kingery (1994) High explosive disseminator for a high explosive air bomb. +Jump up ^ Slavica Terzić, Mirjana Dakić Kolundžija, Milovan Azdejković and Gorgi Minov (2004) Compatibility Of Thermobaric Mixtures Based On Isopropyl Nitrate And Metal Powders. +Jump up ^ Meyer, Rudolf; Josef Köhler and Axel Homburg (2007). Explosives. Weinheim: Wiley-VCH. pp. 312. ISBN 3-527-31656-6. OCLC 165404124. +Jump up ^ Howard C. Hornig (1998) Non-focusing active warhead. +Jump up ^ Chris Ludwig (Talley Defense) Verifying Performance of Thermobaric Materials for Small to Medium Caliber Rocket Warheads. +Jump up ^ Martin M.West (1982) Composite high explosives for high energy blast applications. +Jump up ^ Raafat H. Guirguis (2005) Reactively Induced Fragmenting Explosives. +Jump up ^ Michael Dunning, William Andrews and Kevin Jaansalu (2005) The Fragmentation of Metal Cylinders Using Thermobaric Explosives. +Jump up ^ David L. Frost, Fan Zhang, Stephen B. Murray and Susan McCahan Critical Conditions For Ignition Of Metal Particles In A Condensed Explosive. +Jump up ^ The Army Doctrine and Training Bulletin (2001) The Threat from Blast Weapons. +Jump up ^ INTERNATIONAL DEFENCE REVIEW (2004) ENHANCED BLAST AND THERMOBARICS. +Jump up ^ F. Winterberg Conjectured Metastable Super-Explosives formed under High Pressure for Thermonuclear Ignition. +Jump up ^ Zhang, Fan (Medicine Hat, CA) Murray, Stephen Burke (Medicine Hat, CA) Higgins, Andrew (Montreal, CA) (2005) Super compressed detonation method and device to effect such detonation. +Jump up ^ Nettleton, arch. combust.,1,131, (1981). +Jump up ^ Stephen B. Murray Fundamental and Applied Studies of Fuel-Air Detonation. +Jump up ^ John H. Lee (1992) Chemical initiation of detonation in fuel-air explosive clouds. +Jump up ^ Frank E. Lowther (1989) Nuclear-sized explosions without radiation. +Jump up ^ Nettleton, Comb. and Flame, 24,65 (1975). +Jump up ^ Fire Prev. Sci. and Tech. No. 19,4 (1976) +Jump up ^ May L.Chan (2001) Advanced Thermobaric Explosive Compositions. +Jump up ^ New Thermobaric Materials and Weapon Concepts. +Jump up ^ Robert C. Morris (2003) Small Thermobaric Weapons An Unnoticed Threat.[dead link] +^ Jump up to: a b "Backgrounder on Russian Fuel Air Explosives ("Vacuum Bombs") | Human Rights Watch". Hrw.org. 2000-02-01. Retrieved 2013-04-23. +Jump up ^ Defense Intelligence Agency, "Future Threat to the Soldier System, Volume I; Dismounted Soldier--Middle East Threat", September 1993, p. 73. Obtained by Human Rights Watch under the U.S. Freedom of Information Act. +Jump up ^ "Press | Human Rights Watch". Hrw.org. 2008-12-27. Retrieved 2009-07-30. +Jump up ^ Lester W. Grau and Timothy L. Thomas(2000)"Russian Lessons Learned From the Battles For Grozny" +Jump up ^ "Modern Firearms – GM-94". World.guns.ru. 2011-01-24. Retrieved 2011-07-12. +Jump up ^ "New RPO Shmel-M Infantry Rocket Flamethrower Man-Packable Thermobaric Weapon". defensereview.com. 2006-07-19. Retrieved 2012-08-27. +Jump up ^ "Shmel-M: Infantry Rocket-assisted Flamethrower of Enhanced Range and Lethality". Kbptula.ru. Retrieved 2013-12-28. +Jump up ^ "Modern Firearms – RShG-1". World.guns.ru. 2011-01-24. Retrieved 2011-07-12. +Jump up ^ "Modern Firearms – RMG". World.guns.ru. 2011-01-24. Retrieved 2011-07-12. +Jump up ^ "RMG - A new Multi-Purpose Assault Weapon from Bazalt". defense-update.com. Retrieved 2012-08-27. +Jump up ^ "Kornet-EM: Multi-purpose Long-range Missile System". Kbptula.ru. Retrieved 2013-12-28. +Jump up ^ "TOS-1 Heavy flamethrower system". military-today.com. Retrieved 2012-08-27. +Jump up ^ "SS-26". Missilethreat.com. Retrieved 2013-12-28. +Jump up ^ Air Power Australia (2007-07-04). "How to Destroy the Australian Defence Force". Ausairpower.net. Retrieved 2011-07-12. +Jump up ^ "Russia unveils devastating vacuum bomb". ABC News. 2007. Retrieved 2007-09-12. +Jump up ^ "Video of test explosion". BBC News. 2007. Retrieved 2007-09-12. +Jump up ^ Harding, Luke (2007-09-12). "Russia unveils the father of all bombs". London: The Guardian. Retrieved 2007-09-12. +Jump up ^ Berhie, Saba. "Dropping the Big One | Popular Science". Popsci.com. Retrieved 2011-07-12. +Jump up ^ John Pike (2003-04-22). "XM1060 40mm Thermobaric Grenade". Globalsecurity.org. Retrieved 2011-07-12. +Jump up ^ David Hambling (2005) "Marines Quiet About Brutal New Weapon" +Jump up ^ John Pike (2001-09-11). "AGM-114N Metal Augmented Charge (MAC) Thermobaric Hellfire". Globalsecurity.org. Retrieved 2011-07-12. +^ Jump up to: a b John Pike. "TOS-1 Buratino 220mm Multiple Rocket Launcher". Globalsecurity.org. Retrieved 2013-04-23. +Jump up ^ "Foreign Military Studies Office Publications - A 'Crushing' Victory: Fuel-Air Explosives and Grozny 2000". Fmso.leavenworth.army.mil. Retrieved 2013-04-23. +Jump up ^ "Russian forces faulted in Beslan school tragedy". Christian Science Monitor. 1 September 2006. Retrieved 14 February 2007. +Jump up ^ Russia: Independent Beslan Investigation Sparks Controversy, The Jamestown Foundation, 29 August 2006 +Jump up ^ Beslan still a raw nerve for Russia, BBC News, 1 September 2006 +Jump up ^ ACHING TO KNOW, Los Angeles Times, 27 August 2005 +Jump up ^ Searching for Traces of “Shmel” in Beslan School, Kommersant, 12 September 2005 +Jump up ^ A Reversal Over Beslan Only Fuels Speculation, The Moscow Times, 21 July 2005 +Jump up ^ "MoD's Controversial Thermobaric Weapons Use in Afghanistan". Armedforces-int.com. 2008-06-23. Retrieved 2013-04-23. +Jump up ^ "US Uses Bunker-Busting 'Thermobaric' Bomb for First Time". Commondreams.org. 2002-03-03. Retrieved 2013-04-23. +Jump up ^ John Pike. "BLU-118/B Thermobaric Weapon Demonstration / Hard Target Defeat Program". Globalsecurity.org. Retrieved 2013-04-23. +Jump up ^ "Syria rebels say Assad using 'mass-killing weapons' in Aleppo". October 10, 2012. Retrieved November 11, 2012. +Jump up ^ "Dropping Thermobaric Bombs on Residential Areas in Syria_ Nov. 5. 2012". First Post. November 11, 2012. Retrieved November 11, 2012. +Jump up ^ Cumming-Bruce, Nick (2013-06-04). "U.N. Panel Reports Increasing Brutality by Both Sides in Syria". The New York Times. +Jump up ^ Richard J. Grunawalt. Hospital Ships In The War On Terror: Sanctuaries or Targets? (PDF), Naval War College Review, Winter 2005, pp. 110–11. +Jump up ^ Paul Rogers (2000) "Politics in the Next 50 Years: The Changing Nature of International Conflict" +Jump up ^ J. Gilmore Childers, Henry J. DePippo (February 24, 1998). "Senate Judiciary Committee, Subcommittee on Technology, Terrorism, and Government Information hearing on "Foreign Terrorists in America: Five Years After the World Trade Center"". Fas.org. Retrieved 2011-07-12. +Jump up ^ P. Neuwald, H. Reichenbach, A. L. Kuhl (2003). "Shock-Dispersed-Fuel Charges-Combustion in Chambers and Tunnels". +Jump up ^ David Eshel (2006). "Is the world facing Thermobaric Terrorism?".[dead link] +Jump up ^ Wayne Turnbull (2003). "Bali:Preparations". +External links[edit] +Fuel/Air Explosive (FAE) +Thermobaric Explosive (Global Security) +Aspects of thermobaric weaponry (PDF) – Dr. Anna E Wildegger-Gaissmaier, Australian Defence Force Health +Thermobaric warhead for RPG-7 +XM1060 40 mm Thermobaric Grenade (Global Security) +Defense Update: Fuel-Air Explosive Mine Clearing System +Foreign Military Studies Office – A 'Crushing' Victory: Fuel-Air Explosives and Grozny 2000 +Soon to make a comeback in Afghanistan +Russia claims to have tested the most powerful "Vacuum" weapon +Categories: Explosive weaponsAmmunitionThermobaric weaponsAnti-personnel weapons +Navigation menu +Create accountLog inArticleTalkReadEditView history + +Main page +Contents +Featured content +Current events +Random article +Donate to Wikipedia +Wikimedia Shop +Interaction +Help +About Wikipedia +Community portal +Recent changes +Contact page +Tools +What links here +Related changes +Upload file +Special pages +Permanent link +Page information +Wikidata item +Cite this page +Print/export +Create a book +Download as PDF +Printable version +Languages +العربية +Беларуская +Български +Čeština +Deutsch +Español +فارسی +Français +हिन्दी +Italiano +עברית +Latviešu +Македонски +Nederlands +日本語 +Polski +Русский +Suomi +Svenska +Türkçe +Українська +Tiếng Việt +粵語 +中文 +Edit links +This page was last modified on 28 November 2014 at 10:32. +Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Terms of Use and Privacy Policy. Wikipedia® is a registered trademark of the Wikimedia Foundation, Inc., a non-profit organization. +Privacy policyAbout WikipediaDisclaimersContact WikipediaDevelopersMobile viewWikimedia Foundation Powered by MediaWiki + + +Gunpowder +From Wikipedia, the free encyclopedia +For other uses, see Gunpowder (disambiguation). +In American English, the term gunpowder also refers broadly to any gun propellant.[1] Gunpowder (black powder) as described in this article is not normally used in modern firearms, which instead use smokeless powders. + +Black powder for muzzleloading rifles and pistols in FFFG granulation size. American Quarter (diameter 24 mm) for comparison. +Gunpowder, also known as black powder, is a chemical explosive—the earliest known. It is a mixture of sulfur, charcoal, and potassium nitrate (saltpeter). The sulfur and charcoal act as fuels, and the saltpeter is an oxidizer.[2][3] Because of its burning properties and the amount of heat and gas volume that it generates, gunpowder has been widely used as a propellant in firearms and as a pyrotechnic composition in fireworks. +Gunpowder is assigned the UN number UN0027 and has a hazard class of 1.1D. It has a flash point of approximately 427–464 °C (801–867 °F). The specific flash point may vary based on the specific composition of the gunpowder. Gunpowder's gravity is 1.70–1.82 (mercury method) orŠ 1.92–2.08 (pycnometer), and it has a pH of 6.0–8.0. It is also considered to be an insoluble material.[4] +Gunpowder was, according to prevailing academic consensus, invented in the 9th century in China,[5][6] and the earliest record of a written formula for gunpowder appears in the 11th century Song Dynasty text, Wujing Zongyao.[7] This discovery led to the invention of fireworks and the earliest gunpowder weapons in China. In the centuries following the Chinese discovery, gunpowder weapons began appearing in the Muslim world, Europe, and India. The technology spread from China through the Middle East or Central Asia, and then into Europe.[8] The earliest Western accounts of gunpowder appear in texts written by English philosopher Roger Bacon in the 13th century.[9] +Gunpowder is classified as a low explosive because of its relatively slow decomposition rate and consequently low brisance. Low explosives deflagrate (i.e., burn) at subsonic speeds, whereas high explosives detonate, producing a supersonic wave. Gunpowder's burning rate increases with pressure, so it bursts containers if contained but otherwise just burns in the open. Ignition of the powder packed behind a bullet must generate enough pressure to force it from the muzzle at high speed, but not enough to rupture the gun barrel. Gunpowder thus makes a good propellant, but is less suitable for shattering rock or fortifications. Gunpowder was widely used to fill artillery shells and in mining and civil engineering to blast rock roughly until the second half of the 19th century, when the first high explosives (nitro-explosives) were discovered. Gunpowder is no longer used in modern explosive military warheads, nor is it used as main explosive in mining operations due to its cost relative to that of newer alternatives such as ammonium nitrate/fuel oil (ANFO).[10] Black powder is still used as a delay element in various munitions where its slow-burning properties are valuable. +Formulations used in blasting rock (such as in quarrying) are called blasting powder. +Contents [hide] +1 History +1.1 China +1.2 Middle East +1.3 Mainland Europe +1.4 Britain and Ireland +1.5 India +1.6 Indonesia +2 Manufacturing technology +3 Composition and characteristics +4 Serpentine +5 Corning +6 Modern types +7 Other types of gunpowder +8 Sulfur-free gunpowder +9 Combustion characteristics +9.1 Advantages +9.2 Disadvantages +9.3 Transportation +10 Other uses +11 See also +12 References +13 External links +History[edit] + +Early Chinese rocket + +A Mongol bomb thrown against a charging Japanese samurai during the Mongol invasions of Japan after founding the Yuan Dynasty, 1281. +Main article: History of gunpowder +Gunpowder was invented in China while taoists attempted to create a potion of immortality. Chinese military forces used gunpowder-based weapons (i.e. rockets, guns, cannons) and explosives (i.e. grenades and different types of bombs) against the Mongols when the Mongols attempted to invade and breach city fortifications on China's northern borders. After the Mongols conquered China and founded the Yuan Dynasty, they used the Chinese gunpowder-based weapons technology in their attempted invasion of Japan; they also used gunpowder to fuel rockets. +The mainstream scholarly consensus is that gunpowder was invented in China, spread through the Middle East, and then into Europe,[8] although there is a dispute over how much the Chinese advancements in gunpowder warfare influenced later advancements in the Middle East and Europe.[11][12] The spread of gunpowder across Asia from China is widely attributed to the Mongols. One of the first examples of Europeans encountering gunpowder and firearms is at the Battle of Mohi in 1241. At this battle the Mongols not only used gunpowder in early Chinese firearms but in the earliest grenades as well. +A major problem confronting the study of the early history of gunpowder is ready access to sources close to the events described. Often enough, the first records potentially describing use of gunpowder in warfare were written several centuries after the fact, and may well have been colored by the contemporary experiences of the chronicler.[13] It is also difficult to accurately translate original alchemy texts, especially medieval Chinese texts that try to explain phenomena through metaphor, into modern scientific language with rigidly defined terminology. The translation difficulty has led to errors or loose interpretations bordering on artistic licence.[14][15] Early writings potentially mentioning gunpowder are sometimes marked by a linguistic process where old words acquired new meanings.[16] For instance, the Arabic word naft transitioned from denoting naphtha to denoting gunpowder, and the Chinese word pao evolved from meaning catapult to referring to cannon.[17] According to science and technology historian Bert S. Hall: "It goes without saying, however, that historians bent on special pleading, or simply with axes of their own to grind, can find rich material in these terminological thickets."[18] +China[edit] +Further information: Wujing Zongyao, Four Great Inventions and List of Chinese inventions + +Chinese Ming Dynasty (1368-1644) matchlock firearms +Saltpeter was known to the Chinese by the mid-1st century AD and there is strong evidence of the use of saltpeter and sulfur in various largely medicinal combinations.[19] A Chinese alchemical text dated 492 noted saltpeter burnt with a purple flame, providing a practical and reliable means of distinguishing it from other inorganic salts, thus enabling alchemists to evaluate and compare purification techniques; the earliest Latin accounts of saltpeter purification are dated after 1200.[20] + +Yuan Dynasty bronze hand cannon from 1332 at th (c. 808); it describes mixing six parts sulfur to six parts saltpeter to one part birthwort herb (which would provide carbon).[21] +The first reference to the incendiary properties of such mixtures is the passage of the Zhenyuan miaodao yaolüe, a Taoist text tentatively dated to the mid-9th century AD:[20] "Some have heated together sulfur, realgar and saltpete with honey; smoke and flames result, so that their hands and faces have been burnt, and even the whole house where they were working burned down."[22] The Chinese word for "gunpowder" is Chinese: 火药/火藥; pinyin: huŏ yào /xuou yɑʊ/, which literally means "Fire Medicine";[23] however this name only came into use some centuries after the mixture's discovery.[24] During the 9th century, Taoist monks or alchemists searching for an elixir of immortality had serendipitously stumbled upon gunpowder.[8][25] The Chinese wasted little time in applying gunpowder to the development of weapons, and in the centuries that followed, they produced a variety of gunpowder weapons, including flamethrowers, rockets, bombs, and land mines, before inventing guns as a projectile weapon.[26] Archaeological evidence of a hand cannon has been excavated in Manchuria dated from the late 1200s[27] and the shells of explosive bombs have been discovered in a shipwreck off the shore of Japan dated from 1281, during the Mongol invasions of Japan.[28] +The Chinese "Wu Ching Tsung Yao" (Complete Essentials from the Military Classics), written by Tseng Kung-Liang between 1040–1044, provides encyclopedia references to a variety of mixtures that included petrochemicals—as well as garlic and honey. A slow match for flame throwing mechanisms using the siphon principle and for fireworks and rockets are mentioned. The mixture formulas in this book do not contain enough saltpeter to create an explosive however; being limited to at most 50% saltpeter, they produce an incendiary.[29] The Essentials was however written by a Song Dynasty court bureaucrat, and there's little evidence that it had any immediate impact on warfare; there is no mention of gunpowder use in the chronicles of the wars against the Tanguts in the eleventh century, and China was otherwise mostly at peace during this century. The first chronicled use of "fire spears" (or "fire lances") is at the siege of De'an in 1132.[30] + +Formula for gunpowder in 1044 Wujing zongyao part I vol 12 + + +Instruction for fire bomb in Wujing zongyao + + +Fire bomb + + +Fire grenade + + +Proto-cannon from the Ming Dynasty text Huolongjing + + +Land mine from the Ming Dynasty text Huolongjing + + +Fire arrow rocket launcher from the Wujing zongyao +Middle East[edit] +Main articles: Inventions in the Islamic world and Alchemy and chemistry in Islam + +The Sultani Cannon, a very heavy bronze breech-loading cannon of type used by Ottoman Empire in the conquest of Constantinople, in 1453. +The Muslims acquired knowledge of gunpowder some time between 1240 and 1280, by which time the Syrian Hasan al-Rammah had written, in Arabic, recipes for gunpowder, instructions for the purification of saltpeter, and descriptions of gunpowder incendiaries. Gunpowder arrived in the Middle East, possibly through India, from China. This is implied by al-Rammah's usage of "terms that suggested he derived his knowledge from Chinese sources" and his references to saltpeter as "Chinese snow" Arabic: ثلج الصين‎ thalj al-ṣīn, fireworks as "Chinese flowers" and rockets as "Chinese arrows".[31] However, because al-Rammah attributes his material to "his father and forefathers", al-Hassan argues that gunpowder became prevalent in Syria and Egypt by "the end of the twelfth century or the beginning of the thirteenth".[32] Persians called saltpeter "Chinese salt" [33][34][35][36][37] or "salt from Chinese salt marshes" (namak shūra chīnī Persian: نمک شوره چيني‎).[38][39] + +A picture of a 15th-century Granadian cannon from the book Al-izz wal rifa'a. +Al-Hassan claims that in the Battle of Ain Jalut of 1260, the Mamluks used against the Mongols in "the first cannon in history" gunpowder formula with near-identical ideal composition ratios for explosive gunpowder.[32] Other historians urge caution regarding claims of Islamic firearms use in the 1204-1324 period as late medieval Arabic texts used the same word for gunpowder, naft, that they used for an earlier incendiary, naphtha.[13][17] Khan claims that it was invading Mongols who introduced gunpowder to the Islamic world[40] and cites Mamluk antagonism towards early musketeers in their infantry as an example of how gunpowder weapons were not always met with open acceptance in the Middle East.[41] Similarly, the refusal of their Qizilbash forces to use firearms contributed to the Safavid rout at Chaldiran in 1514.[41] +The earliest surviving documentary evidence for the use of the hand cannon, considered the oldest type of portable firearm and a forerunner of the handgun, are from several Arabic manuscripts dated to the 14th century.[42] Al-Hassan argues that these are based on earlier originals and that they report hand-held cannons being used by the Mamluks at the Battle of Ain Jalut in 1260.[32] +Hasan al-Rammah included 107 gunpowder recipes in his text al-Furusiyyah wa al-Manasib al-Harbiyya (The Book of Military Horsemanship and Ingenious War Devices), 22 of which are for rockets. If one takes the median of 17 of these 22 compositions for rockets (75% nitrates, 9.06% sulfur, and 15.94% carbon), it is nearly identical to the modern reported ideal gunpowder recipe of 75% potassium nitrate, 10% sulfur, and 15% carbon.[32] +The state-controlled manufacture of gunpowder by the Ottoman Empire through early supply chains to obtain nitre, sulfur and high-quality charcoal from oaks in Anatolia contributed significantly to its expansion the 15th and 18th century. It was not until later in the 19th century when the syndicalist production of Turkish gunpowder was greatly reduced, which coincided with the decline of its military might.[43] +Mainland Europe[edit] +Several sources mention Chinese firearms and gunpowder weapons being deployed by the Mongols against European forces at the Battle of Mohi in 1241.[44][45][46] Professor Kenneth Warren Chase credits the Mongols for introducing into Europe gunpowder and its associated weaponry.[47] +C. F. Temler interprets Peter, Bishop of Leon, as reporting the use of cannons in Seville in 1248.[48] +In Europe, one of the first mentions of gunpowder use appears in a passage found in Roger Bacon's Opus Maius and Opus Tertium in what has been interpreted as being firecrackers. The most telling passage reads: "We have an example of these things (that act on the senses) in [the sound and fire of] that children's toy which is made in many [diverse] parts of the world; i.e., a device no bigger than one's thumb. From the violence of that salt called saltpeter [together with sulfur and willow charcoal, combined into a powder] so horrible a sound is made by the bursting of a thing so small, no more than a bit of parchment [containing it], that we find [the ear assaulted by a noise] exceeding the roar of strong thunder, and a flash brighter than the most brilliant lightning."[9] In the early 20th century, British artillery officer Henry William Lovett Hime proposed that another work tentatively attributed to Bacon, Epistola de Secretis Operibus Artis et Naturae, et de Nullitate Magiae contained an encrypted formula for gunpowder. This claim has been disputed by historians of science including Lynn Thorndike, John Maxson Stillman and George Sarton and by Bacon's editor Robert Steele, both in terms of authenticity of the work, and with respect to the decryption method.[9] In any case, the formula claimed to have been decrypted (7:5:5 saltpeter:charcoal:sulfur) is not useful for firearms use or even firecrackers, burning slowly and producing mostly smoke.[49][50] + +Cannon forged in 1667 at the Fortín de La Galera, Nueva Esparta, Venezuela. +The Liber Ignium, or Book of Fires, attributed to Marcus Graecus, is a collection of incendiary recipes, including some gunpowder recipes. Partington dates the gunpowder recipes to approximately 1300.[51] One recipe for "flying fire" (ingis volatilis) involves saltpeter, sulfur, and colophonium, which, when inserted into a reed or hollow wood, "flies away suddenly and burns up everything." Another recipe, for artificial "thunder", specifies a mixture of one pound native sulfur, two pounds linden or willow charcoal, and six pounds of saltpeter.[52] Another specifies a 1:3:9 ratio.[52] +Some of the gunpowder recipes of De Mirabilibus Mundi of Albertus Magnus are identical to the recipes of the Liber Ignium, and according to Partington, "may have been taken from that work, rather than conversely."[53] Partington suggests that some of the book may have been compiled by Albert's students, "but since it is found in thirteenth century manuscripts, it may well be by Albert."[53] Albertus Magnus died in 1280. +A common German folk-tale is of the German priest/monk named Berthold Schwarz who independently invented gunpowder, thus earning it the German name Schwarzpulver or in English Schwarz's powder. Schwarz is also German for black so this folk-tale, while likely containing elements of truth, is considered problematic. +A major advance in manufacturing began in Europe in the late 14th century when the safety and thoroughness of incorporation was improved by wet grinding; liquid, such as distilled spirits or perhaps the urine of wine-drinking bishops[54] was added during the grinding-together of the ingredients and the moist paste dried afterwards. (The principle of wet mixing to prevent the separation of dry ingredients, invented for gunpowder, is used today in the pharmaceutical industry.[55]) It was also discovered that if the paste was rolled into balls before drying the resulting gunpowder absorbed less water from the air during storage and traveled better. The balls were then crushed in a mortar by the gunner immediately before use, with the old problem of uneven particle size and packing causing unpredictable results. +If the right size particles were chosen, however, the result was a great improvement in power. Forming the damp paste into corn-sized clumps by hand or with the use of a sieve instead of larger balls produced a product after drying that loaded much better, as each tiny piece provided its own surrounding air space that allowed much more rapid combustion than a fine powder. This "corned" gunpowder was from 30% to 300% more powerful. An example is cited where 34 pounds of serpentine was needed to shoot a 47 pound ball, but only 18 pounds of corned powder.[54] The optimum size of the grain depended on its use; larger for large cannon, finer for small arms. Larger cast cannons were easily muzzle-loaded with corned powder using a long-handled ladle. Corned powder also retained the advantage of low moisture absorption, as even tiny grains still had much less surface area to attract water than a floury powder. +During this time, European manufacturers also began regularly purifying saltpeter, using wood ashes containing potassium carbonate to precipitate calcium from their dung liquor, and using ox blood, alum, and slices of turnip to clarify the solution.[54] +Gunpowder-making and metal-smelting and casting for shot and cannon fee was closely held by skilled military tradesmen, who formed guilds that collected dues, tested apprentices, and gave pensions. "Fire workers" were also required to craft fireworks for celebrations of victory or peace. During the Renaissance, two European schools of pyrotechnic thought emerged, one in Italy and the other at Nuremberg, Germany. Vannoccio Biringuccio, born in 1480, was a member of the guild Fraternita di Santa Barbara but broke with the tradition of secrecy by setting down everything he knew in a book titled De la pirotechnia, written in vernacular. The first printed book on either gunpowder or metalworking, it was published posthumously in 1540, with 9 editions over 138 years, and also reprinted by MIT Press in 1966.[54] By the mid-17th century fireworks were used for entertainment on an unprecedented scale in Europe, being popular even at resorts and public gardens.[56] +In 1774 Louis XVI ascended to the throne of France at age 20. After he discovered that France was not self-sufficient in gunpowder, a Gunpowder Administration was established; to head it, the lawyer Antoine Lavoisier was appointed. Although from a bourgeois family, after his degree in law Lavoisier became wealthy from a company set up to collect taxes for the Crown; this allowed him to pursue experimental natural science as a hobby.[57] +Without access to cheap Indian saltpeter (controlled by the British), for hundreds of years France had relied on saltpetermen with royal warrants, the droit de fouille or "right to dig", to seize nitrous-containing soil and demolished walls of barnyards, without compensation to the owners.[58] This caused farmers, the wealthy, or entire villages to bribe the petermen and the associated bureaucracy to leave their buildings alone and the saltpeter uncollected. Lavoisier instituted a crash program to increase saltpeter production, revised (and later eliminated) the droit de fouille, researched best refining and powder manufacturing methods, instituted management and record-keeping, and established pricing that encouraged private investment in works. Although saltpeter from new Prussian-style putrefaction works had not been produced yet (the process taking about 18 months), in only a year France had gunpowder to export. A chief beneficiary of this surplus was the American Revolution. By careful testing and adjusting the proportions and grinding time, powder from mills such as at Essonne outside Paris became the best in the world by 1788, and inexpensive.[58] [59] +Britain and Ireland[edit] + +The old Powder or Pouther magazine dating from 1642, built by order of Charles I. Irvine, North Ayrshire, Scotland +Gunpowder production in Britain appears to have started in the mid 14th century AD with the aim of supplying the English Crown.[60] Records show that gunpowder was being made, in England, in 1346, at the Tower of London; a powder house existed at the Tower in 1461; and in 1515 three King's gunpowder makers worked there.[60] Gunpowder was also being made or stored at other Royal castles, such as Portchester. By the early 14th century, according to N.J.G. Pounds's study The Medieval Castle in England and Wales, many English castles had been deserted and others were crumbling. Their military significance faded except on the borders. Gunpowder had made smaller castles useless.[61] +Henry VIII of England was short of gunpowder when he invaded France in 1544 and England needed to import gunpowder via the port of Antwerp in what is now Belgium.[60] +The English Civil War (1642–1645) led to an expansion of the gunpowder industry, with the repeal of the Royal Patent in August 1641.[60] +Two British physicists, Andrew Noble and Frederick Abel, worked to improve the properties of black powder during the late 19th century. This formed the basis for the Noble-Abel gas equation for internal ballistics.[62] +The introduction of smokeless powder in the late 19th century led to a contraction of the gunpowder industry. After the end of World War I, the majority of the United Kingdom gunpowder manufacturers merged into a single company, "Explosives Trades limited"; and number of sites were closed down, including those in Ireland. This company became Nobel Industries Limited; and in 1926 became a founding member of Imperial Chemical Industries. The Home Office removed gunpowder from its list of Permitted Explosives; and shortly afterwards, on 31 December 1931, the former Curtis & Harvey's Glynneath gunpowder factory at Pontneddfechan, in Wales, closed down, and it was demolished by fire in 1932.[63] + +Gunpowder storing barrels at Martello tower in Point Pleasant Park +The last remaining gunpowder mill at the Royal Gunpowder Factory, Waltham Abbey was damaged by a German parachute mine in 1941 and it never reopened.[64] This was followed by the closure of the gunpowder section at the Royal Ordnance Factory, ROF Chorley, the section was closed and demolished at the end of World War II; and ICI Nobel's Roslin gunpowder factory, which closed in 1954.[64][65] +This left the sole United Kingdom gunpowder factory at ICI Nobel's Ardeer site in Scotland; it too closed in October 1976.[64] Since then gunpowder has been imported into the United Kingdom. In the late 1970s/early 1980s gunpowder was bought from eastern Europe, particularly from what was then the German Democratic Republic and former Yugoslavia. +India[edit] + +In the year 1780 the British began to annex the territories of the Sultanate of Mysore, during the Second Anglo-Mysore War. The British battalion was defeated during the Battle of Guntur, by the forces of Hyder Ali, who effectively utilized Mysorean rockets and Rocket artillery against the closely massed British forces. + +Mughal Emperor Shah Jahan, hunting deer using a Matchlock as the sun sets in the horizon. +Gunpowder and gunpowder weapons were transmitted to India through the Mongol invasions of India.[66][67] The Mongols were defeated by Alauddin Khilji of the Delhi Sultanate, and some of the Mongol soldiers remained in northern India after their conversion to Islam.[67] It was written in the Tarikh-i Firishta (1606–1607) that Nasir ud din Mahmud the ruler of the Delhi Sultanate presented the envoy of the Mongol ruler Hulegu Khan with a dazzling pyrotechnics display upon his arrival in Delhi in 1258 AD. Nasir ud din Mahmud tried to express his strength as a ruler and tried to ward off any Mongol attempt similar to the Siege of Baghdad (1258).[68] Firearms known as top-o-tufak also existed in many Muslim kingdoms in India by as early as 1366 AD.[68] From then on the employment of gunpowder warfare in India was prevalent, with events such as the "Siege of Belgaum" in 1473 by Sultan Muhammad Shah Bahmani.[69] +The shipwrecked Ottoman Admiral Seydi Ali Reis is known to have introduced the earliest type of Matchlock weapons, which the Ottomans used against the Portuguese during the Siege of Diu (1531). After that, a diverse variety of firearms; large guns in particular, became visible in Tanjore, Dacca, Bijapur, and Murshidabad.[70] Guns made of bronze were recovered from Calicut (1504)- the former capital of the Zamorins[71] +The Mughal Emperor Akbar mass-produced matchlocks for the Mughal Army. Akbar is personally known to have shot a leading Rajput commander during the Siege of Chittorgarh.[72] The Mughals began to use Bamboo rockets (mainly for signalling) and employ Sappers: special units that undermined heavy stone fortifications to plant gunpowder charges. +The Mughal Emperor Shah Jahan is known to have introduced much more advanced Matchlocks, their designs were a combination of Ottoman and Mughal designs. Shah Jahan also countered the British and other Europeans in his province of Gujarāt, which supplied Europe saltpeter for use in gunpowder warfare during the 17th century.[73] Bengal and Mālwa participated in saltpeter production.[73] The Dutch, French, Portuguese, and English used Chhapra as a center of saltpeter refining.[73] +Ever since the founding of the Sultanate of Mysore by Hyder Ali, French military officers were employed to train the Mysore Army. Hyder Ali and his son Tipu Sultan were the first to introduce modern Cannons and Muskets, their army was also the first in India to have official uniforms. During the Second Anglo-Mysore War Hyder Ali and his son Tipu Sultan unleashed the Mysorean rockets at their British opponents effectively defeating them on various occasions. The Mysorean rockets inspired the development of the Congreve rocket, which the British widely utilized during the Napoleonic Wars and the War of 1812.[74] +Indonesia[edit] +The Javanese Majapahit Empire was arguably able to encompass much of modern day Indonesia due to its unique mastery of bronze smithing and use of a central arsenal fed by a large number of cottage industries within the immediate region. Documentary and archeological evidence indicate that Arab or Indian traders introduced gunpowder, gonnes, muskets, blunderbusses, and cannons to the Javanese, Acehnese, and Batak via long established commercial trade routes around the early to mid 14th century CE.[75] Portuguese and Spanish invaders were unpleasantly surprised and occasionally even outgunned on occasion.[76] The resurgent Singhasari Empire overtook Sriwijaya and later emerged as the Majapahit whose warfare featured the use of fire-arms and cannonade.[77] Circa 1540 CE the Javanese, always alert for new weapons found the newly arrived Portuguese weaponry superior to that of the locally made variants. Javanese bronze breech-loaded swivel-guns, known as meriam, or erroneously as lantaka, was used widely by the Majapahit navy as well as by pirates and rival lords. The demise of the Majapahit empire and the dispersal of disaffected skilled bronze cannon-smiths to Brunei, modern Sumatra, Malaysia and the Philippines lead to widespread use, especially in the Makassar Strait. +Saltpeter harvesting was recorded by Dutch and German travelers as being common in even the smallest villages and was collected from the decomposition process of large dung hills specifically piled for the purpose. The Dutch punishment for possession of non-permitted gunpowder appears to have been amputation.[78] Ownership and manufacture of gunpowder was later prohibited by the colonial Dutch occupiers.[75] According to a colonel McKenzie quoted in Sir Thomas Stamford Raffles, The History of Java (1817), the purest sulfur was supplied from a crater from a mountain near the straits of Bali.[77] +Manufacturing technology[edit] + +Edge-runner mill in a restored mill, at Eleutherian Mills +For the most powerful black powder meal, a wood charcoal is used. The best wood for the purpose is Pacific willow,[79] but others such as alder or buckthorn can be used. In Great Britain between the 15th to 19th centuries charcoal from alder buckthorn was greatly prized for gunpowder manufacture; cottonwood was used by the American Confederate States.[80] The ingredients are reduced in particle size and mixed as intimately as possible. Originally this was with a mortar-and-pestle or a similarly operating stamping-mill, using copper, bronze or other non-sparking materials, until supplanted by the rotating ball mill principle with non-sparking bronze or lead. Historically, a marble or limestone edge runner mill, running on a limestone bed was used in Great Britain; however, by the mid 19th century AD this had changed to either an iron shod stone wheel or a cast iron wheel running on an iron bed.[81] The mix was dampened with alcohol or water during grinding to prevent accidental ignition. This also helps the extremely soluble saltpeter mix into the microscopic nooks and crannies of the very high surface-area charcoal. +Around the late 14th century AD, European powdermakers first began adding liquid during grinding to improve mixing, reduce dust, and with it the risk of explosion.[82] The powder-makers would then shape the resulting paste of dampened gunpowder, known as mill cake, into corns, or grains, to dry. Not only did corned powder keep better because of its reduced surface area, gunners also found that it was more powerful and easier to load into guns. Before long, powder-makers standardized the process by forcing mill cake through sieves instead of corning powder by hand. +The improvement was based on reducing the surface area of a higher density composition. At the beginning of the 19th century, makers increased density further by static pressing. They shoveled damp mill cake into a two-foot square box, placed this beneath a screw press and reduced it to 1/2 its volume. "Presscake" had the hardness of slate. They broke the dried slabs with hammers or rollers, and sorted the granules with sieves into different grades. In the United States, Irenee du Pont, who had learned the trade from Lavoisier, tumbled the dried grains in rotating barrels to round the edges and increase durability during shipping and handling. (Sharp grains rounded off in transport, producing fine "meal dust" that changed the burning properties.) +Another advance was the manufacture of kiln charcoal by distilling wood in heated iron retorts instead of burning it in earthen pits. Controlling the temperature influenced the power and consistency of the finished gunpowder. In 1863, in response to high prices for Indian saltpeter, DuPont chemists developed a process using potash or mined potassium chloride to convert plentiful Chilean sodium nitrate to potassium nitrate.[83] +During the 18th century gunpowder factories became increasingly dependent on mechanical energy.[84] Despite mechanization, production difficulties related to humidity control, especially during the pressing, were still present in the late 19th century. A paper from 1885 laments that "Gunpowder is such a nervous and sensitive spirit, that in almost every process of manufacture it changes under our hands as the weather changes." Pressing times to the desired density could vary by factor of three depending on the atmospheric humidity.[85] +Composition and characteristics[edit] +The term black powder was coined in the late 19th century, primarily in the United States, to distinguish prior gunpowder formulations from the new smokeless powders and semi-smokeless powders, in cases where these are not referred to as cordite. Semi-smokeless powders featured bulk volume properties that approximated black powder, but had significantly reduced amounts of smoke and combustion products. Smokeless powder has different burning properties (pressure vs. time) and can generate higher pressures and work per gram. This can rupture older weapons designed for black powder. Smokeless powders ranged in color from brownish tan to yellow to white. Most of the bulk semi-smokeless powders ceased to be manufactured in the 1920s.[86][87][88] +Black powder is a granular mixture of +a nitrate, typically potassium nitrate (KNO3), which supplies oxygen for the reaction; +charcoal, which provides carbon and other fuel for the reaction, simplified as carbon (C); +sulfur (S), which, while also serving as a fuel, lowers the temperature required to ignite the mixture, thereby increasing the rate of combustion. +Potassium nitrate is the most important ingredient in terms of both bulk and function because the combustion process releases oxygen from the potassium nitrate, promoting the rapid burning of the other ingredients.[89] To reduce the likelihood of accidental ignition by static electricity, the granules of modern black powder are typically coated with graphite, which prevents the build-up of electrostatic charge. +Charcoal does not consist of pure carbon; rather, it consists of partially pyrolyzed cellulose, in which the wood is not completely decomposed. Carbon differs from charcoal. Whereas charcoal's autoignition temperature is relatively low, carbon's is much greater. Thus, a black powder composition containing pure carbon would burn similarly to a match head, at best.[90] +The current standard composition for the black powders that are manufactured by pyrotechnicians was adopted as long ago as 1780. Proportions by weight are 75% potassium nitrate (known as saltpeter or saltpetre), 15% softwood charcoal, and 10% sulfur.[81] These ratios have varied over the centuries and by country, and can be altered somewhat depending on the purpose of the powder. For instance, power grades of black powder, unsuitable for use in firearms but adequate for blasting rock in quarrying operations, is called blasting powder rather than gunpowder with standard proportions of 70% nitrate, 14% charcoal, and 16% sulfur; blasting powder may be made with the cheaper sodium nitrate substituted for potassium nitrate and proportions may be as low as 40% nitrate, 30% charcoal, and 30% sulfur.[91] In 1857, Lamont DuPont solved the main problem of using cheaper sodium nitrate formulations when he patented DuPont "B" Blasting powder. After manufacturing grains from press-cake in the usual way, his process tumbled the powder with graphite dust for 12 hours. This formed a graphite coating on each grain that reduced its ability to absorb moisture.[92] +French war powder in 1879 used the ratio 75% saltpeter, 12.5% charcoal, 12.5% sulfur. English war powder in 1879 used the ratio 75% saltpeter, 15% charcoal, 10% sulfur.[93] The British Congreve rockets used 62.4% saltpeter, 23.2% charcoal and 14.4% sulfur, but the British Mark VII gunpowder was changed to 65% saltpeter, 20% charcoal and 15% sulfur.[94] The explanation for the wide variety in formulation relates to usage. Powder used for rocketry can use a slower burn rate since it accelerates the projectile for a much longer time—whereas powders for weapons such as flintlocks, cap-locks, or matchlocks need a higher burn rate to accelerate the projectile in a much shorter distance. Cannons usually used lower burn rate powders, because most would burst with higher burn rate powders. +Serpentine[edit] +The original dry-compounded powder used in fifteenth-century Europe was known as "Serpentine", either a reference to Satan[95] or to a common artillery piece that used it.[96] The ingredients were ground together with a mortar and pestle, perhaps for 24 hours,[96] resulting in a fine flour. Vibration during transportation could cause the components to separate again, requiring remixing in the field. Also if the quality of the saltpeter was low (for instance if it was contaminated with highly hygroscopic calcium nitrate), or if the powder was simply old (due to the mildly hygroscopic nature of potassium nitrate), in humid weather it would need to be re-dried. The dust from "repairing" powder in the field was a major hazard. +Loading cannons or bombards before the powder-making advances of the Renaissance was a skilled art. Fine powder loaded haphazardly or too tightly would burn incompletely or too slowly. Typically, the breech-loading powder chamber in the rear of the piece was filled only about half full, the serpentine powder neither too compressed nor too loose, a wooden bung pounded in to seal the chamber from the barrel when assembled, and the projectile placed on. A carefully determined empty space was necessary for the charge to burn effectively. When the cannon was fired through the touchhole, turbulence from the initial surface combustion caused the rest of the powder to be rapidly exposed to the flame.[96] +The advent of much more powerful and easy to use corned powder changed this procedure, but serpentine was used with older guns into the seventeenth century.[97] +Corning[edit] +For gunpowder to explode effectively, the combustible ingredients must be reduced to the smallest possible particle sizes, and thoroughly mixed as possible. Once mixed, however, for better results in a gun, makers discovered that the final product should be in the form of individual, dense, grains that spread the fire quickly from grain to grain, much as straw or twigs catch fire more quickly than a pile of sawdust. +Primarily for safety reasons, size reduction and mixing is done while the ingredients are damp, usually with water. After 1800, instead of forming grains by hand or with sieves, the damp mill-cake was pressed in molds to increase its density and extract the liquid, forming press-cake. The pressing took varying amounts of time, depending on conditions such as atmospheric humidity. The hard, dense product was broken again into tiny pieces, which were separated with sieves to produce a uniform product for each purpose: coarse powders for cannons, finer grained powders for muskets, and the finest for small hand guns and priming.[97] Inappropriately fine-grained powder often caused cannons to burst before the projectile could move down the barrel, due to the high initial spike in pressure.[98] Mammoth powder with large grains made for Rodman's 15-inch cannon reduced the pressure to only 20 percent as high as ordinary cannon powder would have produced.[99] +In the mid-nineteenth century, measurements were made determining that the burning rate within a grain of black powder (or a tightly packed mass) is about 0.20 fps, while the rate of ignition propagation from grain to grain is around 30 fps, over two orders of magnitude faster.[97] +Modern types[edit] +Modern corning first compresses the fine black powder meal into blocks with a fixed density (1.7 g/cm³).[100] In the United States, gunpowder grains were designated F (for fine) or C (for coarse). Grain diameter decreased with a larger number of Fs and increased with a larger number of Cs, ranging from about 2 mm for 7F to 15 mm for 7C. Even larger grains were produced for artillery bore diameters greater than about 17 cm (6.7 in). The standard DuPont Mammoth powder developed by Thomas Rodman and Lammot du Pont for use during the American Civil War had grains averaging 0.6 inches diameter, with edges rounded in a glazing barrel.[99] Other versions had grains the size of golf and tennis balls for use in 20-inch (50-cm) Rodman guns.[101] In 1875 DuPont introduced Hexagonal powder for large artillery, which was pressed using shaped plates with a small center core—about 1.5 inches diameter, like a wagon wheel nut, the center hole widened as the grain burned.[102] By 1882 German makers also produced hexagonal grained powders of a similar size for artillery.[102] +By the late 19th century manufacturing focused on standard grades of black powder from Fg used in large bore rifles and shotguns, through FFg (medium and small-bore arms such as muskets and fusils), FFFg (small-bore rifles and pistols), and FFFFg (extreme small bore, short pistols and most commonly for priming flintlocks).[103] A coarser grade for use in military artillery blanks was designated A-1. These grades were sorted on a system of screens with oversize retained on a mesh of 6 wires per inch, A-1 retained on 10 wires per inch, Fg retained on 14, FFg on 24, FFFg on 46, and FFFFg on 60. Fines designated FFFFFg were usually reprocessed to minimize explosive dust hazards.[104] In the United Kingdom, the main service gunpowders were classified RFG (rifle grained fine) with diameter of one or two millimeters and RLG (rifle grained large) for grain diameters between two and six millimeters.[101] Gunpowder grains can alternatively be categorized by mesh size: the BSS sieve mesh size, being the smallest mesh size, which retains no grains. Recognized grain sizes are Gunpowder G 7, G 20, G 40, and G 90. +Owing to the large market of antique and replica black-powder firearms in the US, modern gunpowder substitutes like Pyrodex, Triple Seven and Black Mag3[105] pellets have been developed since the 1970s. These products, which should not be confused with smokeless powders, aim to produce less fouling (solid residue), while maintaining the traditional volumetric measurement system for charges. Claims of less corrosiveness of these products have been controversial however. New cleaning products for black-powder guns have also been developed for this market.[103] +Other types of gunpowder[edit] +Besides black powder, there are other historically important types of gunpowder. "Brown gunpowder" is cited as composed of 79% nitre, 3% sulfur, and 18% charcoal per 100 of dry powder, with about 2% moisture. Prismatic Brown Powder is a large-grained product the Rottweil Company introduced in 1884 in Germany, which was adopted by the British Royal Navy shortly thereafter. The French navy adopted a fine, 3.1 millimeter, not prismatic grained product called Slow Burning Cocoa (SBC) or "cocoa powder". These brown powders reduced burning rate even further by using as little as 2 percent sulfur and using charcoal made from rye straw that had not been completely charred, hence the brown color.[102] +Lesmok powder was a product developed by DuPont in 1911[106] one of several semi-smokeless products in the industry containing a mixture of black and nitrocellulose powder. It was sold to Winchester and others primarily for .22 and .32 small calibers. Its advantage was that it was believed at the time to be less corrosive than smokeless powders then in use. It was not understood in the U.S. until the 1920s that the actual source of corrosion was the potassium chloride residue from potassium chlorate sensitized primers. The bulkier black powder fouling better disperses primer residue. Failure to mitigate primer corrosion by dispersion caused the false impression that nitrocellulose-based powder caused corrosion.[107] Lesmok had some of the bulk of black powder for dispersing primer residue, but somewhat less total bulk than straight black powder, thus requiring less frequent bore cleaning.[108] It was last sold by Winchester in 1947. +Sulfur-free gunpowder[edit] + +Burst barrel of a muzzle loader pistol replica, which was loaded with nitrocellulose powder instead of black powder and couldn't withstand the higher pressures of the modern propellant +The development of smokeless powders, such as cordite, in the late 19th century created the need for a spark-sensitive priming charge, such as gunpowder. However, the sulfur content of traditional gunpowders caused corrosion problems with Cordite Mk I and this led to the introduction of a range of sulfur-free gunpowders, of varying grain sizes.[64] They typically contain 70.5 parts of saltpeter and 29.5 parts of charcoal.[64] Like black powder, they were produced in different grain sizes. In the United Kingdom, the finest grain was known as sulfur-free mealed powder (SMP). Coarser grains were numbered as sulfur-free gunpowder (SFG n): 'SFG 12', 'SFG 20', 'SFG 40' and 'SFG 90', for example; where the number represents the smallest BSS sieve mesh size, which retained no grains. +Sulfur's main role in gunpowder is to decrease the ignition temperature. A sample reaction for sulfur-free gunpowder would be +6 KNO3 + C7H4O → 3 K2CO3 + 4 CO2 + 2 H2O + 3 N2 +Combustion characteristics[edit] +A simple, commonly cited, chemical equation for the combustion of black powder is +2 KNO3 + S + 3 C → K2S + N2 + 3 CO2. +A balanced, but still simplified, equation is[109] +10 KNO3 + 3 S + 8 C → 2 K2CO3 + 3 K2SO4 + 6 CO2 + 5 N2. +Although charcoal's chemical formula varies, it can be best summed up by its empirical formula: C7H4O. +Therefore, an even more accurate equation of the decomposition of regular black powder with the use of sulfur can be described as: +6 KNO3 + C7H4O + 2 S → K2CO3 + K2SO4 + K2S + 4 CO2 + 2 CO + 2 H2O + 3 N2 +Black powder without the use of sulfur: +10 KNO3 + 2 C7H4O → 5 K2CO3 + 4 CO2 + 5 CO + 4 H2O + 5 N2 +The burning of gunpowder does not take place as a single reaction, however, and the byproducts are not easily predicted. One study's results showed that it produced (in order of descending quantities) 55.91% solid products: potassium carbonate, potassium sulfate, potassium sulfide, sulfur, potassium nitrate, potassium thiocyanate, carbon, ammonium carbonate and 42.98% gaseous products: carbon dioxide, nitrogen, carbon monoxide, hydrogen sulfide, hydrogen, methane, 1.11% water. +Black powder made with less-expensive and more plentiful sodium nitrate (in appropriate proportions) works just as well but is more hygroscopic than powders made from Potassium nitrate—popularly known as saltpeter. Because corned black powder grains made with saltpeter are less affected by moisture in the air, they can be stored unsealed without degradation by humidity. Muzzleloaders have been known to fire after hanging on a wall for decades in a loaded state, provided they remained dry. By contrast, black powder made with sodium nitrate must be kept sealed to remain stable. +Gunpowder contains 3 megajoules per kilogram, and contains its own oxidant. For comparison, the energy density of TNT is 4.7 megajoules per kilogram, and the energy density of gasoline is 47.2 megajoules per kilogram. Gunpowder is a low explosive and as such it does not detonate; rather it deflagrates. Since it contains its own oxidizer and additionally burns faster under pressure, its combustion is capable of rupturing containers such as shell, grenade, or improvised "pipe bomb" or "pressure cooker" casings, forming shrapnel. +Advantages[edit] +In quarrying, high explosives are generally preferred for shattering rock. However, because of its low brisance, black powder causes fewer fractures and results in more usable stone compared to other explosives, making black powder useful for blasting monumental stone such as granite and marble. Black powder is well suited for blank rounds, signal flares, burst charges, and rescue-line launches. Black powder is also used in fireworks for lifting shells, in rockets as fuel, and in certain special effects. +Disadvantages[edit] +Black powder has a low energy density compared to modern "smokeless" powders, and thus to achieve high energy loadings, large amounts of black powder are needed with heavy projectiles. Black powder also produces thick smoke as a byproduct, which in military applications may give a soldier's location away to an enemy observer and may also impair aiming for additional shots. +Combustion converts less than half the mass of black powder to gas. The rest ends up as a thick layer of soot inside the barrel. In addition to being a nuisance, the residue from burnt black powder is hygroscopic and with the addition of moisture absorbed from the air, this residue forms a caustic substance. The soot contains potassium oxide or sodium oxide that turns into potassium hydroxide, or sodium hydroxide, which corrodes wrought iron or steel gun barrels. Black powder arms must be well cleaned both inside and out to remove the residue. The matchlock musket or pistol (an early gun ignition system), as well as the flintlock would often be unusable in wet weather, due to powder in the pan being exposed and dampened. Because of this unreliability, soldiers carrying muskets, known as musketeers, were armed with additional weapons such as swords or pikes. The bayonet was developed to allow the musket to be used as a pike, thus eliminating the need for the soldier to carry a secondary weapon. +Transportation[edit] +The United Nations Model Regulations on the Transportation of Dangerous Goods and national transportation authorities, such as United States Department of Transportation, have classified gunpowder (black powder) as a Group A: Primary explosive substance for shipment because it ignites so easily. Complete manufactured devices containing black powder are usually classified as Group D: Secondary detonating substance, or black powder, or article containing secondary detonating substance, such as firework, class D model rocket engine, etc., for shipment because they are harder to ignite than loose powder. As explosives, they all fall into the category of Class 1. +Other uses[edit] +Besides its use as an explosive, gunpowder has been occasionally employed for other purposes; after the Battle of Aspern-Essling (1809), the surgeon of the Napoleonic Army Larrey combated the lack of food for the wounded under his care by preparing a bouillon of horse meat seasoned with gunpowder for lack of salt.[110][111] It was also used for sterilizing on ships when there was no alcohol. +Jack Tars (British sailors) used gunpowder to create tattoos when ink wasn't available, by pricking the skin and rubbing the powder into the wound in a method known as traumatic tattooing.[112] +Christiaan Huygens experimented with gunpowder in 1673 in an early attempt to build an internal combustion engine, but he did not succeed. Modern attempts to recreate his invention were similarly unsuccessful. +Fireworks use gunpowder as lifting and burst charges, although sometimes other more powerful compositions are added to the burst charge to improve performance in small shells or provide a louder report. Most modern firecrackers no longer contain black powder. +Beginning in the 1930s, gunpowder or smokeless powder was used in rivet guns, stun guns for animals, cable splicers and other industrial construction tools.[113] The "stud gun" drove nails or screws into solid concrete, a function not possible with hydraulic tools. See Powder-actuated tool. Shotguns have been used to eliminate persistent material rings in operating rotary kilns (such as those for cement, lime, phosphate, etc.) and clinker in operating furnaces, and commercial tools make the method more reliable.[114] +Near London in 1853, Captain Shrapnel demonstrated a method for crushing gold-bearing ores by firing them from a cannon into an iron chamber, and "much satisfaction was expressed by all present". He hoped it would be useful on the goldfields of California and Australia. Nothing came of the invention, as continuously-operating crushing machines that achieved more reliable comminution were already coming into use.[115] +See also[edit] +Ballistics +Black powder substitute +Faversham explosives industry +Bulk loaded liquid propellants +Gunpowder magazine +Gunpowder Plot +Berthold Schwarz +Gunpowder warfare +History of gunpowder +Technology of the Song Dynasty +References[edit] +Jump up ^ http://www.merriam-webster.com/dictionary/gunpowder +Jump up ^ Jai Prakash Agrawal (2010). High Energy Materials: Propellants, Explosives and Pyrotechnics. Wiley-VCH. p. 69. ISBN 978-3-527-32610-5. +Jump up ^ David Cressy, Saltpeter: The Mother of Gunpowder (Oxford University Press, 2013) +Jump up ^ Owen Compliance Services. "Black Powder". Material Safety Data Sheet. Retrieved 31 August 2014. +Jump up ^ http://www.history.com/shows/ancient-discoveries/articles/who-built-it-first-2 +Jump up ^ http://chemistry.about.com/od/historyofchemistry/a/gunpowder.htm +Jump up ^ Chase 2003:31 : "the earliest surviving formulas for gunpowder can be found in the Wujing zongyao, a military work from around 1040" +^ Jump up to: a b c Buchanan 2006, p. 2 "With its ninth century AD origins in China, the knowledge of gunpowder emerged from the search by alchemists for the secrets of life, to filter through the channels of Middle Eastern culture, and take root in Europe with consequences that form the context of the studies in this volume." +^ Jump up to: a b c Joseph Needham; Gwei-Djen Lu; Ling Wang (1987). Science and civilisation in China, Volume 5, Part 7. Cambridge University Press. pp. 48–50. ISBN 978-0-521-30358-3. +Jump up ^ Hazel Rossotti (2002). Fire: Servant, Scourge, and Enigma. Courier Dover Publications. pp. 132–137. ISBN 978-0-486-42261-9. +Jump up ^ Jack Kelly Gunpowder: Alchemy, Bombards, and Pyrotechnics: The History of the Explosive that Changed the World, Perseus Books Group: 2005, ISBN 0-465-03722-4, ISBN 978-0-465-03722-3: 272 pages +Jump up ^ St. C. Easton: "Roger Bacon and his Search for a Universal Science", Oxford (1962) +^ Jump up to: a b Gábor Ágoston (2005). Guns for the sultan: military power and the weapons industry in the Ottoman Empire. Cambridge University Press. p. 15. ISBN 978-0-521-84313-3. +Jump up ^ Ingham-Brown, George (1989) The Big Bang: A History of Explosives, Sutton Publishers, ISBN 0-7509-1878-0, ISBN 978-0-7509-1878-7, page vi +Jump up ^ Kelly, Jack (2005) Gunpowder: Alchemy, Bombards, and Pyrotechnics: The History of the Explosive that Changed the World, Perseus Books Group, ISBN 0-465-03722-4, ISBN 978-0-465-03722-3, page 22 +Jump up ^ Bert S. Hall, "Introduction, 1999" pp. xvi–xvii to the reprinting of James Riddick Partington (1960). A history of Greek fire and gunpowder. JHU Press. ISBN 978-0-8018-5954-0. +^ Jump up to: a b Peter Purton (2009). A History of the Late Medieval Siege, 1200–1500. Boydell & Brewer. pp. 108–109. ISBN 978-1-84383-449-6. +Jump up ^ Bert S. Hall, "Introduction, 1999" p. xvii to the reprinting of James Riddick Partington (1960). A history of Greek fire and gunpowder. JHU Press. ISBN 978-0-8018-5954-0. +Jump up ^ Buchanan. "Editor's Introduction: Setting the Context", in Buchanan 2006. +^ Jump up to: a b Chase 2003:31–32 +Jump up ^ Lorge, Peter A. (2008). The Asian military revolution, 1300-2000 : from gunpowder to the bomb (1. publ. ed.). Cambridge: Cambridge University Press. p. 32. ISBN 978052160954-8. +Jump up ^ Kelly 2004:4 +Jump up ^ The Big Book of Trivia Fun, Kidsbooks, 2004 +Jump up ^ Peter Allan Lorge (2008), The Asian military revolution: from gunpowder to the bomb, Cambridge University Press, p. 18, ISBN 978-0-521-60954-8 +Jump up ^ Needham 1986, p. 7 "Without doubt it was in the previous century, around +850, that the early alchemical experiments on the constituents of gunpowder, with its self-contained oxygen, reached their climax in the appearance of the mixture itself." +Jump up ^ Chase 2003:1 "The earliest known formula for gunpowder can be found in a Chinese work dating probably from the 800s. The Chinese wasted little time in applying it to warfare, and they produced a variety of gunpowder weapons, including flamethrowers, rockets, bombs, and land mines, before inventing firearms." +Jump up ^ Chase 2003:1 +Jump up ^ Delgado, James (February 2003). "Relics of the Kamikaze". Archaeology (Archaeological Institute of America) 56 (1). +Jump up ^ Chase 2003:31 +Jump up ^ Peter Allan Lorge (2008), The Asian military revolution: from gunpowder to the bomb, Cambridge University Press, pp. 33–34, ISBN 978-0-521-60954-8 +Jump up ^ Kelly 2004:22 'Around year 1240, Arabs acquired knowledge of saltpeter ("Chinese snow") from the East, perhaps through India. They knew of gunpowder soon afterward. They also learned about fireworks ("Chinese flowers") and rockets ("Chinese arrows"). Arab warriors had acquired fire lances before year 1280. Around that same year, a Syrian named Hasan al-Rammah wrote a book that, as he put it, "treats of machines of fire to be used for amusement or for useful purposes." He talked of rockets, fireworks, fire lances, and other incendiaries, using terms that suggested he derived his knowledge from Chinese sources. He gave instructions for the purification of saltpeter and recipes for making different types of gunpowder.' +^ Jump up to: a b c d Hassan, Ahmad Y. "Transfer of Islamic Technology to the West: Part III". History of Science and Technology in Islam. +Jump up ^ Peter Watson (2006). Ideas: A History of Thought and Invention, from Fire to Freud. HarperCollins. p. 304. ISBN 978-0-06-093564-1. The first use of a metal tube in this context was made around 1280 in the wars between the Song and the Mongols, where a new term, chong, was invented to describe the new horror...Like paper, it reached the West via the Muslims, in this case the writings of the Andalusian botanist Ibn al-Baytar, who died in Damascus in 1248. The Arabic term for saltpetre is 'Chinese snow' while the Persian usage is 'Chinese salt'.28 +Jump up ^ Cathal J. Nolan (2006). The age of wars of religion, 1000–1650: an encyclopedia of global warfare and civilization. Volume 1 of Greenwood encyclopedias of modern world wars. Greenwood Publishing Group. p. 365. ISBN 0-313-33733-0. Retrieved 2011-11-28. In either case, there is linguistic evidence of Chinese origins of the technology: in Damascus, Arabs called the saltpeter used in making gunpowder " Chinese snow," while in Iran it was called "Chinese salt." Whatever the migratory route +Jump up ^ Oliver Frederick Gillilan Hogg (1970). Artillery: its origin, heyday, and decline. Archon Books. p. 123. The Chinese were certainly acquainted with saltpetre, the essential ingredient of gunpowder. They called it Chinese Snow and employed it early in the Christian era in the manufacture of fireworks and rockets. +Jump up ^ Oliver Frederick Gillilan Hogg (1963). English artillery, 1326–1716: being the history of artillery in this country prior to the formation of the Royal Regiment of Artillery. Royal Artillery Institution. p. 42. The Chinese were certainly acquainted with saltpetre, the essential ingredient of gunpowder. They called it Chinese Snow and employed it early in the Christian era in the manufacture of fireworks and rockets. +Jump up ^ Oliver Frederick Gillilan Hogg (1993). Clubs to cannon: warfare and weapons before the introduction of gunpowder (reprint ed.). Barnes & Noble Books. p. 216. ISBN 1-56619-364-8. Retrieved 2011-11-28. The Chinese were certainly acquainted with saltpetre, the essential ingredient of gunpowder. They called it Chinese snow and used it early in the Christian era in the manufacture of fireworks and rockets. +Jump up ^ Partington, J. R. (1960). A History of Greek Fire and Gunpowder (illustrated, reprint ed.). JHU Press. p. 335. ISBN 0801859549. Retrieved 2014-11-21. +Jump up ^ Needham, Joseph; Yu, Ping-Yu (1980). Needham, Joseph, ed. Science and Civilisation in China: Volume 5, Chemistry and Chemical Technology, Part 4, Spagyrical Discovery and Invention: Apparatus, Theories and Gifts. Volume 5 (Issue 4 of Science and Civilisation in China). Contributors Joseph Needham, Lu Gwei-Djen, Nathan Sivin (illustrated, reprint ed.). Cambridge University Press. p. 194. ISBN 052108573X. Retrieved 2014-11-21. +Jump up ^ Khan 1996 +^ Jump up to: a b Khan 2004:6 +Jump up ^ Ancient Discoveries, Episode 12: Machines of the East, History Channel, 2007 (Part 4 and Part 5) +Jump up ^ Nelson, Cameron Rubaloff (2010-07). Manufacture and transportation of gunpowder in the Ottoman Empire: 1400-1800 M.A. Thesis. +Jump up ^ William H. McNeill (1992). The Rise of the West: A History of the Human Community. University of Chicago Press. p. 492. ISBN 0-226-56141-0. Retrieved 29 July 2011. +Jump up ^ Michael Kohn (2006), Dateline Mongolia: An American Journalist in Nomad's Land, RDR Books, p. 28, ISBN 1-57143-155-1, retrieved 29 July 2011 +Jump up ^ Robert Cowley (1993). Robert Cowley, ed. Experience of War (reprint ed.). Random House Inc. p. 86. ISBN 0-440-50553-4. Retrieved 29 July 2011. +Jump up ^ Kenneth Warren Chase (2003). Firearms: a global history to 1700 (illustrated ed.). Cambridge University Press. p. 58. ISBN 0-521-82274-2. Retrieved 29 July 2011. +Jump up ^ C. F. Temler, Historische Abhandlungen der Koniglichen Gesellschaft der Wissenschaften zu Kopenhagen ... ubersetzt ... von V. A. Heinze, Kiel, Dresden and Leipzig, 1782, i, 168, as cited in Partington, p. 228, footnote 6. +Jump up ^ Joseph Needham; Gwei-Djen Lu; Ling Wang (1987). Science and civilisation in China, Volume 5, Part 7. Cambridge University Press. p. 358. ISBN 978-0-521-30358-3. +Jump up ^ Bert S. Hall, "Introduction, 1999" p. xxiv to the reprinting of James Riddick Partington (1960). A history of Greek fire and gunpowder. JHU Press. ISBN 978-0-8018-5954-0. +Jump up ^ Partington 1960:60 +^ Jump up to: a b Partington 1960:48–49, 54 +^ Jump up to: a b Partington 1960:82–83 +^ Jump up to: a b c d Kelly 2004, p.61 +Jump up ^ Molerus, Otto. "History of Civilization in the Western Hemisphere from the Point of View of Particulate Technology, Part 2," Advanced Powder Technology 7 (1996): 161-66 +Jump up ^ Microsoft Encarta Online Encyclopedia 2007 Archived 31 October 2009. +Jump up ^ In 1777 Lavoisier named oxygen, which had earlier been isolated by Priestley; the realization that saltpeter contained this substance was fundamental to understanding gunpowder. +^ Jump up to: a b Kelly 2004, p.164 +Jump up ^ Metzner, Paul (1998), Crescendo of the Virtuoso: Spectacle, Skill, and Self-Promotion in Paris during the Age of Revolution, University of California Press +^ Jump up to: a b c d Cocroft 2000, "Success to the Black Art!". Chapter 1 +Jump up ^ Ross, Charles. The Custom of the Castle: From Malory to Macbeth. Berkeley: University of California Press, c1997. [1] pages 131-130 +Jump up ^ The Noble-Abel Equation of State: Thermodynamic Derivations for Ballistics Modelling +Jump up ^ Pritchard, Tom; Evans, Jack; Johnson, Sydney (1985), The Old Gunpowder Factory at Glynneath, Merthyr Tydfil: Merthyr Tydfil & District Naturalists' Society +^ Jump up to: a b c d e Cocroft 2000, "The demise of gunpowder". Chapter 4 +Jump up ^ MacDougall, Ian (2000). 'Oh, ye had to be careful' : personal recollections by Roslin gunpowder mill and bomb factory workers. East Linton, Scotland: Tuckwell Press in association with the European Ethnological Research Centre and the Scottish Working People's History Trust. ISBN 1-86232-126-4. +Jump up ^ Iqtidar Alam Khan (2004). Gunpowder And Firearms: Warfare In Medieval India. Oxford University Press. ISBN 978-0-19-566526-0. +^ Jump up to: a b Iqtidar Alam Khan (25 April 2008). Historical Dictionary of Medieval India. Scarecrow Press. p. 157. ISBN 978-0-8108-5503-8. +^ Jump up to: a b Khan 2004:9–10 +Jump up ^ Khan 2004:10 +Jump up ^ Partington (Johns Hopkins University Press edition, 1999), 225 +Jump up ^ Partington (Johns Hopkins University Press edition, 1999), 226 +Jump up ^ http://www.youtube.com/watch?v=DTfEDaWMj4o +^ Jump up to: a b c "India." Encyclopædia Britannica. Encyclopedia Britannica 2008 Ultimate Reference Suite. Chicago: Encyclopedia Britannica, 2008. +Jump up ^ "rocket and missile system." Encyclopædia Britannica. Encyclopædia Britannica 2008 Ultimate Reference Suite. Chicago: Encyclopædia Britannica, 2008. +^ Jump up to: a b Dipanegara, P. B. R. Carey, Babad Dipanagara: an account of the outbreak of the Java war, 1825-30 : the Surakarta court version of the Babad Dipanagara with translations into English and Indonesian volume 9: Council of the M.B.R.A.S. by Art Printing Works: 1981. +Jump up ^ Atsushi, Ota (2006). Changes of regime and social dynamics in West Java : society, state, and the outer world of Banten, 1750-1830. Leiden: Brill. ISBN 90-04-15091-9. +^ Jump up to: a b Thomas Stamford Raffles, The History of Java, Oxford University Press, 1965 (originally published in 1817), ISBN 0-19-580347-7 +Jump up ^ Raffles, Thomas Stamford (1978). The History of Java ([Repr.]. ed.). Kuala Lumpur: Oxford University Press. ISBN 0-19-580347-7. +Jump up ^ US Department of Agriculture (1917). Department Bulleting No. 316: Willows: Their growth, use, and importance. The Department. p. 31. +Jump up ^ Kelly 2004, p.200 +^ Jump up to: a b Earl 1978, Chapter 2: The Development of Gunpowder +Jump up ^ Kelly 2004:60–63 +Jump up ^ Kelly 2004, p.199 +Jump up ^ Frangsmyr, Tore, J. L. Heilbron, and Robin E. Rider, editors The Quantifying Spirit in the Eighteenth Century. Berkeley: University of California Press, c1990. http://ark.cdlib.org/ark:/13030/ft6d5nb455/ p. 292. +Jump up ^ C.E. Munroe (1885) "Notes on the literature of explosives no. VIII", Proceedings of the US Naval Institute, no. XI, p. 285 +Jump up ^ The History of the 10.4×38 Swiss Cartridge +Jump up ^ Blackpowder to Pyrodex and Beyond by Randy Wakeman at Chuck Hawks +Jump up ^ The History and Art of Shotshells by Jon Farrar, Nebraskaland Magazine +Jump up ^ Buchanan. "Editor's Introduction: Setting the Context", in Buchanan 2006, p. 4. +Jump up ^ Black Powder Recipes, Ulrich Bretscher +Jump up ^ Julian S. Hatcher, Hatcher's Notebook, Military Service Publishing Company, 1947. Chapter XIII Notes on Gunpowder, pages 300-305. +Jump up ^ Kelly 2004, p.218 +Jump up ^ Book title Workshop Receipts Publisher William Clowes and Son limited Author Ernest Spon. Date 1 August 1873. +Jump up ^ GunpowderTranslation. Academic. Retrieved 2014-08-31. +Jump up ^ Cathal J. Nolan (2006), The age of wars of religion, 1000-1650: an encyclopedia of global warfare and civilization, Greenwood Publishing Group, p. 365, ISBN 978-0-313-33733-8 +^ Jump up to: a b c Kelly 2004, p58 +^ Jump up to: a b c John Francis Guilmartin (2003). Gunpowder & galleys: changing technology & Mediterranean warfare at sea in the 16th century. Conway Maritime Press. pp. 109–110 and 298–300. ISBN 0851779514. +Jump up ^ T.J. Rodman (1861), Reports of experiments on the properties of metals for cannon and the qualities of cannon powder, p. 270 +^ Jump up to: a b Kelly 2004, p.195 +Jump up ^ Tenney L. Davis (1943). The Chemistry of Powder and Explosives (PDF). p. 139. +^ Jump up to: a b Brown, G.I. (1998) The Big Bang: A history of Explosives Sutton Publishing pp.22&32 ISBN 0-7509-1878-0 +^ Jump up to: a b c Kelly 2004, p.224 +^ Jump up to: a b Rodney James (2011). The ABCs of Reloading: The Definitive Guide for Novice to Expert (9 ed.). Krause Publications. pp. 53–59. ISBN 978-1-4402-1396-0. +Jump up ^ Sharpe, Philip B. (1953) Complete Guide to Handloading Funk & Wagnalls p.137 +Jump up ^ Wakeman, Randy. "Blackpowder to Pyrodex and Beyond". Retrieved 31 August 2014. +Jump up ^ "LESMOK POWDER". +Jump up ^ Julian S. Hatcher, Hatcher's Notebook, Stackpole Books, 1962. Chapter XIV, Gun Corrosion and Ammunition Developments, pages 346-349. +Jump up ^ Wakeman, Randy. "Blackpowder to Pyrodex and Beyond". +Jump up ^ Flash! Bang! Whiz!, University of Denver +Jump up ^ Parker, Harold T. (1983). Three Napoleonic battles. (Repr., Durham, 1944. ed.). Durham, NC: Duke Univ. Pr. p. 83. ISBN 0-8223-0547-X. +Jump up ^ Larrey is quoted in French at Dr Béraud, Études Hygiéniques de la chair de cheval comme aliment, Musée des Familles (1841-42). +Jump up ^ Rediker, Marcus (1989). Between the devil and the deep blue sea : merchant seamen, pirates, and the Anglo-American maritime world, 1700-1750 (1st pbk. ed. ed.). Cambridge: Cambridge University Press. p. 12. ISBN 9780521379830. +Jump up ^ "Gunpowder Now Used To Drive Rivets And Splice Cables", April 1932, Popular Science +Jump up ^ "MasterBlaster System". Remington Products. +Jump up ^ Mining Journal 22 January 1853, p. 61 +Benton, Captain James G. (1862). A Course of Instruction in Ordnance and Gunnery (2 ed.). West Point, New York: Thomas Publications. ISBN 1-57747-079-6.. +Brown, G. I. (1998). The Big Bang: A History of Explosives. Sutton Publishing. ISBN 0-7509-1878-0.. +Buchanan, Brenda J., ed. (2006). Gunpowder, Explosives and the State: A Technological History. Aldershot: Ashgate. ISBN 0-7546-5259-9.. +Chase, Kenneth (2003). Firearms: A Global History to 1700. Cambridge University Press. ISBN 0-521-82274-2.. +Cocroft, Wayne (2000). Dangerous Energy: The archaeology of gunpowder and military explosives manufacture. Swindon: English Heritage. ISBN 1-85074-718-0.. +Crosby, Alfred W. (2002). Throwing Fire: Projectile Technology Through History. Cambridge University Press. ISBN 0-521-79158-8.. +Earl, Brian (1978). Cornish Explosives. Cornwall: The Trevithick Society. ISBN 0-904040-13-5.. +al-Hassan, Ahmad Y.. "History of Science and Technology in Islam". |chapter= ignored (help). +Johnson, Norman Gardner. "explosive". Encyclopædia Britannica. Chicago: Encyclopædia Britannica Online.. +Kelly, Jack (2004). Gunpowder: Alchemy, Bombards, & Pyrotechnics: The History of the Explosive that Changed the World. Basic Books. ISBN 0-465-03718-6.. +Khan, Iqtidar Alam (1996). "Coming of Gunpowder to the Islamic World and North India: Spotlight on the Role of the Mongols". Journal of Asian History 30: 41–5.. +Khan, Iqtidar Alam (2004). "Gunpowder and Firearms: Warfare in Medieval India". Oxford University Press. doi:10.1086/ahr.111.3.817.. +Needham, Joseph (1986). "Science & Civilisation in China". V:7: The Gunpowder Epic. Cambridge University Press. ISBN 0-521-30358-3.. +Norris, John (2003). Early Gunpowder Artillery: 1300-1600. Marlborough: The Crowood Press. ISBN 9781861266156.. +Partington, J.R. (1960). A History of Greek Fire and Gunpowder. Cambridge, UK: W. Heffer & Sons.. +Partington, James Riddick; Hall, Bert S. (1999). A History of Greek Fire and Gunpowder. Baltimore: Johns Hopkins University Press. doi:10.1353/tech.2000.0031. ISBN 0-8018-5954-9. +Urbanski, Tadeusz (1967). "Chemistry and Technology of Explosives" III. New York: Pergamon Press.. +External links[edit] + Wikimedia Commons has media related to Gunpowder. + Look up gunpowder in Wiktionary, the free dictionary. +Gun and Gunpowder +The Origins of Gunpowder +Cannons and Gunpowder +Oare Gunpowder Works, Kent, UK +Royal Gunpowder Mills +The DuPont Company on the Brandywine A digital exhibit produced by the Hagley Library that covers the founding and early history of the DuPont Company powder yards in Delaware +"Ulrich Bretschler's Gunpowder Chemistry page". +Video Demonstration of the Medieval Siege Society's Guns, Including showing ignition of gunpowder +Black Powder Recipes +"Dr. Sasse's investigations (and others) found via search at US DTIC.MIL These contain scientific studies of BP properties and details of measurement techniques.". +Categories: GunpowderChinese inventionsExplosivesFirearm propellantsPyrotechnic compositionsRocket fuelsSolid fuels +Navigation menu +Create accountLog inArticleTalkReadEditView history + +Main page +Contents +Featured content +Current events +Random article +Donate to Wikipedia +Wikimedia Shop +Interaction +Help +About Wikipedia +Community portal +Recent changes +Contact page +Tools +What links here +Related changes +Upload file +Special pages +Permanent link +Page information +Wikidata item +Cite this page +Print/export +Create a book +Download as PDF +Printable version +Languages +Afrikaans +العربية +Aragonés +Asturianu +Azərbaycanca +Башҡортса +Беларуская +Беларуская (тарашкевіца)‎ +Български +Bosanski +Brezhoneg +Буряад +Català +Чӑвашла +Čeština +Corsu +Cymraeg +Dansk +Deutsch +Eesti +Ελληνικά +Español +Esperanto +Euskara +فارسی +Français +Gaeilge +Galego +贛語 +Хальмг +한국어 +हिन्दी +Hrvatski +Ilokano +Bahasa Indonesia +Íslenska +Italiano +עברית +Kapampangan +Kiswahili +Kurdî +Latina +Latviešu +Lietuvių +Limburgs +Magyar +Македонски +മലയാളം +مصرى +Монгол +Nederlands +नेपाली +नेपाल भाषा +日本語 +Нохчийн +Norsk bokmål +Norsk nynorsk +Occitan +Oʻzbekcha +پنجابی +Polski +Português +Română +Runa Simi +Русский +Саха тыла +Scots +Shqip +Sicilianu +Simple English +Slovenčina +Slovenščina +کوردی +Српски / srpski +Srpskohrvatski / српскохрватски +Suomi +Svenska +Tagalog +தமிழ் +Татарча/tatarça +ไทย +Türkçe +Українська +اردو +Tiếng Việt +Võro +Winaray +ייִדיש +粵語 +Žemaitėška +中文 +Edit links +This page was last modified on 28 November 2014 at 05:37. +Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Terms of Use and Privacy Policy. Wikipedia® is a registered trademark of the Wikimedia Foundation, Inc., a non-profit organization. +Privacy policyAbout WikipediaDisclaimersContact WikipediaDevelopersMobile viewWikimedia Foundation Powered by MediaWiki + + +Smokeless powder +From Wikipedia, the free encyclopedia + +Finnish smokeless powder +Smokeless powder is the name given to a number of propellants used in firearms and artillery that produce negligible smoke when fired, unlike the black powder they replaced. The term is unique to the United States and is generally not used in other English-speaking countries, which initially used proprietary names such as "Ballistite" and "Cordite" but gradually shifted to "propellant" as the generic term. +The basis of the term smokeless is that the combustion products are mainly gaseous, compared to around 55% solid products (mostly potassium carbonate, potassium sulfate, and potassium sulfide) for black powder.[1] Despite its name, smokeless powder is not completely smoke-free;[2] while there may be little noticeable smoke from small-arms ammunition, smoke from artillery fire can be substantial. This article focuses on nitrocellulose formulations, but the term smokeless powder was also used to describe various picrate mixtures with nitrate, chlorate, or dichromate oxidizers during the late 19th century, before the advantages of nitrocellulose became evident.[3] +Since the 14th century[4] gunpowder was not actually a physical "powder," and smokeless powder can only be produced as a pelletized or extruded granular material. Smokeless powder allowed the development of modern semi- and fully automatic firearms and lighter breeches and barrels for artillery. Burnt black powder leaves a thick, heavy fouling that is hygroscopic and causes rusting of the barrel. The fouling left by smokeless powder exhibits none of these properties (though some primer compounds can leave hygroscopic salts that have a similar effect; non-corrosive primer compounds were introduced in the 1920s[5][6]). This makes an autoloading firearm with many moving parts feasible (which would otherwise jam or seize under heavy black powder fouling). +Smokeless powders are classified as, typically, division 1.3 explosives under the UN Recommendations on the transportation of Dangerous goods – Model Regulations, regional regulations (such as ADR) and national regulations (such the United States' ATF). However, they are used as solid propellants; in normal use, they undergo deflagration rather than detonation. +Contents [hide] +1 Background +2 Nitroglycerine and guncotton +3 Propellant improvements +4 Chemical formulations +5 Instability and stabilization +6 Physical variations +7 Smokeless propellant components +8 Manufacturing +9 Flashless propellant +10 See also +11 References +11.1 Notes +11.2 Sources +12 External links +Background[edit] +Military commanders had been complaining since the Napoleonic Wars about the problems of giving orders on a battlefield obscured by the smoke of firing. Verbal commands could not be heard above the noise of the guns, and visual signals could not be seen through the thick smoke from the gunpowder used by the guns. Unless there was a strong wind, after a few shots, soldiers using black powder ammunition would have their view obscured by a huge cloud of smoke. Snipers or other concealed shooters were given away by a cloud of smoke over the firing position. Black powder is also corrosive, making cleaning mandatory after every use. Likewise, black powder's tendency to produce severe fouling caused actions to jam and often made reloading difficult. +Nitroglycerine and guncotton[edit] +Nitroglycerine was synthesized by the Italian chemist Ascanio Sobrero in 1847.[7] It was subsequently developed and manufactured by Alfred Nobel as an industrial explosive, but even then it was unsuitable as a propellant: despite its energetic and smokeless qualities, it detonates instead of deflagrating smoothly, making it more amenable to shattering a gun than propelling a projectile out of it. Nitroglycerine per se is also highly unstable, making it unfit to be carried in battlefield conditions. +A major step forward was the discovery of guncotton, a nitrocellulose-based material, by Swiss chemist Christian Friedrich Schönbein in 1846. He promoted its use as a blasting explosive[8] and sold manufacturing rights to the Austrian Empire. Guncotton was more powerful than gunpowder, but at the same time was once again somewhat more unstable. John Taylor obtained an English patent for guncotton; and John Hall & Sons began manufacture in Faversham. +English interest languished after an explosion destroyed the Faversham factory in 1847. Austrian Baron Wilhelm Lenk von Wolfsberg built two guncotton plants producing artillery propellent, but it too was dangerous under field conditions, and guns that could fire thousands of rounds using gunpowder would reach their service life after only a few hundred shots with the more powerful guncotton. Small arms could not withstand the pressures generated by guncotton at all. +After one of the Austrian factories blew up in 1862, Thomas Prentice & Company began manufacturing guncotton in Stowmarket in 1863; and British War Office chemist Sir Frederick Abel began thorough research at Waltham Abbey Royal Gunpowder Mills leading to a manufacturing process that eliminated the impurities in nitrocellulose making it safer to produce and a stable product safer to handle. Abel patented this process in 1865, when the second Austrian guncotton factory exploded. After the Stowmarket factory exploded in 1871, Waltham Abbey began production of guncotton for torpedo and mine warheads.[9] +Propellant improvements[edit] +In 1863, Prussian artillery captain Johann F. E. Schultze patented a small arms propellent of nitrated hardwood impregnated with saltpetre or barium nitrate. Prentice received an 1866 patent for a sporting powder of nitrated paper manufactured at Stowmarket, but ballistic uniformity suffered as the paper absorbed atmospheric moisture. In 1871, Frederick Volkmann received an Austrian patent for a colloided version of Schultze powder called Collodin, which he manufactured near Vienna for use in sporting firearms. Austrian patents were not published at the time, and the Austrian Empire considered the operation a violation of the government monopoly on explosives manufacture and closed the Volkmann factory in 1875.[9] In 1882, the Explosives Company at Stowmarket patented an improved formulation of nitrated cotton gelatinised by ether-alcohol with nitrates of potassium and barium. These propellants were suitable for shotguns but not rifles.[10] + +Poudre B single-base smokeless powder flakes +In 1884, Paul Vieille invented a smokeless powder called Poudre B (short for poudre blanche—white powder, as distinguished from black powder)[11] made from 68.2% insoluble nitrocellulose, 29.8% soluble nitrocellusose gelatinized with ether and 2% paraffin. This was adopted for the Lebel rifle.[12] It was passed through rollers to form paper thin sheets, which were cut into flakes of the desired size.[11] The resulting propellant, today known as pyrocellulose, contains somewhat less nitrogen than guncotton and is less volatile. A particularly good feature of the propellant is that it will not detonate unless it is compressed, making it very safe to handle under normal conditions. +Vieille's powder revolutionized the effectiveness of small guns, because it gave off almost no smoke and was three times more powerful than black powder. Higher muzzle velocity meant a flatter trajectory and less wind drift and bullet drop, making 1000 meter shots practicable. Since less powder was needed to propel a bullet, the cartridge could be made smaller and lighter. This allowed troops to carry more ammunition for the same weight. Also, it would burn even when wet. Black powder ammunition had to be kept dry and was almost always stored and transported in watertight cartridges. +Other European countries swiftly followed and started using their own versions of Poudre B, the first being Germany and Austria, which introduced new weapons in 1888. Subsequently Poudre B was modified several times with various compounds being added and removed. Krupp began adding diphenylamine as a stabilizer in 1888.[9] +Meanwhile, in 1887, Alfred Nobel obtained an English patent for a smokeless gunpowder he called Ballistite. In this propellant the fibrous structure of cotton (nitro-cellulose) was destroyed by a nitro-glycerine solution instead of a solvent.[13] In England in 1889, a similar powder was patented by Hiram Maxim, and in the USA in 1890 by Hudson Maxim.[14] Ballistite was patented in the United States in 1891. +The Germans adopted ballistite for naval use in 1898, calling it WPC/98. The Italians adopted it as filite, in cord instead of flake form, but realising its drawbacks changed to a formulation with nitroglycerine they called solenite. In 1891 the Russians tasked the chemist Mendeleef with finding a suitable propellant, he created nitrocellulose gelatinised by ether-alcohol, which produced more nitrogen and more uniform colloidal structure than the French use of nitro-cottons in Poudre B. He called it pyro-collodion.[13] +Britain conducted trials on all the various types of propellant brought to their attention, but were dissatisfied with them all and sought something superior to all existing types. In 1889, Sir Frederick Abel, James Dewar and Dr W Kellner patented (Nos 5614 and 11,664 in the names of Abel and Dewar) a new formulation that was manufactured at the Royal Gunpowder Factory at Waltham Abbey. It entered British service in 1891 as Cordite Mark 1. Its main composition was 58% Nitro-glycerine, 37% Guncotton and 3% mineral jelly. A modified version, Cordite MD, entered service in 1901, this increased guncotton to 65% and reduced nitro-glycerine to 30%, this change reduced the combustion temperature and hence erosion and barrel wear. Cordite's advantages over gunpowder were reduced maximum pressure in the chamber (hence lighter breeches, etc.) but longer high pressure. Cordite could be made in any desired shape or size.[15] The creation of cordite led to a lengthy court battle between Nobel, Maxim, and another inventor over alleged British patent infringement. +The Anglo-American Explosives Company began manufacturing its shotgun powder in Oakland, New Jersey in 1890. DuPont began producing guncotton at Carneys Point Township, New Jersey in 1891.[3] Charles E. Munroe of the Naval Torpedo Station in Newport, Rhode Island patented a formulation of guncotton colloided with nitrobenzene, called Indurite, in 1891.[16] Several United States firms began producing smokeless powder when Winchester Repeating Arms Company started loading sporting cartridges with Explosives Company powder in 1893. California Powder Works began producing a mixture of nitroglycerine and nitrocellulose with ammonium picrate as Peyton Powder, Leonard Smokeless Powder Company began producing nitroglycerine-nitrocellulose Ruby powders, Laflin & Rand negotiated a license to produce Ballistite, and DuPont started producing smokeless shotgun powder. The United States Army evaluated 25 varieties of smokeless powder and selected Ruby and Peyton Powders as the most suitable for use in the Krag-Jørgensen service rifle. Ruby was preferred, because tin-plating was required to protect brass cartridge cases from picric acid in the Peyton Powder. Rather than paying the required royalties for Ballistite, Laflin & Rand financed Leonard's reorganization as the American Smokeless Powder Company. United States Army Lieutenant Whistler assisted American Smokeless Powder Company factory superintendent Aspinwall in formulating an improved powder named W.A. for their efforts. W.A. smokeless powder was the standard for United States military service rifles from 1897 until 1908.[3] +In 1897, United States Navy Lieutenant John Bernadou patented a nitrocellulose powder colloided with ether-alcohol.[16] The Navy licensed or sold patents for this formulation to DuPont and the California Powder Works while retaining manufacturing rights for the Naval Powder Factory, Indian Head, Maryland constructed in 1900. The United States Army adopted the Navy single-base formulation in 1908 and began manufacture at Picatinny Arsenal.[3] By that time Laflin & Rand had taken over the American Powder Company to protect their investment, and Laflin & Rand had been purchased by DuPont in 1902.[17] Upon securing a 99-year lease of the Explosives Company in 1903, DuPont enjoyed use of all significant smokeless powder patents in the United States, and was able to optimize production of smokeless powder.[3] When government anti-trust action forced divestiture in 1912, DuPont retained the nitrocellulose smokeless powder formulations used by the United States military and released the double-base formulations used in sporting ammunition to the reorganized Hercules Powder Company. These newer propellants were more stable and thus safer to handle than Poudre B, and also more powerful. +Chemical formulations[edit] +"Double base" redirects here. For the musical instrument, see double bass. +Currently, propellants using nitrocellulose (detonation velocity 7,300 m/s (23,950 ft/s)) (typically an ether-alcohol colloid of nitrocellulose) as the sole explosive propellant ingredient are described as single-base powder.[18] +Propellants mixtures containing nitrocellulose and nitroglycerin (detonation velocity 7,700 m/s (25,260 ft/s)) as explosive propellant ingredients are known as double-base powder.[19] +During the 1930s triple-base propellant containing nitrocellulose, nitroglycerin, and a substantial quantity of nitroguanidine (detonation velocity 8,200 m/s (26,900 ft/s)) as explosive propellant ingredients was developed. These propellant mixtures have reduced flash and flame temperature without sacrificing chamber pressure compared to single and double base propellants, albeit at the cost of more smoke. +In practice, triple base propellants are reserved mainly for large caliber ammunition such as used in (naval) artillery and tank guns. During World War II it had some use by British artillery. After that war it became the standard propellant in all British large caliber ammunition designs except small-arms. Most western nations, except the United States, followed a similar path. +In the late 20th century new propellant formulations started to appear. These are based on nitroguanidine and high explosives of the RDX (detonation velocity 8,750 m/s (28,710 ft/s)) type. +Instability and stabilization[edit] +Nitrocellulose deteriorates with time, yielding acidic byproducts. Those byproducts catalyze the further deterioration, increasing its rate. The released heat, in case of bulk storage of the powder, or too large blocks of solid propellant, can cause self-ignition of the material. Single-base nitrocellulose propellants are hygroscopic and most susceptible to degradation; double-base and triple-base propellants tend to deteriorate more slowly. To neutralize the decomposition products, which could otherwise cause corrosion of metals of the cartridges and gun barrels, calcium carbonate is added to some formulations. +To prevent buildup of the deterioration products, stabilizers are added. Diphenylamine is one of the most common stabilizers used. Nitrated analogs of diphenylamine formed in the process of stabilizing decomposing powder are sometimes used as stabilizers themselves.[20][21] The stabilizers are added in the amount of 0.5–2% of the total amount of the formulation; higher amounts tend to degrade its ballistic properties. The amount of the stabilizer is depleted with time. Propellants in storage should be periodically tested for the amount of stabilizer remaining, as its depletion may lead to auto-ignition of the propellant. +Physical variations[edit] + +Ammunition handloading powders +Smokeless powder may be corned into small spherical balls or extruded into cylinders or strips with many cross-sectional shapes (strips with various rectangular proportions, single or multi-hole cylinders, slotted cylinders) using solvents such as ether. These extrusions can be cut into short ('flakes') or long pieces ('cords' many inches long). Cannon powder has the largest pieces. +The properties of the propellant are greatly influenced by the size and shape of its pieces. The specific surface area of the propellant influences the speed of burning, and the size and shape of the particles determine the specific surface area. By manipulation of the shape it is possible to influence the burning rate and hence the rate at which pressure builds during combustion. Smokeless powder burns only on the surfaces of the pieces. Larger pieces burn more slowly, and the burn rate is further controlled by flame-deterrent coatings that retard burning slightly. The intent is to regulate the burn rate so that a more or less constant pressure is exerted on the propelled projectile as long as it is in the barrel so as to obtain the highest velocity. The perforations stabilize the burn rate because as the outside burns inward (thus shrinking the burning surface area) the inside is burning outward (thus increasing the burning surface area, but faster, so as to fill up the increasing volume of barrel presented by the departing projectile).[22] Fast-burning pistol powders are made by extruding shapes with more area such as flakes or by flattening the spherical granules. Drying is usually performed under a vacuum. The solvents are condensed and recycled. The granules are also coated with graphite to prevent static electricity sparks from causing undesired ignitions.[23] +Faster-burning propellants generate higher temperatures and higher pressures, however they also increase wear on gun barrels. +Smokeless propellant components[edit] +The propellant formulations may contain various energetic and auxiliary components: +Propellants: +Nitrocellulose, an energetic component of most smokeless propellants[24] +Nitroglycerin, an energetic component of double-base and triple-base formulations[24] +Nitroguanidine, a component of triple-base formulations[24] +D1NA (bis-nitroxyethylnitramine)[25] +Fivonite (tetramethylolcyclopentanone)[25] +DGN (di-ethylene glycol dinitrate)[26] +Acetyl cellulose[27] +Deterrents, (or moderants), to slow the burning rate +Centralites (symmetrical diphenyl urea—primarily diethyl or dimethyl)[28][29] +Dibutyl phthalate[24][29] +Dinitrotoluene (toxic, carcinogenic, and obsolete)[24][30] +Akardite (asymmetrical diphenyl urea)[26] +ortho-tolyl urethane[31] +Polyester adipate +Camphor (obsolete)[29] +Stabilizers, to prevent or slow down self-decomposition[32] +Diphenylamine[33] +Petroleum jelly[34] +Calcium carbonate[24] +Magnesium oxide[26] +Sodium bicarbonate[27] +beta-naphthol methyl ether[31] +Amyl alcohol (obsolete)[35] +Aniline (obsolete)[36] +Decoppering additives, to hinder the buildup of copper residues from the gun barrel rifling +Tin metal and compounds (e.g., tin dioxide)[24][37] +Bismuth metal and compounds (e.g., bismuth trioxide, bismuth subcarbonate, bismuth nitrate, bismuth antimonide); the bismuth compounds are favored as copper dissolves in molten bismuth, forming brittle and easily removable alloy +Lead foil and lead compounds, phased out due to toxicity[25] +Flash reducers, to reduce the brightness of the muzzle flash (all have a disadvantage: the production of smoke)[38] +Potassium chloride[39] +Potassium nitrate +Potassium sulfate[24][37] +Potassium hydrogen tartarate (a byproduct of wine production formerly used by French artillery)[39] +Wear reduction additives, to lower the wear of the gun barrel liners[40] +Wax +Talc +Titanium dioxide +Polyurethane jackets over the powder bags, in large guns +Other additives +Ethyl acetate, a solvent for manufacture of spherical powder[34] +Rosin, a surfactant to hold the grain shape of spherical powder +Graphite, a lubricant to cover the grains and prevent them from sticking together, and to dissipate static electricity[23] +Manufacturing[edit] +This section describes procedures used in the United States. See Cordite for alternative procedures formerly used in the United Kingdom. +The United States Navy manufactured single-base tubular powder for naval artillery at Indian Head, Maryland, beginning in 1900. Similar procedures were used for United States Army production at Picatinny Arsenal beginning in 1907[18] and for manufacture of smaller grained Improved Military Rifle (IMR) powders after 1914. Short-fiber cotton linter was boiled in a solution of sodium hydroxide to remove vegetable waxes, and then dried before conversion to nitrocellulose by mixing with concentrated nitric and sulfuric acids. Nitrocellulose still resembles fibrous cotton at this point in the manufacturing process, and was typically identified as pyrocellulose because it would spontaneously ignite in air until unreacted acid was removed. The term guncotton was also used; although some references identify guncotton as a more extensively nitrated and refined product used in torpedo and mine warheads prior to use of TNT.[41] +Unreacted acid was removed from pyrocellulose pulp by a multistage draining and water washing process similar to that used in paper mills during production of chemical woodpulp. Pressurized alcohol removed remaining water from drained pyrocellulose prior to mixing with ether and diphenylamine. The mixture was then fed through a press extruding a long turbular cord form to be cut into grains of the desired length.[42] +Alcohol and ether were then evaporated from "green" powder grains to a remaining solvent concentration between 3 percent for rifle powders and 7 percent for large artillery powder grains. Burning rate is inversely proportional to solvent concentration. Grains were coated with electrically conductive graphite to minimize generation of static electricity during subsequent blending. "Lots" containing more than ten tonnes of powder grains were mixed through a tower arrangement of blending hoppers to minimize ballistic differences. Each blended lot was then subjected to testing to determine the correct loading charge for the desired performance.[43][44] +Military quantities of old smokeless powder were sometimes reworked into new lots of propellants.[45] Through the 1920s Dr. Fred Olsen worked at Picatinny Arsenal experimenting with ways to salvage tons of single-base cannon powder manufactured for World War I. Dr. Olsen was employed by Western Cartridge Company in 1929 and developed a process for manufacturing spherical smokeless powder by 1933.[46] Reworked powder or washed pyrocellulose can be dissolved in ethyl acetate containing small quantities of desired stabilizers and other additives. The resultant syrup, combined with water and surfactants, can be heated and agitated in a pressurized container until the syrup forms an emulsion of small spherical globules of the desired size. Ethyl acetate distills off as pressure is slowly reduced to leave small spheres of nitrocellulose and additives. The spheres can be subsequently modified by adding nitroglycerine to increase energy, flattening between rollers to a uniform minimum dimension, coating with phthalate deterrents to retard ignition, and/or glazing with graphite to improve flow characteristics during blending.[47][48] +Modern smokeless powder is produced in the United States by St. Marks Powder, Inc. owned by General Dynamics.[49] +Flashless propellant[edit] +Muzzle flash is the light emitted in the vicinity of the muzzle by the hot propellant gases and the chemical reactions that follow as the gases mix with the surrounding air. Before projectiles exit a slight pre-flash may occur from gases leaking past the projectiles. Following muzzle exit the heat of gases is usually sufficient to emit visible radiation – the primary flash. The gases expand but as they pass through the Mach disc they are re-compressed to produce an intermediate flash. Hot combustible gases (e.g. hydrogen and carbon-monoxide) may follow when they mix with oxygen in the surrounding air to produce the secondary flash, the brightest. The secondary flash does not usually occur with small-arms.[50] +Nitrocellulose contains insufficient oxygen to completely oxidize its carbon and hydrogen. The oxygen deficit is increased by addition of graphite and organic stabilizers. Products of combustion within the gun barrel include flammable gasses like hydrogen and carbon monoxide. At high temperature, these flammable gasses will ignite when turbulently mixed with atmospheric oxygen beyond the muzzle of the gun. During night engagements the flash produced by ignition can reveal the location of the gun to enemy forces[51] and cause temporary night-blindness among the gun crew by photo-bleaching visual purple.[52] +Flash suppressors are commonly used on small arms to reduce the flash signature, but this approach is not practical for artillery. Artillery muzzle flash up to 150 feet (46 m) from the muzzle has been observed, and can be reflected off clouds and be visible for distances up to 30 miles (48 km).[51] For artillery the most effective method is a propellant that produces a large proportion of inert nitrogen at relatively low temperatures that dilutes the combustible gases. Triple based propellants are used for this because of the nitrogen in the nitroguandine.[53] +Before the use of triple based propellants the usual method of flash reduction was to add inorganic salts like potassium chloride so their specific heat capacity might reduce the temperature of combustion gasses and their finely divided particulate smoke might block visible wavelengths of radiant energy of combustion.[39] +See also[edit] +Portal icon Pyrotechnics portal +Antique guns +Ballistite +Cordite +Firearms +Gunpowder +Nitrocellulose +Small arms +Brown-brown – a drug created by mixing cocaine with cartridge powder +References[edit] +Notes[edit] +Jump up ^ Hatcher, Julian S. and Barr, Al Handloading Hennage Lithograph Company (1951) p.34 +Jump up ^ Fairfield, A. P., CDR USN Naval Ordnance Lord Baltimore Press (1921) p.44 +^ Jump up to: a b c d e Sharpe, Philip B. Complete Guide to Handloading 3rd Edition (1953) Funk & Wagnalls pp.146-149 +Jump up ^ seegunpowder +Jump up ^ Sharpe, Philip B. Complete Guide To Handloading (1953) Funk & Wagnalls p.60 +Jump up ^ Davis, William C., Jr. Handloading (1981) National Rifle Association p.21 +Jump up ^ Davis, Tenney L. The Chemistry of Powder & Explosives (1943) page 195 +Jump up ^ Davis, William C., Jr. Handloading National Rifle Association of America (1981) p.28 +^ Jump up to: a b c Sharpe, Philip B. Complete Guide to Handloading 3rd Edition (1953) Funk & Wagnalls pp.141-144 +Jump up ^ Hogg, Oliver F. G. Artillery: Its Origin, Heyday and Decline (1969) p.138-139 +^ Jump up to: a b Davis, Tenney L. The Chemistry of Powder & Explosives (1943) pages 289–292 +Jump up ^ Hogg, Oliver F. G. Artillery: Its Origin, Heyday and Decline (1969) p.139 +^ Jump up to: a b Hogg, Oliver F. G. Artillery: Its Origin, Heyday and Decline (1969) p.140 +Jump up ^ U.S. Patent 430,212 – Manufacture of explosive – H. S. Maxim +Jump up ^ Hogg, Oliver F. G. Artillery: Its Origin, Heyday and Decline (1969) p.141 +^ Jump up to: a b Davis, Tenney L. The Chemistry of Powder & Explosives (1943) pages 296-297 +Jump up ^ "Laflin & Rand Powder Company". DuPont. Retrieved 2012-02-24. +^ Jump up to: a b Davis, Tenny L. The Chemistry of Powder & Explosives (1943) p.297 +Jump up ^ Davis, Tenny L. The Chemistry of Powder & Explosives (1943) p.298 +Jump up ^ Fairfield, A. P., CDR USN Naval Ordnance Lord Baltimore Press (1921) p.28 +Jump up ^ Davis, Tenny L. The Chemistry of Powder & Explosives (1943) p. 310 +Jump up ^ Fairfield, A. P., CDR USN Naval Ordnance Lord Baltimore Press (1921) pp.41–43 +^ Jump up to: a b Davis, Tenny L. The Chemistry of Powder & Explosives (1943) p.306 +^ Jump up to: a b c d e f g h Campbell, John Naval Weapons of World War Two (1985) p. 5 +^ Jump up to: a b c Campbell, John Naval Weapons of World War Two (1985) p. 104 +^ Jump up to: a b c Campbell, John Naval Weapons of World War Two (1985) p. 221 +^ Jump up to: a b Campbell, John Naval Weapons of World War Two (1985) p. 318 +Jump up ^ Davis, Tenny L. The Chemistry of Powder & Explosives (1943) pages 317–320 +^ Jump up to: a b c Davis, William C., Jr. Handloading National Rifle Association of America (1981) p.30 +Jump up ^ Davis, William C., Jr. Handloading National Rifle Association of America (1981) p.31 +^ Jump up to: a b Campbell, John Naval Weapons of World War Two (1985) p. 174 +Jump up ^ Davis, Tenny L. The Chemistry of Powder & Explosives (1943) pages 307–311 +Jump up ^ Davis, Tenny L. The Chemistry of Powder & Explosives (1943) p. 302 +^ Jump up to: a b Davis, Tenny L. The Chemistry of Powder & Explosives (1943) p. 296 +Jump up ^ Davis, Tenny L. The Chemistry of Powder & Explosives (1943) p. 307 +Jump up ^ Davis, Tenny L. The Chemistry of Powder & Explosives (1943) p. 308 +^ Jump up to: a b Davis, William C., Jr. Handloading National Rifle Association of America (1981) p.32 +Jump up ^ Davis, Tenny L. The Chemistry of Powder & Explosives (1943) pages 322–327 +^ Jump up to: a b c Davis, Tenny L. The Chemistry of Powder & Explosives (1943) pages 323–327 +Jump up ^ "USA 16"/50 (40.6 cm) Mark 7". NavWeaps. 2008-11-03. Retrieved 2008-12-05. +Jump up ^ Fairfield, A. P., CDR USN Naval Ordnance Lord Baltimore Press (1921) pages 28–31 +Jump up ^ Fairfield, A. P., CDR USN Naval Ordnance Lord Baltimore Press (1921) pages 31–35 +Jump up ^ Fairfield, A. P., CDR USN Naval Ordnance Lord Baltimore Press (1921) pages 35–41 +Jump up ^ Davis, Tenny L. The Chemistry of Powder & Explosives (1943) pages 293 & 306 +Jump up ^ Fairfield, A. P., CDR USN Naval Ordnance Lord Baltimore Press (1921) p.39 +Jump up ^ Matunas, E. A. Winchester-Western Ball Powder Loading Data Olin Corporation (1978) p.3 +Jump up ^ Davis, Tenny L. The Chemistry of Powder & Explosives (1943) pages 328–330 +Jump up ^ Wolfe, Dave Propellant Profiles Volume 1 Wolfe Publishing Company (1982) pages 136–137 +Jump up ^ General Dynamics Commercial Powder Applications. +Jump up ^ Moss G. M., Leeming D. W., Farrar C. L. Military Ballisitcs (1969) pages 55–56 +^ Jump up to: a b Davis, Tenny L. The Chemistry of Powder & Explosives (1943) pages 322–323 +Jump up ^ Milner p.68 +Jump up ^ Moss G. M., Leeming D. W., Farrar C. L. Military Ballisitcs (1969) pages 59–60 +Sources[edit] +Campbell, John (1985). Naval Weapons of World War Two. Naval Institute Press. ISBN 0-87021-459-4. +Davis, Tenney L. (1943). The Chemistry of Powder & Explosives (Angriff Press [1992] ed.). John Wiley & Sons Inc. ISBN 0-913022-00-4. +Davis, William C., Jr. (1981). Handloading. National Rifle Association of America. ISBN 0-935998-34-9. +Fairfield, A. P., CDR USN (1921). Naval Ordnance. Lord Baltimore Press. +Hatcher, Julian S. and Barr, Al (1951). Handloading. Hennage Lithograph Company. +Matunas, E. A. (1978). Winchester-Western Ball Powder Loading Data. Olin Corporation. +Milner, Marc (1985). North Atlantic Run. Naval Institute Press. ISBN 0-87021-450-0. +Wolfe, Dave (1982). Propellant Profiles Volume 1. Wolfe Publishing Company. ISBN 0-935632-10-7. +External links[edit] +The Manufacture of Smokeless Powders and their Forensic Analysis: A Brief Review – Robert M. Heramb, Bruce R. McCord +Hudson Maxim papers (1851-1925) at Hagley Museum and Library. Collection includes material relating to Maxim's patent on the process of making smokeless powder. +Categories: CorditeExplosivesFirearm propellantsSolid fuels +Navigation menu +Create accountLog inArticleTalkReadEditView history + +Main page +Contents +Featured content +Current events +Random article +Donate to Wikipedia +Wikimedia Shop +Interaction +Help +About Wikipedia +Community portal +Recent changes +Contact page +Tools +What links here +Related changes +Upload file +Special pages +Permanent link +Page information +Wikidata item +Cite this page +Print/export +Create a book +Download as PDF +Printable version +Languages +العربية +Български +Dansk +Deutsch +Español +فارسی +Français +Bahasa Indonesia +Íslenska +Italiano +עברית +Nederlands +日本語 +Polski +Português +Русский +Svenska +தமிழ் +中文 +Edit links +This page was last modified on 25 July 2014 at 22:33. +Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Terms of Use and Privacy Policy. Wikipedia® is a registered trademark of the Wikimedia Foundation, Inc., a non-profit organization. +Privacy policyAbout WikipediaDisclaimersContact WikipediaDevelopersMobile viewWikimedia Foundation Powered by MediaWiki + + +Deflagration +From Wikipedia, the free encyclopedia + +[hide]This article has multiple issues. Please help improve it or discuss these issues on the talk page. +This article needs additional citations for verification. (April 2011) +This article may be too technical for most readers to understand. (December 2013) + +A log in a fireplace. +Deflagration [1] (Lat: de + flagrare, "to burn down") is a term describing subsonic combustion propagating through heat transfer; hot burning material heats the next layer of cold material and ignites it. Most "fire" found in daily life, from flames to explosions, is deflagration. Deflagration is different from detonation, which is supersonic and propagates through shock. +Contents [hide] +1 Applications +2 Oil/wax fire and water +3 Flame physics +4 Damaging deflagration events +5 See also +6 References +Applications[edit] +In engineering applications, deflagrations are easier to control than detonations. Consequently, they are better suited when the goal is to move an object (a bullet in a gun, or a piston in an internal combustion engine) with the force of the expanding gas. Typical examples of deflagrations are the combustion of a gas-air mixture in a gas stove or a fuel-air mixture in an internal combustion engine, and the rapid burning of gunpowder in a firearm or of pyrotechnic mixtures in fireworks. Deflagration systems and products can also be used in mining, demolition and stone quarrying via gas pressure blasting as a beneficial alternative to high explosives. +Oil/wax fire and water[edit] +Adding water to a burning hydrocarbon such as oil or wax produces a deflagration. The water boils rapidly and ejects the burning material as a fine spray of droplets. A deflagration then occurs as the fine mist of oil ignites and burns extremely rapidly. These are particularly common in chip pan fires, which are responsible for one in five household fires in Britain.[2] +Flame physics[edit] +The underlying flame physics can be understood with the help of an idealized model consisting of a uniform one-dimensional tube of unburnt and burned gaseous fuel, separated by a thin transitional region of width \delta\; in which the burning occurs. The burning region is commonly referred to as the flame or flame front. In equilibrium, thermal diffusion across the flame front is balanced by the heat supplied by burning. +There are two characteristic timescales which are important here. The first is the thermal diffusion timescale \tau_d\;, which is approximately equal to +\tau_d \simeq \delta^2 / \kappa, +where \kappa \; is the thermal diffusivity. The second is the burning timescale \tau_b that strongly decreases with temperature, typically as +\tau_b\propto \exp[\Delta U/(k_B T_f)], +where \Delta U\; is the activation barrier for the burning reaction and T_f\; is the temperature developed as the result of burning; the value of this so-called "flame temperature" can be determined from the laws of thermodynamics. +For a stationary moving deflagration front, these two timescales must be equal: the heat generated by burning is equal to the heat carried away by heat transfer. This makes it possible to calculate the characteristic width \delta\; of the flame front: +\tau_b = \tau_d\;, +thus + \delta \simeq \sqrt {\kappa \tau_b} . +Now, the thermal flame front propagates at a characteristic speed S_l\;, which is simply equal to the flame width divided by the burn time: +S_l \simeq \delta / \tau_b \simeq \sqrt {\kappa / \tau_b} . +This simplified model neglects the change of temperature and thus the burning rate across the deflagration front. This model also neglects the possible influence of turbulence. As a result, this derivation gives only the laminar flame speed -- hence the designation S_l\;. +Damaging deflagration events[edit] +Damage to buildings, equipment and people can result from a large-scale, short-duration deflagration. The potential damage is primarily a function of the total amount of fuel burned in the event (total energy available), the maximum flame velocity that is achieved, and the manner in which the expansion of the combustion gases is contained. +In free-air deflagrations, there is a continuous variation in deflagration effects relative to the maximum flame velocity. When flame velocities are low, the effect of a deflagration is to release heat. Some authors use the term flash fire to describe these low-speed deflagrations. At flame velocities near the speed of sound, the energy released is in the form of pressure and the results resemble a detonation. Between these extremes both heat and pressure are released. +When a low-speed deflagration occurs within a closed vessel or structure, pressure effects can produce damage due to expansion of gases as a secondary effect. The heat released by the deflagration causes the combustion gases and excess air to expand thermally. The net result is that the volume of the vessel or structure must expand to accommodate the hot combustion gases, or the vessel must be strong enough to withstand the additional internal pressure, or it fails, allowing the gases to escape. The risks of deflagration inside waste storage drums is a growing concern in storage facilities. +See also[edit] + Look up deflagration in Wiktionary, the free dictionary. +Pressure piling +References[edit] +Jump up ^ "Glossary D-H". Hutchisonrodway.co.nz. Retrieved 2013-12-29. +Jump up ^ UK Fire Service advice on chip pan fires +Categories: Explosives +Navigation menu +Create accountLog inArticleTalkReadEditView history + +Main page +Contents +Featured content +Current events +Random article +Donate to Wikipedia +Wikimedia Shop +Interaction +Help +About Wikipedia +Community portal +Recent changes +Contact page +Tools +What links here +Related changes +Upload file +Special pages +Permanent link +Page information +Wikidata item +Cite this page +Print/export +Create a book +Download as PDF +Printable version +Languages +Català +Čeština +Deutsch +Español +Français +Italiano +Lietuvių +Nederlands +Norsk bokmål +Polski +Português +Русский +Српски / srpski +Svenska +Edit links +This page was last modified on 2 October 2014 at 16:44. +Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Terms of Use and Privacy Policy. Wikipedia® is a registered trademark of the Wikimedia Foundation, Inc., a non-profit organization. +Privacy policyAbout WikipediaDisclaimersContact WikipediaDevelopersMobile viewWikimedia Foundation Powered by MediaWiki + + +United Kingdom +From Wikipedia, the free encyclopedia +This article is about the sovereign state. For the island, see Great Britain. For other uses, see United Kingdom (disambiguation) and UK (disambiguation). +Page semi-protected +United Kingdom of Great +Britain and Northern Ireland[show] + +A flag featuring both cross and saltire in red, white and blue Coat of arms containing shield and crown in centre, flanked by lion and unicorn +Flag Royal coat of arms[nb 1] +Anthem: "God Save the Queen"[nb 2] +MENU0:00 +Two islands to the north-west of continental Europe. Highlighted are the larger island and the north-eastern fifth of the smaller island to the west. +Location of the United Kingdom (dark green) +– in Europe (green & dark grey) +– in the European Union (green) +Capital +and largest city London +51°30′N 0°7′W +Official language +and national language English +Recognised regional +languages Cornish, Irish, Scots, Scottish Gaelic, Ulster-Scots, Welsh[nb 3] +Ethnic groups (2011) 87.1% White +7.0% Asian +3.0% Black +2.0% Mixed +0.9% Other +Demonym British, Briton +Government Unitary parliamentary constitutional monarchy + - Monarch Elizabeth II + - Prime Minister David Cameron +Legislature Parliament + - Upper house House of Lords + - Lower house House of Commons +Formation + - Acts of Union 1707 1 May 1707 + - Acts of Union 1800 1 January 1801 + - Irish Free State Constitution Act 5 December 1922 +Area + - Total 243,610 km2 (80th) +94,060 sq mi + - Water (%) 1.34 +Population + - 2013 estimate 64,100,000[3] (22nd) + - 2011 census 63,181,775[4] (22nd) + - Density 255.6/km2 (51st) +661.9/sq mi +GDP (PPP) 2014 estimate + - Total $2.435 trillion[5] (10th) + - Per capita $37,744[5] (27th) +GDP (nominal) 2014 estimate + - Total $2.848 trillion[5] (6th) + - Per capita $44,141[5] (22nd) +Gini (2012) positive decrease 32.8[6] +medium · 33rd +HDI (2013) Steady 0.892[7] +very high · 14th +Currency Pound sterling (GBP) +Time zone GMT (UTC​) + - Summer (DST) BST (UTC+1) +Date format dd/mm/yyyy (AD) +Drives on the left +Calling code +44 +ISO 3166 code GB +Internet TLD .uk +The United Kingdom of Great Britain and Northern Ireland Listeni/ɡreɪt ˈbrɪt(ə)n ənd ˈnɔːð(ə)n ˈʌɪələnd/, commonly known as the United Kingdom (UK) or Britain, is a sovereign state in Europe. Lying off the north-western coast of the European mainland, the country includes the island of Great Britain (a term also applied loosely to refer to the whole country),[8] the north-eastern part of the island of Ireland, and many smaller islands. Northern Ireland is the only part of the UK that shares a land border with another state: the Republic of Ireland.[nb 4] Apart from this land border, the UK is surrounded by the Atlantic Ocean, with the North Sea in the east and the English Channel in the south. The Irish Sea lies between Great Britain and Ireland. The UK has an area of 243,610 square kilometres (94,060 sq mi), making it the 78th-largest sovereign state in the world and the 11th-largest in Europe. +The United Kingdom is the 22nd-most populous country, with an estimated 64.1 million inhabitants.[3] It is a constitutional monarchy with a parliamentary system of governance.[9][10] Its capital city is London, an important global city and financial centre with the fourth-largest urban area in Europe.[11] The current monarch—since 6 February 1952—is Queen Elizabeth II. The UK consists of four countries: England, Scotland, Wales, and Northern Ireland.[12] The latter three have devolved administrations,[13] each with varying powers,[14][15] based in their capitals, Edinburgh, Cardiff, and Belfast, respectively. Guernsey, Jersey, and the Isle of Man are not part of the United Kingdom, being Crown dependencies with the British Government responsible for defence and international representation.[16] The UK has fourteen Overseas Territories,[17] including the disputed Falkland Islands, Gibraltar, and Indian Ocean Territory. +The relationships among the countries of the United Kingdom have changed over time. Wales was annexed by the Kingdom of England under the Acts of Union of 1536 and 1543. A treaty between England and Scotland resulted in a unified Kingdom of Great Britain in 1707, which in 1801, merged with the Kingdom of Ireland to form the United Kingdom of Great Britain and Ireland. In 1922, five-sixths of Ireland seceded from the country, leaving the present formulation of the United Kingdom of Great Britain and Northern Ireland.[nb 5] British Overseas Territories, formerly colonies, are the remnants of the British Empire which, at its height in the late 19th and early 20th centuries, encompassed almost a quarter of the world's land mass and was the largest empire in history. British influence can be observed in the language, culture, and legal systems of many of its former colonies. +The United Kingdom is a developed country and has the world's sixth-largest economy by nominal GDP and tenth-largest by purchasing power parity. The country is considered to have a high-income economy and is categorised as very high in the Human Development Index, currently ranking 14th in the world. It was the world's first industrialised country and the world's foremost power during the 19th and early 20th centuries.[18][19] The UK remains a great power with considerable economic, cultural, military, scientific, and political influence internationally.[20][21] It is a recognised nuclear weapons state and its military expenditure ranks fifth or sixth in the world.[22][23] The UK has been a permanent member of the United Nations Security Council since its first session in 1946. It has been a member state of the European Union (EU) and its predecessor, the European Economic Community (EEC), since 1973; it is also a member of the Commonwealth of Nations, the Council of Europe, the G7, the G8, the G20, NATO, the Organisation for Economic Co-operation and Development (OECD), and the World Trade Organization (WTO). +Contents [hide] +1 Etymology and terminology +2 History +2.1 Before 1707 +2.2 Since the Acts of Union of 1707 +3 Geography +3.1 Climate +3.2 Administrative divisions +4 Dependencies +5 Politics +5.1 Government +5.2 Devolved administrations +5.3 Law and criminal justice +5.4 Foreign relations +5.5 Military +6 Economy +6.1 Science and technology +6.2 Transport +6.3 Energy +7 Demographics +7.1 Ethnic groups +7.2 Languages +7.3 Religion +7.4 Migration +7.5 Education +7.6 Healthcare +8 Culture +8.1 Literature +8.2 Music +8.3 Visual art +8.4 Cinema +8.5 Media +8.6 Philosophy +8.7 Sport +8.8 Symbols +9 See also +10 Notes +11 References +12 Further reading +13 External links +Etymology and terminology +See also: Britain (placename) and Terminology of the British Isles +The 1707 Acts of Union declared that the kingdoms of England and Scotland were "United into One Kingdom by the Name of Great Britain", though the new state is also referred to in the Acts as the "Kingdom of Great Britain", "United Kingdom of Great Britain" and "United Kingdom".[24][25][nb 6] However, the term "united kingdom" is only found in informal use during the 18th century and the country was only occasionally referred to as he "United Kingdom of Great Britain".[26] The Acts of Union 1800 united the Kingdom of Great Britain and the Kingdom of Ireland in 1801, forming the United Kingdom of Great Britain and Ireland. The name "United Kingdom of Great Britain and Northern Ireland" was adopted following the independence of the Irish Free State, and the partition of Ireland, in 1922, which left Northern Ireland as the only part of the island of Ireland within the UK.[27] +Although the United Kingdom, as a sovereign state, is a country, England, Scotland, Wales, and to a lesser degree, Northern Ireland, are also regarded as countries, though they are not sovereign states.[28][29] Scotland, Wales and Northern Ireland have devolved self-government.[30][31] The British Prime Minister's website has used the phrase "countries within a country" to describe the United Kingdom.[12] Some statistical summaries, such as those for the twelve NUTS 1 regions of the UK, also refer to Scotland, Wales and Northern Ireland as "regions".[32][33] Northern Ireland is also referred to as a "province".[28][34] With regard to Northern Ireland, the descriptive name used "can be controversial, with the choice often revealing one's political preferences."[35] +The term Britain is often used as synonym for the United Kingdom. The term Great Britain, by contrast, refers conventionally to the island of Great Britain, or politically to England, Scotland and Wales in combination.[36][37][38] However, it is sometimes used as a loose synonym for the United Kingdom as a whole.[39][40] GB and GBR are the standard country codes for the United Kingdom (see ISO 3166-2 and ISO 3166-1 alpha-3) and are consequently used by international organisations to refer to the United Kingdom. Additionally, the United Kingdom's Olympic team competes under the name "Great Britain" or "Team GB".[41][42] +The adjective British is commonly used to refer to matters relating to the United Kingdom. The term has no definite legal connotation, but is used in law to refer to UK citizenship and matters to do with nationality.[43] People of the United Kingdom use a number of different terms to describe their national identity and may identify themselves as being British; or as being English, Scottish, Welsh, Northern Irish, or Irish;[44] or as being both.[45] +In 2006, a new design of British passport was introduced. Its first page shows the long form name of the state in English, Welsh and Scottish Gaelic.[46] In Welsh, the long form name of the state is "Teyrnas Unedig Prydain Fawr a Gogledd Iwerddon" with "Teyrnas Unedig" being used as a short form name on government websites.[47] In Scottish Gaelic, the long form is "Rìoghachd Aonaichte Bhreatainn is Èireann a Tuath" and the short form "Rìoghachd Aonaichte". +History +See also: History of the British Isles +Before 1707 + +Stonehenge, in Wiltshire, was erected around 2500 BC. +Main articles: History of England, History of Wales, History of Scotland, History of Ireland and History of the formation of the United Kingdom +Settlement by anatomically modern humans of what was to become the United Kingdom occurred in waves beginning by about 30,000 years ago.[48] By the end of the region's prehistoric period, the population is thought to have belonged, in the main, to a culture termed Insular Celtic, comprising Brythonic Britain and Gaelic Ireland.[49] The Roman conquest, beginning in 43 AD, and the 400-year rule of southern Britain, was followed by an invasion by Germanic Anglo-Saxon settlers, reducing the Brythonic area mainly to what was to become Wales and the historic Kingdom of Strathclyde.[50] Most of the region settled by the Anglo-Saxons became unified as the Kingdom of England in the 10th century.[51] Meanwhile, Gaelic-speakers in north west Britain (with connections to the north-east of Ireland and traditionally supposed to have migrated from there in the 5th century)[52][53] united with the Picts to create the Kingdom of Scotland in the 9th century.[54] +In 1066, the Normans invaded England from France and after its conquest, seized large parts of Wales, conquered much of Ireland and were invited to settle in Scotland, bringing to each country feudalism on the Northern French model and Norman-French culture.[55] The Norman elites greatly influenced, but eventually assimilated with, each of the local cultures.[56] Subsequent medieval English kings completed the conquest of Wales and made an unsuccessful attempt to annex Scotland. Thereafter, Scotland maintained its independence, albeit in near-constant conflict with England. The English monarchs, through inheritance of substantial territories in France and claims to the French crown, were also heavily involved in conflicts in France, most notably the Hundred Years War, while the Kings of Scots were in an alliance with the French during this period.[57] + +The Bayeux Tapestry depicts the Battle of Hastings and the events leading to it. +The early modern period saw religious conflict resulting from the Reformation and the introduction of Protestant state churches in each country.[58] Wales was fully incorporated into the Kingdom of England,[59] and Ireland was constituted as a kingdom in personal union with the English crown.[60] In what was to become Northern Ireland, the lands of the independent Catholic Gaelic nobility were confiscated and given to Protestant settlers from England and Scotland.[61] +In 1603, the kingdoms of England, Scotland and Ireland were united in a personal union when James VI, King of Scots, inherited the crowns of England and Ireland and moved his court from Edinburgh to London; each country nevertheless remained a separate political entity and retained its separate political, legal, and religious institutions.[62][63] +In the mid-17th century, all three kingdoms were involved in a series of connected wars (including the English Civil War) which led to the temporary overthrow of the monarchy and the establishment of the short-lived unitary republic of the Commonwealth of England, Scotland and Ireland.[64][65] +Although the monarchy was restored, it ensured (with the Glorious Revolution of 1688) that, unlike much of the rest of Europe, royal absolutism would not prevail, and a professed Catholic could never accede to the throne. The British constitution would develop on the basis of constitutional monarchy and the parliamentary system.[66] During this period, particularly in England, the development of naval power (and the interest in voyages of discovery) led to the acquisition and settlement of overseas colonies, particularly in North America.[67][68] +Since the Acts of Union of 1707 +Main article: History of the United Kingdom + +The Treaty of Union led to a single united kingdom encompassing all Great Britain. +On 1 May 1707, the united kingdom of Great Britain came into being, the result of Acts of Union being passed by the parliaments of England and Scotland to ratify the 1706 Treaty of Union and so unite the two kingdoms.[69][70][71] +In the 18th century, cabinet government developed under Robert Walpole, in practice the first prime minister (1721–1742). A series of Jacobite Uprisings sought to remove the Protestant House of Hanover from the British throne and restore the Catholic House of Stuart. The Jacobites were finally defeated at the Battle of Culloden in 1746, after which the Scottish Highlanders were brutally suppressed. The British colonies in North America that broke away from Britain in the American War of Independence became the United States of America in 1782. British imperial ambition turned elsewhere, particularly to India.[72] +During the 18th century, Britain was involved in the Atlantic slave trade. British ships transported an estimated 2 million slaves from Africa to the West Indies before banning the trade in 1807.[73] The term 'United Kingdom' became official in 1801 when the parliaments of Britain and Ireland each passed an Act of Union, uniting the two kingdoms and creating the United Kingdom of Great Britain and Ireland.[74] +In the early 19th century, the British-led Industrial Revolution began to transform the country. It slowly led to a shift in political power away from the old Tory and Whig landowning classes towards the new industrialists. An alliance of merchants and industrialists with the Whigs would lead to a new party, the Liberals, with an ideology of free trade and laissez-faire. In 1832 Parliament passed the Great Reform Act, which began the transfer of political power from the aristocracy to the middle classes. In the countryside, enclosure of the land was driving small farmers out. Towns and cities began to swell with a new urban working class. Few ordinary workers had the vote, and they created their own organisations in the form of trade unions. +Painting of a bloody battle. Horses and infantry fight or lie on grass. +The Battle of Waterloo marked the end of the Napoleonic Wars and the start of Pax Britannica. +After the defeat of France in the Revolutionary and Napoleonic Wars (1792–1815), the UK emerged as the principal naval and imperial power of the 19th century (with London the largest city in the world from about 1830).[75] Unchallenged at sea, British dominance was later described as Pax Britannica.[76][77] By the time of the Great Exhibition of 1851, Britain was described as the "workshop of the world".[78] The British Empire was expanded to include India, large parts of Africa and many other territories throughout the world. Alongside the formal control it exerted over its own colonies, British dominance of much of world trade meant that it effectively controlled the economies of many countries, such as China, Argentina and Siam.[79][80] Domestically, political attitudes favoured free trade and laissez-faire policies and a gradual widening of the voting franchise. During the century, the population increased at a dramatic rate, accompanied by rapid urbanisation, causing significant social and economic stresses.[81] After 1875, the UK's industrial monopoly was challenged by Germany and the USA. To seek new markets and sources of raw materials, the Conservative Party under Disraeli launched a period of imperialist expansion in Egypt, South Africa and elsewhere. Canada, Australia and New Zealand became self-governing dominions.[82] +Social reform and home rule for Ireland were important domestic issues after 1900. The Labour Party emerged from an alliance of trade unions and small Socialist groups in 1900, and suffragettes campaigned for women's right to vote before 1914. +Black-and-white photo of two dozen men in military uniforms and metal helmets sitting or standing in a muddy trench. +Infantry of the Royal Irish Rifles during the Battle of the Somme. More than 885,000 British soldiers died on the battlefields of World War I. +The UK fought with France, Russia and (after 1917) the US, against Germany and its allies in World War I (1914–18).[83] The UK armed forces were engaged across much of the British Empire and in several regions of Europe, particularly on the Western front.[84] The high fatalities of trench warfare caused the loss of much of a generation of men, with lasting social effects in the nation and a great disruption in the social order. +After the war, the UK received the League of Nations mandate over a number of former German and Ottoman colonies. The British Empire reached its greatest extent, covering a fifth of the world's land surface and a quarter of its population.[85] However, the UK had suffered 2.5 million casualties and finished the war with a huge national debt.[84] The rise of Irish Nationalism and disputes within Ireland over the terms of Irish Home Rule led eventually to the partition of the island in 1921,[86] and the Irish Free State became independent with Dominion status in 1922. Northern Ireland remained part of the United Kingdom.[87] A wave of strikes in the mid-1920s culminated in the UK General Strike of 1926. The UK had still not recovered from the effects of the war when the Great Depression (1929–32) occurred. This led to considerable unemployment and hardship in the old industrial areas, as well as political and social unrest in the 1930s. A coalition government was formed in 1931.[88] +The UK entered World War II by declaring war on Germany in 1939, after it had invaded Poland and Czechoslovakia. In 1940, Winston Churchill became prime minister and head of a coalition government. Despite the defeat of its European allies in the first year of the war, the UK continued the fight alone against Germany. In 1940, the RAF defeated the German Luftwaffe in a struggle for control of the skies in the Battle of Britain. The UK suffered heavy bombing during the Blitz. There were also eventual hard-fought victories in the Battle of the Atlantic, the North Africa campaign and Burma campaign. UK forces played an important role in the Normandy landings of 1944, achieved with its ally the US. After Germany's defeat, the UK was one of the Big Three powers who met to plan the post-war world; it was an original signatory to the Declaration of the United Nations. The UK became one of the five permanent members of the United Nations Security Council. However, the war left the UK severely weakened and depending financially on Marshall Aid and loans from the United States.[89] +Map of the world. Canada, the eastern United States, countries in east Africa, India, most of Australasia and some other countries are highlighted in pink. +Territories that were at one time part of the British Empire. Current British Overseas Territories are underlined in red. +In the immediate post-war years, the Labour government initiated a radical programme of reforms, which had a significant effect on British society in the following decades.[90] Major industries and public utilities were nationalised, a Welfare State was established, and a comprehensive, publicly funded healthcare system, the National Health Service, was created.[91] The rise of nationalism in the colonies coincided with Britain's now much-diminished economic position, so that a policy of decolonisation was unavoidable. Independence was granted to India and Pakistan in 1947.[92] Over the next three decades, most colonies of the British Empire gained their independence. Many became members of the Commonwealth of Nations.[93] +Although the UK was the third country to develop a nuclear weapons arsenal (with its first atomic bomb test in 1952), the new post-war limits of Britain's international role were illustrated by the Suez Crisis of 1956. The international spread of the English language ensured the continuing international influence of its literature and culture. From the 1960s onward, its popular culture was also influential abroad. As a result of a shortage of workers in the 1950s, the UK government encouraged immigration from Commonwealth countries. In the following decades, the UK became a multi-ethnic society.[94] Despite rising living standards in the late 1950s and 1960s, the UK's economic performance was not as successful as many of its competitors, such as West Germany and Japan. In 1973, the UK joined the European Economic Community (EEC), and when the EEC became the European Union (EU) in 1992, it was one of the 12 founding members. + +After the two vetos of France in 1961 and 1967, the UK entered in the European Union in 1973. In 1975, 67% of Britons voted yes to the permanence in the European Union. +From the late 1960s, Northern Ireland suffered communal and paramilitary violence (sometimes affecting other parts of the UK) conventionally known as the Troubles. It is usually considered to have ended with the Belfast "Good Friday" Agreement of 1998.[95][96][97] +Following a period of widespread economic slowdown and industrial strife in the 1970s, the Conservative Government of the 1980s initiated a radical policy of monetarism, deregulation, particularly of the financial sector (for example, Big Bang in 1986) and labour markets, the sale of state-owned companies (privatisation), and the withdrawal of subsidies to others.[98] This resulted in high unemployment and social unrest, but ultimately also economic growth, particularly in the services sector. From 1984, the economy was helped by the inflow of substantial North Sea oil revenues.[99] +Around the end of the 20th century there were major changes to the governance of the UK with the establishment of devolved administrations for Scotland, Wales and Northern Ireland.[13][100] The statutory incorporation followed acceptance of the European Convention on Human Rights. The UK is still a key global player diplomatically and militarily. It plays leading roles in the EU, UN and NATO. However, controversy surrounds some of Britain's overseas military deployments, particularly in Afghanistan and Iraq.[101] +The 2008 global financial crisis severely affected the UK economy. The coalition government of 2010 introduced austerity measures intended to tackle the substantial public deficits which resulted.[102] In 2014 the Scottish Government held a referendum on Scottish independence, with the majority of voters rejecting the independence proposal and opting to remain within the United Kingdom.[103] +Geography +Main article: Geography of the United Kingdom +Map of United Kingdom showing hilly regions to north and west, and flattest region in the south-east. +The topography of the UK +The total area of the United Kingdom is approximately 243,610 square kilometres (94,060 sq mi). The country occupies the major part of the British Isles[104] archipelago and includes the island of Great Britain, the northeastern one-sixth of the island of Ireland and some smaller surrounding islands. It lies between the North Atlantic Ocean and the North Sea with the south-east coast coming within 22 miles (35 km) of the coast of northern France, from which it is separated by the English Channel.[105] In 1993 10% of the UK was forested, 46% used for pastures and 25% cultivated for agriculture.[106] The Royal Greenwich Observatory in London is the defining point of the Prime Meridian.[107] +The United Kingdom lies between latitudes 49° to 61° N, and longitudes 9° W to 2° E. Northern Ireland shares a 224-mile (360 km) land boundary with the Republic of Ireland.[105] The coastline of Great Britain is 11,073 miles (17,820 km) long.[108] It is connected to continental Europe by the Channel Tunnel, which at 31 miles (50 km) (24 miles (38 km) underwater) is the longest underwater tunnel in the world.[109] +England accounts for just over half of the total area of the UK, covering 130,395 square kilometres (50,350 sq mi).[110] Most of the country consists of lowland terrain,[106] with mountainous terrain north-west of the Tees-Exe line; including the Cumbrian Mountains of the Lake District, the Pennines and limestone hills of the Peak District, Exmoor and Dartmoor. The main rivers and estuaries are the Thames, Severn and the Humber. England's highest mountain is Scafell Pike (978 metres (3,209 ft)) in the Lake District. Its principal rivers are the Severn, Thames, Humber, Tees, Tyne, Tweed, Avon, Exe and Mersey.[106] +Scotland accounts for just under a third of the total area of the UK, covering 78,772 square kilometres (30,410 sq mi)[111] and including nearly eight hundred islands,[112] predominantly west and north of the mainland; notably the Hebrides, Orkney Islands and Shetland Islands. The topography of Scotland is distinguished by the Highland Boundary Fault – a geological rock fracture – which traverses Scotland from Arran in the west to Stonehaven in the east.[113] The faultline separates two distinctively different regions; namely the Highlands to the north and west and the lowlands to the south and east. The more rugged Highland region contains the majority of Scotland's mountainous land, including Ben Nevis which at 1,343 metres (4,406 ft) is the highest point in the British Isles.[114] Lowland areas – especially the narrow waist of land between the Firth of Clyde and the Firth of Forth known as the Central Belt – are flatter and home to most of the population including Glasgow, Scotland's largest city, and Edinburgh, its capital and political centre. +A view of Ben Nevis in the distance, fronted by rolling plains +Ben Nevis, in Scotland, is the highest point in the British Isles +Wales accounts for less than a tenth of the total area of the UK, covering 20,779 square kilometres (8,020 sq mi).[115] Wales is mostly mountainous, though South Wales is less mountainous than North and mid Wales. The main population and industrial areas are in South Wales, consisting of the coastal cities of Cardiff, Swansea and Newport, and the South Wales Valleys to their north. The highest mountains in Wales are in Snowdonia and include Snowdon (Welsh: Yr Wyddfa) which, at 1,085 metres (3,560 ft), is the highest peak in Wales.[106] The 14, or possibly 15, Welsh mountains over 3,000 feet (914 m) high are known collectively as the Welsh 3000s. Wales has over 2,704 kilometres (1,680 miles) of coastline.[116] Several islands lie off the Welsh mainland, the largest of which is Anglesey (Ynys Môn) in the northwest. +Northern Ireland, separated from Great Britain by the Irish Sea and North Channel, has an area of 14,160 square kilometres (5,470 sq mi) and is mostly hilly. It includes Lough Neagh which, at 388 square kilometres (150 sq mi), is the largest lake in the British Isles by area.[117] The highest peak in Northern Ireland is Slieve Donard in the Mourne Mountains at 852 metres (2,795 ft).[106] +Climate +Main article: Climate of the United Kingdom +The United Kingdom has a temperate climate, with plentiful rainfall all year round.[105] The temperature varies with the seasons seldom dropping below −11 °C (12 °F) or rising above 35 °C (95 °F).[118] The prevailing wind is from the south-west and bears frequent spells of mild and wet weather from the Atlantic Ocean,[105] although the eastern parts are mostly sheltered from this wind since the majority of the rain falls over the western regions the eastern parts are therefore the driest. Atlantic currents, warmed by the Gulf Stream, bring mild winters; especially in the west where winters are wet and even more so over high ground. Summers are warmest in the south-east of England, being closest to the European mainland, and coolest in the north. Heavy snowfall can occur in winter and early spring on high ground, and occasionally settles to great depth away from the hills. +Administrative divisions +Main article: Administrative geography of the United Kingdom +Each country of the United Kingdom has its own system of administrative and geographic demarcation, whose origins often pre-date the formation of the United Kingdom. Thus there is "no common stratum of administrative unit encompassing the United Kingdom".[119] Until the 19th century there was little change to those arrangements, but there has since been a constant evolution of role and function.[120] Change did not occur in a uniform manner and the devolution of power over local government to Scotland, Wales and Northern Ireland means that future changes are unlikely to be uniform either. +The organisation of local government in England is complex, with the distribution of functions varying according to local arrangements. Legislation concerning local government in England is the responsibility of the UK parliament and the Government of the United Kingdom, as England has no devolved parliament. The upper-tier subdivisions of England are the nine Government office regions or European Union government office regions.[121] One region, Greater London, has had a directly elected assembly and mayor since 2000 following popular support for the proposal in a referendum.[122] It was intended that other regions would also be given their own elected regional assemblies, but a proposed assembly in the North East region was rejected by a referendum in 2004.[123] Below the regional tier, some parts of England have county councils and district councils and others have unitary authorities; while London consists of 32 London boroughs and the City of London. Councillors are elected by the first-past-the-post system in single-member wards or by the multi-member plurality system in multi-member wards.[124] +For local government purposes, Scotland is divided into 32 council areas, with wide variation in both size and population. The cities of Glasgow, Edinburgh, Aberdeen and Dundee are separate council areas, as is the Highland Council which includes a third of Scotland's area but only just over 200,000 people. Local councils are made up of elected councillors, of whom there are currently 1,222;[125] they are paid a part-time salary. Elections are conducted by single transferable vote in multi-member wards that elect either three or four councillors. Each council elects a Provost, or Convenor, to chair meetings of the council and to act as a figurehead for the area. Councillors are subject to a code of conduct enforced by the Standards Commission for Scotland.[126] The representative association of Scotland's local authorities is the Convention of Scottish Local Authorities (COSLA).[127] +Local government in Wales consists of 22 unitary authorities. These include the cities of Cardiff, Swansea and Newport which are unitary authorities in their own right.[128] Elections are held every four years under the first-past-the-post system.[129] The most recent elections were held in May 2012, except for the Isle of Anglesey. The Welsh Local Government Association represents the interests of local authorities in Wales.[130] +Local government in Northern Ireland has since 1973 been organised into 26 district councils, each elected by single transferable vote. Their powers are limited to services such as collecting waste, controlling dogs and maintaining parks and cemeteries.[131] On 13 March 2008 the executive agreed on proposals to create 11 new councils and replace the present system.[132] The next local elections were postponed until 2016 to facilitate this.[133] +Dependencies + +A view of the Caribbean Sea from the Cayman Islands, one of the world's foremost international financial centres[134] and tourist destinations.[135] +Main articles: British Overseas Territories, Crown dependencies and British Islands +The United Kingdom has sovereignty over seventeen territories which do not form part of the United Kingdom itself: fourteen British Overseas Territories[136] and three Crown dependencies.[137] +The fourteen British Overseas Territories are: Anguilla; Bermuda; the British Antarctic Territory; the British Indian Ocean Territory; the British Virgin Islands; the Cayman Islands; the Falkland Islands; Gibraltar; Montserrat; Saint Helena, Ascension and Tristan da Cunha; the Turks and Caicos Islands; the Pitcairn Islands; South Georgia and the South Sandwich Islands; and Sovereign Base Areas on Cyprus.[138] British claims in Antarctica are not universally recognised.[139] Collectively Britain's overseas territories encompass an approximate land area of 1,727,570 square kilometres (667,018 sq mi) and a population of approximately 260,000 people.[140] They are the remnants of the British Empire and several have specifically voted to remain British territories (Bermuda in 1995, Gibraltar in 2002 and the Falkland Islands in 2013).[141] +The Crown dependencies are possessions of the Crown, as opposed to overseas territories of the UK.[142] They comprise three independently administered jurisdictions: the Channel Islands of Jersey and Guernsey in the English Channel, and the Isle of Man in the Irish Sea. By mutual agreement, the British Government manages the islands' foreign affairs and defence and the UK Parliament has the authority to legislate on their behalf. However, internationally, they are regarded as "territories for which the United Kingdom is responsible".[143] The power to pass legislation affecting the islands ultimately rests with their own respective legislative assemblies, with the assent of the Crown (Privy Council or, in the case of the Isle of Man, in certain circumstances the Lieutenant-Governor).[144] Since 2005 each Crown dependency has had a Chief Minister as its head of government.[145] +Politics +Main articles: Politics of the United Kingdom, Monarchy of the United Kingdom and Elections in the United Kingdom +Elderly lady with a yellow hat and grey hair is smiling in outdoor setting. +Elizabeth II, Queen of the United Kingdom and the other Commonwealth realms +The United Kingdom is a unitary state under a constitutional monarchy. Queen Elizabeth II is the head of state of the UK as well as monarch of fifteen other independent Commonwealth countries. The monarch has "the right to be consulted, the right to encourage, and the right to warn".[146] The United Kingdom is one of only four countries in the world to have an uncodified constitution.[147][nb 7] The Constitution of the United Kingdom thus consists mostly of a collection of disparate written sources, including statutes, judge-made case law and international treaties, together with constitutional conventions. As there is no technical difference between ordinary statutes and "constitutional law", the UK Parliament can perform "constitutional reform" simply by passing Acts of Parliament, and thus has the political power to change or abolish almost any written or unwritten element of the constitution. However, no Parliament can pass laws that future Parliaments cannot change.[148] +Government +Main article: Government of the United Kingdom +The UK has a parliamentary government based on the Westminster system that has been emulated around the world: a legacy of the British Empire. The parliament of the United Kingdom that meets in the Palace of Westminster has two houses; an elected House of Commons and an appointed House of Lords. All bills passed are given Royal Assent before becoming law. +The position of prime minister,[nb 8] the UK's head of government,[149] belongs to the person most likely to command the confidence of the House of Commons; this individual is typically the leader of the political party or coalition of parties that holds the largest number of seats in that chamber. The prime minister chooses a cabinet and they are formally appointed by the monarch to form Her Majesty's Government. By convention, the Queen respects the prime minister's decisions of government.[150] +Large sand-coloured building of Gothic design beside brown river and road bridge. The building has several large towers, including large clock-tower. +The Palace of Westminster, seat of both houses of the Parliament of the United Kingdom +The cabinet is traditionally drawn from members of a prime minister's party or coalition and mostly from the House of Commons but always from both legislative houses, the cabinet being responsible to both. Executive power is exercised by the prime minister and cabinet, all of whom are sworn into the Privy Council of the United Kingdom, and become Ministers of the Crown. The current Prime Minister is David Cameron, who has been in office since 11 May 2010.[151] Cameron is the leader of the Conservative Party and heads a coalition with the Liberal Democrats. For elections to the House of Commons, the UK is currently divided into 650 constituencies,[152] each electing a single member of parliament (MP) by simple plurality. General elections are called by the monarch when the prime minister so advises. The Parliament Acts 1911 and 1949 require that a new election must be called no later than five years after the previous general election.[153] +The UK's three major political parties are the Conservative Party (Tories), the Labour Party and the Liberal Democrats, representing the British traditions of conservatism, socialism and social liberalism, respectively. During the 2010 general election these three parties won 622 out of 650 seats available in the House of Commons.[154][155] Most of the remaining seats were won by parties that contest elections only in one part of the UK: the Scottish National Party (Scotland only); Plaid Cymru (Wales only); and the Alliance Party, Democratic Unionist Party, Social Democratic and Labour Party and Sinn Féin (Northern Ireland only[nb 9]). In accordance with party policy, no elected Sinn Féin members of parliament have ever attended the House of Commons to speak on behalf of their constituents because of the requirement to take an oath of allegiance to the monarch. +Devolved administrations +Main articles: Devolution in the United Kingdom, Northern Ireland Executive, Scottish Government and Welsh Government +Modern one-story building with grass on roof and large sculpted grass area in front. Behind are residential buildings in a mixture of styles. +The Scottish Parliament Building in Holyrood is the seat of the Scottish Parliament. +Scotland, Wales and Northern Ireland each have their own government or executive, led by a First Minister (or, in the case of Northern Ireland, a diarchal First Minister and deputy First Minister), and a devolved unicameral legislature. England, the largest country of the United Kingdom, has no such devolved executive or legislature and is administered and legislated for directly by the UK government and parliament on all issues. This situation has given rise to the so-called West Lothian question which concerns the fact that members of parliament from Scotland, Wales and Northern Ireland can vote, sometimes decisively,[156] on matters that only affect England.[157] The McKay Commission reported on this matter in March 2013 recommending that laws affecting only England should need support from a majority of English members of parliament.[158] +The Scottish Government and Parliament have wide-ranging powers over any matter that has not been specifically reserved to the UK parliament, including education, healthcare, Scots law and local government.[159] At the 2011 elections the Scottish National Party won re-election and achieved an overall majority in the Scottish parliament, with its leader, Alex Salmond, as First Minister of Scotland.[160][161] In 2012, the UK and Scottish governments signed the Edinburgh Agreement setting out the terms for a referendum on Scottish independence in 2014, which was defeated 55% to 45%. +The Welsh Government and the National Assembly for Wales have more limited powers than those devolved to Scotland.[162] The Assembly is able to legislate on devolved matters through Acts of the Assembly, which require no prior consent from Westminster. The 2011 elections resulted in a minority Labour administration led by Carwyn Jones.[163] +The Northern Ireland Executive and Assembly have powers similar to those devolved to Scotland. The Executive is led by a diarchy representing unionist and nationalist members of the Assembly. Currently, Peter Robinson (Democratic Unionist Party) and Martin McGuinness (Sinn Féin) are First Minister and deputy First Minister respectively.[164] Devolution to Northern Ireland is contingent on participation by the Northern Ireland administration in the North-South Ministerial Council, where the Northern Ireland Executive cooperates and develops joint and shared policies with the Government of Ireland. The British and Irish governments co-operate on non-devolved matters affecting Northern Ireland through the British–Irish Intergovernmental Conference, which assumes the responsibilities of the Northern Ireland administration in the event of its non-operation. +The UK does not have a codified constitution and constitutional matters are not among the powers devolved to Scotland, Wales or Northern Ireland. Under the doctrine of parliamentary sovereignty, the UK Parliament could, in theory, therefore, abolish the Scottish Parliament, Welsh Assembly or Northern Ireland Assembly.[165][166] Indeed, in 1972, the UK Parliament unilaterally prorogued the Parliament of Northern Ireland, setting a precedent relevant to contemporary devolved institutions.[167] In practice, it would be politically difficult for the UK Parliament to abolish devolution to the Scottish Parliament and the Welsh Assembly, given the political entrenchment created by referendum decisions.[168] The political constraints placed upon the UK Parliament's power to interfere with devolution in Northern Ireland are even greater than in relation to Scotland and Wales, given that devolution in Northern Ireland rests upon an international agreement with the Government of Ireland.[169] +Law and criminal justice +Main article: Law of the United Kingdom + +The Royal Courts of Justice of England and Wales +The United Kingdom does not have a single legal system, as Article 19 of the 1706 Treaty of Union provided for the continuation of Scotland's separate legal system.[170] Today the UK has three distinct systems of law: English law, Northern Ireland law and Scots law. A new Supreme Court of the United Kingdom came into being in October 2009 to replace the Appellate Committee of the House of Lords.[171][172] The Judicial Committee of the Privy Council, including the same members as the Supreme Court, is the highest court of appeal for several independent Commonwealth countries, the British Overseas Territories and the Crown Dependencies.[173] +Both English law, which applies in England and Wales, and Northern Ireland law are based on common-law principles.[174] The essence of common law is that, subject to statute, the law is developed by judges in courts, applying statute, precedent and common sense to the facts before them to give explanatory judgements of the relevant legal principles, which are reported and binding in future similar cases (stare decisis).[175] The courts of England and Wales are headed by the Senior Courts of England and Wales, consisting of the Court of Appeal, the High Court of Justice (for civil cases) and the Crown Court (for criminal cases). The Supreme Court is the highest court in the land for both criminal and civil appeal cases in England, Wales and Northern Ireland and any decision it makes is binding on every other court in the same jurisdiction, often having a persuasive effect in other jurisdictions.[176] + +The High Court of Justiciary – the supreme criminal court of Scotland. +Scots law is a hybrid system based on both common-law and civil-law principles. The chief courts are the Court of Session, for civil cases,[177] and the High Court of Justiciary, for criminal cases.[178] The Supreme Court of the United Kingdom serves as the highest court of appeal for civil cases under Scots law.[179] Sheriff courts deal with most civil and criminal cases including conducting criminal trials with a jury, known as sheriff solemn court, or with a sheriff and no jury, known as sheriff summary Court.[180] The Scots legal system is unique in having three possible verdicts for a criminal trial: "guilty", "not guilty" and "not proven". Both "not guilty" and "not proven" result in an acquittal.[181] +Crime in England and Wales increased in the period between 1981 and 1995, though since that peak there has been an overall fall of 48% in crime from 1995 to 2007/08,[182] according to crime statistics. The prison population of England and Wales has almost doubled over the same period, to over 80,000, giving England and Wales the highest rate of incarceration in Western Europe at 147 per 100,000.[183] Her Majesty's Prison Service, which reports to the Ministry of Justice, manages most of the prisons within England and Wales. Crime in Scotland fell to its lowest recorded level for 32 years in 2009/10, falling by ten per cent.[184] At the same time Scotland's prison population, at over 8,000,[185] is at record levels and well above design capacity.[186] The Scottish Prison Service, which reports to the Cabinet Secretary for Justice, manages Scotland's prisons. +Foreign relations +Main article: Foreign relations of the United Kingdom + +The Prime Minister of the United Kingdom, David Cameron, and the President of the United States, Barack Obama, during the 2010 G-20 Toronto summit. +The UK is a permanent member of the United Nations Security Council, a member of NATO, the Commonwealth of Nations, G7, G8, G20, the OECD, the WTO, the Council of Europe, the OSCE, and is a member state of the European Union. The UK is said to have a "Special Relationship" with the United States and a close partnership with France—the "Entente cordiale"—and shares nuclear weapons technology with both countries.[187][188] The UK is also closely linked with the Republic of Ireland; the two countries share a Common Travel Area and co-operate through the British-Irish Intergovernmental Conference and the British-Irish Council. Britain's global presence and influence is further amplified through its trading relations, foreign investments, official development assistance and military engagements.[189] +Military + +Troopers of the Blues and Royals during the 2007 Trooping the Colour ceremony +Main article: British Armed Forces +The armed forces of the United Kingdom—officially, Her Majesty's Armed Forces—consist of three professional service branches: the Royal Navy and Royal Marines (forming the Naval Service), the British Army and the Royal Air Force.[190] The forces are managed by the Ministry of Defence and controlled by the Defence Council, chaired by the Secretary of State for Defence. The Commander-in-Chief is the British monarch, Elizabeth II, to whom members of the forces swear an oath of allegiance.[191] The Armed Forces are charged with protecting the UK and its overseas territories, promoting the UK's global security interests and supporting international peacekeeping efforts. They are active and regular participants in NATO, including the Allied Rapid Reaction Corps, as well as the Five Power Defence Arrangements, RIMPAC and other worldwide coalition operations. Overseas garrisons and facilities are maintained in Ascension Island, Belize, Brunei, Canada, Cyprus, Diego Garcia, the Falkland Islands, Germany, Gibraltar, Kenya and Qatar.[192] +The British armed forces played a key role in establishing the British Empire as the dominant world power in the 18th, 19th and early 20th centuries. Throughout its unique history the British forces have seen action in a number of major wars, such as the Seven Years' War, the Napoleonic Wars, the Crimean War, World War I and World War II—as well as many colonial conflicts. By emerging victorious from such conflicts, Britain has often been able to decisively influence world events. Since the end of the British Empire, the UK has nonetheless remained a major military power. Following the end of the Cold War, defence policy has a stated assumption that "the most demanding operations" will be undertaken as part of a coalition.[193] Setting aside the intervention in Sierra Leone, recent UK military operations in Bosnia, Kosovo, Afghanistan, Iraq and, most recently, Libya, have followed this approach. The last time the British military fought alone was the Falklands War of 1982. +According to various sources, including the Stockholm International Peace Research Institute and the International Institute for Strategic Studies, the United Kingdom has the fifth- or sixth-highest military expenditure in the world. Total defence spending currently accounts for around 2.4% of total national GDP.[22][23] +Economy +Main article: Economy of the United Kingdom + +The Bank of England – the central bank of the United Kingdom +The UK has a partially regulated market economy.[194] Based on market exchange rates the UK is today the sixth-largest economy in the world and the third-largest in Europe after Germany and France, having fallen behind France for the first time in over a decade in 2008.[195] HM Treasury, led by the Chancellor of the Exchequer, is responsible for developing and executing the British government's public finance policy and economic policy. The Bank of England is the UK's central bank and is responsible for issuing notes and coins in the nation's currency, the pound sterling. Banks in Scotland and Northern Ireland retain the right to issue their own notes, subject to retaining enough Bank of England notes in reserve to cover their issue. Pound sterling is the world's third-largest reserve currency (after the US Dollar and the Euro).[196] Since 1997 the Bank of England's Monetary Policy Committee, headed by the Governor of the Bank of England, has been responsible for setting interest rates at the level necessary to achieve the overall inflation target for the economy that is set by the Chancellor each year.[197] +The UK service sector makes up around 73% of GDP.[198] London is one of the three "command centres" of the global economy (alongside New York City and Tokyo),[199] it is the world's largest financial centre alongside New York,[200][201][202] and it has the largest city GDP in Europe.[203] Edinburgh is also one of the largest financial centres in Europe.[204] Tourism is very important to the British economy and, with over 27 million tourists arriving in 2004, the United Kingdom is ranked as the sixth major tourist destination in the world and London has the most international visitors of any city in the world.[205][206] The creative industries accounted for 7% GVA in 2005 and grew at an average of 6% per annum between 1997 and 2005.[207] + +The Airbus A350 has its wings and engines manufactured in the UK. +The Industrial Revolution started in the UK with an initial concentration on the textile industry,[208] followed by other heavy industries such as shipbuilding, coal mining and steelmaking.[209][210] +The empire was exploited as an overseas market for British products, allowing the UK to dominate international trade in the 19th century. As other nations industrialised, coupled with economic decline after two world wars, the United Kingdom began to lose its competitive advantage and heavy industry declined, by degrees, throughout the 20th century. Manufacturing remains a significant part of the economy but accounted for only 16.7% of national output in 2003.[211] +The automotive industry is a significant part of the UK manufacturing sector and employs over 800,000 people, with a turnover of some £52 billion, generating £26.6 billion of exports.[212] +The aerospace industry of the UK is the second- or third-largest national aerospace industry in the world depending upon the method of measurement and has an annual turnover of around £20 billion. The wings for the Airbus A380 and the A350 XWB are designed and manufactured at Airbus UK's world-leading Broughton facility, whilst over a quarter of the value of the Boeing 787 comes from UK manufacturers including Eaton (fuel subsystem pumps), Messier-Bugatti-Dowty (the landing gear) and Rolls-Royce (the engines). Other key names include GKN Aerospace – an expert in metallic and composite aerostructures that's involved in almost every civil and military fixed and rotary wing aircraft in production and development today.[213][214][215][216] +BAE Systems - plays a critical role on some of the world's biggest defence aerospace projects. The company makes large sections of the Typhoon Eurofighter at its sub-assembly plant in Salmesbury and assembles the aircraft for the RAF at its Warton Plant, near Preston. It is also a principal subcontractor on the F35 Joint Strike Fighter - the world's largest single defence project - for which it designs and manufactures a range of components including the aft fuselage, vertical and horizontal tail and wing tips and fuel system. As well as this it manufactures the Hawk, the world's most successful jet training aircraft.[216] Airbus UK also manufactures the wings for the A400m military transporter. Rolls-Royce, is the world's second-largest aero-engine manufacturer. Its engines power more than 30 types of commercial aircraft and it has more than 30,000 engines currently in service across both the civil and defence sectors. Agusta Westland designs and manufactures complete helicopters in the UK.[216] +The UK space industry is growing very fast. Worth £9.1bn in 2011 and employing 29,000 people, it is growing at a rate of some 7.5 per cent annually, according to its umbrella organisation, the UK Space Agency. Government strategy is for the space industry to be a £40bn business for the UK by 2030, capturing a 10 per cent share of the $250bn world market for commercial space technology.[216] On 16 July 2013, the British government pledged £60m to the Skylon project: this investment will provide support at a "crucial stage" to allow a full-scale prototype of the SABRE engine to be built. +The pharmaceutical industry plays an important role in the UK economy and the country has the third-highest share of global pharmaceutical R&D expenditures (after the United States and Japan).[217][218] +Agriculture is intensive, highly mechanised and efficient by European standards, producing about 60% of food needs with less than 1.6% of the labour force (535,000 workers).[219] Around two-thirds of production is devoted to livestock, one-third to arable crops. Farmers are subsidised by the EU's Common Agricultural Policy. The UK retains a significant, though much reduced fishing industry. It is also rich in a number of natural resources including coal, petroleum, natural gas, tin, limestone, iron ore, salt, clay, chalk, gypsum, lead, silica and an abundance of arable land. + +The City of London is the world's largest financial centre alongside New York[200][201][202] +In the final quarter of 2008 the UK economy officially entered recession for the first time since 1991.[220] Unemployment increased from 5.2% in May 2008 to 7.6% in May 2009 and by January 2012 the unemployment rate among 18 to 24-year-olds had risen from 11.9% to 22.5%, the highest since current records began in 1992.[221][222] Total UK government debt rose from 44.4% of GDP in 2007 to 82.9% of GDP in 2011.[223] In February 2013, the UK lost its top AAA credit rating for the first time since 1978.[224] +Inflation-adjusted wages in the UK fell by 3.2% between the third quarter of 2010 and the third quarter of 2012.[225] Since the 1980s, economic inequality has grown faster in the UK than in any other developed country.[226] +The poverty line in the UK is commonly defined as being 60% of the median household income.[nb 10] In 2007–2008 13.5 million people, or 22% of the population, lived below this line. This is a higher level of relative poverty than all but four other EU members.[227] In the same year 4.0 million children, 31% of the total, lived in households below the poverty line after housing costs were taken into account. This is a decrease of 400,000 children since 1998–1999.[228] The UK imports 40% of its food supplies.[229] The Office for National Statistics has estimated that in 2011, 14 million people were at risk of poverty or social exclusion, and that one person in 20 (5.1%) was now experiencing "severe material depression,"[230] up from 3 million people in 1977.[231][232] +Science and technology +Main article: Science and technology in the United Kingdom + +Charles Darwin (1809–82), whose theory of evolution by natural selection is the foundation of modern biological sciences +England and Scotland were leading centres of the Scientific Revolution from the 17th century[233] and the United Kingdom led the Industrial Revolution from the 18th century,[208] and has continued to produce scientists and engineers credited with important advances.[234] Major theorists from the 17th and 18th centuries include Isaac Newton, whose laws of motion and illumination of gravity have been seen as a keystone of modern science;[235] from the 19th century Charles Darwin, whose theory of evolution by natural selection was fundamental to the development of modern biology, and James Clerk Maxwell, who formulated classical electromagnetic theory; and more recently Stephen Hawking, who has advanced major theories in the fields of cosmology, quantum gravity and the investigation of black holes.[236] Major scientific discoveries from the 18th century include hydrogen by Henry Cavendish;[237] from the 20th century penicillin by Alexander Fleming,[238] and the structure of DNA, by Francis Crick and others.[239] Major engineering projects and applications by people from the UK in the 18th century include the steam locomotive, developed by Richard Trevithick and Andrew Vivian;[240] from the 19th century the electric motor by Michael Faraday, the incandescent light bulb by Joseph Swan,[241] and the first practical telephone, patented by Alexander Graham Bell;[242] and in the 20th century the world's first working television system by John Logie Baird and others,[243] the jet engine by Frank Whittle, the basis of the modern computer by Alan Turing, and the World Wide Web by Tim Berners-Lee.[244] +Scientific research and development remains important in British universities, with many establishing science parks to facilitate production and co-operation with industry.[245] Between 2004 and 2008 the UK produced 7% of the world's scientific research papers and had an 8% share of scientific citations, the third and second highest in the world (after the United States and China, and the United States, respectively).[246] Scientific journals produced in the UK include Nature, the British Medical Journal and The Lancet.[247] +Transport +Main article: Transport in the United Kingdom + +Heathrow Terminal 5 building. London Heathrow Airport has the most international passenger traffic of any airport in the world.[248][249] +A radial road network totals 29,145 miles (46,904 km) of main roads, 2,173 miles (3,497 km) of motorways and 213,750 miles (344,000 km) of paved roads.[105] In 2009 there were a total of 34 million licensed vehicles in Great Britain.[250] +The UK has a railway network of 10,072 miles (16,209 km) in Great Britain and 189 miles (304 km) in Northern Ireland. Railways in Northern Ireland are operated by NI Railways, a subsidiary of state-owned Translink. In Great Britain, the British Rail network was privatised between 1994 and 1997. Network Rail owns and manages most of the fixed assets (tracks, signals etc.). About 20 privately owned (and foreign state-owned railways including: Deutsche Bahn; SNCF and Nederlandse Spoorwegen) Train Operating Companies (including state-owned East Coast), operate passenger trains and carry over 18,000 passenger trains daily. There are also some 1,000 freight trains in daily operation.[105] The UK government is to spend £30 billion on a new high-speed railway line, HS2, to be operational by 2025.[251] Crossrail, under construction in London, Is Europe's largest construction project with a £15 billion projected cost.[252][253] +In the year from October 2009 to September 2010 UK airports handled a total of 211.4 million passengers.[254] In that period the three largest airports were London Heathrow Airport (65.6 million passengers), Gatwick Airport (31.5 million passengers) and London Stansted Airport (18.9 million passengers).[254] London Heathrow Airport, located 15 miles (24 km) west of the capital, has the most international passenger traffic of any airport in the world[248][249] and is the hub for the UK flag carrier British Airways, as well as for BMI and Virgin Atlantic.[255] +Energy +Main article: Energy in the United Kingdom + +An oil platform in the North Sea +In 2006, the UK was the world's ninth-largest consumer of energy and the 15th-largest producer.[256] The UK is home to a number of large energy companies, including two of the six oil and gas "supermajors" – BP and Royal Dutch Shell – and BG Group.[257][258] In 2011, 40% of the UK's electricity was produced by gas, 30% by coal, 19% by nuclear power and 4.2% by wind, hydro, biofuels and wastes.[259] +In 2009, the UK produced 1.5 million barrels per day (bbl/d) of oil and consumed 1.7 million bbl/d.[260] Production is now in decline and the UK has been a net importer of oil since 2005.[260] In 2010 the UK had around 3.1 billion barrels of proven crude oil reserves, the largest of any EU member state.[260] In 2009, 66.5% of the UK's oil supply was imported.[261] +In 2009, the UK was the 13th-largest producer of natural gas in the world and the largest producer in the EU.[262] Production is now in decline and the UK has been a net importer of natural gas since 2004.[262] In 2009, half of British gas was supplied from imports and this is expected to increase to at least 75% by 2015, as domestic reserves are depleted.[259] +Coal production played a key role in the UK economy in the 19th and 20th centuries. In the mid-1970s, 130 million tonnes of coal was being produced annually, not falling below 100 million tonnes until the early 1980s. During the 1980s and 1990s the industry was scaled back considerably. In 2011, the UK produced 18.3 million tonnes of coal.[263] In 2005 it had proven recoverable coal reserves of 171 million tons.[263] The UK Coal Authority has stated there is a potential to produce between 7 billion tonnes and 16 billion tonnes of coal through underground coal gasification (UCG) or 'fracking',[264] and that, based on current UK coal consumption, such reserves could last between 200 and 400 years.[265] However, environmental and social concerns have been raised over chemicals getting into the water table and minor earthquakes damaging homes.[266][267] +In the late 1990s, nuclear power plants contributed around 25% of total annual electricity generation in the UK, but this has gradually declined as old plants have been shut down and ageing-related problems affect plant availability. In 2012, the UK had 16 reactors normally generating about 19% of its electricity. All but one of the reactors will be retired by 2023. Unlike Germany and Japan, the UK intends to build a new generation of nuclear plants from about 2018.[259] +Demographics +Main article: Demographics of the United Kingdom + +Map of population density in the UK as at the 2011 census. +A census is taken simultaneously in all parts of the UK every ten years.[268] The Office for National Statistics is responsible for collecting data for England and Wales, the General Register Office for Scotland and the Northern Ireland Statistics and Research Agency each being responsible for censuses in their respective countries.[269] In the 2011 census the total population of the United Kingdom was 63,181,775.[270] It is the third-largest in the European Union, the fifth-largest in the Commonwealth and the 21st-largest in the world. 2010 was the third successive year in which natural change contributed more to population growth than net long-term international migration.[271][271] Between 2001 and 2011 the population increased by an average annual rate of approximately 0.7 per cent.[270] This compares to 0.3 per cent per year in the period 1991 to 2001 and 0.2 per cent in the decade 1981 to 1991.[271] The 2011 census also confirmed that the proportion of the population aged 0–14 has nearly halved (31 per cent in 1911 compared to 18 in 2011) and the proportion of older people aged 65 and over has more than trebled (from 5 to 16 per cent).[270] It has been estimated that the number of people aged 100 or over will rise steeply to reach over 626,000 by 2080.[272] +England's population in 2011 was found to be 53 million.[273] It is one of the most densely populated countries in the world, with 383 people resident per square kilometre in mid-2003,[274] with a particular concentration in London and the south-east.[275] The 2011 census put Scotland's population at 5.3 million,[276] Wales at 3.06 million and Northern Ireland at 1.81 million.[273] In percentage terms England has had the fastest growing population of any country of the UK in the period from 2001 to 2011, with an increase of 7.9%. +In 2012 the average total fertility rate (TFR) across the UK was 1.92 children per woman.[277] While a rising birth rate is contributing to current population growth, it remains considerably below the 'baby boom' peak of 2.95 children per woman in 1964,[278] below the replacement rate of 2.1, but higher than the 2001 record low of 1.63.[277] In 2012, Scotland had the lowest TFR at only 1.67, followed by Wales at 1.88, England at 1.94, and Northern Ireland at 2.03.[277] In 2011, 47.3% of births in the UK were to unmarried women.[279] A government figure estimated that there are 3.6 million homosexual people in Britain comprising 6 per cent of the population.[280] +view talk edit +view talk edit +Largest urban areas of the United Kingdom +United Kingdom 2011 census Built-up areas[281][282][283] +Rank Urban area Pop. Principal settlement Rank Urban area Pop. Principal settlement +Greater London Urban Area +Greater London Urban Area +Greater Manchester Urban Area +Greater Manchester Urban Area +1 Greater London Urban Area 9,787,426 London 11 Bristol Urban Area 617,280 Bristol West Midlands Urban Area +West Midlands Urban Area +West Yorkshire Urban Area +West Yorkshire Urban Area +2 Greater Manchester Urban Area 2,553,379 Manchester 12 Belfast Metropolitan Urban Area 579,236 Belfast +3 West Midlands Urban Area 2,440,986 Birmingham 13 Leicester Urban Area 508,916 Leicester +4 West Yorkshire Urban Area 1,777,934 Leeds 14 Edinburgh 488,610 Edinburgh +5 Greater Glasgow 976,970 Glasgow 15 Brighton/Worthing/Littlehampton 474,485 Brighton +6 Liverpool Urban Area 864,122 Liverpool 16 South East Dorset conurbation 466,266 Bournemouth +7 South Hampshire 855,569 Southampton 17 Cardiff Urban Area 390,214 Cardiff +8 Tyneside 774,891 Newcastle 18 Teesside 376,633 Middlesbrough +9 Nottingham Urban Area 729,977 Nottingham 19 The Potteries Urban Area 372,775 Stoke-on-Trent +10 Sheffield Urban Area 685,368 Sheffield 20 Coventry and Bedworth Urban Area 359,262 Coventry + +Ethnic groups + +Map showing the percentage of the population who are not white according to the 2011 census. +Ethnic group 2011 +population 2011 +% +White 55,010,359 87.1 +White: Irish Traveller 63,193 0.1 +Asian or Asian British: Indian 1,451,862 +2.3 +Asian or Asian British: Pakistani 1,173,892 +1.9 +Asian or Asian British: Bangladeshi 451,529 +0.7 +Asian or Asian British: Chinese 433,150 +0.7 +Asian or Asian British: Asian Other 861,815 +1.4 +Asian or Asian British: Total 4,373,339 +7.0 +Black or Black British 1,904,684 +3.0 +British Mixed 1,250,229 +2.0 +Other: Total 580,374 +0.9 +Total[284] 63,182,178 +100 +Historically, indigenous British people were thought to be descended from the various ethnic groups that settled there before the 11th century: the Celts, Romans, Anglo-Saxons, Norse and the Normans. Welsh people could be the oldest ethnic group in the UK.[285] A 2006 genetic study shows that more than 50 per cent of England's gene pool contains Germanic Y chromosomes.[286] Another 2005 genetic analysis indicates that "about 75 per cent of the traceable ancestors of the modern British population had arrived in the British isles by about 6,200 years ago, at the start of the British Neolithic or Stone Age", and that the British broadly share a common ancestry with the Basque people.[287][288][289] +The UK has a history of small-scale non-white immigration, with Liverpool having the oldest Black population in the country dating back to at least the 1730s during the period of the African slave trade,[290] and the oldest Chinese community in Europe, dating to the arrival of Chinese seamen in the 19th century.[291] In 1950 there were probably fewer than 20,000 non-white residents in Britain, almost all born overseas.[292] +Since 1948 substantial immigration from Africa, the Caribbean and South Asia has been a legacy of ties forged by the British Empire. Migration from new EU member states in Central and Eastern Europe since 2004 has resulted in growth in these population groups but, as of 2008, the trend is reversing. Many of these migrants are returning to their home countries, leaving the size of these groups unknown.[293] In 2011, 86% of the population identified themselves as White, meaning 12.9% of the UK population identify themselves as of mixed ethnic minority. +Ethnic diversity varies significantly across the UK. 30.4% of London's population and 37.4% of Leicester's was estimated to be non-white in 2005,[294][295] whereas less than 5% of the populations of North East England, Wales and the South West were from ethnic minorities, according to the 2001 census.[296] In 2011, 26.5% of primary and 22.2% of secondary pupils at state schools in England were members of an ethnic minority.[297] +The non-white British population of England and Wales increased by 38% from 6.6 million in 2001 to 9.1 million in 2009.[298] The fastest-growing group was the mixed-ethnicity population, which doubled from 672,000 in 2001 to 986,600 in 2009. Also in the same period, a decrease of 36,000 white British people was recorded.[299] +Languages +Main article: Languages of the United Kingdom + +The English-speaking world. Countries in dark blue have a majority of native speakers; countries where English is an official but not a majority language are shaded in light blue. English is one of the official languages of the European Union[300] and the United Nations[301] +The UK's de facto official language is English.[302][303] It is estimated that 95% of the UK's population are monolingual English speakers.[304] 5.5% of the population are estimated to speak languages brought to the UK as a result of relatively recent immigration.[304] South Asian languages, including Bengali, Tamil, Punjabi, Hindi and Gujarati, are the largest grouping and are spoken by 2.7% of the UK population.[304] According to the 2011 census, Polish has become the second-largest language spoken in England and has 546,000 speakers.[305] +Four Celtic languages are spoken in the UK: Welsh; Irish; Scottish Gaelic; and Cornish. All are recognised as regional or minority languages, subject to specific measures of protection and promotion under the European Charter for Regional or Minority Languages[2][306] and the Framework Convention for the Protection of National Minorities.[307] In the 2001 Census over a fifth (21%) of the population of Wales said they could speak Welsh,[308] an increase from the 1991 Census (18%).[309] In addition it is estimated that about 200,000 Welsh speakers live in England.[310] In the same census in Northern Ireland 167,487 people (10.4%) stated that they had "some knowledge of Irish" (see Irish language in Northern Ireland), almost exclusively in the nationalist (mainly Catholic) population. Over 92,000 people in Scotland (just under 2% of the population) had some Gaelic language ability, including 72% of those living in the Outer Hebrides.[311] The number of schoolchildren being taught through Welsh, Scottish Gaelic and Irish is increasing.[312] Among emigrant-descended populations some Scottish Gaelic is still spoken in Canada (principally Nova Scotia and Cape Breton Island),[313] and Welsh in Patagonia, Argentina.[314] +Scots, a language descended from early northern Middle English, has limited recognition alongside its regional variant, Ulster Scots in Northern Ireland, without specific commitments to protection and promotion.[2][315] +It is compulsory for pupils to study a second language up to the age of 14 in England,[316] and up to age 16 in Scotland. French and German are the two most commonly taught second languages in England and Scotland. All pupils in Wales are taught Welsh as a second language up to age 16, or are taught in Welsh.[317] +Religion +Main article: Religion in the United Kingdom + +Westminster Abbey is used for the coronation of British monarchs +Forms of Christianity have dominated religious life in what is now the United Kingdom for over 1,400 years.[318] Although a majority of citizens still identify with Christianity in many surveys, regular church attendance has fallen dramatically since the middle of the 20th century,[319] while immigration and demographic change have contributed to the growth of other faiths, most notably Islam.[320] This has led some commentators to variously describe the UK as a multi-faith,[321] secularised,[322] or post-Christian society.[323] +In the 2001 census 71.6% of all respondents indicated that they were Christians, with the next largest faiths (by number of adherents) being Islam (2.8%), Hinduism (1.0%), Sikhism (0.6%), Judaism (0.5%), Buddhism (0.3%) and all other religions (0.3%).[324] 15% of respondents stated that they had no religion, with a further 7% not stating a religious preference.[325] A Tearfund survey in 2007 showed only one in ten Britons actually attend church weekly.[326] Between the 2001 and 2011 census there was a decrease in the amount of people who identified as Christian by 12%, whilst the percentage of those reporting no religious affiliation doubled. This contrasted with growth in the other main religious group categories, with the number of Muslims increasing by the most substantial margin to a total of about 5%.[327] +The Church of England is the established church in England.[328] It retains a representation in the UK Parliament and the British monarch is its Supreme Governor.[329] In Scotland the Presbyterian Church of Scotland is recognised as the national church. It is not subject to state control, and the British monarch is an ordinary member, required to swear an oath to "maintain and preserve the Protestant Religion and Presbyterian Church Government" upon his or her accession.[330][331] The (Anglican) Church in Wales was disestablished in 1920 and, as the (Anglican) Church of Ireland was disestablished in 1870 before the partition of Ireland, there is no established church in Northern Ireland.[332] Although there are no UK-wide data in the 2001 census on adherence to individual Christian denominations, it has been estimated that 62% of Christians are Anglican, 13.5% Catholic, 6% Presbyterian, 3.4% Methodist with small numbers of other Protestant denominations such as Open Brethren, and Orthodox churches.[333] +Migration +Main article: Immigration to the United Kingdom since 1922 +See also: Foreign-born population of the United Kingdom + +Estimated foreign-born population by country of birth, April 2007 – March 2008 +The United Kingdom has experienced successive waves of migration. The Great Famine in Ireland, then part of the United Kingdom, resulted in perhaps a million people migrating to Great Brtain.[334] Unable to return to Poland at the end of World War II, over 120,000 Polish veterans remained in the UK permanently.[335] After World War II, there was significant immigration from the colonies and newly independent former colonies, partly as a legacy of empire and partly driven by labour shortages. Many of these migrants came from the Caribbean and the Indian subcontinent.[336] The British Asian population has increased from 2.2 million in 2001 to over 4.2 million in 2011.[337] +One of the more recent trends in migration has been the arrival of workers from the new EU member states in Eastern Europe. In 2010, there were 7.0 million foreign-born residents in the UK, corresponding to 11.3% of the total population. Of these, 4.76 million (7.7%) were born outside the EU and 2.24 million (3.6%) were born in another EU Member State.[338] The proportion of foreign-born people in the UK remains slightly below that of many other European countries.[339] However, immigration is now contributing to a rising population[340] with arrivals and UK-born children of migrants accounting for about half of the population increase between 1991 and 2001. Analysis of Office for National Statistics (ONS) data shows that a net total of 2.3 million migrants moved to the UK in the 15 years from 1991 to 2006.[341][342] In 2008 it was predicted that migration would add 7 million to the UK population by 2031,[343] though these figures are disputed.[344] The ONS reported that net migration rose from 2009 to 2010 by 21 per cent to 239,000.[345] In 2011 the net increase was 251,000: immigration was 589,000, while the number of people emigrating (for more than 12 months) was 338,000.[346][347] +195,046 foreign nationals became British citizens in 2010,[348] compared to 54,902 in 1999.[348][349] A record 241,192 people were granted permanent settlement rights in 2010, of whom 51 per cent were from Asia and 27 per cent from Africa.[350] 25.5 per cent of babies born in England and Wales in 2011 were born to mothers born outside the UK, according to official statistics released in 2012.[351] +Citizens of the European Union, including those of the UK, have the right to live and work in any EU member state.[352] The UK applied temporary restrictions to citizens of Romania and Bulgaria, which joined the EU in January 2007.[353] Research conducted by the Migration Policy Institute for the Equality and Human Rights Commission suggests that, between May 2004 and September 2009, 1.5 million workers migrated from the new EU member states to the UK, two-thirds of them Polish, but that many subsequently returned home, resulting in a net increase in the number of nationals of the new member states in the UK of some 700,000 over that period.[354][355] The late-2000s recession in the UK reduced the economic incentive for Poles to migrate to the UK,[356] the migration becoming temporary and circular.[357] In 2009, for the first time since enlargement, more nationals of the eight central and eastern European states that had joined the EU in 2004 left the UK than arrived.[358] In 2011, citizens of the new EU member states made up 13% of the immigrants entering the country.[346] + +Estimated number of British citizens living overseas by country, 2006 +The UK government has introduced a points-based immigration system for immigration from outside the European Economic Area to replace former schemes, including the Scottish Government's Fresh Talent Initiative.[359] In June 2010 the UK government introduced a temporary limit of 24,000 on immigration from outside the EU, aiming to discourage applications before a permanent cap was imposed in April 2011.[360] The cap has caused tension within the coalition: business secretary Vince Cable has argued that it is harming British businesses.[361] +Emigration was an important feature of British society in the 19th century. Between 1815 and 1930 around 11.4 million people emigrated from Britain and 7.3 million from Ireland. Estimates show that by the end of the 20th century some 300 million people of British and Irish descent were permanently settled around the globe.[362] Today, at least 5.5 million UK-born people live abroad,[363][364][365] mainly in Australia, Spain, the United States and Canada.[363][366] +Education +Main article: Education in the United Kingdom +See also: Education in England, Education in Northern Ireland, Education in Scotland and Education in Wales + +King's College, part of the University of Cambridge, which was founded in 1209 +Education in the United Kingdom is a devolved matter, with each country having a separate education system. +Whilst education in England is the responsibility of the Secretary of State for Education, the day-to-day administration and funding of state schools is the responsibility of local authorities.[367] Universally free of charge state education was introduced piecemeal between 1870 and 1944.[368][369] Education is now mandatory from ages five to sixteen (15 if born in late July or August). In 2011, the Trends in International Mathematics and Science Study (TIMSS) rated 13–14-year-old pupils in England and Wales 10th in the world for maths and 9th for science.[370] The majority of children are educated in state-sector schools, a small proportion of which select on the grounds of academic ability. Two of the top ten performing schools in terms of GCSE results in 2006 were state-run grammar schools. Over half of students at the leading universities of Cambridge and Oxford had attended state schools.[371] Despite a fall in actual numbers the proportion of children in England attending private schools has risen to over 7%.[372] In 2010, more than 45% of places at the University of Oxford and 40% at the University of Cambridge were taken by students from private schools, even though they educate just 7% of the population.[373] England has the two oldest universities in English-speaking world, Universities of Oxford and Cambridge (jointly known as "Oxbridge") with history of over eight centuries. The United Kingdom has 9 universities featured in the Times Higher Education top 100 rankings, making it second to the United States in terms of representation.[374] + +Queen's University Belfast, built in 1849[375] +Education in Scotland is the responsibility of the Cabinet Secretary for Education and Lifelong Learning, with day-to-day administration and funding of state schools the responsibility of Local Authorities. Two non-departmental public bodies have key roles in Scottish education. The Scottish Qualifications Authority is responsible for the development, accreditation, assessment and certification of qualifications other than degrees which are delivered at secondary schools, post-secondary colleges of further education and other centres.[376] The Learning and Teaching Scotland provides advice, resources and staff development to education professionals.[377] Scotland first legislated for compulsory education in 1496.[378] The proportion of children in Scotland attending private schools is just over 4%, and it has been rising slowly in recent years.[379] Scottish students who attend Scottish universities pay neither tuition fees nor graduate endowment charges, as fees were abolished in 2001 and the graduate endowment scheme was abolished in 2008.[380] +The Welsh Government has responsibility for education in Wales. A significant number of Welsh students are taught either wholly or largely in the Welsh language; lessons in Welsh are compulsory for all until the age of 16.[381] There are plans to increase the provision of Welsh-medium schools as part of the policy of creating a fully bilingual Wales. +Education in Northern Ireland is the responsibility of the Minister of Education and the Minister for Employment and Learning, although responsibility at a local level is administered by five education and library boards covering different geographical areas. The Council for the Curriculum, Examinations & Assessment (CCEA) is the body responsible for advising the government on what should be taught in Northern Ireland's schools, monitoring standards and awarding qualifications.[382] +A government commission's report in 2014 found that privately educated people comprise 7% of the general population of the UK but much larger percentages of the top professions, the most extreme case quoted being 71% of senior judges.[383][384] +Healthcare +Main article: Healthcare in the United Kingdom + +The Royal Aberdeen Children's Hospital, an NHS Scotland specialist children's hospital +Healthcare in the United Kingdom is a devolved matter and each country has its own system of private and publicly funded health care, together with alternative, holistic and complementary treatments. Public healthcare is provided to all UK permanent residents and is mostly free at the point of need, being paid for from general taxation. The World Health Organization, in 2000, ranked the provision of healthcare in the United Kingdom as fifteenth best in Europe and eighteenth in the world.[385][386] +Regulatory bodies are organised on a UK-wide basis such as the General Medical Council, the Nursing and Midwifery Council and non-governmental-based, such as the Royal Colleges. However, political and operational responsibility for healthcare lies with four national executives; healthcare in England is the responsibility of the UK Government; healthcare in Northern Ireland is the responsibility of the Northern Ireland Executive; healthcare in Scotland is the responsibility of the Scottish Government; and healthcare in Wales is the responsibility of the Welsh Assembly Government. Each National Health Service has different policies and priorities, resulting in contrasts.[387][388] +Since 1979 expenditure on healthcare has been increased significantly to bring it closer to the European Union average.[389] The UK spends around 8.4 per cent of its gross domestic product on healthcare, which is 0.5 percentage points below the Organisation for Economic Co-operation and Development average and about one percentage point below the average of the European Union.[390] +Culture +Main article: Culture of the United Kingdom +The culture of the United Kingdom has been influenced by many factors including: the nation's island status; its history as a western liberal democracy and a major power; as well as being a political union of four countries with each preserving elements of distinctive traditions, customs and symbolism. As a result of the British Empire, British influence can be observed in the language, culture and legal systems of many of its former colonies including Australia, Canada, India, Ireland, New Zealand, South Africa and the United States. The substantial cultural influence of the United Kingdom has led it to be described as a "cultural superpower."[391][392] +Literature +Main article: British literature + +The Chandos portrait, believed to depict William Shakespeare +'British literature' refers to literature associated with the United Kingdom, the Isle of Man and the Channel Islands. Most British literature is in the English language. In 2005, some 206,000 books were published in the United Kingdom and in 2006 it was the largest publisher of books in the world.[393] +The English playwright and poet William Shakespeare is widely regarded as the greatest dramatist of all time,[394][395][396] and his contemporaries Christopher Marlowe and Ben Jonson have also been held in continuous high esteem. More recently the playwrights Alan Ayckbourn, Harold Pinter, Michael Frayn, Tom Stoppard and David Edgar have combined elements of surrealism, realism and radicalism. +Notable pre-modern and early-modern English writers include Geoffrey Chaucer (14th century), Thomas Malory (15th century), Sir Thomas More (16th century), John Bunyan (17th century) and John Milton (17th century). In the 18th century Daniel Defoe (author of Robinson Crusoe) and Samuel Richardson were pioneers of the modern novel. In the 19th century there followed further innovation by Jane Austen, the gothic novelist Mary Shelley, the children's writer Lewis Carroll, the Brontë sisters, the social campaigner Charles Dickens, the naturalist Thomas Hardy, the realist George Eliot, the visionary poet William Blake and romantic poet William Wordsworth. 20th-century English writers include the science-fiction novelist H. G. Wells; the writers of children's classics Rudyard Kipling, A. A. Milne (the creator of Winnie-the-Pooh), Roald Dahl and Enid Blyton; the controversial D. H. Lawrence; the modernist Virginia Woolf; the satirist Evelyn Waugh; the prophetic novelist George Orwell; the popular novelists W. Somerset Maugham and Graham Greene; the crime writer Agatha Christie (the best-selling novelist of all time);[397] Ian Fleming (the creator of James Bond); the poets T.S. Eliot, Philip Larkin and Ted Hughes; the fantasy writers J. R. R. Tolkien, C. S. Lewis and J. K. Rowling; the graphic novelist Alan Moore, whose novel Watchmen is often cited by critics as comic's greatest series and graphic novel[398] and one of the best-selling graphic novels ever published.[399] + +A photograph of Victorian era novelist Charles Dickens +Scotland's contributions include the detective writer Arthur Conan Doyle (the creator of Sherlock Holmes), romantic literature by Sir Walter Scott, the children's writer J. M. Barrie, the epic adventures of Robert Louis Stevenson and the celebrated poet Robert Burns. More recently the modernist and nationalist Hugh MacDiarmid and Neil M. Gunn contributed to the Scottish Renaissance. A more grim outlook is found in Ian Rankin's stories and the psychological horror-comedy of Iain Banks. Scotland's capital, Edinburgh, was UNESCO's first worldwide City of Literature.[400] +Britain's oldest known poem, Y Gododdin, was composed in Yr Hen Ogledd (The Old North), most likely in the late 6th century. It was written in Cumbric or Old Welsh and contains the earliest known reference to King Arthur.[401] From around the seventh century, the connection between Wales and the Old North was lost, and the focus of Welsh-language culture shifted to Wales, where Arthurian legend was further developed by Geoffrey of Monmouth.[402] Wales's most celebrated medieval poet, Dafydd ap Gwilym (fl.1320–1370), composed poetry on themes including nature, religion and especially love. He is widely regarded as one of the greatest European poets of his age.[403] Until the late 19th century the majority of Welsh literature was in Welsh and much of the prose was religious in character. Daniel Owen is credited as the first Welsh-language novelist, publishing Rhys Lewis in 1885. The best-known of the Anglo-Welsh poets are both Thomases. Dylan Thomas became famous on both sides of the Atlantic in the mid-20th century. He is remembered for his poetry – his "Do not go gentle into that good night; Rage, rage against the dying of the light." is one of the most quoted couplets of English language verse – and for his 'play for voices', Under Milk Wood. The influential Church in Wales 'poet-priest' and Welsh nationalist R. S. Thomas was nominated for the Nobel Prize in Literature in 1996. Leading Welsh novelists of the twentieth century include Richard Llewellyn and Kate Roberts.[404][405] +Authors of other nationalities, particularly from Commonwealth countries, the Republic of Ireland and the United States, have lived and worked in the UK. Significant examples through the centuries include Jonathan Swift, Oscar Wilde, Bram Stoker, George Bernard Shaw, Joseph Conrad, T.S. Eliot, Ezra Pound and more recently British authors born abroad such as Kazuo Ishiguro and Sir Salman Rushdie.[406][407] +Music +Main article: Music of the United Kingdom +See also: British rock + +The Beatles are the most commercially successful and critically acclaimed band in the history of music, selling over a billion records internationally.[408][409][410] +Various styles of music are popular in the UK from the indigenous folk music of England, Wales, Scotland and Northern Ireland to heavy metal. Notable composers of classical music from the United Kingdom and the countries that preceded it include William Byrd, Henry Purcell, Sir Edward Elgar, Gustav Holst, Sir Arthur Sullivan (most famous for working with the librettist Sir W. S. Gilbert), Ralph Vaughan Williams and Benjamin Britten, pioneer of modern British opera. Sir Peter Maxwell Davies is one of the foremost living composers and current Master of the Queen's Music. The UK is also home to world-renowned symphonic orchestras and choruses such as the BBC Symphony Orchestra and the London Symphony Chorus. Notable conductors include Sir Simon Rattle, John Barbirolli and Sir Malcolm Sargent. Some of the notable film score composers include John Barry, Clint Mansell, Mike Oldfield, John Powell, Craig Armstrong, David Arnold, John Murphy, Monty Norman and Harry Gregson-Williams. George Frideric Handel, although born German, was a naturalised British citizen[411] and some of his best works, such as Messiah, were written in the English language.[412] Andrew Lloyd Webber has achieved enormous worldwide commercial success and is a prolific composer of musical theatre, works which have dominated London's West End for a number of years and have travelled to Broadway in New York.[413] +The Beatles have international sales of over one billion units and are the biggest-selling and most influential band in the history of popular music.[408][409][410][414] Other prominent British contributors to have influenced popular music over the last 50 years include; The Rolling Stones, Led Zeppelin, Pink Floyd, Queen, the Bee Gees, and Elton John, all of whom have world wide record sales of 200 million or more.[415][416][417][418][419][420] The Brit Awards are the BPI's annual music awards, and some of the British recipients of the Outstanding Contribution to Music award include; The Who, David Bowie, Eric Clapton, Rod Stewart and The Police.[421] More recent UK music acts that have had international success include Coldplay, Radiohead, Oasis, Spice Girls, Robbie Williams, Amy Winehouse and Adele.[422] +A number of UK cities are known for their music. Acts from Liverpool have had more UK chart number one hit singles per capita (54) than any other city worldwide.[423] Glasgow's contribution to music was recognised in 2008 when it was named a UNESCO City of Music, one of only three cities in the world to have this honour.[424] +Visual art +Main article: Art of the United Kingdom + +J. M. W. Turner self-portrait, oil on canvas, c. 1799 +The history of British visual art forms part of western art history. Major British artists include: the Romantics William Blake, John Constable, Samuel Palmer and J.M.W. Turner; the portrait painters Sir Joshua Reynolds and Lucian Freud; the landscape artists Thomas Gainsborough and L. S. Lowry; the pioneer of the Arts and Crafts Movement William Morris; the figurative painter Francis Bacon; the Pop artists Peter Blake, Richard Hamilton and David Hockney; the collaborative duo Gilbert and George; the abstract artist Howard Hodgkin; and the sculptors Antony Gormley, Anish Kapoor and Henry Moore. During the late 1980s and 1990s the Saatchi Gallery in London helped to bring to public attention a group of multi-genre artists who would become known as the "Young British Artists": Damien Hirst, Chris Ofili, Rachel Whiteread, Tracey Emin, Mark Wallinger, Steve McQueen, Sam Taylor-Wood and the Chapman Brothers are among the better-known members of this loosely affiliated movement. +The Royal Academy in London is a key organisation for the promotion of the visual arts in the United Kingdom. Major schools of art in the UK include: the six-school University of the Arts London, which includes the Central Saint Martins College of Art and Design and Chelsea College of Art and Design; Goldsmiths, University of London; the Slade School of Fine Art (part of University College London); the Glasgow School of Art; the Royal College of Art; and The Ruskin School of Drawing and Fine Art (part of the University of Oxford). The Courtauld Institute of Art is a leading centre for the teaching of the history of art. Important art galleries in the United Kingdom include the National Gallery, National Portrait Gallery, Tate Britain and Tate Modern (the most-visited modern art gallery in the world, with around 4.7 million visitors per year).[425] +Cinema +Main article: Cinema of the United Kingdom + +Film director Alfred Hitchcock +The United Kingdom has had a considerable influence on the history of the cinema. The British directors Alfred Hitchcock, whose film Vertigo is considered by some critics as the best film of all time,[426] and David Lean are among the most critically acclaimed of all-time.[427] Other important directors including Charlie Chaplin,[428] Michael Powell,[429] Carol Reed[430] and Ridley Scott.[431] Many British actors have achieved international fame and critical success, including: Julie Andrews,[432] Richard Burton,[433] Michael Caine,[434] Charlie Chaplin,[435] Sean Connery,[436] Vivien Leigh,[437] David Niven,[438] Laurence Olivier,[439] Peter Sellers,[440] Kate Winslet,[441] and Daniel Day-Lewis, the only person to win an Oscar in the best actor category three times.[442] Some of the most commercially successful films of all time have been produced in the United Kingdom, including the two highest-grossing film franchises (Harry Potter and James Bond).[443] Ealing Studios has a claim to being the oldest continuously working film studio in the world.[444] +Despite a history of important and successful productions, the industry has often been characterised by a debate about its identity and the level of American and European influence. British producers are active in international co-productions and British actors, directors and crew feature regularly in American films. Many successful Hollywood films have been based on British people, stories or events, including Titanic, The Lord of the Rings, Pirates of the Caribbean. +In 2009, British films grossed around $2 billion worldwide and achieved a market share of around 7% globally and 17% in the United Kingdom.[445] UK box-office takings totalled £944 million in 2009, with around 173 million admissions.[445] The British Film Institute has produced a poll ranking of what it considers to be the 100 greatest British films of all time, the BFI Top 100 British films.[446] The annual British Academy Film Awards, hosted by the British Academy of Film and Television Arts, are the British equivalent of the Oscars.[447] +Media +Main article: Media of the United Kingdom + +Broadcasting House in London, headquarters of the BBC, the oldest and largest broadcaster in the world.[448][449][450] +The BBC, founded in 1922, is the UK's publicly funded radio, television and Internet broadcasting corporation, and is the oldest and largest broadcaster in the world.[448][449][450] It operates numerous television and radio stations in the UK and abroad and its domestic services are funded by the television licence.[451][452] Other major players in the UK media include ITV plc, which operates 11 of the 15 regional television broadcasters that make up the ITV Network,[453] and News Corporation, which owns a number of national newspapers through News International such as the most popular tabloid The Sun and the longest-established daily "broadsheet" The Times,[454] as well as holding a large stake in satellite broadcaster British Sky Broadcasting.[455] London dominates the media sector in the UK: national newspapers and television and radio are largely based there, although Manchester is also a significant national media centre. Edinburgh and Glasgow, and Cardiff, are important centres of newspaper and broadcasting production in Scotland and Wales respectively.[456] The UK publishing sector, including books, directories and databases, journals, magazines and business media, newspapers and news agencies, has a combined turnover of around £20 billion and employs around 167,000 people.[457] +In 2009, it was estimated that individuals viewed a mean of 3.75 hours of television per day and 2.81 hours of radio. In that year the main BBC public service broadcasting channels accounted for an estimated 28.4% of all television viewing; the three main independent channels accounted for 29.5% and the increasingly important other satellite and digital channels for the remaining 42.1%.[458] Sales of newspapers have fallen since the 1970s and in 2009 42% of people reported reading a daily national newspaper.[459] In 2010 82.5% of the UK population were Internet users, the highest proportion amongst the 20 countries with the largest total number of users in that year.[460] +Philosophy +Main article: British philosophy +The United Kingdom is famous for the tradition of 'British Empiricism', a branch of the philosophy of knowledge that states that only knowledge verified by experience is valid, and 'Scottish Philosophy', sometimes referred to as the 'Scottish School of Common Sense'.[461] The most famous philosophers of British Empiricism are John Locke, George Berkeley and David Hume; while Dugald Stewart, Thomas Reid and William Hamilton were major exponents of the Scottish "common sense" school. Two Britons are also notable for a theory of moral philosophy utilitarianism, first used by Jeremy Bentham and later by John Stuart Mill in his short work Utilitarianism.[462][463] Other eminent philosophers from the UK and the unions and countries that preceded it include Duns Scotus, John Lilburne, Mary Wollstonecraft, Sir Francis Bacon, Adam Smith, Thomas Hobbes, William of Ockham, Bertrand Russell and A.J. "Freddie" Ayer. Foreign-born philosophers who settled in the UK include Isaiah Berlin, Karl Marx, Karl Popper and Ludwig Wittgenstein. +Sport +Main article: Sport in the United Kingdom + +Wembley Stadium, London, home of the England national football team, is one of the most expensive stadia ever built.[464] +Major sports, including association football, tennis, rugby union, rugby league, golf, boxing, rowing and cricket, originated or were substantially developed in the UK and the states that preceded it. With the rules and codes of many modern sports invented and codified in late 19th-century Victorian Britain, in 2012, the President of the IOC, Jacques Rogge, stated; "This great, sports-loving country is widely recognized as the birthplace of modern sport. It was here that the concepts of sportsmanship and fair play were first codified into clear rules and regulations. It was here that sport was included as an educational tool in the school curriculum".[465][466] +In most international competitions, separate teams represent England, Scotland and Wales. Northern Ireland and the Republic of Ireland usually field a single team representing all of Ireland, with notable exceptions being association football and the Commonwealth Games. In sporting contexts, the English, Scottish, Welsh and Irish / Northern Irish teams are often referred to collectively as the Home Nations. There are some sports in which a single team represents the whole of United Kingdom, including the Olympics, where the UK is represented by the Great Britain team. The 1908, 1948 and 2012 Summer Olympics were held in London, making it the first city to host the games three times. Britain has participated in every modern Olympic Games to date and is third in the medal count. +A 2003 poll found that football is the most popular sport in the United Kingdom.[467] Each of the Home Nations has its own football association, national team and league system. The English top division, the Premier League, is the most watched football league in the world.[468] The first-ever international football match was contested by England and Scotland on 30 November 1872.[469] England, Scotland, Wales and Northern Ireland compete as separate countries in international competitions.[470] A Great Britain Olympic football team was assembled for the first time to compete in the London 2012 Olympic Games. However, the Scottish, Welsh and Northern Irish football associations declined to participate, fearing that it would undermine their independent status – a fear confirmed by FIFA president Sepp Blatter.[471] + +The Millennium Stadium, Cardiff, opened for the 1999 Rugby World Cup. +Cricket was invented in England. The England cricket team, controlled by the England and Wales Cricket Board,[472] is the only national team in the UK with Test status. Team members are drawn from the main county sides, and include both English and Welsh players. Cricket is distinct from football and rugby where Wales and England field separate national teams, although Wales had fielded its own team in the past. Irish and Scottish players have played for England because neither Scotland nor Ireland have Test status and have only recently started to play in One Day Internationals.[473][474] Scotland, England (and Wales), and Ireland (including Northern Ireland) have competed at the Cricket World Cup, with England reaching the finals on three occasions. There is a professional league championship in which clubs representing 17 English counties and 1 Welsh county compete.[475] +Rugby league is a popular sport in some regions of the UK. It originated in Huddersfield and is generally played in Northern England.[476] A single 'Great Britain Lions' team had competed in the Rugby League World Cup and Test match games, but this changed in 2008 when England, Scotland and Ireland competed as separate nations.[477] Great Britain is still being retained as the full national team for Ashes tours against Australia, New Zealand and France. Super League is the highest level of professional rugby league in the UK and Europe. It consists of 11 teams from Northern England, 1 from London, 1 from Wales and 1 from France. +In rugby union, England, Scotland, Wales, Ireland, France and Italy compete in the Six Nations Championship; the premier international tournament in the northern hemisphere. Sport governing bodies in England, Scotland, Wales and Ireland organise and regulate the game separately.[478] If any of the British teams or the Irish team beat the other three in a tournament, then it is awarded the Triple Crown.[479] + +The Wimbledon Championships, a Grand Slam tennis tournament, is held in Wimbledon, London every June or July. +Thoroughbred racing, which originated under Charles II of England as the "sport of kings", is popular throughout the UK with world-famous races including the Grand National, the Epsom Derby, Royal Ascot and the Cheltenham National Hunt Festival (including the Cheltenham Gold Cup). The UK has proved successful in the international sporting arena in rowing. +The UK is closely associated with motorsport. Many teams and drivers in Formula One (F1) are based in the UK, and the country has won more drivers' and constructors' titles than any other. The UK hosted the very first F1 Grand Prix in 1950 at Silverstone, the current location of the British Grand Prix held each year in July. The country also hosts legs of the Grand Prix motorcycle racing, World Rally Championship and FIA World Endurance Championship. The premier national auto racing event is the British Touring Car Championship (BTCC). Motorcycle road racing has a long tradition with races such as the Isle of Man TT and the North West 200. +Golf is the sixth-most popular sport, by participation, in the UK. Although The Royal and Ancient Golf Club of St Andrews in Scotland is the sport's home course,[480] the world's oldest golf course is actually Musselburgh Links' Old Golf Course.[481] +Snooker is one of the UK's popular sporting exports, with the world championships held annually in Sheffield.[482] The modern game of lawn tennis first originated in the city of Birmingham between 1859 and 1865.[483] The Championships, Wimbledon are international tennis events held in Wimbledon in south London every summer and are regarded as the most prestigious event of the global tennis calendar. In Northern Ireland Gaelic football and hurling are popular team sports, both in terms of participation and spectating, and Irish expatriates in the UK and the US also play them.[484] Shinty (or camanachd) is popular in the Scottish Highlands.[485] +Symbols +Main article: Symbols of the United Kingdom, the Channel Islands and the Isle of Man + +The Statue of Britannia in Plymouth. Britannia is a national personification of the UK. +The flag of the United Kingdom is the Union Flag (also referred to as the Union Jack). It was created in 1606 by the superimposition of the Flag of England on the Flag of Scotland and updated in 1801 with the addition of Saint Patrick's Flag. Wales is not represented in the Union Flag, as Wales had been conquered and annexed to England prior to the formation of the United Kingdom. The possibility of redesigning the Union Flag to include representation of Wales has not been completely ruled out.[486] The national anthem of the United Kingdom is "God Save the King", with "King" replaced with "Queen" in the lyrics whenever the monarch is a woman. +Britannia is a national personification of the United Kingdom, originating from Roman Britain.[487] Britannia is symbolised as a young woman with brown or golden hair, wearing a Corinthian helmet and white robes. She holds Poseidon's three-pronged trident and a shield, bearing the Union Flag. Sometimes she is depicted as riding on the back of a lion. Since the height of the British Empire in the late 19th century, Britannia has often been associated with British maritime dominance, as in the patriotic song "Rule, Britannia!". Up until 2008, the lion symbol was depicted behind Britannia on the British fifty pence coin and on the back of the British ten pence coin. It is also used as a symbol on the non-ceremonial flag of the British Army. The bulldog is sometimes used as a symbol of the United Kingdom and has been associated with Winston Churchill's defiance of Nazi Germany.[488] +See also +Outline of the United Kingdom + United Kingdom – Wikipedia book +Walking in the United Kingdom +Flag of the United Kingdom.svgUnited Kingdom portal Flag of Europe.svgEuropean Union portal Europe green light.pngEurope portal +Notes +Jump up ^ The Royal coat of arms used in Scotland: + Royal Coat of Arms of the United Kingdom (Scotland).svg +Jump up ^ There is no authorised version of the national anthem as the words are a matter of tradition; only the first verse is usually sung.[1] No law was passed making "God Save the Queen" the official anthem. In the English tradition, such laws are not necessary; proclamation and usage are sufficient to make it the national anthem. "God Save the Queen" also serves as the Royal anthem for several other countries, namely certain Commonwealth realms. +Jump up ^ Under the Council of Europe's European Charter for Regional or Minority Languages, Scots, Ulster-Scots, Welsh, Cornish, Irish and Scottish Gaelic, are officially recognised as regional or minority languages by the British government for the purposes of the Charter. See also Languages of the United Kingdom.[2] +Jump up ^ Although Northern Ireland is the only part of the UK that shares a land border with another state, two of its Overseas Territories also share land borders with other states. Gibraltar shares a border with Spain, while the Sovereign Base Areas of Akrotiri and Dhekelia share borders with the Republic of Cyprus, Turkish Republic of Northern Cyprus and UN buffer zone separating the two Cypriot polities. +Jump up ^ The Anglo-Irish Treaty was signed on 6 December 1921 to resolve the Irish War of Independence. Effective one year later, it established the Irish Free State as a separate dominion within the Commonwealth. The UK's current name was adopted in 1927 to reflect the change. +Jump up ^ Compare to section 1 of both of the 1800 Acts of Union which reads: the Kingdoms of Great Britain and Ireland shall...be united into one Kingdom, by the Name of "The United Kingdom of Great Britain and Ireland" +Jump up ^ New Zealand, Israel and San Marino are the other countries with uncodified constitutions. +Jump up ^ Since the early twentieth century the prime minister has held the office of First Lord of the Treasury, and in recent decades has also held the office of Minister for the Civil Service. +Jump up ^ Sinn Féin, an Irish republican party, also contests elections in the Republic of Ireland. +Jump up ^ In 2007–2008, this was calculated to be £115 per week for single adults with no dependent children; £199 per week for couples with no dependent children; £195 per week for single adults with two dependent children under 14; and £279 per week for couples with two dependent children under 14. +References +Jump up ^ National Anthem, British Monarchy official website. Retrieved 16 November 2013. +^ Jump up to: a b c "List of declarations made with respect to treaty No. 148". Council of Europe. Retrieved 12 December 2013. +^ Jump up to: a b "Population Estimates for UK, England and Wales, Scotland and Northern Ireland, Mid-2013". Office for National Statistics. Retrieved 26 June 2014. +Jump up ^ "2011 UK censuses". Office for National Statistics. Retrieved 17 December 2012. +^ Jump up to: a b c d "United Kingdom". International Monetary Fund. Retrieved 1 November 2014. +Jump up ^ "Gini coefficient of equivalised disposable income (source: SILC)". Eurostat Data Explorer. Retrieved 13 August 2013. +Jump up ^ "2014 Human Development Report". 14 March 2013. pp. 22–25. Retrieved 27 July 2014. +Jump up ^ "Definition of Great Britain in English". Oxford University Press. Retrieved 29 October 2014. Great Britain is the name for the island that comprises England, Scotland, and Wales, although the term is also used loosely to refer to the United Kingdom. +Jump up ^ The British Monarchy, What is constitutional monarchy?. Retrieved 17 July 2013 +Jump up ^ CIA, The World Factbook. Retrieved 17 July 2013 +Jump up ^ "The World Factbook". Central Intelligence Agency. 1 February 2014. Retrieved 23 February 2014. +^ Jump up to: a b "Countries within a country". Prime Minister's Office. 10 January 2003. +^ Jump up to: a b "Devolution of powers to Scotland, Wales, and Northern Ireland". United Kingdom Government. Retrieved 17 April 2013. In a similar way to how the government is formed from members from the two Houses of Parliament, members of the devolved legislatures nominate ministers from among themselves to comprise an executive, known as the devolved administrations... +Jump up ^ "Fall in UK university students". BBC News. 29 January 2009. +Jump up ^ "Country Overviews: United Kingdom". Transport Research Knowledge Centre. Retrieved 28 March 2010. +Jump up ^ "Key facts about the United Kingdom". Directgov. Retrieved 3 May 2011. The full title of this country is 'the United Kingdom of Great Britain and Northern Ireland'. 'The UK' is made up of England, Scotland, Wales and Northern Ireland. 'Britain' is used informally, usually meaning the United Kingdom. 'Great Britain' is made up of England, Scotland and Wales. The Channel Islands and the Isle of Man are not part of the UK.[dead link] +Jump up ^ "Working with Overseas Territories". Foreign and Commonwealth Office. Retrieved 3 May 2011. +Jump up ^ Mathias, P. (2001). The First Industrial Nation: the Economic History of Britain, 1700–1914. London: Routledge. ISBN 0-415-26672-6. +Jump up ^ Ferguson, Niall (2004). Empire: The rise and demise of the British world order and the lessons for global power. New York: Basic Books. ISBN 0-465-02328-2. +Jump up ^ Sheridan, Greg (15 May 2010). "Cameron has chance to make UK great again". The Australian (Sydney). Retrieved 23 May 2011. +Jump up ^ Dugan, Emily (18 November 2012). "Britain is now most powerful nation on earth". The Independent (London). Retrieved 18 November 2012. +^ Jump up to: a b "The 15 countries with the highest military expenditure in 2013 (table)" (PDF). Stockholm International Peace Research Institute. Retrieved 4 May 2014. +^ Jump up to: a b The Military Balance 2014: Top 15 Defence Budgets 2013 (IISS) +Jump up ^ "Treaty of Union, 1706". Scots History Online. Retrieved 23 August 2011. +Jump up ^ Barnett, Hilaire; Jago, Robert (2011). Constitutional & Administrative Law (8th ed.). Abingdon: Routledge. p. 165. ISBN 978-0-415-56301-7. +Jump up ^ Gascoigne, Bamber. "History of Great Britain (from 1707)". History World. Retrieved 18 July 2011. +Jump up ^ Cottrell, P. (2008). The Irish Civil War 1922–23. p. 85. ISBN 1-84603-270-9. +^ Jump up to: a b S. Dunn; H. Dawson (2000), An Alphabetical Listing of Word, Name and Place in Northern Ireland and the Living Language of Conflict, Lampeter: Edwin Mellen Press, One specific problem - in both general and particular senses - is to know what to call Northern Ireland itself: in the general sense, it is not a country, or a province, or a state - although some refer to it contemptuously as a statelet: the least controversial word appears to be jurisdiction, but this might change. +Jump up ^ "Changes in the list of subdivision names and code elements". ISO 3166-2. International Organization for Standardization. 15 December 2011. Retrieved 28 May 2012. +Jump up ^ Population Trends, Issues 75–82, p.38, 1994, UK Office of Population Censuses and Surveys +Jump up ^ Life in the United Kingdom: a journey to citizenship, p. 7, United Kingdom Home Office, 2007, ISBN 978-0-11-341313-3. +Jump up ^ "Statistical bulletin: Regional Labour Market Statistics". Retrieved 5 March 2014. +Jump up ^ "13.4% Fall In Earnings Value During Recession". Retrieved 5 March 2014. +Jump up ^ Murphy, Dervla (1979). A Place Apart. London: Penguin. ISBN 978-0-14-005030-1. +Jump up ^ Whyte, John; FitzGerald, Garret (1991). Interpreting Northern Ireland. Oxford: Clarendon Press. ISBN 978-0-19-827380-6. +Jump up ^ "Guardian Unlimited Style Guide". London: Guardian News and Media Limited. 19 December 2008. Retrieved 23 August 2011. +Jump up ^ "BBC style guide (Great Britain)". BBC News. 19 August 2002. Retrieved 23 August 2011. +Jump up ^ "Key facts about the United Kingdom". Government, citizens and rights. HM Government. Retrieved 24 August 2011.[dead link] +Jump up ^ "Merriam-Webster Dictionary Online Definition of ''Great Britain''". Merriam Webster. 31 August 2012. Retrieved 9 April 2013. +Jump up ^ New Oxford American Dictionary: "Great Britain: England, Wales, and Scotland considered as a unit. The name is also often used loosely to refer to the United Kingdom." +Jump up ^ "Great Britain". International Olympic Committee. Retrieved 10 May 2011. +Jump up ^ "Team GB – Our Greatest Team". British Olympic Association. Retrieved 10 May 2011.[dead link] +Jump up ^ Bradley, Anthony Wilfred; Ewing, Keith D. (2007). Constitutional and administrative law 1 (14th ed.). Harlow: Pearson Longman. p. 36. ISBN 978-1-4058-1207-8. +Jump up ^ "Which of these best describes the way you think of yourself?". Northern Ireland Life and Times Survey 2010. ARK – Access Research Knowledge. 2010. Retrieved 1 July 2010. +Jump up ^ Schrijver, Frans (2006). Regionalism after regionalisation: Spain, France and the United Kingdom. Amsterdam University Press. pp. 275–277. ISBN 978-90-5629-428-1. +Jump up ^ Jack, Ian (11 December 2010). "Why I'm saddened by Scotland going Gaelic". The Guardian (London). +Jump up ^ Ffeithiau allweddol am y Deyrnas Unedig : Directgov – Llywodraeth, dinasyddion a hawliau[dead link] +Jump up ^ "Ancient skeleton was 'even older'". BBC News. 30 October 2007. Retrieved 27 April 2011. +Jump up ^ Koch, John T. (2006). Celtic culture: A historical encyclopedia. Santa Barbara, CA: ABC-CLIO. p. 973. ISBN 978-1-85109-440-0. +Jump up ^ Davies, John; Jenkins, Nigel; Baines, Menna; Lynch, Peredur I., eds. (2008). The Welsh Academy Encyclopaedia of Wales. Cardiff: University of Wales Press. p. 915. ISBN 978-0-7083-1953-6. +Jump up ^ "Short Athelstan biography". BBC History. Retrieved 9 April 2013. +Jump up ^ Mackie, J.D. (1991). A History of Scotland. London: Penguin. pp. 18–19. ISBN 978-0-14-013649-4. +Jump up ^ Campbell, Ewan (1999). Saints and Sea-kings: The First Kingdom of the Scots. Edinburgh: Canongate. pp. 8–15. ISBN 0-86241-874-7. +Jump up ^ Haigh, Christopher (1990). The Cambridge Historical Encyclopedia of Great Britain and Ireland. Cambridge University Press. p. 30. ISBN 978-0-521-39552-6. +Jump up ^ Ganshof, F.L. (1996). Feudalism. University of Toronto. p. 165. ISBN 978-0-8020-7158-3. +Jump up ^ Chibnall, Marjorie (1999). The debate on the Norman Conquest. Manchester University Press. pp. 115–122. ISBN 978-0-7190-4913-2. +Jump up ^ Keen, Maurice. "The Hundred Years War". BBC History. +Jump up ^ The Reformation in England and Scotland and Ireland: The Reformation Period & Ireland under Elizabth I, Encyclopædia Britannica Online. +Jump up ^ "British History in Depth – Wales under the Tudors". BBC History. 5 November 2009. Retrieved 21 September 2010. +Jump up ^ Nicholls, Mark (1999). A history of the modern British Isles, 1529–1603: The two kingdoms. Oxford: Blackwell. pp. 171–172. ISBN 978-0-631-19334-0. +Jump up ^ Canny, Nicholas P. (2003). Making Ireland British, 1580–1650. Oxford University Press. pp. 189–200. ISBN 978-0-19-925905-2. +Jump up ^ Ross, D. (2002). Chronology of Scottish History. Glasgow: Geddes & Grosset. p. 56. ISBN 1-85534-380-0 +Jump up ^ Hearn, J. (2002). Claiming Scotland: National Identity and Liberal Culture. Edinburgh University Press. p. 104. ISBN 1-902930-16-9 +Jump up ^ "English Civil Wars". Encyclopaedia Britannica. Retrieved 28 April 2013. +Jump up ^ "Scotland and the Commonwealth: 1651–1660". Archontology.org. 14 March 2010. Retrieved 20 April 2010. +Jump up ^ Lodge, Richard (2007) [1910]. The History of England – From the Restoration to the Death of William III (1660–1702). Read Books. p. 8. ISBN 978-1-4067-0897-4. +Jump up ^ "Tudor Period and the Birth of a Regular Navy". Royal Navy History. Institute of Naval History. Retrieved 24 December 2010.[dead link] +Jump up ^ Canny, Nicholas (1998). The Origins of Empire, The Oxford History of the British Empire Volume I. Oxford University Press. ISBN 0-19-924676-9. +Jump up ^ "Articles of Union with Scotland 1707". UK Parliament. Retrieved 19 October 2008. +Jump up ^ "Acts of Union 1707". UK Parliament. Retrieved 6 January 2011. +Jump up ^ "Treaty (act) of Union 1706". Scottish History online. Retrieved 3 February 2011. +Jump up ^ Library of Congress, The Impact of the American Revolution Abroad, p. 73. +Jump up ^ Loosemore, Jo (2007). Sailing against slavery. BBC Devon. 2007. +Jump up ^ "The Act of Union". Act of Union Virtual Library. Retrieved 15 May 2006. +Jump up ^ Tellier, L.-N. (2009). Urban World History: an Economic and Geographical Perspective. Quebec: PUQ. p. 463. ISBN 2-7605-1588-5. +Jump up ^ Sondhaus, L. (2004). Navies in Modern World History. London: Reaktion Books. p. 9. ISBN 1-86189-202-0. +Jump up ^ Porter, Andrew (1998). The Nineteenth Century, The Oxford History of the British Empire Volume III. Oxford University Press. p. 332. ISBN 0-19-924678-5. +Jump up ^ "The Workshop of the World". BBC History. Retrieved 28 April 2013. +Jump up ^ Porter, Andrew (1998). The Nineteenth Century, The Oxford History of the British Empire Volume III. Oxford University Press. p. 8. ISBN 0-19-924678-5. +Jump up ^ Marshall, P.J. (1996). The Cambridge Illustrated History of the British Empire. Cambridge University Press. pp. 156–57. ISBN 0-521-00254-0. +Jump up ^ Tompson, Richard S. (2003). Great Britain: a reference guide from the Renaissance to the present. New York: Facts on File. p. 63. ISBN 978-0-8160-4474-0. +Jump up ^ Hosch, William L. (2009). World War I: People, Politics, and Power. America at War. New York: Britannica Educational Publishing. p. 21. ISBN 978-1-61530-048-8. +Jump up ^ Turner, John (1988). Britain and the First World War. London: Unwin Hyman. pp. 22–35. ISBN 978-0-04-445109-9. +^ Jump up to: a b Westwell, I.; Cove, D. (eds) (2002). History of World War I, Volume 3. London: Marshall Cavendish. pp. 698 and 705. ISBN 0-7614-7231-2. +Jump up ^ Turner, J. (1988). Britain and the First World War. Abingdon: Routledge. p. 41. ISBN 0-04-445109-1. +Jump up ^ SR&O 1921, No. 533 of 3 May 1921. +Jump up ^ "The Anglo-Irish Treaty, 6 December 1921". CAIN. Retrieved 15 May 2006. +Jump up ^ Rubinstein, W. D. (2004). Capitalism, Culture, and Decline in Britain, 1750–1990. Abingdon: Routledge. p. 11. ISBN 0-415-03719-0. +Jump up ^ "Britain to make its final payment on World War II loan from U.S.". The New York Times. 28 December 2006. Retrieved 25 August 2011. +Jump up ^ Francis, Martin (1997). Ideas and policies under Labour, 1945–1951: Building a new Britain. Manchester University Press. pp. 225–233. ISBN 978-0-7190-4833-3. +Jump up ^ Lee, Stephen J. (1996). Aspects of British political history, 1914–1995. London; New York: Routledge. pp. 173–199. ISBN 978-0-415-13103-2. +Jump up ^ Larres, Klaus (2009). A companion to Europe since 1945. Chichester: Wiley-Blackwell. p. 118. ISBN 978-1-4051-0612-2. +Jump up ^ "Country List". Commonwealth Secretariat. 19 March 2009. Retrieved 11 September 2012.[dead link] +Jump up ^ Julios, Christina (2008). Contemporary British identity: English language, migrants, and public discourse. Studies in migration and diaspora. Aldershot: Ashgate. p. 84. ISBN 978-0-7546-7158-9. +Jump up ^ Aughey, Arthur (2005). The Politics of Northern Ireland: Beyond the Belfast Agreement. London: Routledge. p. 7. ISBN 978-0-415-32788-6. +Jump up ^ "The troubles were over, but the killing continued. Some of the heirs to Ireland's violent traditions refused to give up their inheritance." Holland, Jack (1999). Hope against History: The Course of Conflict in Northern Ireland. New York: Henry Holt. p. 221. ISBN 978-0-8050-6087-4. +Jump up ^ Elliot, Marianne (2007). The Long Road to Peace in Northern Ireland: Peace Lectures from the Institute of Irish Studies at Liverpool University. University of Liverpool Institute of Irish Studies, Liverpool University Press. p. 2. ISBN 1-84631-065-2. +Jump up ^ Dorey, Peter (1995). British politics since 1945. Making contemporary Britain. Oxford: Blackwell. pp. 164–223. ISBN 978-0-631-19075-2. +Jump up ^ Griffiths, Alan; Wall, Stuart (2007). Applied Economics (11th ed.). Harlow: Financial Times Press. p. 6. ISBN 978-0-273-70822-3. Retrieved 26 December 2010. +Jump up ^ Keating, Michael (1 January 1998). "Reforging the Union: Devolution and Constitutional Change in the United Kingdom". Publius: the Journal of Federalism 28 (1): 217. doi:10.1093/oxfordjournals.pubjof.a029948. Retrieved 4 February 2009. +Jump up ^ Jackson, Mike (3 April 2011). "Military action alone will not save Libya". Financial Times (London). +Jump up ^ "United Kingdom country profile". BBC. 24 January 2013. Retrieved 9 April 2013. +Jump up ^ "Scotland to hold independence poll in 2014 – Salmond". BBC News. 10 January 2012. Retrieved 10 January 2012. +Jump up ^ Oxford English Dictionary: "British Isles: a geographical term for the islands comprising Great Britain and Ireland with all their offshore islands including the Isle of Man and the Channel Islands." +^ Jump up to: a b c d e f "United Kingdom". The World Factbook. Central Intelligence Agency. Retrieved 23 September 2008. +^ Jump up to: a b c d e Latimer Clarke Corporation Pty Ltd. "United Kingdom – Atlapedia Online". Atlapedia.com. Retrieved 26 October 2010. +Jump up ^ ROG Learing Team (23 August 2002). "The Prime Meridian at Greenwich". Royal Museums Greenwich. Royal Museums Greenwich. Retrieved 11 September 2012. +Jump up ^ Neal, Clare. "How long is the UK coastline?". British Cartographic Society. Retrieved 26 October 2010. +Jump up ^ "The Channel Tunnel". Eurotunnel. Retrieved 29 November 2010.[dead link] +Jump up ^ "England – Profile". BBC News. 11 February 2010. +Jump up ^ "Scotland Facts". Scotland Online Gateway. Archived from the original on 21 June 2008. Retrieved 16 July 2008. +Jump up ^ Winter, Jon (19 May 2001). "The complete guide to Scottish Islands". The Independent (London). +Jump up ^ "Overview of Highland Boundary Fault". Gazetteer for Scotland. University of Edinburgh. Retrieved 27 December 2010. +Jump up ^ "Ben Nevis Weather". Ben Nevis Weather. Retrieved 26 October 2008. +Jump up ^ "Profile: Wales". BBC News. 9 June 2010. Retrieved 7 November 2010. +Jump up ^ Giles Darkes (26 April 2014). "How long is the UK coastline?". The British Cartographic Society. +Jump up ^ "Geography of Northern Ireland". University of Ulster. Retrieved 22 May 2006. +Jump up ^ "UK climate summaries". Met Office. Retrieved 1 May 2011. +Jump up ^ United Nations Economic and Social Council (August 2007). "Ninth UN Conference on the standardization of Geographical Names". UN Statistics Division. Archived from the original on 1 December 2009. Retrieved 21 October 2008. +Jump up ^ Barlow, I.M. (1991). Metropolitan Government. London: Routledge. ISBN 978-0-415-02099-2. +Jump up ^ "Welcome to the national site of the Government Office Network". Government Offices. Archived from the original on 15 June 2009. Retrieved 3 July 2008. +Jump up ^ "A short history of London government". Greater London Authority. Archived from the original on 21 April 2008. Retrieved 4 October 2008. +Jump up ^ Sherman, Jill; Norfolk, Andrew (5 November 2004). "Prescott's dream in tatters as North East rejects assembly". The Times (London). Retrieved 15 February 2008. The Government is now expected to tear up its twelve-year-old plan to create eight or nine regional assemblies in England to mirror devolution in Scotland and Wales. (subscription required) +Jump up ^ "Local Authority Elections". Local Government Association. Retrieved 3 October 2008.[dead link] +Jump up ^ "STV in Scotland: Local Government Elections 2007". Political Studies Association. Archived from the original on 20 March 2011. Retrieved 2 August 2008. +Jump up ^ Ethical Standards in Public Life framework: "Ethical Standards in Public Life". The Scottish Government. Retrieved 3 October 2008. +Jump up ^ "Who we are". Convention of Scottish Local Authorities. Retrieved 5 July 2011. +Jump up ^ "Local Authorities". The Welsh Assembly Government. Retrieved 31 July 2008. +Jump up ^ "Local government elections in Wales". The Electoral Commission. 2008. Retrieved 8 April 2011. +Jump up ^ "Welsh Local Government Association". Welsh Local Government Association. Retrieved 20 March 2008. +Jump up ^ Devenport, Mark (18 November 2005). "NI local government set for shake-up". BBC News. Retrieved 15 November 2008. +Jump up ^ "Foster announces the future shape of local government" (Press release). Northern Ireland Executive. 13 March 2008. Retrieved 20 October 2008. +Jump up ^ "Local Government elections to be aligned with review of public administration" (Press release). Northern Ireland Office. 25 April 2008. Retrieved 2 August 2008.[dead link] +Jump up ^ "CIBC PWM Global – Introduction to The Cayman Islands". Cibc.com. 11 July 2012. Retrieved 17 August 2012. +Jump up ^ Rappeport, Laurie. "Cayman Islands Tourism". Washington DC: USA Today Travel Tips. Retrieved 9 April 2013. +Jump up ^ "Working with Overseas Territories". Foreign & Commonwealth Office. 6 October 2010. Retrieved 5 November 2010. +Jump up ^ http://www.justice.gov.uk/downloads/about/moj/our-responsibilities/Background_Briefing_on_the_Crown_Dependencies2.pdf +Jump up ^ "Overseas Territories". Foreign & Commonwealth Office. Retrieved 6 September 2010. +Jump up ^ "The World Factbook". CIA. Retrieved 26 December 2010. +Jump up ^ "Country profiles". Foreign & Commonwealth Office. 21 February 2008. Retrieved 6 September 2010.[dead link] +Jump up ^ Davison, Phil (18 August 1995). "Bermudians vote to stay British". The Independent (London). Retrieved 11 September 2012. +Jump up ^ The Committee Office, House of Commons. "House of Commons – Crown Dependencies – Justice Committee". Publications.parliament.uk. Retrieved 7 November 2010. +Jump up ^ Fact sheet on the UK's relationship with the Crown Dependencies – gov.uk, Ministry of Justice. Retrieved 25 August 2014. +Jump up ^ "Profile of Jersey". States of Jersey. Retrieved 31 July 2008. The legislature passes primary legislation, which requires approval by The Queen in Council, and enacts subordinate legislation in many areas without any requirement for Royal Sanction and under powers conferred by primary legislation. +Jump up ^ "Chief Minister to meet Channel Islands counterparts – Isle of Man Public Services" (Press release). Isle of Man Government. 29 May 2012. Retrieved 9 April 2013.[dead link] +Jump up ^ Bagehot, Walter (1867). The English Constitution. London: Chapman and Hall. p. 103. +Jump up ^ Carter, Sarah. "A Guide To the UK Legal System". University of Kent at Canterbury. Retrieved 16 May 2006. +Jump up ^ "Parliamentary sovereignty". UK Parliament. n.d. Archived from the original on 27 May 2012. +Jump up ^ "The Government, Prime Minister and Cabinet". Public services all in one place. Directgov. Retrieved 12 February 2010. +Jump up ^ "Brown is UK's new prime minister". BBC News. 27 June 2007. Retrieved 23 January 2008. +Jump up ^ "David Cameron is UK's new prime minister". BBC News. 11 May 2010. Retrieved 11 May 2010. +Jump up ^ November 2010 "Elections and voting". UK Parliament. Archived from the original on 14 November 2010. Retrieved 14 November 2010. +Jump up ^ November 2010 "The Parliament Acts". UK Parliament. Archived from the original on 14 November 2010. +Jump up ^ "United Kingdom". European Election Database. Norwegian Social Science Data Services. Retrieved 3 July 2010. +Jump up ^ Wainwright, Martin (28 May 2010). "Thirsk and Malton: Conservatives take final seat in parliament". The Guardian (London). Retrieved 3 July 2010. +Jump up ^ "Scots MPs attacked over fees vote". BBC News. 27 January 2004. Retrieved 21 October 2008. +Jump up ^ Taylor, Brian (1 June 1998). "Talking Politics: The West Lothian Question". BBC News. Retrieved 21 October 2008. +Jump up ^ "England-only laws 'need majority from English MPs'". BBC News. 25 March 2013. Retrieved 28 April 2013. +Jump up ^ "Scotland's Parliament – powers and structures". BBC News. 8 April 1999. Retrieved 21 October 2008. +Jump up ^ "Salmond elected as first minister". BBC News. 16 May 2007. Retrieved 21 October 2008. +Jump up ^ "Scottish election: SNP wins election". BBC News. 6 May 2011. +Jump up ^ "Structure and powers of the Assembly". BBC News. 9 April 1999. Retrieved 21 October 2008. +Jump up ^ "Carwyn Jones clinches leadership in Wales". WalesOnline (Media Wales). 1 December 2009. Retrieved 1 December 2009. +Jump up ^ "Devolved Government – Ministers and their departments". Northern Ireland Executive. Archived from the original on 22 August 2007. +Jump up ^ Burrows, N. (1999). "Unfinished Business: The Scotland Act 1998". The Modern Law Review 62 (2): 241–60 [p. 249]. doi:10.1111/1468-2230.00203. The UK Parliament is sovereign and the Scottish Parliament is subordinate. The White Paper had indicated that this was to be the approach taken in the legislation. The Scottish Parliament is not to be seen as a reflection of the settled will of the people of Scotland or of popular sovereignty but as a reflection of its subordination to a higher legal authority. Following the logic of this argument, the power of the Scottish Parliament to legislate can be withdrawn or overridden... +Jump up ^ Elliot, M. (2004). "United Kingdom: Parliamentary sovereignty under pressure". International Journal of Constitutional Law 2 (3): 545–627 [pp. 553–554]. doi:10.1093/icon/2.3.545. Notwithstanding substantial differences among the schemes, an important common factor is that the U.K. Parliament has not renounced legislative sovereignty in relation to the three nations concerned. For example, the Scottish Parliament is empowered to enact primary legislation on all matters, save those in relation to which competence is explicitly denied ... but this power to legislate on what may be termed "devolved matters" is concurrent with the Westminster Parliament's general power to legislate for Scotland on any matter at all, including devolved matters ... In theory, therefore, Westminster may legislate on Scottish devolved matters whenever it chooses... +Jump up ^ Walker, G. (2010). "Scotland, Northern Ireland, and Devolution, 1945–1979". Journal of British Studies 39 (1): 124 & 133. doi:10.1086/644536. +Jump up ^ Gamble, A. "The Constitutional Revolution in the United Kingdom". Publius 36 (1): 19–35 [p. 29]. doi:10.1093/publius/pjj011. The British parliament has the power to abolish the Scottish parliament and the Welsh assembly by a simple majority vote in both houses, but since both were sanctioned by referenda, it would be politically difficult to abolish them without the sanction of a further vote by the people. In this way several of the constitutional measures introduced by the Blair government appear to be entrenched and not subject to a simple exercise of parliamentary sovereignty at Westminster. +Jump up ^ Meehan, E. (1999). "The Belfast Agreement—Its Distinctiveness and Points of Cross-Fertilization in the UK's Devolution Programme". Parliamentary Affairs 52 (1): 19–31 [p. 23]. doi:10.1093/pa/52.1.19. [T]he distinctive involvement of two governments in the Northern Irish problem means that Northern Ireland's new arrangements rest upon an intergovernmental agreement. If this can be equated with a treaty, it could be argued that the forthcoming distribution of power between Westminster and Belfast has similarities with divisions specified in the written constitutions of federal states... Although the Agreement makes the general proviso that Westminster's 'powers to make legislation for Northern Ireland' remains 'unaffected', without an explicit categorical reference to reserved matters, it may be more difficult than in Scotland or Wales for devolved powers to be repatriated. The retraction of devolved powers would not merely entail consultation in Northern Ireland backed implicitly by the absolute power of parliamentary sovereignty but also the renegotiation of an intergovernmental agreement. +Jump up ^ "The Treaty (act) of the Union of Parliament 1706". Scottish History Online. Retrieved 5 October 2008. +Jump up ^ "UK Supreme Court judges sworn in". BBC News. 1 October 2009. +Jump up ^ "Constitutional reform: A Supreme Court for the United Kingdom". Department for Constitutional Affairs. July 2003. Retrieved 13 May 2013. +Jump up ^ "Role of the JCPC". Judicial Committee of the Privy Council. Retrieved 28 April 2013. +Jump up ^ Bainham, Andrew (1998). The international survey of family law: 1996. The Hague: Martinus Nijhoff. p. 298. ISBN 978-90-411-0573-8. +Jump up ^ Adeleye, Gabriel; Acquah-Dadzie, Kofi; Sienkewicz, Thomas; McDonough, James (1999). World dictionary of foreign expressions. Waucojnda, IL: Bolchazy-Carducci. p. 371. ISBN 978-0-86516-423-9. +Jump up ^ "The Australian courts and comparative law". Australian Law Postgraduate Network. Retrieved 28 December 2010. +Jump up ^ "Court of Session – Introduction". Scottish Courts. Retrieved 5 October 2008.[dead link] +Jump up ^ "High Court of Justiciary – Introduction". Scottish Courts. Retrieved 5 October 2008.[dead link] +Jump up ^ "House of Lords – Practice Directions on Permission to Appeal". UK Parliament. Retrieved 22 June 2009. +Jump up ^ "Introduction". Scottish Courts. Retrieved 5 October 2008.[dead link] +Jump up ^ Samuel Bray (2005). "Not proven: introducing a third verdict". The University of Chicago Law Review 72 (4): 1299. Retrieved 30 November 2013. +Jump up ^ "Police-recorded crime down by 9%". BBC News. 17 July 2008. Retrieved 21 October 2008. +Jump up ^ "New record high prison population". BBC News. 8 February 2008. Retrieved 21 October 2008. +Jump up ^ "Crime falls to 32 year low" (Press release). Scottish Government. 7 September 2010. Retrieved 21 April 2011. +Jump up ^ "Prisoner Population at Friday 22 August 2008". Scottish Prison Service. Retrieved 28 August 2008. +Jump up ^ "Scots jail numbers at record high". BBC News. 29 August 2008. Retrieved 21 October 2008. +Jump up ^ Swaine, Jon (13 January 2009). "Barack Obama presidency will strengthen special relationship, says Gordon Brown". The Daily Telegraph (London). Retrieved 3 May 2011. +Jump up ^ Kirchner, E. J.; Sperling, J. (2007). Global Security Governance: Competing Perceptions of Security in the 21st Century. London: Taylor & Francis. p. 100. ISBN 0-415-39162-8 +Jump up ^ The Committee Office, House of Commons (19 February 2009). "DFID's expenditure on development assistance". UK Parliament. Retrieved 28 April 2013. +Jump up ^ "Ministry of Defence". Ministry of Defence. Retrieved 21 February 2012. +Jump up ^ "Speaker addresses Her Majesty Queen Elizabeth II". UK Parliament. 30 March 2012. Retrieved 28 April 2013. +Jump up ^ "House of Commons Hansard". UK Parliament. Retrieved 23 October 2008. +Jump up ^ UK 2005: The Official Yearbook of the United Kingdom of Great Britain and Northern Ireland. Office for National Statistics. p. 89. +Jump up ^ "Principles for Economic Regulation". Department for Business, Innovation & Skills. April 2011. Retrieved 1 May 2011. +Jump up ^ "United Kingdom". International Monetary Fund. Retrieved 1 October 2009. +Jump up ^ Chavez-Dreyfuss, Gertrude (1 April 2008). "Global reserves, dollar share up at end of 2007-IMF". Reuters. Retrieved 21 December 2009. +Jump up ^ "More About the Bank". Bank of England. n.d. Archived from the original on 12 March 2008. +Jump up ^ "Index of Services (experimental)". Office for National Statistics. 7 May 2006. Archived from the original on 7 May 2006. +Jump up ^ Sassen, Saskia (2001). The Global City: New York, London, Tokyo (2nd ed.). Princeton University Press. ISBN 0-691-07866-1. +^ Jump up to: a b "Global Financial Centres 7". Z/Yen. 2010. Retrieved 21 April 2010. +^ Jump up to: a b "Worldwide Centres of Commerce Index 2008". Mastercard. Retrieved 5 July 2011. +^ Jump up to: a b Zumbrun, Joshua (15 July 2008). ""World's Most Economically Powerful Cities".". Forbes (New York). Archived from the original on 19 May 2011. Retrieved 3 October 2010. +Jump up ^ "Global city GDP rankings 2008–2025". PricewaterhouseCoopers. Archived from the original on 19 May 2011. Retrieved 16 November 2010. +Jump up ^ Lazarowicz, Mark (Labour MP) (30 April 2003). "Financial Services Industry". UK Parliament. Retrieved 17 October 2008. +Jump up ^ International Tourism Receipts[dead link]. UNWTO Tourism Highlights, Edition 2005. page 12. World Tourism Organisation. Retrieved 24 May 2006. +Jump up ^ Bremner, Caroline (10 January 2010). "Euromonitor International's Top City Destination Ranking". Euromonitor International. Archived from the original on 19 May 2011. Retrieved 31 May 2011. +Jump up ^ "From the Margins to the Mainstream – Government unveils new action plan for the creative industries". DCMS. 9 March 2007. Retrieved 9 March 2007.[dead link] +^ Jump up to: a b "European Countries – United Kingdom". Europa (web portal). Retrieved 15 December 2010. +Jump up ^ Harrington, James W.; Warf, Barney (1995). Industrial location: Principles, practices, and policy. London: Routledge. p. 121. ISBN 978-0-415-10479-1. +Jump up ^ Spielvogel, Jackson J. (2008). Western Civilization: Alternative Volume: Since 1300. Belmont, CA: Thomson Wadsworth. ISBN 978-0-495-55528-5. +Jump up ^ Hewitt, Patricia (15 July 2004). "TUC Manufacturing Conference". Department of Trade and Industry. Retrieved 16 May 2006. +Jump up ^ "Industry topics". Society of Motor Manufacturers and Traders. 2011. Retrieved 5 July 2011. +Jump up ^ Robertson, David (9 January 2009). "The Aerospace industry has thousands of jobs in peril". The Times (London). Retrieved 9 June 2011. (subscription required) +Jump up ^ "Facts & Figures – 2009". Aerospace & Defence Association of Europe. Retrieved 9 June 2011.[dead link] +Jump up ^ "UK Aerospace Industry Survey – 2010". ADS Group. Retrieved 9 June 2011. +^ Jump up to: a b c d http://www.theengineer.co.uk/aerospace/in-depth/reasons-to-be-cheerful-about-the-uk-aerospace-sector/1017274.article +Jump up ^ "The Pharmaceutical sector in the UK". Department for Business, Innovation & Skills. Retrieved 9 June 2011. +Jump up ^ "Ministerial Industry Strategy Group – Pharmaceutical Industry: Competitiveness and Performance Indicators". Department of Health. Retrieved 9 June 2011.[dead link] +Jump up ^ [1][dead link] +Jump up ^ "UK in recession as economy slides". BBC News. 23 January 2009. Retrieved 23 January 2009. +Jump up ^ "UK youth unemployment at its highest in two decades: 22.5%". MercoPress. 15 April 2012. +Jump up ^ Groom, Brian (19 January 2011). "UK youth unemployment reaches record". Financial Times (London). +Jump up ^ "Release: EU Government Debt and Deficit returns". Office for National Statistics. March 2012. Retrieved 17 August 2012. +Jump up ^ "UK loses top AAA credit rating for first time since 1978". BBC News. 23 February 2013. Retrieved 23 February 2013. +Jump up ^ "Britain sees real wages fall 3.2%". Daily Express (London). 2 March 2013. +Jump up ^ Beckford, Martin (5 December 2011). "Gap between rich and poor growing fastest in Britain". The Daily Telegraph (London). +Jump up ^ "United Kingdom: Numbers in low income". The Poverty Site. Retrieved 25 September 2009. +Jump up ^ "United Kingdom: Children in low income households". The Poverty Site. Retrieved 25 September 2009. +Jump up ^ "Warning of food price hike crisis". BBC News. 4 April 2009. +Jump up ^ Andrews, J. (16 January 2013). "How poor is Britain now". Yahoo! Finance UK +Jump up ^ Glynn, S.; Booth, A. (1996). Modern Britain: An Economic and Social History. London: Routledge. +Jump up ^ "Report highlights 'bleak' poverty levels in the UK" Phys.org, 29 March 2013 +Jump up ^ Gascoin, J. "A reappraisal of the role of the universities in the Scientific Revolution", in Lindberg, David C. and Westman, Robert S., eds (1990), Reappraisals of the Scientific Revolution. Cambridge University Press. p. 248. ISBN 0-521-34804-8. +Jump up ^ Reynolds, E.E.; Brasher, N.H. (1966). Britain in the Twentieth Century, 1900–1964. Cambridge University Press. p. 336. OCLC 474197910 +Jump up ^ Burtt, E.A. (2003) [1924].The Metaphysical Foundations of Modern Science. Mineola, NY: Courier Dover. p. 207. ISBN 0-486-42551-7. +Jump up ^ Hatt, C. (2006). Scientists and Their Discoveries. London: Evans Brothers. pp. 16, 30 and 46. ISBN 0-237-53195-X. +Jump up ^ Jungnickel, C.; McCormmach, R. (1996). Cavendish. American Philosophical Society. ISBN 0-87169-220-1. +Jump up ^ "The Nobel Prize in Physiology or Medicine 1945: Sir Alexander Fleming, Ernst B. Chain, Sir Howard Florey". The Nobel Foundation. Archived from the original on 21 June 2011. +Jump up ^ Hatt, C. (2006). Scientists and Their Discoveries. London: Evans Brothers. p. 56. ISBN 0-237-53195-X. +Jump up ^ James, I. (2010). Remarkable Engineers: From Riquet to Shannon. Cambridge University Press. pp. 33–6. ISBN 0-521-73165-8. +Jump up ^ Bova, Ben (2002) [1932]. The Story of Light. Naperville, IL: Sourcebooks. p. 238. ISBN 978-1-4022-0009-0. +Jump up ^ "Alexander Graham Bell (1847–1922)". Scottish Science Hall of Fame. Archived from the original on 21 June 2011. +Jump up ^ "John Logie Baird (1888–1946)". BBC History. Archived from the original on 21 June 2011. +Jump up ^ Cole, Jeffrey (2011). Ethnic Groups of Europe: An Encyclopedia. Santa Barbara, CA: ABC-CLIO. p. 121. ISBN 1-59884-302-8. +Jump up ^ Castells, M.; Hall, P.; Hall, P.G. (2004). Technopoles of the World: the Making of Twenty-First-Century Industrial Complexes. London: Routledge. pp. 98–100. ISBN 0-415-10015-1. +Jump up ^ "Knowledge, networks and nations: scientific collaborations in the twenty-first century". Royal Society. 2011. Archived from the original on 22 June 2011. +Jump up ^ McCook, Alison. "Is peer review broken?". Reprinted from the Scientist 20(2) 26, 2006. Archived from the original on 21 June 2011. +^ Jump up to: a b "Heathrow 'needs a third runway'". BBC News. 25 June 2008. Retrieved 17 October 2008. +^ Jump up to: a b "Statistics: Top 30 World airports" (Press release). Airports Council International. July 2008. Retrieved 15 October 2008. +Jump up ^ "Transport Statistics Great Britain: 2010". Department for Transport. Archived from the original on 16 December 2010. +Jump up ^ "Major new rail lines considered". BBC News. 21 June 2008. Archived from the original on 9 October 2010. +Jump up ^ "Crossrail's giant tunnelling machines unveiled". BBC News. 2 January 2012. +Jump up ^ Leftly, Mark (29 August 2010). "Crossrail delayed to save £1bn". The Independent on Sunday (London). +^ Jump up to: a b "Size of Reporting Airports October 2009 – September 2010". Civil Aviation Authority. Retrieved 5 December 2010. +Jump up ^ "BMI being taken over by Lufthansa". BBC News. 29 October 2008. Retrieved 23 December 2009. +Jump up ^ "United Kingdom Energy Profile". U.S. Energy Information Administration. Retrieved 4 November 2010. +Jump up ^ Mason, Rowena (24 October 2009). "Let the battle begin over black gold". The Daily Telegraph (London). Retrieved 26 November 2010. +Jump up ^ Heath, Michael (26 November 2010). "RBA Says Currency Containing Prices, Rate Level 'Appropriate' in Near Term". Bloomberg (New York). Retrieved 26 November 2010. +^ Jump up to: a b c "Nuclear Power in the United Kingdom". World Nuclear Association. April 2013. Retrieved 9 April 2013. +^ Jump up to: a b c "United Kingdom – Oil". U.S. Energy Information Administration. Retrieved 4 November 2010.[dead link] +Jump up ^ "Diminishing domestic reserves, escalating imports". EDF Energy. Retrieved 9 April 2013. +^ Jump up to: a b "United Kingdom – Natural Gas". U.S. Energy Information Administration. Retrieved 4 November 2010.[dead link] +^ Jump up to: a b "United Kingdom – Quick Facts Energy Overview". U.S. Energy Information Administration. Retrieved 4 November 2010.[dead link] +Jump up ^ The Coal Authority (10 April 2006). "Coal Reserves in the United Kingdom". The Coal Authority. Archived from the original on 4 January 2009. Retrieved 5 July 2011. +Jump up ^ "England Expert predicts 'coal revolution'". BBC News. 16 October 2007. Retrieved 23 September 2008. +Jump up ^ Watts, Susan (20 March 2012). "Fracking: Concerns over gas extraction regulations". BBC News. Retrieved 9 April 2013. +Jump up ^ "Quit fracking aboot". Friends of the Earth Scotland. Retrieved 9 April 2013. +Jump up ^ "Census Geography". Office for National Statistics. 30 October 2007. Archived from the original on 4 June 2011. Retrieved 14 April 2012. +Jump up ^ "Welcome to the 2011 Census for England and Wales". Office for National Statistics. n.d. Retrieved 11 October 2008. +^ Jump up to: a b c "2011 Census: Population Estimates for the United Kingdom". Office for National Statistics. 27 March 2011. Retrieved 18 December 2012. +^ Jump up to: a b c "Annual Mid-year Population Estimates, 2010". Office for National Statistics. 2011. Retrieved 14 April 2012. +Jump up ^ Batty, David (30 December 2010). "One in six people in the UK today will live to 100, study says". The Guardian (London). +^ Jump up to: a b "2011 UK censuses". Office for National Statistics. Retrieved 18 December 2012. +Jump up ^ "Population: UK population grows to 59.6 million" (Press release). Office for National Statistics. 24 June 2004. Archived from the original on 22 July 2004. Retrieved 14 April 2012. +Jump up ^ Khan, Urmee (16 September 2008). "England is most crowded country in Europe". The Daily Telegraph (London). Retrieved 5 September 2009. +Jump up ^ Carrell, Severin (17 December 2012). "Scotland's population at record high". The Guardian. London. Retrieved 18 December 2012. +^ Jump up to: a b c "Vital Statistics: Population and Health Reference Tables (February 2014 Update): Annual Time Series Data". ONS. Retrieved 27 April 2014. +Jump up ^ Boseley, Sarah (14 July 2008). "The question: What's behind the baby boom?". The Guardian (London). p. 3. Retrieved 28 August 2009. +Jump up ^ Tables, Graphs and Maps Interface (TGM) table. Eurostat (26 February 2013). Retrieved 12 July 2013. +Jump up ^ Campbell, Denis (11 December 2005). "3.6m people in Britain are gay – official". The Observer (London). Retrieved 28 April 2013. +Jump up ^ "2011 Census - Built-up areas". ONS. Retrieved 1 July 2013. +Jump up ^ Mid-2012 Population Estimates for Settlements and Localities in Scotland General Register Office for Scotland +Jump up ^ "Belfast Metropolitan Urban Area NISRA 2005". Retrieved 28 April 2013. +Jump up ^ 2011 Census: KS201UK Ethnic group, local authorities in the United Kingdom, Accessed 21 February 2014 +Jump up ^ "Welsh people could be most ancient in UK, DNA suggests". BBC News. 19 June 2012. Retrieved 28 April 2013. +Jump up ^ Thomas, Mark G. et al. "Evidence for a segregated social structure in early Anglo-Saxon England". Proceedings of the Royal Society B: Biological Sciences 273(1601): 2651–2657. +Jump up ^ Owen, James (19 July 2005). "Review of 'The Tribes of Britain'". National Geographic (Washington DC). +Jump up ^ Oppenheimer, Stephen (October 2006). "Myths of British ancestry" at the Wayback Machine (archived 26 September 2006). Prospect (London). Retrieved 5 November 2010. +Jump up ^ Henderson, Mark (23 October 2009). "Scientist – Griffin hijacked my work to make race claim about 'British aborigines'". The Times (London). Retrieved 26 October 2009. (subscription required) +Jump up ^ Costello, Ray (2001). Black Liverpool: The Early History of Britain's Oldest Black Community 1730–1918. Liverpool: Picton Press. ISBN 1-873245-07-6. +Jump up ^ "Culture and Ethnicity Differences in Liverpool – Chinese Community". Chambré Hardman Trust. Retrieved 26 October 2009. +Jump up ^ Coleman, David; Compton, Paul; Salt, John (2002). "The demographic characteristics of immigrant populations", Council of Europe, p.505. ISBN 92-871-4974-7. +Jump up ^ Mason, Chris (30 April 2008). "'Why I left UK to return to Poland'". BBC News. +Jump up ^ "Resident population estimates by ethnic group (percentages): London". Office for National Statistics. Retrieved 23 April 2008. +Jump up ^ "Resident population estimates by ethnic group (percentages): Leicester". Office for National Statistics. Retrieved 23 April 2008. +Jump up ^ "Census 2001 – Ethnicity and religion in England and Wales". Office for National Statistics. Retrieved 23 April 2008. +Jump up ^ Loveys, Kate (22 June 2011). "One in four primary school pupils are from an ethnic minority and almost a million schoolchildren do not speak English as their first language". Daily Mail (London). Retrieved 28 June 2011. +Jump up ^ Rogers, Simon (19 May 2011). "Non-white British population reaches 9.1 million". The Guardian (London). +Jump up ^ Wallop, Harry (18 May 2011). "Population growth of last decade driven by non-white British". The Daily Telegraph (London). +Jump up ^ "Official EU languages". European Commission. 8 May 2009. Retrieved 16 October 2009. +Jump up ^ "Language Courses in New York". United Nations. 2006. Retrieved 29 November 2010. +Jump up ^ "English language – Government, citizens and rights". Directgov. Retrieved 23 August 2011. +Jump up ^ "Commonwealth Secretariat – UK". Commonwealth Secretariat. Retrieved 23 August 2011. +^ Jump up to: a b c "Languages across Europe: United Kingdom". BBC. Retrieved 4 February 2013. +Jump up ^ Booth, Robert (30 January 2013). "Polish becomes England's second language". The Guardian (London). Retrieved 4 February 2012. +Jump up ^ European Charter for Regional or Minority Languages, Strasbourg, 5.XI.1992 - http://conventions.coe.int/treaty/en/Treaties/Html/148.htm +Jump up ^ Framework Convention for the Protection of National Minorities, Strasbourg, 1.II.1995 - http://conventions.coe.int/Treaty/en/Treaties/Html/157.htm +Jump up ^ National Statistics Online – Welsh Language[dead link]. National Statistics Office. +Jump up ^ "Differences in estimates of Welsh Language Skills". Office for National Statistics. Archived from the original on 12 January 2010. Retrieved 30 December 2008. +Jump up ^ Wynn Thomas, Peter (March 2007). "Welsh today". Voices. BBC. Retrieved 5 July 2011. +Jump up ^ "Scotland's Census 2001 – Gaelic Report". General Register Office for Scotland. Retrieved 28 April 2013. +Jump up ^ "Local UK languages 'taking off'". BBC News. 12 February 2009. +Jump up ^ Edwards, John R. (2010). Minority languages and group identity: cases and categories. John Benjamins. pp. 150–158. ISBN 978-90-272-1866-7. Retrieved 12 March 2011. +Jump up ^ Koch, John T. (2006). Celtic culture: a historical encyclopedia. ABC-CLIO. p. 696. ISBN 978-1-85109-440-0. +Jump up ^ "Language Data – Scots". European Bureau for Lesser-Used Languages. Archived from the original on 23 June 2007. Retrieved 2 November 2008. +Jump up ^ "Fall in compulsory language lessons". BBC News. 4 November 2004. +Jump up ^ "The School Gate for parents in Wales". BBC. Retrieved 28 April 2013. +Jump up ^ Cannon, John, ed. (2nd edn., 2009). A Dictionary of British History. Oxford University Press. p. 144. ISBN 0-19-955037-9. +Jump up ^ Field, Clive D. (November 2009). "British religion in numbers"[dead link]. BRIN Discussion Series on Religious Statistics, Discussion Paper 001. Retrieved 3 June 2011. +Jump up ^ Yilmaz, Ihsan (2005). Muslim Laws, Politics and Society in Modern Nation States: Dynamic Legal Pluralisms in England, Turkey, and Pakistan. Aldershot: Ashgate Publishing. pp. 55–6. ISBN 0-7546-4389-1. +Jump up ^ Brown, Callum G. (2006). Religion and Society in Twentieth-Century Britain. Harlow: Pearson Education. p. 291. ISBN 0-582-47289-X. +Jump up ^ Norris, Pippa; Inglehart, Ronald (2004). Sacred and Secular: Religion and Politics Worldwide. Cambridge University Press. p. 84. ISBN 0-521-83984-X. +Jump up ^ Fergusson, David (2004). Church, State and Civil Society. Cambridge University Press. p. 94. ISBN 0-521-52959-X. +Jump up ^ "UK Census 2001". National Office for Statistics. Archived from the original on 12 March 2007. Retrieved 22 April 2007. +Jump up ^ "Religious Populations". Office for National Statistics. 11 October 2004. Archived from the original on 6 June 2011. +Jump up ^ "United Kingdom: New Report Finds Only One in 10 Attend Church". News.adventist.org. 4 April 2007. Retrieved 12 September 2010. +Jump up ^ Philby, Charlotte (12 December 2012). "Less religious and more ethnically diverse: Census reveals a picture of Britain today". The Independent (London). +Jump up ^ The History of the Church of England. The Church of England. Retrieved 23 November 2008. +Jump up ^ "Queen and Church of England". British Monarchy Media Centre. Archived from the original on 8 October 2006. Retrieved 5 June 2010. +Jump up ^ "Queen and the Church". The British Monarchy (Official Website). Archived from the original on 7 June 2011. +Jump up ^ "How we are organised". Church of Scotland. Archived from the original on 7 June 2011. +Jump up ^ Weller, Paul (2005). Time for a Change: Reconfiguring Religion, State, and Society. London: Continuum. pp. 79–80. ISBN 0567084876. +Jump up ^ Peach, Ceri, "United Kingdom, a major transformation of the religious landscape", in H. Knippenberg. ed. (2005). The Changing Religious Landscape of Europe. Amsterdam: Het Spinhuis. pp. 44–58. ISBN 90-5589-248-3. +Jump up ^ Richards, Eric (2004). Britannia's children: Emigration from England, Scotland, Wales and Ireland since 1600. London: Hambledon, p. 143. ISBN 978-1-85285-441-6. +Jump up ^ Gibney, Matthew J.; Hansen, Randall (2005). Immigration and asylum: from 1900 to the present, ABC-CLIO, p. 630. ISBN 1-57607-796-9 +Jump up ^ "Short history of immigration". BBC. 2005. Retrieved 28 August 2010. +Jump up ^ Rogers, Simon (11 December 2012). "Census 2011 mapped and charted: England & Wales in religion, immigration and race". London: Guardian. Retrieved 11 December 2012. +Jump up ^ 6.5% of the EU population are foreigners and 9.4% are born abroad, Eurostat, Katya Vasileva, 34/2011. +Jump up ^ Muenz, Rainer (June 2006). "Europe: Population and Migration in 2005". Migration Policy Institute. Retrieved 2 April 2007. +Jump up ^ "Immigration and births to non-British mothers pushes British population to record high". London Evening Standard. 21 August 2008. +Jump up ^ Doughty, Steve; Slack, James (3 June 2008). "Third World migrants behind our 2.3m population boom". Daily Mail (London). +Jump up ^ Bentham, Martin (20 October 2008). "Tories call for tougher control of immigration". London Evening Standard. +Jump up ^ "Minister rejects migrant cap plan". BBC News. 8 September 2008. Retrieved 26 April 2011. +Jump up ^ Johnston, Philip (5 January 2007). "Immigration 'far higher' than figures say". The Daily Telegraph (London). Retrieved 20 April 2007. +Jump up ^ Travis, Alan (25 August 2011). "UK net migration rises 21%". The Guardian (London). +^ Jump up to: a b "Migration Statistics Quarterly Report May 2012". Office for National Statistics. 24 May 2012. +Jump up ^ "Migration to UK more than double government target". BBC News. 24 May 2012. +^ Jump up to: a b "Citizenship". Home Office. August 2011. Retrieved 24 October 2011.[dead link] +Jump up ^ Bamber, David (20 December 2000). "Migrant squad to operate in France". The Daily Telegraph (London). +Jump up ^ "Settlement". Home Office. August 2011. Retrieved 24 October 2011.[dead link] +Jump up ^ "Births in England and Wales by parents' country of birth, 2011". Office for National Statistics. 30 August 2012. Retrieved 28 April 2013. +Jump up ^ "Right of Union citizens and their family members to move and reside freely within the territory of the Member States". European Commission. Retrieved 28 April 2013. +Jump up ^ Doward, Jamie; Temko, Ned (23 September 2007). "Home Office shuts the door on Bulgaria and Romania". The Observer (London). p. 2. Retrieved 23 August 2008. +Jump up ^ Sumption, Madeleine; Somerville, Will (January 2010). The UK's new Europeans: Progress and challenges five years after accession. Policy Report (London: Equality and Human Rights Commission). p. 13. ISBN 978-1-84206-252-4. Retrieved 19 January 2010. +Jump up ^ Doward, Jamie; Rogers, Sam (17 January 2010). "Young, self-reliant, educated: portrait of UK's eastern European migrants". The Observer (London). Retrieved 19 January 2010. +Jump up ^ Hopkirk, Elizabeth (20 October 2008). "Packing up for home: Poles hit by UK's economic downturn". London Evening Standard. +Jump up ^ "Migrants to UK 'returning home'". BBC News. 8 September 2009. Retrieved 8 September 2009. +Jump up ^ "UK sees shift in migration trend". BBC News. 27 May 2010. Retrieved 28 May 2010. +Jump up ^ "Fresh Talent: Working in Scotland". London: UK Border Agency. Retrieved 30 October 2010. +Jump up ^ Boxell, James (28 June 2010). "Tories begin consultation on cap for migrants". Financial Times (London). Retrieved 17 September 2010. +Jump up ^ "Vince Cable: Migrant cap is hurting economy". The Guardian (London). Press Association. 17 September 2010. Retrieved 17 September 2010. +Jump up ^ Richards (2004), pp. 6–7. +^ Jump up to: a b Sriskandarajah, Dhananjayan; Drew, Catherine (11 December 2006). "Brits Abroad: Mapping the scale and nature of British emigration". Institute for Public Policy Research. Retrieved 20 January 2007. +Jump up ^ "Brits Abroad: world overview". BBC. n.d. Retrieved 20 April 2007. +Jump up ^ Casciani, Dominic (11 December 2006). "5.5 m Britons 'opt to live abroad'". BBC News. Retrieved 20 April 2007. +Jump up ^ "Brits Abroad: Country-by-country". BBC News. 11 December 2006. +Jump up ^ "Local Authorities". Department for Children, Schools and Families. Retrieved 21 December 2008. +Jump up ^ Gordon, J.C.B. (1981). Verbal Deficit: A Critique. London: Croom Helm. p. 44 note 18. ISBN 978-0-85664-990-5. +Jump up ^ Section 8 ('Duty of local education authorities to secure provision of primary and secondary schools'), Sections 35–40 ('Compulsory attendance at Primary and Secondary Schools') and Section 61 ('Prohibition of fees in schools maintained by local education authorities ...'), Education Act 1944. +Jump up ^ "England's pupils in global top 10". BBC News. 10 December 2008. +Jump up ^ "More state pupils in universities". BBC News. 19 July 2007. +Jump up ^ MacLeod, Donald (9 November 2007). "Private school pupil numbers in decline". The Guardian (London). Retrieved 31 March 2010. +Jump up ^ Frankel, Hannah (3 September 2010). "Is Oxbridge still a preserve of the posh?". TES (London). Retrieved 9 April 2013. +Jump up ^ "World's top 100 universities 2013: their reputations ranked by Times Higher Education". The Guardian (London). 2013. Retrieved 23 October 2014. +Jump up ^ Davenport, F.; Beech, C.; Downs, T.; Hannigan, D. (2006). Ireland. Lonely Planet, 7th edn. ISBN 1-74059-968-3. p. 564. +Jump up ^ "About SQA". Scottish Qualifications Authority. 10 April 2013. Retrieved 28 April 2013. +Jump up ^ "About Learning and Teaching Scotland". Learning and Teaching Scotland. Retrieved 28 April 2013. +Jump up ^ "Brain drain in reverse". Scotland Online Gateway. July 2002. Archived from the original on 4 December 2007. +Jump up ^ "Increase in private school intake". BBC News. 17 April 2007. +Jump up ^ "MSPs vote to scrap endowment fee". BBC News. 28 February 2008. +Jump up ^ What will your child learn?[dead link] The Welsh Assembly Government. Retrieved 22 January 2010. +Jump up ^ CCEA. "About Us – What we do". Council for the Curriculum Examinations & Assessment. Retrieved 28 April 2013. +Jump up ^ Elitist Britain?, Social Mobility and Child Poverty Commission, 28 August 2014 +Jump up ^ Arnett, George (28 August 2014). "Elitism in Britain - breakdown by profession". The Guardian: Datablog. +Jump up ^ Haden, Angela; Campanini, Barbara, eds. (2000). The world health report 2000 – Health systems: improving performance. Geneva: World Health Organisation. ISBN 92-4-156198-X. Retrieved 5 July 2011. +Jump up ^ World Health Organization. "Measuring overall health system performance for 191 countries". New York University. Retrieved 5 July 2011. +Jump up ^ "'Huge contrasts' in devolved NHS". BBC News. 28 August 2008. +Jump up ^ Triggle, Nick (2 January 2008). "NHS now four different systems". BBC News. +Jump up ^ Fisher, Peter. "The NHS from Thatcher to Blair". NHS Consultants Association (International Association of Health Policy). The Budget ... was even more generous to the NHS than had been expected amounting to an annual rise of 7.4% above the rate of inflation for the next 5 years. This would take us to 9.4% of GDP spent on health ie around EU average. +Jump up ^ "OECD Health Data 2009 – How Does the United Kingdom Compare". Paris: Organisation for Economic Co-operation and Development. Retrieved 28 April 2013.[dead link] +Jump up ^ "The cultural superpower: British cultural projection abroad". Journal of the British Politics Society, Norway. Volume 6. No. 1. Winter 2011 +Jump up ^ Sheridan, Greg (15 May 2010). "Cameron has chance to make UK great again". The Australian (Sydney). Retrieved 20 May 2012. +Jump up ^ Goldfarb, Jeffrey (10 May 2006). "Bookish Britain overtakes America as top publisher". RedOrbit (Texas). Reuters. +Jump up ^ "William Shakespeare (English author)". Britannica Online encyclopedia. Retrieved 26 February 2006. +Jump up ^ MSN Encarta Encyclopedia article on Shakespeare. Archived from the original on 9 February 2006. Retrieved 26 February 2006. +Jump up ^ William Shakespeare. Columbia Electronic Encyclopedia. Retrieved 26 February 2006. +Jump up ^ "Mystery of Christie's success is solved". The Daily Telegraph (London). 19 December 2005. Retrieved 14 November 2010. +Jump up ^ "All-Time Essential Comics". IGN. Retrieved 15 August 2013. +Jump up ^ Johnston, Rich."Before Watchmen To Double Up For Hardcover Collections". Bleeding Cool. 10 December 2012. Retrieved 15 August 2013. +Jump up ^ "Edinburgh, UK appointed first UNESCO City of Literature". Unesco. 2004. Retrieved 28 April 2013.[dead link] +Jump up ^ "Early Welsh poetry". BBC Wales. Retrieved 29 December 2010. +Jump up ^ Lang, Andrew (2003) [1913]. History of English Literature from Beowulf to Swinburne. Holicong, PA: Wildside Press. p. 42. ISBN 978-0-8095-3229-2. +Jump up ^ "Dafydd ap Gwilym". Academi website. Academi. 2011. Retrieved 3 January 2011. Dafydd ap Gwilym is widely regarded as one of the greatest Welsh poets of all time, and amongst the leading European poets of the Middle Ages. +Jump up ^ True birthplace of Wales's literary hero. BBC News. Retrieved 28 April 2012 +Jump up ^ Kate Roberts: Biography at the Wayback Machine. BBC Wales. Retrieved 28 April 2012 +Jump up ^ Swift, Jonathan; Fox, Christopher (1995). Gulliver's travels: complete, authoritative text with biographical and historical contexts, critical history, and essays from five contemporary critical perspectives. Basingstoke: Macmillan. p. 10. ISBN 978-0-333-63438-7. +Jump up ^ "Bram Stoker." (PDF). The New York Times. 23 April 1912. Retrieved 1 January 2011. +^ Jump up to: a b "1960–1969". EMI Group. Retrieved 31 May 2008. +^ Jump up to: a b "Paul At Fifty". Time (New York). 8 June 1992. +^ Jump up to: a b Most Successful Group The Guinness Book of Records 1999, p. 230. Retrieved 19 March 2011. +Jump up ^ "British Citizen by Act of Parliament: George Frideric Handel". UK Parliament. 20 July 2009. Retrieved 11 September 2009.[dead link] +Jump up ^ Andrews, John (14 April 2006). "Handel all'inglese". Playbill (New York). Retrieved 11 September 2009. +Jump up ^ Citron, Stephen (2001). Sondheim and Lloyd-Webber: The new musical. London: Chatto & Windus. ISBN 978-1-85619-273-6. +Jump up ^ "Beatles a big hit with downloads". Belfast Telegraph. 25 November 2010. Retrieved 16 May 2011. +Jump up ^ "British rock legends get their own music title for PlayStation3 and PlayStation2" (Press release). EMI. 2 February 2009. +Jump up ^ Khan, Urmee (17 July 2008). "Sir Elton John honoured in Ben and Jerry ice cream". The Daily Telegraph (London). +Jump up ^ Alleyne, Richard (19 April 2008). "Rock group Led Zeppelin to reunite". The Daily Telegraph (London). Retrieved 31 March 2010. +Jump up ^ Fresco, Adam (11 July 2006). "Pink Floyd founder Syd Barrett dies at home". The Times (London). Retrieved 31 March 2010. (subscription required) +Jump up ^ Holton, Kate (17 January 2008). "Rolling Stones sign Universal album deal". Reuters. Retrieved 26 October 2008. +Jump up ^ Walker, Tim (12 May 2008). "Jive talkin': Why Robin Gibb wants more respect for the Bee Gees". The Independent (London). Retrieved 26 October 2008. +Jump up ^ "Brit awards winners list 2012: every winner since 1977". The Guardian (London). Retrieved 28 February 2012. +Jump up ^ Corner, Lewis (16 February 2012). "Adele, Coldplay biggest-selling UK artists worldwide in 2011". Digital Spy. Retrieved 22 March 2012. +Jump up ^ Hughes, Mark (14 January 2008). "A tale of two cities of culture: Liverpool vs Stavanger". The Independent (London). Retrieved 2 August 2009. +Jump up ^ "Glasgow gets city of music honour". BBC News. 20 August 2008. Retrieved 2 August 2009. +Jump up ^ Bayley, Stephen (24 April 2010). "The startling success of Tate Modern". The Times (London). Retrieved 19 January 2011. (subscription required) +Jump up ^ "Vertigo is named 'greatest film of all time'". BBC News. 2 August 2012. Retrieved 18 August 2012. +Jump up ^ "The Directors' Top Ten Directors". British Film Institute. Archived from the original on 27 May 2012. +Jump up ^ "Chaplin, Charles (1889–1977)". British Film Institute. Retrieved 25 January 2011. +Jump up ^ "Powell, Michael (1905–1990)". British Film Institute. Retrieved 25 January 2011. +Jump up ^ "Reed, Carol (1906–1976)". British Film Institute. Retrieved 25 January 2011. +Jump up ^ "Scott, Sir Ridley (1937–)". British Film Institute. Retrieved 25 January 2011. +Jump up ^ "Andrews, Julie (1935–)". British Film Institute. Retrieved 11 December 2010. +Jump up ^ "Burton, Richard (1925–1984)". British Film Institute. Retrieved 11 December 2010. +Jump up ^ "Caine, Michael (1933–)". British Film Institute. Retrieved 11 December 2010. +Jump up ^ "Chaplin, Charles (1889–1977)". British Film Institute. Retrieved 11 December 2010. +Jump up ^ "Connery, Sean (1930–)". British Film Institute. Retrieved 11 December 2010. +Jump up ^ "Leigh, Vivien (1913–1967)". British Film Institute. Retrieved 11 December 2010. +Jump up ^ "Niven, David (1910–1983)". British Film Institute. Retrieved 11 December 2010. +Jump up ^ "Olivier, Laurence (1907–1989)". British Film Institute. Retrieved 11 December 2010. +Jump up ^ "Sellers, Peter (1925–1980)". British Film Institute. Retrieved 11 December 2010. +Jump up ^ "Winslet, Kate (1975–)". British Film Institute. Retrieved 11 December 2010. +Jump up ^ "Daniel Day-Lewis makes Oscar history with third award"'. BBC News. Retrieved 15 August 2013 +Jump up ^ "Harry Potter becomes highest-grossing film franchise". The Guardian (London). 11 September 2007. Retrieved 2 November 2010. +Jump up ^ "History of Ealing Studios". Ealing Studios. Retrieved 5 June 2010. +^ Jump up to: a b "UK film – the vital statistics". UK Film Council. Retrieved 22 October 2010.[dead link] +Jump up ^ "The BFI 100". British Film Institute. 6 September 2006. Archived from the original on 1 April 2011. +Jump up ^ "Baftas fuel Oscars race". BBC News. 26 February 2001. Retrieved 14 February 2011. +^ Jump up to: a b "BBC: World's largest broadcaster & Most trusted media brand". Media Newsline. Archived from the original on 5 October 2010. Retrieved 23 September 2010. +^ Jump up to: a b "Digital licence". Prospect. Retrieved 23 September 2010. +^ Jump up to: a b "About the BBC – What is the BBC". BBC Online. Retrieved 23 September 2010. +Jump up ^ Newswire7 (13 August 2009). "BBC: World's largest broadcaster & Most trusted media brand". Media Newsline. Archived from the original on 17 June 2011. +Jump up ^ "TV Licence Fee: facts & figures". BBC Press Office. April 2010. Archived from the original on 17 June 2011. +Jump up ^ "Publications & Policies: The History of ITV". ITV.com. Archived from the original on 17 June 2011. +Jump up ^ "Publishing". News Corporation. Archived from the original on 17 June 2011. +Jump up ^ "Direct Broadcast Satellite Television". News Corporation. Archived from the original on 17 June 2011. +Jump up ^ William, D. (2010). UK Cities: A Look at Life and Major Cities in England, Scotland, Wales and Northern Ireland. Eastbourne: Gardners Books. ISBN 978-9987-16-021-1, pp. 22, 46, 109 and 145. +Jump up ^ "Publishing". Department of Culture, Media and Sport. Archived from the original on 17 June 2011. +Jump up ^ Ofcom "Communication Market Report 2010", 19 August 2010, pp. 97, 164 and 191 +Jump up ^ "Social Trends: Lifestyles and social participation". Office for National Statistics. 16 February 2010. Archived from the original on 17 June 2011. +Jump up ^ "Top 20 countries with the highest number of Internet users". Internet World Stats. Archived from the original on 17 June 2011. +Jump up ^ Fieser, James, ed. (2000). A bibliography of Scottish common sense philosophy: Sources and origins. Bristol: Thoemmes Press. Retrieved 17 December 2010. +Jump up ^ Palmer, Michael (1999). Moral Problems in Medicine: A Practical Coursebook. Cambridge: Lutterworth Press. p. 66. ISBN 978-0-7188-2978-0. +Jump up ^ Scarre, Geoffrey (1995). Utilitarianism. London: Routledge. p. 82. ISBN 978-0-415-12197-2. +Jump up ^ Gysin, Christian (9 March 2007). "Wembley kick-off: Stadium is ready and England play first game in fortnight". Daily Mail (London). Retrieved 19 March 2007. +Jump up ^ "Opening ceremony of the games of the XXX Olympiad". Olympic.org. Retrieved 30 November 2013 +Jump up ^ "Unparalleled Sporting History" . Reuters. Retrieved 30 November 2013 +Jump up ^ "Rugby Union 'Britain's Second Most Popular Sport'". Ipsos-Mori. 22 December 2003. Retrieved 28 April 2013. +Jump up ^ Ebner, Sarah (2 July 2013). "History and time are key to power of football, says Premier League chief". The Times (London). Retrieved 30 November 2013. +Jump up ^ Mitchell, Paul (November 2005). "The first international football match". BBC Sport Scotland. Retrieved 15 December 2013. +Jump up ^ "Why is there no GB Olympics football team?". BBC Sport. 5 August 2008. Retrieved 31 December 2010. +Jump up ^ "Blatter against British 2012 team". BBC News. 9 March 2008. Retrieved 2 April 2008. +Jump up ^ "About ECB". England and Wales Cricket Board. n.d. Retrieved 28 April 2013. +Jump up ^ McLaughlin, Martyn (4 August 2009). "Howzat happen? England fields a Gaelic-speaking Scotsman in Ashes". The Scotsman (Edinburgh). Retrieved 30 December 2010. +Jump up ^ "Uncapped Joyce wins Ashes call up". BBC Sport. 15 November 2006. Retrieved 30 December 2010. +Jump up ^ "Glamorgan". BBC South East Wales. August 2009. Retrieved 30 December 2010. +Jump up ^ Ardener, Shirley (2007). Professional identities: policy and practice in business and bureaucracy. New York: Berghahn. p. 27. ISBN 978-1-84545-054-0. +Jump up ^ "Official Website of Rugby League World Cup 2008". Archived from the original on 16 October 2007. +Jump up ^ Louw, Jaco; Nesbit, Derrick (2008). The Girlfriends Guide to Rugby. Johannesburg: South Publishers. ISBN 978-0-620-39541-0. +Jump up ^ "Triple Crown". RBS 6 Nations. Retrieved 6 March 2011. +Jump up ^ "Tracking the Field". Ipsos MORI. Archived from the original on 5 February 2009. Retrieved 17 October 2008. +Jump up ^ "Links plays into the record books". BBC News. 17 March 2009. +Jump up ^ Chowdhury, Saj (22 January 2007). "China in Ding's hands". BBC Sport. Retrieved 2 January 2011. +Jump up ^ "Lawn Tennis and Major T.Gem". The Birmingham Civic Society. Archived from the original on 18 August 2011. Retrieved 31 December 2010. +Jump up ^ Gould, Joe (10 April 2007). "The ancient Irish sport of hurling catches on in America". Columbia News Service (Columbia Journalism School). Retrieved 17 May 2011. +Jump up ^ "Shinty". Scottishsport.co.uk. Retrieved 28 April 2013. +Jump up ^ "Welsh dragon call for Union flag". BBC News. 27 November 2007. Retrieved 17 October 2008. +Jump up ^ "Britannia on British Coins". Chard. Retrieved 25 June 2006. +Jump up ^ Baker, Steve (2001). Picturing the Beast. University of Illinois Press. p. 52. ISBN 0-252-07030-5. +Further reading +Hitchens, Peter (2000). The Abolition of Britain: from Winston Churchill to Princess Diana. Second ed. San Francisco, Calif.: Encounter Books. xi, 332 p. ISBN 1-893554-18-X. +Lambert, Richard S. (1964). The Great Heritage: a History of Britain for Canadians. House of Grant, 1964 (and earlier editions and/or printings). +External links +Find more about +United Kingdom +at Wikipedia's sister projects +Search Wiktionary Definitions from Wiktionary +Search Commons Media from Commons +Search Wikinews News stories from Wikinews +Search Wikiquote Quotations from Wikiquote +Search Wikisource Source texts from Wikisource +Search Wikibooks Textbooks from Wikibooks +Search Wikivoyage Travel guide from Wikivoyage +Search Wikiversity Learning resources from Wikiversity +Government +Official website of HM Government +Official website of the British Monarchy +Official Yearbook of the United Kingdom statistics +The official site of the British Prime Minister's Office +General information +United Kingdom from the BBC News +United Kingdom entry at The World Factbook +United Kingdom from UCB Libraries GovPubs +United Kingdom at DMOZ +United Kingdom Encyclopædia Britannica entry +United Kingdom from the OECD +United Kingdom at the EU + Wikimedia Atlas of United Kingdom + Geographic data related to United Kingdom at OpenStreetMap +Key Development Forecasts for the United Kingdom from International Futures +Travel +Official tourist guide to Britain +[hide] v t e +United Kingdom topics +History +Chronology +Formation Georgian era Victorian era Edwardian era World War I Interwar World War II UK since 1945 (Postwar Britain) +By topic +Economic Empire Maritime Military +Geography +Administrative +Countries of the United Kingdom Crown dependencies Overseas territories City status Towns Former colonies +Physical +British Isles terminology Great Britain Geology Northern Ireland Lakes and lochs Mountains Rivers Volcanoes +Resources +Energy/Renewable energy Biodiesel Coal Geothermal Hydraulic frac. Hydroelectricity Marine North Sea oil Solar Wind Food Agriculture Fishing English Scottish Hunting Materials Flora Forestry Mining +Politics +Constitution Courts Elections Foreign relations Judiciary Law Law enforcement Legislation Monarchy monarchs Nationality Parliament House of Commons House of Lords Political parties +Government +Cabinet list Civil service Departments Prime Minister list +Military +Royal Navy Army Royal Air Force Weapons of mass destruction +Economy +Banks Bank of England Budget Economic geography Pound (currency) Stock Exchange Taxation Telecommunications Tourism Transport +Society +Affordability of housing Crime Demography Drug policy Education Ethnic groups Health care Immigration Languages Poverty Food banks Prostitution Public holidays Social care Social structure +Culture +Art Cinema Cuisine Identity Literature Media television Music Religion Sport Symbols Theatre +[show] +Countries of the United Kingdom +Outline Index +Book Category Portal WikiProject +[show] +Gnome-globe.svg Geographic locale +[show] v t e +Member states of the European Union +[show] +International organisations +[show] v t e +English-speaking world +[show] v t e +National personifications +Coordinates: 55°N 3°W +Categories: United KingdomBritish IslandsConstitutional monarchiesCountries in EuropeEnglish-speaking countries and territoriesG20 nationsG7 nationsG8 nationsIsland countriesLiberal democraciesMember states of NATOMember states of the Commonwealth of NationsMember states of the Council of EuropeMember states of the European UnionMember states of the Union for the MediterraneanMember states of the United NationsNorthern EuropeWestern Europe +Navigation menu +Create accountLog inArticleTalkReadView sourceView history + +Main page +Contents +Featured content +Current events +Random article +Donate to Wikipedia +Wikimedia Shop +Interaction +Help +About Wikipedia +Community portal +Recent changes +Contact page +Tools +What links here +Related changes +Upload file +Special pages +Permanent link +Page information +Wikidata item +Cite this page +Print/export +Create a book +Download as PDF +Printable version +Languages +Адыгэбзэ +Afrikaans +Akan +Alemannisch +አማርኛ +Ænglisc +Аҧсшәа +العربية +Aragonés +ܐܪܡܝܐ +Armãneashti +Arpetan +Asturianu +Avañe'ẽ +Авар +Azərbaycanca +বাংলা +Bahasa Banjar +Bân-lâm-gú +Башҡортса +Беларуская +Беларуская (тарашкевіца)‎ +भोजपुरी +Bikol Central +Bislama +Български +Boarisch +བོད་ཡིག +Bosanski +Brezhoneg +Буряад +Català +Чӑвашла +Cebuano +Čeština +Chavacano de Zamboanga +ChiShona +Corsu +Cymraeg +Dansk +Deutsch +ދިވެހިބަސް +Diné bizaad +Dolnoserbski +ཇོང་ཁ +Eesti +Ελληνικά +Emiliàn e rumagnòl +Español +Esperanto +Estremeñu +Euskara +فارسی +Fiji Hindi +Føroyskt +Français +Frysk +Furlan +Gaeilge +Gaelg +Gagauz +Gàidhlig +Galego +贛語 +ગુજરાતી +客家語/Hak-kâ-ngî +Хальмг +한국어 +Hausa +Hawaii +Հայերեն +हिन्दी +Hornjoserbsce +Hrvatski +Ido +Igbo +Ilokano +বিষ্ণুপ্রিয়া মণিপুরী +Bahasa Indonesia +Interlingua +Interlingue +Ирон +IsiZulu +Íslenska +Italiano +עברית +Basa Jawa +Kalaallisut +ಕನ್ನಡ +Kapampangan +Къарачай-малкъар +ქართული +Kaszëbsczi +Қазақша +Kernowek +Kinyarwanda +Kiswahili +Коми +Kongo +Kreyòl ayisyen +Kurdî +Кыргызча +Кырык мары +Ladino +Лезги +ລາວ +Latgaļu +Latina +Latviešu +Lëtzebuergesch +Lietuvių +Ligure +Limburgs +Lingála +Lojban +Lumbaart +Magyar +Македонски +Malagasy +മലയാളം +Malti +Māori +मराठी +მარგალური +مصرى +مازِرونی +Bahasa Melayu +Mìng-dĕ̤ng-ngṳ̄ +Mirandés +Монгол +မြန်မာဘာသာ +Nāhuatl +Dorerin Naoero +Nederlands +Nedersaksies +नेपाली +नेपाल भाषा +日本語 +Napulitano +Нохчийн +Nordfriisk +Norfuk / Pitkern +Norsk bokmål +Norsk nynorsk +Nouormand +Novial +Occitan +Олык марий +ଓଡ଼ିଆ +Oromoo +Oʻzbekcha +ਪੰਜਾਬੀ +Pangasinan +پنجابی +Papiamentu +پښتو +Перем Коми +ភាសាខ្មែរ +Picard +Piemontèis +Tok Pisin +Plattdüütsch +Polski +Ποντιακά +Português +Qırımtatarca +Reo tahiti +Ripoarisch +Română +Romani +Rumantsch +Runa Simi +Русиньскый +Русский +Саха тыла +Sámegiella +संस्कृतम् +Sardu +Scots +Seeltersk +Shqip +Sicilianu +සිංහල +Simple English +SiSwati +Slovenčina +Slovenščina +Словѣньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ +Ślůnski +Soomaaliga +کوردی +Sranantongo +Српски / srpski +Srpskohrvatski / српскохрватски +Basa Sunda +Suomi +Svenska +Tagalog +தமிழ் +Taqbaylit +Tarandíne +Татарча/tatarça +తెలుగు +Tetun +ไทย +Тоҷикӣ +ᏣᎳᎩ +Tsetsêhestâhese +Türkçe +Twi +Удмурт +ᨅᨔ ᨕᨘᨁᨗ +Українська +اردو +ئۇيغۇرچە / Uyghurche +Vahcuengh +Vèneto +Vepsän kel’ +Tiếng Việt +Volapük +Võro +Walon +文言 +West-Vlams +Winaray +Wolof +吴语 +ייִדיש +Yorùbá +粵語 +Zazaki +Zeêuws +Žemaitėška +中文 +Edit links +This page was last modified on 22 November 2014 at 11:19. +Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Terms of Use and Privacy Policy. Wikipedia® is a registered trademark of the Wikimedia Foundation, Inc., a non-profit organization. +Privacy policyAbout WikipediaDisclaimersContact WikipediaDevelopersMobile viewWikimedia Foundation Powered by MediaWiki + + +World Trade Organization +From Wikipedia, the free encyclopedia +"WTO" redirects here. For other uses, see WTO (disambiguation). +World Trade Organization (English) +Organisation mondiale du commerce (French) +Organización Mundial del Comercio (Spanish) +World Trade Organization (logo and wordmark).svg +Official logo of WTO +WTO members and observers.svg + Members + Members, dually represented by the EU + Observers + Non-members +Abbreviation WTO +Formation 1 January 1995; 19 years ago +Type International trade organization +Purpose Liberalize international trade +Headquarters Centre William Rappard, Geneva, Switzerland +Coordinates 46.12°N 6.09°ECoordinates: 46.12°N 6.09°E +Region served Worldwide +Membership 160 member states[1] +Official language English, French, Spanish[2] +Director-General Roberto Azevêdo +Budget 196 million Swiss francs (approx. 209 million US$) in 2011.[3] +Staff 640[4] +Website www.wto.org +The World Trade Organization (WTO) is an organization that intends to supervise and liberalize international trade. The organization officially commenced on 1 January 1995 under the Marrakech Agreement, replacing the General Agreement on Tariffs and Trade (GATT), which commenced in 1948.[5] The organization deals with regulation of trade between participating countries by providing a framework for negotiating and formalizing trade agreements and a dispute resolution process aimed at enforcing participants' adherence to WTO agreements, which are signed by representatives of member governments[6]:fol.9–10 and ratified by their parliaments.[7] Most of the issues that the WTO focuses on derive from previous trade negotiations, especially from the Uruguay Round (1986–1994). +The organization is attempting to complete negotiations on the Doha Development Round, which was launched in 2001 with an explicit focus on addressing the needs of developing countries. As of June 2012, the future of the Doha Round remained uncertain: the work programme lists 21 subjects in which the original deadline of 1 January 2005 was missed, and the round is still incomplete.[8] The conflict between free trade on industrial goods and services but retention of protectionism on farm subsidies to domestic agricultural sector (requested by developed countries) and the substantiation of the international liberalization of fair trade on agricultural products (requested by developing countries) remain the major obstacles. These points of contention have hindered any progress to launch new WTO negotiations beyond the Doha Development Round. As a result of this impasse, there has been an increasing number of bilateral free trade agreements signed.[9] As of July 2012, there were various negotiation groups in the WTO system for the current agricultural trade negotiation which is in the condition of stalemate.[10] +WTO's current Director-General is Roberto Azevêdo,[11][12] who leads a staff of over 600 people in Geneva, Switzerland.[13] A trade facilitation agreement known as the Bali Package was reached by all members on 7 December 2013, the first comprehensive agreement in the organization's history.[14][15] +Contents [hide] +1 History +1.1 GATT rounds of negotiations +1.1.1 From Geneva to Tokyo +1.1.2 Uruguay Round +1.2 Ministerial conferences +1.3 Doha Round (Doha Agenda) +2 Functions +3 Principles of the trading system +4 Organizational structure +5 Decision-making +6 Dispute settlement +7 Accession and membership +7.1 Accession process +7.2 Members and observers +8 Agreements +9 Office of director-general +9.1 List of directors-general +10 See also +11 Notes and references +12 External links +History + +The economists Harry White (left) and John Maynard Keynes at the Bretton Woods Conference. Both had been strong advocates of a central-controlled international trade environment and recommended the establishment of three institutions: the IMF (for fiscal and monetary issues); the World Bank (for financial and structural issues); and the ITO (for international economic cooperation).[16] +The WTO's predecessor, the General Agreement on Tariffs and Trade (GATT), was established after World War II in the wake of other new multilateral institutions dedicated to international economic cooperation – notably the Bretton Woods institutions known as the World Bank and the International Monetary Fund. A comparable international institution for trade, named the International Trade Organization was successfully negotiated. The ITO was to be a United Nations specialized agency and would address not only trade barriers but other issues indirectly related to trade, including employment, investment, restrictive business practices, and commodity agreements. But the ITO treaty was not approved by the U.S. and a few other signatories and never went into effect.[17][18][19] +In the absence of an international organization for trade, the GATT would over the years "transform itself" into a de facto international organization.[20] +GATT rounds of negotiations +See also: General Agreement on Tariffs and Trade +The GATT was the only multilateral instrument governing international trade from 1946 until the WTO was established on 1 January 1995.[21] Despite attempts in the mid-1950s and 1960s to create some form of institutional mechanism for international trade, the GATT continued to operate for almost half a century as a semi-institutionalized multilateral treaty regime on a provisional basis.[22] +From Geneva to Tokyo +Seven rounds of negotiations occurred under GATT. The first real GATT trade rounds concentrated on further reducing tariffs. Then, the Kennedy Round in the mid-sixties brought about a GATT anti-dumping Agreement and a section on development. The Tokyo Round during the seventies was the first major attempt to tackle trade barriers that do not take the form of tariffs, and to improve the system, adopting a series of agreements on non-tariff barriers, which in some cases interpreted existing GATT rules, and in others broke entirely new ground. Because these plurilateral agreements were not accepted by the full GATT membership, they were often informally called "codes". Several of these codes were amended in the Uruguay Round, and turned into multilateral commitments accepted by all WTO members. Only four remained plurilateral (those on government procurement, bovine meat, civil aircraft and dairy products), but in 1997 WTO members agreed to terminate the bovine meat and dairy agreements, leaving only two.[21] +Uruguay Round +Main article: Uruguay Round + +During the Doha Round, the US government blamed Brazil and India for being inflexible and the EU for impeding agricultural imports.[23] The then-President of Brazil, Luiz Inácio Lula da Silva (above right), responded to the criticisms by arguing that progress would only be achieved if the richest countries (especially the US and countries in the EU) made deeper cuts in agricultural subsidies and further opened their markets for agricultural goods.[24] +Well before GATT's 40th anniversary, its members concluded that the GATT system was straining to adapt to a new globalizing world economy.[25][26] In response to the problems identified in the 1982 Ministerial Declaration (structural deficiencies, spill-over impacts of certain countries' policies on world trade GATT could not manage etc.), the eighth GATT round – known as the Uruguay Round – was launched in September 1986, in Punta del Este, Uruguay.[25] +It was the biggest negotiating mandate on trade ever agreed: the talks were going to extend the trading system into several new areas, notably trade in services and intellectual property, and to reform trade in the sensitive sectors of agriculture and textiles; all the original GATT articles were up for review.[26] The Final Act concluding the Uruguay Round and officially establishing the WTO regime was signed 15 April 1994, during the ministerial meeting at Marrakesh, Morocco, and hence is known as the Marrakesh Agreement.[27] +The GATT still exists as the WTO's umbrella treaty for trade in goods, updated as a result of the Uruguay Round negotiations (a distinction is made between GATT 1994, the updated parts of GATT, and GATT 1947, the original agreement which is still the heart of GATT 1994).[25] GATT 1994 is not however the only legally binding agreement included via the Final Act at Marrakesh; a long list of about 60 agreements, annexes, decisions and understandings was adopted. The agreements fall into a structure with six main parts: +The Agreement Establishing the WTO +Goods and investment – the Multilateral Agreements on Trade in Goods including the GATT 1994 and the Trade Related Investment Measures (TRIMS) +Services — the General Agreement on Trade in Services +Intellectual property – the Agreement on Trade-Related Aspects of Intellectual Property Rights (TRIPS) +Dispute settlement (DSU) +Reviews of governments' trade policies (TPRM)[28] +In terms of the WTO's principle relating to tariff "ceiling-binding" (No. 3), the Uruguay Round has been successful in increasing binding commitments by both developed and developing countries, as may be seen in the percentages of tariffs bound before and after the 1986–1994 talks.[29] +Ministerial conferences + +The World Trade Organization Ministerial Conference of 1998, in the Palace of Nations (Geneva, Switzerland). +The highest decision-making body of the WTO is the Ministerial Conference, which usually meets every two years. It brings together all members of the WTO, all of which are countries or customs unions. The Ministerial Conference can take decisions on all matters under any of the multilateral trade agreements. The inaugural ministerial conference was held in Singapore in 1996. Disagreements between largely developed and developing economies emerged during this conference over four issues initiated by this conference, which led to them being collectively referred to as the "Singapore issues". The second ministerial conference was held in Geneva in Switzerland. The third conference in Seattle, Washington ended in failure, with massive demonstrations and police and National Guard crowd-control efforts drawing worldwide attention. The fourth ministerial conference was held in Doha in the Persian Gulf nation of Qatar. The Doha Development Round was launched at the conference. The conference also approved the joining of China, which became the 143rd member to join. The fifth ministerial conference was held in Cancún, Mexico, aiming at forging agreement on the Doha round. An alliance of 22 southern states, the G20 developing nations (led by India, China,[30] Brazil, ASEAN led by the Philippines), resisted demands from the North for agreements on the so-called "Singapore issues" and called for an end to agricultural subsidies within the EU and the US. The talks broke down without progress. +The sixth WTO ministerial conference was held in Hong Kong from 13–18 December 2005. It was considered vital if the four-year-old Doha Development Round negotiations were to move forward sufficiently to conclude the round in 2006. In this meeting, countries agreed to phase out all their agricultural export subsidies by the end of 2013, and terminate any cotton export subsidies by the end of 2006. Further concessions to developing countries included an agreement to introduce duty-free, tariff-free access for goods from the Least Developed Countries, following the Everything but Arms initiative of the European Union — but with up to 3% of tariff lines exempted. Other major issues were left for further negotiation to be completed by the end of 2010. The WTO General Council, on 26 May 2009, agreed to hold a seventh WTO ministerial conference session in Geneva from 30 November-3 December 2009. A statement by chairman Amb. Mario Matus acknowledged that the prime purpose was to remedy a breach of protocol requiring two-yearly "regular" meetings, which had lapsed with the Doha Round failure in 2005, and that the "scaled-down" meeting would not be a negotiating session, but "emphasis will be on transparency and open discussion rather than on small group processes and informal negotiating structures". The general theme for discussion was "The WTO, the Multilateral Trading System and the Current Global Economic Environment"[31] +Doha Round (Doha Agenda) +Main article: Doha Development Round + +The Doha Development Round started in 2001 is at an impasse. +The WTO launched the current round of negotiations, the Doha Development Round, at the fourth ministerial conference in Doha, Qatar in November 2001. This was to be an ambitious effort to make globalization more inclusive and help the world's poor, particularly by slashing barriers and subsidies in farming.[32] The initial agenda comprised both further trade liberalization and new rule-making, underpinned by commitments to strengthen substantial assistance to developing countries.[33] +The negotiations have been highly contentious. Disagreements still continue over several key areas including agriculture subsidies, which emerged as critical in July 2006.[34] According to a European Union statement, "The 2008 Ministerial meeting broke down over a disagreement between exporters of agricultural bulk commodities and countries with large numbers of subsistence farmers on the precise terms of a 'special safeguard measure' to protect farmers from surges in imports."[35] The position of the European Commission is that "The successful conclusion of the Doha negotiations would confirm the central role of multilateral liberalisation and rule-making. It would confirm the WTO as a powerful shield against protectionist backsliding."[33] An impasse remains and, as of August 2013, agreement has not been reached, despite intense negotiations at several ministerial conferences and at other sessions. On 27 March 2013, the chairman of agriculture talks announced "a proposal to loosen price support disciplines for developing countries’ public stocks and domestic food aid." He added: “...we are not yet close to agreement—in fact, the substantive discussion of the proposal is only beginning.”[36] +[show]v · t · eGATT and WTO trade rounds[37] +Functions +Among the various functions of the WTO, these are regarded by analysts as the most important: +It oversees the implementation, administration and operation of the covered agreements.[38][39] +It provides a forum for negotiations and for settling disputes.[40][41] +Additionally, it is the WTO's duty to review and propagate the national trade policies, and to ensure the coherence and transparency of trade policies through surveillance in global economic policy-making.[39][41] Another priority of the WTO is the assistance of developing, least-developed and low-income countries in transition to adjust to WTO rules and disciplines through technical cooperation and training.[42] +(i) The WTO shall facilitate the implementation, administration and operation and further the objec­tives of this Agreement and of the Multilateral Trade Agreements, and shall also provide the frame work for the implementation, administration and operation of the multilateral Trade Agreements. +(ii) The WTO shall provide the forum for negotiations among its members concerning their multilateral trade relations in matters dealt with under the Agreement in the Annexes to this Agreement. +(iii) The WTO shall administer the Understanding on Rules and Procedures Governing the Settlement of Disputes. +(iv) The WTO shall administer Trade Policy Review Mechanism. +(v) With a view to achieving greater coherence in global economic policy making, the WTO shall cooperate, as appropriate, with the international Monetary Fund (IMF) and with the International Bank for Reconstruction and Development (IBRD) and its affiliated agencies. [43] +The above five listings are the additional functions of the World Trade Organization. As globalization proceeds in today's society, the necessity of an International Organization to manage the trading systems has been of vital importance. As the trade volume increases, issues such as protectionism, trade barriers, subsidies, violation of intellectual property arise due to the differences in the trading rules of every nation. The World Trade Organization serves as the mediator between the nations when such problems arise. WTO could be referred to as the product of globalization and also as one of the most important organizations in today's globalized society. +The WTO is also a center of economic research and analysis: regular assessments of the global trade picture in its annual publications and research reports on specific topics are produced by the organization.[44] Finally, the WTO cooperates closely with the two other components of the Bretton Woods system, the IMF and the World Bank.[40] +Principles of the trading system +The WTO establishes a framework for trade policies; it does not define or specify outcomes. That is, it is concerned with setting the rules of the trade policy games.[45] Five principles are of particular importance in understanding both the pre-1994 GATT and the WTO: +Non-discrimination. It has two major components: the most favoured nation (MFN) rule, and the national treatment policy. Both are embedded in the main WTO rules on goods, services, and intellectual property, but their precise scope and nature differ across these areas. The MFN rule requires that a WTO member must apply the same conditions on all trade with other WTO members, i.e. a WTO member has to grant the most favorable conditions under which it allows trade in a certain product type to all other WTO members.[45] "Grant someone a special favour and you have to do the same for all other WTO members."[29] National treatment means that imported goods should be treated no less favorably than domestically produced goods (at least after the foreign goods have entered the market) and was introduced to tackle non-tariff barriers to trade (e.g. technical standards, security standards et al. discriminating against imported goods).[45] +Reciprocity. It reflects both a desire to limit the scope of free-riding that may arise because of the MFN rule, and a desire to obtain better access to foreign markets. A related point is that for a nation to negotiate, it is necessary that the gain from doing so be greater than the gain available from unilateral liberalization; reciprocal concessions intend to ensure that such gains will materialise.[46] +Binding and enforceable commitments. The tariff commitments made by WTO members in a multilateral trade negotiation and on accession are enumerated in a schedule (list) of concessions. These schedules establish "ceiling bindings": a country can change its bindings, but only after negotiating with its trading partners, which could mean compensating them for loss of trade. If satisfaction is not obtained, the complaining country may invoke the WTO dispute settlement procedures.[29][46] +Transparency. The WTO members are required to publish their trade regulations, to maintain institutions allowing for the review of administrative decisions affecting trade, to respond to requests for information by other members, and to notify changes in trade policies to the WTO. These internal transparency requirements are supplemented and facilitated by periodic country-specific reports (trade policy reviews) through the Trade Policy Review Mechanism (TPRM).[47] The WTO system tries also to improve predictability and stability, discouraging the use of quotas and other measures used to set limits on quantities of imports.[29] +Safety valves. In specific circumstances, governments are able to restrict trade. The WTO's agreements permit members to take measures to protect not only the environment but also public health, animal health and plant health.[48] +There are three types of provision in this direction: +articles allowing for the use of trade measures to attain non-economic objectives; +articles aimed at ensuring "fair competition"; members must not use environmental protection measures as a means of disguising protectionist policies.[48] +provisions permitting intervention in trade for economic reasons.[47] +Exceptions to the MFN principle also allow for preferential treatment of developing countries, regional free trade areas and customs unions.[6]:fol.93 +Organizational structure +The General Council has the following subsidiary bodies which oversee committees in different areas: +Council for Trade in Goods +There are 11 committees under the jurisdiction of the Goods Council each with a specific task. All members of the WTO participate in the committees. The Textiles Monitoring Body is separate from the other committees but still under the jurisdiction of Goods Council. The body has its own chairman and only 10 members. The body also has several groups relating to textiles.[49] +Council for Trade-Related Aspects of Intellectual Property Rights +Information on intellectual property in the WTO, news and official records of the activities of the TRIPS Council, and details of the WTO's work with other international organizations in the field.[50] +Council for Trade in Services +The Council for Trade in Services operates under the guidance of the General Council and is responsible for overseeing the functioning of the General Agreement on Trade in Services (GATS). It is open to all WTO members, and can create subsidiary bodies as required.[51] +Trade Negotiations Committee +The Trade Negotiations Committee (TNC) is the committee that deals with the current trade talks round. The chair is WTO's director-general. As of June 2012 the committee was tasked with the Doha Development Round.[52] +The Service Council has three subsidiary bodies: financial services, domestic regulations, GATS rules and specific commitments.[49] The council has several different committees, working groups, and working parties.[53] There are committees on the following: Trade and Environment; Trade and Development (Subcommittee on Least-Developed Countries); Regional Trade Agreements; Balance of Payments Restrictions; and Budget, Finance and Administration. There are working parties on the following: Accession. There are working groups on the following: Trade, debt and finance; and Trade and technology transfer. +Decision-making +The WTO describes itself as "a rules-based, member-driven organization — all decisions are made by the member governments, and the rules are the outcome of negotiations among members".[54] The WTO Agreement foresees votes where consensus cannot be reached, but the practice of consensus dominates the process of decision-making.[55] +Richard Harold Steinberg (2002) argues that although the WTO's consensus governance model provides law-based initial bargaining, trading rounds close through power-based bargaining favouring Europe and the U.S., and may not lead to Pareto improvement.[56] +Dispute settlement +Main article: Dispute settlement in the WTO +In 1994, the WTO members agreed on the Understanding on Rules and Procedures Governing the Settlement of Disputes (DSU) annexed to the "Final Act" signed in Marrakesh in 1994.[57] Dispute settlement is regarded by the WTO as the central pillar of the multilateral trading system, and as a "unique contribution to the stability of the global economy".[58] WTO members have agreed that, if they believe fellow-members are violating trade rules, they will use the multilateral system of settling disputes instead of taking action unilaterally.[59] +The operation of the WTO dispute settlement process involves the DSB panels, the Appellate Body, the WTO Secretariat, arbitrators, independent experts and several specialized institutions.[60] Bodies involved in the dispute settlement process, World Trade Organization. +Accession and membership +Main article: World Trade Organization accession and membership +The process of becoming a WTO member is unique to each applicant country, and the terms of accession are dependent upon the country's stage of economic development and current trade regime.[61] The process takes about five years, on average, but it can last more if the country is less than fully committed to the process or if political issues interfere. The shortest accession negotiation was that of the Kyrgyz Republic, while the longest was that of Russia, which, having first applied to join GATT in 1993, was approved for membership in December 2011 and became a WTO member on 22 August 2012.[62] The second longest was that of Vanuatu, whose Working Party on the Accession of Vanuatu was established on 11 July 1995. After a final meeting of the Working Party in October 2001, Vanuatu requested more time to consider its accession terms. In 2008, it indicated its interest to resume and conclude its WTO accession. The Working Party on the Accession of Vanuatu was reconvened informally on 4 April 2011 to discuss Vanuatu's future WTO membership. The re-convened Working Party completed its mandate on 2 May 2011. The General Council formally approved the Accession Package of Vanuatu on 26 October 2011. On 24 August 2012, the WTO welcomed Vanuatu as its 157th member.[63] An offer of accession is only given once consensus is reached among interested parties.[64] +Accession process + +WTO accession progress: + Members (including dual-representation with the European Union) + Draft Working Party Report or Factual Summary adopted + Goods and/or Services offers submitted + Memorandum on Foreign Trade Regime (FTR) submitted + Observer, negotiations to start later or no Memorandum on FTR submitted + Frozen procedures or no negotiations in the last 3 years + No official interaction with the WTO +A country wishing to accede to the WTO submits an application to the General Council, and has to describe all aspects of its trade and economic policies that have a bearing on WTO agreements.[65] The application is submitted to the WTO in a memorandum which is examined by a working party open to all interested WTO Members.[66] +After all necessary background information has been acquired, the working party focuses on issues of discrepancy between the WTO rules and the applicant's international and domestic trade policies and laws. The working party determines the terms and conditions of entry into the WTO for the applicant nation, and may consider transitional periods to allow countries some leeway in complying with the WTO rules.[61] +The final phase of accession involves bilateral negotiations between the applicant nation and other working party members regarding the concessions and commitments on tariff levels and market access for goods and services. The new member's commitments are to apply equally to all WTO members under normal non-discrimination rules, even though they are negotiated bilaterally.[65] +When the bilateral talks conclude, the working party sends to the general council or ministerial conference an accession package, which includes a summary of all the working party meetings, the Protocol of Accession (a draft membership treaty), and lists ("schedules") of the member-to-be's commitments. Once the general council or ministerial conference approves of the terms of accession, the applicant's parliament must ratify the Protocol of Accession before it can become a member.[67] Some countries may have faced tougher and a much longer accession process due to challenges during negotiations with other WTO members, such as Vietnam, whose negotiations took more than 11 years before it became official member in January 2007.[68] +Members and observers +The WTO has 160 members and 24 observer governments.[69] In addition to states, the European Union is a member. WTO members do not have to be full sovereign nation-members. Instead, they must be a customs territory with full autonomy in the conduct of their external commercial relations. Thus Hong Kong has been a member since 1995 (as "Hong Kong, China" since 1997) predating the People's Republic of China, which joined in 2001 after 15 years of negotiations. The Republic of China (Taiwan) acceded to the WTO in 2002 as "Separate Customs Territory of Taiwan, Penghu, Kinmen and Matsu" (Chinese Taipei) despite its disputed status.[70] The WTO Secretariat omits the official titles (such as Counselor, First Secretary, Second Secretary and Third Secretary) of the members of Chinese Taipei's Permanent Mission to the WTO, except for the titles of the Permanent Representative and the Deputy Permanent Representative.[71] +As of 2007, WTO member states represented 96.4% of global trade and 96.7% of global GDP.[72] Iran, followed by Algeria, are the economies with the largest GDP and trade outside the WTO, using 2005 data.[73][74] With the exception of the Holy See, observers must start accession negotiations within five years of becoming observers. A number of international intergovernmental organizations have also been granted observer status to WTO bodies.[75] 14 UN member states have no official affiliation with the WTO. +Agreements +Further information: Uruguay Round +The WTO oversees about 60 different agreements which have the status of international legal texts. Member countries must sign and ratify all WTO agreements on accession.[76] A discussion of some of the most important agreements follows. The Agreement on Agriculture came into effect with the establishment of the WTO at the beginning of 1995. The AoA has three central concepts, or "pillars": domestic support, market access and export subsidies. The General Agreement on Trade in Services was created to extend the multilateral trading system to service sector, in the same way as the General Agreement on Tariffs and Trade (GATT) provided such a system for merchandise trade. The agreement entered into force in January 1995. The Agreement on Trade-Related Aspects of Intellectual Property Rights sets down minimum standards for many forms of intellectual property (IP) regulation. It was negotiated at the end of the Uruguay Round of the General Agreement on Tariffs and Trade (GATT) in 1994.[77] +The Agreement on the Application of Sanitary and Phytosanitary Measures—also known as the SPS Agreement—was negotiated during the Uruguay Round of GATT, and entered into force with the establishment of the WTO at the beginning of 1995. Under the SPS agreement, the WTO sets constraints on members' policies relating to food safety (bacterial contaminants, pesticides, inspection and labelling) as well as animal and plant health (imported pests and diseases). The Agreement on Technical Barriers to Trade is an international treaty of the World Trade Organization. It was negotiated during the Uruguay Round of the General Agreement on Tariffs and Trade, and entered into force with the establishment of the WTO at the end of 1994. The object ensures that technical negotiations and standards, as well as testing and certification procedures, do not create unnecessary obstacles to trade".[78] The Agreement on Customs Valuation, formally known as the Agreement on Implementation of Article VII of GATT, prescribes methods of customs valuation that Members are to follow. Chiefly, it adopts the "transaction value" approach. +In December 2013, the biggest agreement within the WTO was signed and known as the Bali Package.[79] +Office of director-general + +The headquarters of the World Trade Organization, in Geneva, Switzerland. +The procedures for the appointment of the WTO director-general were published in January 2003.[80] Additionally, there are four deputy directors-general. As of 1 October 2013, under director-general Roberto Azevêdo, the four deputy directors-general are Yi Xiaozhun of China, Karl-Ernst Brauner of Germany, Yonov Frederick Agah of Nigeria and David Shark of the United States.[81] +List of directors-general +Source: Official website[82] +Brazil Roberto Azevedo, 2013– +France Pascal Lamy, 2005–2013 +Thailand Supachai Panitchpakdi, 2002–2005 +New Zealand Mike Moore, 1999–2002 +Italy Renato Ruggiero, 1995–1999 +Republic of Ireland Peter Sutherland, 1995 +(Heads of the precursor organization, GATT): +Republic of Ireland Peter Sutherland, 1993–1995 +Switzerland Arthur Dunkel, 1980–1993 +Switzerland Olivier Long, 1968–1980 +United Kingdom Eric Wyndham White, 1948–1968 +See also +Agreement on Trade Related Investment Measures (TRIMS) +Agreement on Trade-Related Aspects of Intellectual Property Rights (TRIPS) +Aide-mémoire non-paper +Anti-globalization movement +Criticism of the World Trade Organization +Foreign Affiliate Trade Statistics +Global administrative law +Globality +Information Technology Agreement +International Trade Centre +Labour Standards in the World Trade Organisation +List of member states of the World Trade Organization +North American Free Trade Agreement (NAFTA) +Subsidy +Swiss Formula +Trade bloc +Washington Consensus +World Trade Report +World Trade Organization Ministerial Conference of 1999 protest activity +China and the World Trade Organization +Notes and references +Jump up ^ Members and Observers at WTO official website +Jump up ^ Languages, Documentation and Information Management Division at WTO official site +Jump up ^ "WTO Secretariat budget for 2011". WTO official site. Retrieved 25 August 2008. +Jump up ^ Understanding the WTO: What We Stand For_ Fact File +Jump up ^ World Trade Organization - UNDERSTANDING THE WTO: BASICS +^ Jump up to: a b Understanding the WTO Handbook at WTO official website. (Note that the document's printed folio numbers do not match the pdf page numbers.) +Jump up ^ Malanczuk, P. (1999). "International Organisations and Space Law: World Trade Organization". Encyclopaedia Britannica 442. p. 305. Bibcode:1999ESASP.442..305M. +Jump up ^ Understanding the WTO: The Doha Agenda +Jump up ^ The Challenges to the World Trade Organization: It’s All About Legitimacy THE BROOKINGS INSTITUTION, Policy Paper 2011-04 +Jump up ^ GROUPS IN THE WTO Updated 1 July 2013 +Jump up ^ Bourcier, Nicolas (21 May 2013). "Roberto Azevedo's WTO appointment gives Brazil a seat at the top table". Guardian Weekly. Retrieved 2 September 2013. +Jump up ^ "Roberto Azevêdo takes over". WTO official website. 1 September 2013. Retrieved 2 September 2013. +Jump up ^ "Overview of the WTO Secretariat". WTO official website. Retrieved 2 September 2013. +Jump up ^ Ninth WTO Ministerial Conference | WTO - MC9 +Jump up ^ BBC News - WTO agrees global trade deal worth $1tn +Jump up ^ A.E. Eckes Jr., US Trade History, 73 +* A. Smithies, Reflections on the Work of Keynes, 578–601 +* N. Warren, Internet and Globalization, 193 +Jump up ^ P. van den Bossche, The Law and Policy of the World Trade Organization, 80 +Jump up ^ Palmeter-Mavroidis, Dispute Settlement, 2 +Jump up ^ Fergusson, Ian F. (9 May 2007). "The World Trade Organization: Background and Issues" (PDF). Congressional Research Service. p. 4. Retrieved 15 August 2008. +Jump up ^ It was contemplated that the GATT would be applied for several years until the ITO came into force. However, since the ITO was never brought into being, the GATT gradually became the focus for international governmental cooperation on trade matters with economist Nicholas Halford overseeing the implementation of GATT in members policies. (P. van den Bossche, The Law and Policy of the World Trade Organization, 81; J.H. Jackson, Managing the Trading System, 134). +^ Jump up to: a b The GATT Years: from Havana to Marrakesh, WTO official site +Jump up ^ Footer, M. E. Analysis of the World Trade Organization, 17 +Jump up ^ B.S. Klapper, With a "Short Window" +Jump up ^ Lula, Time to Get Serious about Agricultural Subsidies +^ Jump up to: a b c P. Gallagher, The First Ten Years of the WTO, 4 +^ Jump up to: a b The Uruguay Round, WTO official site +Jump up ^ "Legal texts – Marrakesh agreement". WTO. Retrieved 30 May 2010. +Jump up ^ Overview: a Navigational Guide, WTO official site. For the complete list of "The Uruguay Round Agreements", see WTO legal texts, WTO official site, and Uruguay Round Agreements, Understandings, Decisions and Declarations, WorldTradeLaw.net +^ Jump up to: a b c d Principles of the Trading System, WTO official site +Jump up ^ "Five Years of China WTO Membership. EU and US Perspectives about China's Compliance with Transparency Commitments and the Transitional Review Mechanism". Papers.ssrn.com. Retrieved 30 May 2010. +Jump up ^ WTO to hold 7th Ministerial Conference on 30 November-2 December 2009 WTO official website +Jump up ^ "In the twilight of Doha". The Economist (The Economist): 65. 27 July 2006. +^ Jump up to: a b European Commission The Doha Round +Jump up ^ Fergusson, Ian F. (18 January 2008). "World Trade Organization Negotiations: The Doha Development Agenda" (PDF). Congressional Research Service. Retrieved 13 April 2012. Page 9 (folio CRS-6) +Jump up ^ WTO trade negotiations: Doha Development Agenda Europa press release, 31 October 2011 +Jump up ^ "Members start negotiating proposal on poor countries’ food stockholding". WTO official website. 27 March 2013. Retrieved 2 September 2013. +Jump up ^ a)The GATT years: from Havana to Marrakesh, World Trade Organization +b)Timeline: World Trade Organization – A chronology of key events, BBC News +c)Brakman-Garretsen-Marrewijk-Witteloostuijn, Nations and Firms in the Global Economy, Chapter 10: Trade and Capital Restriction +Jump up ^ Functions of the WTO, IISD +^ Jump up to: a b Main Functions, WTO official site +^ Jump up to: a b A Bredimas, International Economic Law, II, 17 +^ Jump up to: a b C. Deere, Decision-making in the WTO: Medieval or Up-to-Date? +Jump up ^ WTO Assistance for Developing Countries[dead link], WTO official site +Jump up ^ Sinha, Aparijita. [1]. "What are the functions and objectives of the WTO?". Retrieved on 13 April, 2014. +Jump up ^ Economic research and analysis, WTO official site +^ Jump up to: a b c B. Hoekman, The WTO: Functions and Basic Principles, 42 +^ Jump up to: a b B. Hoekman, The WTO: Functions and Basic Principles, 43 +^ Jump up to: a b B. Hoekman, The WTO: Functions and Basic Principles, 44 +^ Jump up to: a b Understanding the WTO: What we stand for +^ Jump up to: a b "Fourth level: down to the nitty-gritty". WTO official site. Retrieved 18 August 2008. +Jump up ^ "Intellectual property – overview of TRIPS Agreement". Wto.org. 15 April 1994. Retrieved 30 May 2010. +Jump up ^ "The Services Council, its Committees and other subsidiary bodies". WTO official site. Retrieved 14 August 2008. +Jump up ^ "The Trade Negotiations Committee". WTO official site. Retrieved 14 August 2008. +Jump up ^ "WTO organization chart". WTO official site. Retrieved 14 August 2008. +Jump up ^ Decision-making at WTO official site +Jump up ^ Decision-Making in the World Trade Organization Abstract from Journal of International Economic Law at Oxford Journals +Jump up ^ Steinberg, Richard H. "In the Shadow of Law or Power? Consensus-based Bargaining and Outcomes in the GATT/WTO." International Organization. Spring 2002. pp. 339–374. +Jump up ^ Stewart-Dawyer, The WTO Dispute Settlement System, 7 +Jump up ^ S. Panitchpakdi, The WTO at ten, 8. +Jump up ^ Settling Disputes:a Unique Contribution, WTO official site +Jump up ^ "Disputes – Dispute Settlement CBT – WTO Bodies involved in the dispute settlement process – The Dispute Settlement Body (DSB) – Page 1". WTO. 25 July 1996. Retrieved 21 May 2011. +^ Jump up to: a b Accessions Summary, Center for International Development +Jump up ^ Ministerial Conference approves Russia's WTO membership WTO News Item, 16 December 2011 +Jump up ^ Accession status: Vanuatu. WTO. Retrieved on 12 July 2013. +Jump up ^ C. Michalopoulos, WTO Accession, 64 +^ Jump up to: a b Membership, Alliances and Bureaucracy, WTO official site +Jump up ^ C. Michalopoulos, WTO Accession, 62–63 +Jump up ^ How to Become a Member of the WTO, WTO official site +Jump up ^ Napier, Nancy K.; Vuong, Quan Hoang (2013). What we see, why we worry, why we hope: Vietnam going forward. Boise, ID, USA: Boise State University CCI Press. p. 140. ISBN 978-0985530587. +Jump up ^ "Members and Observers". World Trade Organization. 24 August 2012. +Jump up ^ Jackson, J. H. Sovereignty, 109 +Jump up ^ ROC Government Publication +Jump up ^ "Accession in perspective". World Trade Organization. Retrieved 22 December 2013. +Jump up ^ "ANNEX 1. STATISTICAL SURVEY". World Trade Organization. 2005. Retrieved 22 December 2013. +Jump up ^ Arjomandy, Danial (21 November 2013). "Iranian Membership in the World Trade Organization: An Unclear Future". Iranian Studies. Retrieved 22 December 2013. +Jump up ^ International intergovernmental organizations granted observer status to WTO bodies at WTO official website +Jump up ^ "Legal texts – the WTO agreements". WTO. Retrieved 30 May 2010. +Jump up ^ Understanding the WTO - Intellectual property: protection and enforcement. WTO. Retrieved on 29 July 2013. +Jump up ^ "A Summary of the Final Act of the Uruguay Round". Wto.org. Retrieved 30 May 2010. +Jump up ^ Zarocostas, John (7 December 2013). "Global Trade Deal Reached". WWD. Retrieved 8 December 2013. +Jump up ^ "WT/L/509". WTO. Retrieved 18 February 2013. +Jump up ^ "Director-General Elect Azevêdo announces his four Deputy Directors-General". 17 August 2013. Retrieved 2 September 2013. +Jump up ^ "Previous GATT and WTO Directors-General". WTO. Retrieved 21 May 2011. +External links + Wikiquote has quotations related to: World Trade Organization + Wikimedia Commons has media related to World Trade Organization. +Official pages +Official WTO homepage +WTO 10th Anniversary PDF (1.40 MB) — Highlights of the first decade, Annual Report 2005 pages 116–166 +Glossary of terms—a guide to 'WTO-speak' +International Trade Centre — joint UN/WTO agency +Government pages on the WTO +European Union position on the WTO +Media pages on the WTO +World Trade Organization +BBC News — Profile: WTO +Guardian Unlimited — Special Report: The World Trade Organisation ongoing coverage +Non-governmental organization pages on the WTO +Gatt.org — Parody of official WTO page by The Yes Men +Public Citizen +Transnational Institute: Beyond the WTO +[show] v t e +World Trade Organization +[show] v t e +International trade +[show] v t e +International organizations +Authority control +WorldCat VIAF: 149937768 LCCN: no94018277 ISNI: 0000 0001 2296 2735 GND: 2145784-0 SELIBR: 135910 ULAN: 500292980 NDL: 00577475 NKC: kn20010711437 BNE: XX4574846 +Categories: World Trade OrganizationInternational tradeInternational trade organizationsOrganisations based in GenevaOrganizations established in 1995World government +Navigation menu +Create accountLog inArticleTalkReadView sourceView history + +Main page +Contents +Featured content +Current events +Random article +Donate to Wikipedia +Wikimedia Shop +Interaction +Help +About Wikipedia +Community portal +Recent changes +Contact page +Tools +What links here +Related changes +Upload file +Special pages +Permanent link +Page information +Wikidata item +Cite this page +Print/export +Create a book +Download as PDF +Printable version +Languages +Afrikaans +العربية +Aragonés +Asturianu +Azərbaycanca +বাংলা +Bân-lâm-gú +Беларуская +Беларуская (тарашкевіца)‎ +Български +Bosanski +Brezhoneg +Català +Čeština +Cymraeg +Dansk +Deutsch +Eesti +Ελληνικά +Español +Esperanto +Euskara +فارسی +Fiji Hindi +Føroyskt +Français +Frysk +Galego +ગુજરાતી +客家語/Hak-kâ-ngî +한국어 +Հայերեն +हिन्दी +Hrvatski +Ido +Ilokano +Bahasa Indonesia +Íslenska +Italiano +עברית +Basa Jawa +ಕನ್ನಡ +Къарачай-малкъар +ქართული +Қазақша +Kiswahili +Latina +Latviešu +Lietuvių +Magyar +Македонски +മലയാളം +मराठी +مصرى +Bahasa Melayu +Baso Minangkabau +မြန်မာဘာသာ +Nederlands +नेपाली +नेपाल भाषा +日本語 +Нохчийн +Norsk bokmål +Norsk nynorsk +Occitan +Oʻzbekcha +ਪੰਜਾਬੀ +پنجابی +پښتو +ភាសាខ្មែរ +Piemontèis +Polski +Português +Română +Русиньскый +Русский +Саха тыла +Shqip +සිංහල +Simple English +Slovenčina +Slovenščina +کوردی +Српски / srpski +Srpskohrvatski / српскохрватски +Suomi +Svenska +Tagalog +தமிழ் +Татарча/tatarça +తెలుగు +ไทย +Тоҷикӣ +Türkçe +Türkmençe +Українська +اردو +ئۇيغۇرچە / Uyghurche +Tiếng Việt +Winaray +ייִדיש +Yorùbá +粵語 +Žemaitėška +中文 +Edit links +This page was last modified on 22 November 2014 at 14:33. +Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Terms of Use and Privacy Policy. Wikipedia® is a registered trademark of the Wikimedia Foundation, Inc., a non-profit organization. +Privacy policyAbout WikipediaDisclaimersContact WikipediaDevelopersMobile viewWikimedia Foundation Powered by MediaWiki \ No newline at end of file diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/facet/facet_builder_datetime.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/facet/facet_builder_datetime.go new file mode 100644 index 0000000000..ff5167f21b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/facet/facet_builder_datetime.go @@ -0,0 +1,161 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package facet + +import ( + "reflect" + "sort" + "time" + + "github.com/blevesearch/bleve/v2/numeric" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/size" +) + +var reflectStaticSizeDateTimeFacetBuilder int +var reflectStaticSizedateTimeRange int + +func init() { + var dtfb DateTimeFacetBuilder + reflectStaticSizeDateTimeFacetBuilder = int(reflect.TypeOf(dtfb).Size()) + var dtr dateTimeRange + reflectStaticSizedateTimeRange = int(reflect.TypeOf(dtr).Size()) +} + +type dateTimeRange struct { + start time.Time + end time.Time +} + +type DateTimeFacetBuilder struct { + size int + field string + termsCount map[string]int + total int + missing int + ranges map[string]*dateTimeRange + sawValue bool +} + +func NewDateTimeFacetBuilder(field string, size int) *DateTimeFacetBuilder { + return &DateTimeFacetBuilder{ + size: size, + field: field, + termsCount: make(map[string]int), + ranges: make(map[string]*dateTimeRange, 0), + } +} + +func (fb *DateTimeFacetBuilder) Size() int { + sizeInBytes := reflectStaticSizeDateTimeFacetBuilder + size.SizeOfPtr + + len(fb.field) + + for k, _ := range fb.termsCount { + sizeInBytes += size.SizeOfString + len(k) + + size.SizeOfInt + } + + for k, _ := range fb.ranges { + sizeInBytes += size.SizeOfString + len(k) + + size.SizeOfPtr + reflectStaticSizedateTimeRange + } + + return sizeInBytes +} + +func (fb *DateTimeFacetBuilder) AddRange(name string, start, end time.Time) { + r := dateTimeRange{ + start: start, + end: end, + } + fb.ranges[name] = &r +} + +func (fb *DateTimeFacetBuilder) Field() string { + return fb.field +} + +func (fb *DateTimeFacetBuilder) UpdateVisitor(term []byte) { + fb.sawValue = true + // only consider the values which are shifted 0 + prefixCoded := numeric.PrefixCoded(term) + shift, err := prefixCoded.Shift() + if err == nil && shift == 0 { + i64, err := prefixCoded.Int64() + if err == nil { + t := time.Unix(0, i64) + + // look at each of the ranges for a match + for rangeName, r := range fb.ranges { + if (r.start.IsZero() || t.After(r.start) || t.Equal(r.start)) && (r.end.IsZero() || t.Before(r.end)) { + fb.termsCount[rangeName] = fb.termsCount[rangeName] + 1 + fb.total++ + } + } + } + } +} + +func (fb *DateTimeFacetBuilder) StartDoc() { + fb.sawValue = false +} + +func (fb *DateTimeFacetBuilder) EndDoc() { + if !fb.sawValue { + fb.missing++ + } +} + +func (fb *DateTimeFacetBuilder) Result() *search.FacetResult { + rv := search.FacetResult{ + Field: fb.field, + Total: fb.total, + Missing: fb.missing, + } + + rv.DateRanges = make([]*search.DateRangeFacet, 0, len(fb.termsCount)) + + for term, count := range fb.termsCount { + dateRange := fb.ranges[term] + tf := &search.DateRangeFacet{ + Name: term, + Count: count, + } + if !dateRange.start.IsZero() { + start := dateRange.start.Format(time.RFC3339Nano) + tf.Start = &start + } + if !dateRange.end.IsZero() { + end := dateRange.end.Format(time.RFC3339Nano) + tf.End = &end + } + rv.DateRanges = append(rv.DateRanges, tf) + } + + sort.Sort(rv.DateRanges) + + // we now have the list of the top N facets + if fb.size < len(rv.DateRanges) { + rv.DateRanges = rv.DateRanges[:fb.size] + } + + notOther := 0 + for _, nr := range rv.DateRanges { + notOther += nr.Count + } + rv.Other = fb.total - notOther + + return &rv +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/facet/facet_builder_numeric.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/facet/facet_builder_numeric.go new file mode 100644 index 0000000000..f19634d7b6 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/facet/facet_builder_numeric.go @@ -0,0 +1,155 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package facet + +import ( + "reflect" + "sort" + + "github.com/blevesearch/bleve/v2/numeric" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/size" +) + +var reflectStaticSizeNumericFacetBuilder int +var reflectStaticSizenumericRange int + +func init() { + var nfb NumericFacetBuilder + reflectStaticSizeNumericFacetBuilder = int(reflect.TypeOf(nfb).Size()) + var nr numericRange + reflectStaticSizenumericRange = int(reflect.TypeOf(nr).Size()) +} + +type numericRange struct { + min *float64 + max *float64 +} + +type NumericFacetBuilder struct { + size int + field string + termsCount map[string]int + total int + missing int + ranges map[string]*numericRange + sawValue bool +} + +func NewNumericFacetBuilder(field string, size int) *NumericFacetBuilder { + return &NumericFacetBuilder{ + size: size, + field: field, + termsCount: make(map[string]int), + ranges: make(map[string]*numericRange, 0), + } +} + +func (fb *NumericFacetBuilder) Size() int { + sizeInBytes := reflectStaticSizeNumericFacetBuilder + size.SizeOfPtr + + len(fb.field) + + for k, _ := range fb.termsCount { + sizeInBytes += size.SizeOfString + len(k) + + size.SizeOfInt + } + + for k, _ := range fb.ranges { + sizeInBytes += size.SizeOfString + len(k) + + size.SizeOfPtr + reflectStaticSizenumericRange + } + + return sizeInBytes +} + +func (fb *NumericFacetBuilder) AddRange(name string, min, max *float64) { + r := numericRange{ + min: min, + max: max, + } + fb.ranges[name] = &r +} + +func (fb *NumericFacetBuilder) Field() string { + return fb.field +} + +func (fb *NumericFacetBuilder) UpdateVisitor(term []byte) { + fb.sawValue = true + // only consider the values which are shifted 0 + prefixCoded := numeric.PrefixCoded(term) + shift, err := prefixCoded.Shift() + if err == nil && shift == 0 { + i64, err := prefixCoded.Int64() + if err == nil { + f64 := numeric.Int64ToFloat64(i64) + + // look at each of the ranges for a match + for rangeName, r := range fb.ranges { + if (r.min == nil || f64 >= *r.min) && (r.max == nil || f64 < *r.max) { + fb.termsCount[rangeName] = fb.termsCount[rangeName] + 1 + fb.total++ + } + } + } + } +} + +func (fb *NumericFacetBuilder) StartDoc() { + fb.sawValue = false +} + +func (fb *NumericFacetBuilder) EndDoc() { + if !fb.sawValue { + fb.missing++ + } +} + +func (fb *NumericFacetBuilder) Result() *search.FacetResult { + rv := search.FacetResult{ + Field: fb.field, + Total: fb.total, + Missing: fb.missing, + } + + rv.NumericRanges = make([]*search.NumericRangeFacet, 0, len(fb.termsCount)) + + for term, count := range fb.termsCount { + numericRange := fb.ranges[term] + tf := &search.NumericRangeFacet{ + Name: term, + Count: count, + Min: numericRange.min, + Max: numericRange.max, + } + + rv.NumericRanges = append(rv.NumericRanges, tf) + } + + sort.Sort(rv.NumericRanges) + + // we now have the list of the top N facets + if fb.size < len(rv.NumericRanges) { + rv.NumericRanges = rv.NumericRanges[:fb.size] + } + + notOther := 0 + for _, nr := range rv.NumericRanges { + notOther += nr.Count + } + rv.Other = fb.total - notOther + + return &rv +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/facet/facet_builder_terms.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/facet/facet_builder_terms.go new file mode 100644 index 0000000000..c5a1c83181 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/facet/facet_builder_terms.go @@ -0,0 +1,115 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package facet + +import ( + "reflect" + "sort" + + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/size" +) + +var reflectStaticSizeTermsFacetBuilder int + +func init() { + var tfb TermsFacetBuilder + reflectStaticSizeTermsFacetBuilder = int(reflect.TypeOf(tfb).Size()) +} + +type TermsFacetBuilder struct { + size int + field string + termsCount map[string]int + total int + missing int + sawValue bool +} + +func NewTermsFacetBuilder(field string, size int) *TermsFacetBuilder { + return &TermsFacetBuilder{ + size: size, + field: field, + termsCount: make(map[string]int), + } +} + +func (fb *TermsFacetBuilder) Size() int { + sizeInBytes := reflectStaticSizeTermsFacetBuilder + size.SizeOfPtr + + len(fb.field) + + for k, _ := range fb.termsCount { + sizeInBytes += size.SizeOfString + len(k) + + size.SizeOfInt + } + + return sizeInBytes +} + +func (fb *TermsFacetBuilder) Field() string { + return fb.field +} + +func (fb *TermsFacetBuilder) UpdateVisitor(term []byte) { + fb.sawValue = true + fb.termsCount[string(term)] = fb.termsCount[string(term)] + 1 + fb.total++ +} + +func (fb *TermsFacetBuilder) StartDoc() { + fb.sawValue = false +} + +func (fb *TermsFacetBuilder) EndDoc() { + if !fb.sawValue { + fb.missing++ + } +} + +func (fb *TermsFacetBuilder) Result() *search.FacetResult { + rv := search.FacetResult{ + Field: fb.field, + Total: fb.total, + Missing: fb.missing, + } + + rv.Terms = &search.TermFacets{} + + for term, count := range fb.termsCount { + tf := &search.TermFacet{ + Term: term, + Count: count, + } + + rv.Terms.Add(tf) + } + + sort.Sort(rv.Terms) + + // we now have the list of the top N facets + trimTopN := fb.size + if trimTopN > rv.Terms.Len() { + trimTopN = rv.Terms.Len() + } + rv.Terms.TrimToTopN(trimTopN) + + notOther := 0 + for _, tf := range rv.Terms.Terms() { + notOther += tf.Count + } + rv.Other = fb.total - notOther + + return &rv +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/facets_builder.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/facets_builder.go new file mode 100644 index 0000000000..de5a157486 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/facets_builder.go @@ -0,0 +1,399 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package search + +import ( + "encoding/json" + "reflect" + "sort" + + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeFacetsBuilder int +var reflectStaticSizeFacetResult int +var reflectStaticSizeTermFacet int +var reflectStaticSizeNumericRangeFacet int +var reflectStaticSizeDateRangeFacet int + +func init() { + var fb FacetsBuilder + reflectStaticSizeFacetsBuilder = int(reflect.TypeOf(fb).Size()) + var fr FacetResult + reflectStaticSizeFacetResult = int(reflect.TypeOf(fr).Size()) + var tf TermFacet + reflectStaticSizeTermFacet = int(reflect.TypeOf(tf).Size()) + var nrf NumericRangeFacet + reflectStaticSizeNumericRangeFacet = int(reflect.TypeOf(nrf).Size()) + var drf DateRangeFacet + reflectStaticSizeDateRangeFacet = int(reflect.TypeOf(drf).Size()) +} + +type FacetBuilder interface { + StartDoc() + UpdateVisitor(term []byte) + EndDoc() + + Result() *FacetResult + Field() string + + Size() int +} + +type FacetsBuilder struct { + indexReader index.IndexReader + facetNames []string + facets []FacetBuilder + facetsByField map[string][]FacetBuilder + fields []string +} + +func NewFacetsBuilder(indexReader index.IndexReader) *FacetsBuilder { + return &FacetsBuilder{ + indexReader: indexReader, + } +} + +func (fb *FacetsBuilder) Size() int { + sizeInBytes := reflectStaticSizeFacetsBuilder + size.SizeOfPtr + + for k, v := range fb.facets { + sizeInBytes += size.SizeOfString + v.Size() + len(fb.facetNames[k]) + } + + for _, entry := range fb.fields { + sizeInBytes += size.SizeOfString + len(entry) + } + + return sizeInBytes +} + +func (fb *FacetsBuilder) Add(name string, facetBuilder FacetBuilder) { + if fb.facetsByField == nil { + fb.facetsByField = map[string][]FacetBuilder{} + } + + fb.facetNames = append(fb.facetNames, name) + fb.facets = append(fb.facets, facetBuilder) + fb.facetsByField[facetBuilder.Field()] = append(fb.facetsByField[facetBuilder.Field()], facetBuilder) + fb.fields = append(fb.fields, facetBuilder.Field()) +} + +func (fb *FacetsBuilder) RequiredFields() []string { + return fb.fields +} + +func (fb *FacetsBuilder) StartDoc() { + for _, facetBuilder := range fb.facets { + facetBuilder.StartDoc() + } +} + +func (fb *FacetsBuilder) EndDoc() { + for _, facetBuilder := range fb.facets { + facetBuilder.EndDoc() + } +} + +func (fb *FacetsBuilder) UpdateVisitor(field string, term []byte) { + if facetBuilders, ok := fb.facetsByField[field]; ok { + for _, facetBuilder := range facetBuilders { + facetBuilder.UpdateVisitor(term) + } + } +} + +type TermFacet struct { + Term string `json:"term"` + Count int `json:"count"` +} + +type TermFacets struct { + termFacets []*TermFacet + termLookup map[string]*TermFacet +} + +func (tf *TermFacets) Terms() []*TermFacet { + if tf == nil { + return []*TermFacet{} + } + return tf.termFacets +} + +func (tf *TermFacets) TrimToTopN(n int) { + tf.termFacets = tf.termFacets[:n] +} + +func (tf *TermFacets) Add(termFacets ...*TermFacet) { + for _, termFacet := range termFacets { + if tf.termLookup == nil { + tf.termLookup = map[string]*TermFacet{} + } + + if term, ok := tf.termLookup[termFacet.Term]; ok { + term.Count += termFacet.Count + return + } + + // if we got here it wasn't already in the existing terms + tf.termFacets = append(tf.termFacets, termFacet) + tf.termLookup[termFacet.Term] = termFacet + } +} + +func (tf *TermFacets) Len() int { + // Handle case where *TermFacets is not fully initialized in index_impl.go.init() + if tf == nil { + return 0 + } + + return len(tf.termFacets) +} +func (tf *TermFacets) Swap(i, j int) { + tf.termFacets[i], tf.termFacets[j] = tf.termFacets[j], tf.termFacets[i] +} +func (tf *TermFacets) Less(i, j int) bool { + if tf.termFacets[i].Count == tf.termFacets[j].Count { + return tf.termFacets[i].Term < tf.termFacets[j].Term + } + return tf.termFacets[i].Count > tf.termFacets[j].Count +} + +// TermFacets used to be a type alias for []*TermFacet. +// To maintain backwards compatibility, we have to implement custom +// JSON marshalling. +func (tf *TermFacets) MarshalJSON() ([]byte, error) { + return json.Marshal(tf.termFacets) +} + +func (tf *TermFacets) UnmarshalJSON(b []byte) error { + termFacets := []*TermFacet{} + err := json.Unmarshal(b, &termFacets) + if err != nil { + return err + } + + for _, termFacet := range termFacets { + tf.Add(termFacet) + } + + return nil +} + +type NumericRangeFacet struct { + Name string `json:"name"` + Min *float64 `json:"min,omitempty"` + Max *float64 `json:"max,omitempty"` + Count int `json:"count"` +} + +func (nrf *NumericRangeFacet) Same(other *NumericRangeFacet) bool { + if nrf.Min == nil && other.Min != nil { + return false + } + if nrf.Min != nil && other.Min == nil { + return false + } + if nrf.Min != nil && other.Min != nil && *nrf.Min != *other.Min { + return false + } + if nrf.Max == nil && other.Max != nil { + return false + } + if nrf.Max != nil && other.Max == nil { + return false + } + if nrf.Max != nil && other.Max != nil && *nrf.Max != *other.Max { + return false + } + + return true +} + +type NumericRangeFacets []*NumericRangeFacet + +func (nrf NumericRangeFacets) Add(numericRangeFacet *NumericRangeFacet) NumericRangeFacets { + for _, existingNr := range nrf { + if numericRangeFacet.Same(existingNr) { + existingNr.Count += numericRangeFacet.Count + return nrf + } + } + // if we got here it wasn't already in the existing terms + nrf = append(nrf, numericRangeFacet) + return nrf +} + +func (nrf NumericRangeFacets) Len() int { return len(nrf) } +func (nrf NumericRangeFacets) Swap(i, j int) { nrf[i], nrf[j] = nrf[j], nrf[i] } +func (nrf NumericRangeFacets) Less(i, j int) bool { + if nrf[i].Count == nrf[j].Count { + return nrf[i].Name < nrf[j].Name + } + return nrf[i].Count > nrf[j].Count +} + +type DateRangeFacet struct { + Name string `json:"name"` + Start *string `json:"start,omitempty"` + End *string `json:"end,omitempty"` + Count int `json:"count"` +} + +func (drf *DateRangeFacet) Same(other *DateRangeFacet) bool { + if drf.Start == nil && other.Start != nil { + return false + } + if drf.Start != nil && other.Start == nil { + return false + } + if drf.Start != nil && other.Start != nil && *drf.Start != *other.Start { + return false + } + if drf.End == nil && other.End != nil { + return false + } + if drf.End != nil && other.End == nil { + return false + } + if drf.End != nil && other.End != nil && *drf.End != *other.End { + return false + } + + return true +} + +type DateRangeFacets []*DateRangeFacet + +func (drf DateRangeFacets) Add(dateRangeFacet *DateRangeFacet) DateRangeFacets { + for _, existingDr := range drf { + if dateRangeFacet.Same(existingDr) { + existingDr.Count += dateRangeFacet.Count + return drf + } + } + // if we got here it wasn't already in the existing terms + drf = append(drf, dateRangeFacet) + return drf +} + +func (drf DateRangeFacets) Len() int { return len(drf) } +func (drf DateRangeFacets) Swap(i, j int) { drf[i], drf[j] = drf[j], drf[i] } +func (drf DateRangeFacets) Less(i, j int) bool { + if drf[i].Count == drf[j].Count { + return drf[i].Name < drf[j].Name + } + return drf[i].Count > drf[j].Count +} + +type FacetResult struct { + Field string `json:"field"` + Total int `json:"total"` + Missing int `json:"missing"` + Other int `json:"other"` + Terms *TermFacets `json:"terms,omitempty"` + NumericRanges NumericRangeFacets `json:"numeric_ranges,omitempty"` + DateRanges DateRangeFacets `json:"date_ranges,omitempty"` +} + +func (fr *FacetResult) Size() int { + return reflectStaticSizeFacetResult + size.SizeOfPtr + + len(fr.Field) + + fr.Terms.Len()*(reflectStaticSizeTermFacet+size.SizeOfPtr) + + len(fr.NumericRanges)*(reflectStaticSizeNumericRangeFacet+size.SizeOfPtr) + + len(fr.DateRanges)*(reflectStaticSizeDateRangeFacet+size.SizeOfPtr) +} + +func (fr *FacetResult) Merge(other *FacetResult) { + fr.Total += other.Total + fr.Missing += other.Missing + fr.Other += other.Other + if fr.Terms != nil && other.Terms != nil { + for _, term := range other.Terms.termFacets { + fr.Terms.Add(term) + } + } + if fr.NumericRanges != nil && other.NumericRanges != nil { + for _, nr := range other.NumericRanges { + fr.NumericRanges = fr.NumericRanges.Add(nr) + } + } + if fr.DateRanges != nil && other.DateRanges != nil { + for _, dr := range other.DateRanges { + fr.DateRanges = fr.DateRanges.Add(dr) + } + } +} + +func (fr *FacetResult) Fixup(size int) { + if fr.Terms != nil { + sort.Sort(fr.Terms) + if fr.Terms.Len() > size { + moveToOther := fr.Terms.termFacets[size:] + for _, mto := range moveToOther { + fr.Other += mto.Count + } + fr.Terms.termFacets = fr.Terms.termFacets[0:size] + } + } else if fr.NumericRanges != nil { + sort.Sort(fr.NumericRanges) + if len(fr.NumericRanges) > size { + moveToOther := fr.NumericRanges[size:] + for _, mto := range moveToOther { + fr.Other += mto.Count + } + fr.NumericRanges = fr.NumericRanges[0:size] + } + } else if fr.DateRanges != nil { + sort.Sort(fr.DateRanges) + if len(fr.DateRanges) > size { + moveToOther := fr.DateRanges[size:] + for _, mto := range moveToOther { + fr.Other += mto.Count + } + fr.DateRanges = fr.DateRanges[0:size] + } + } +} + +type FacetResults map[string]*FacetResult + +func (fr FacetResults) Merge(other FacetResults) { + for name, oFacetResult := range other { + facetResult, ok := fr[name] + if ok { + facetResult.Merge(oFacetResult) + } else { + fr[name] = oFacetResult + } + } +} + +func (fr FacetResults) Fixup(name string, size int) { + facetResult, ok := fr[name] + if ok { + facetResult.Fixup(size) + } +} + +func (fb *FacetsBuilder) Results() FacetResults { + fr := make(FacetResults) + for i, facetBuilder := range fb.facets { + facetResult := facetBuilder.Result() + fr[fb.facetNames[i]] = facetResult + } + return fr +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/format/html/html.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/format/html/html.go new file mode 100644 index 0000000000..a0658d9c7f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/format/html/html.go @@ -0,0 +1,91 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package html + +import ( + "html" + + "github.com/blevesearch/bleve/v2/registry" + "github.com/blevesearch/bleve/v2/search/highlight" +) + +const Name = "html" + +const defaultHTMLHighlightBefore = "" +const defaultHTMLHighlightAfter = "" + +type FragmentFormatter struct { + before string + after string +} + +func NewFragmentFormatter(before, after string) *FragmentFormatter { + return &FragmentFormatter{ + before: before, + after: after, + } +} + +func (a *FragmentFormatter) Format(f *highlight.Fragment, orderedTermLocations highlight.TermLocations) string { + rv := "" + curr := f.Start + for _, termLocation := range orderedTermLocations { + if termLocation == nil { + continue + } + // make sure the array positions match + if !termLocation.ArrayPositions.Equals(f.ArrayPositions) { + continue + } + if termLocation.Start < curr { + continue + } + if termLocation.End > f.End { + break + } + // add the stuff before this location + rv += html.EscapeString(string(f.Orig[curr:termLocation.Start])) + // start the tag + rv += a.before + // add the term itself + rv += html.EscapeString(string(f.Orig[termLocation.Start:termLocation.End])) + // end the tag + rv += a.after + // update current + curr = termLocation.End + } + // add any remaining text after the last token + rv += html.EscapeString(string(f.Orig[curr:f.End])) + + return rv +} + +func Constructor(config map[string]interface{}, cache *registry.Cache) (highlight.FragmentFormatter, error) { + before := defaultHTMLHighlightBefore + beforeVal, ok := config["before"].(string) + if ok { + before = beforeVal + } + after := defaultHTMLHighlightAfter + afterVal, ok := config["after"].(string) + if ok { + after = afterVal + } + return NewFragmentFormatter(before, after), nil +} + +func init() { + registry.RegisterFragmentFormatter(Name, Constructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/fragmenter/simple/simple.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/fragmenter/simple/simple.go new file mode 100644 index 0000000000..34e5c9597e --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/fragmenter/simple/simple.go @@ -0,0 +1,153 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package simple + +import ( + "unicode/utf8" + + "github.com/blevesearch/bleve/v2/registry" + "github.com/blevesearch/bleve/v2/search/highlight" +) + +const Name = "simple" + +const defaultFragmentSize = 200 + +type Fragmenter struct { + fragmentSize int +} + +func NewFragmenter(fragmentSize int) *Fragmenter { + return &Fragmenter{ + fragmentSize: fragmentSize, + } +} + +func (s *Fragmenter) Fragment(orig []byte, ot highlight.TermLocations) []*highlight.Fragment { + var rv []*highlight.Fragment + maxbegin := 0 +OUTER: + for currTermIndex, termLocation := range ot { + // start with this + // it should be the highest scoring fragment with this term first + start := termLocation.Start + end := start + used := 0 + for end < len(orig) && used < s.fragmentSize { + r, size := utf8.DecodeRune(orig[end:]) + if r == utf8.RuneError { + continue OUTER // bail + } + end += size + used++ + } + + // if we still have more characters available to us + // push back towards beginning + // without cross maxbegin + for start > 0 && used < s.fragmentSize { + if start > len(orig) { + // bail if out of bounds, possibly due to token replacement + // e.g with a regexp replacement + continue OUTER + } + r, size := utf8.DecodeLastRune(orig[0:start]) + if r == utf8.RuneError { + continue OUTER // bail + } + if start-size >= maxbegin { + start -= size + used++ + } else { + break + } + } + + // however, we'd rather have the tokens centered more in the frag + // lets try to do that as best we can, without affecting the score + // find the end of the last term in this fragment + minend := end + for _, innerTermLocation := range ot[currTermIndex:] { + if innerTermLocation.End > end { + break + } + minend = innerTermLocation.End + } + + // find the smaller of the two rooms to move + roomToMove := utf8.RuneCount(orig[minend:end]) + roomToMoveStart := 0 + if start >= maxbegin { + roomToMoveStart = utf8.RuneCount(orig[maxbegin:start]) + } + if roomToMoveStart < roomToMove { + roomToMove = roomToMoveStart + } + + offset := roomToMove / 2 + + for offset > 0 { + r, size := utf8.DecodeLastRune(orig[0:start]) + if r == utf8.RuneError { + continue OUTER // bail + } + start -= size + + r, size = utf8.DecodeLastRune(orig[0:end]) + if r == utf8.RuneError { + continue OUTER // bail + } + end -= size + offset-- + } + + rv = append(rv, &highlight.Fragment{Orig: orig, Start: start - offset, End: end - offset}) + // set maxbegin to the end of the current term location + // so that next one won't back up to include it + maxbegin = termLocation.End + + } + if len(ot) == 0 { + // if there were no terms to highlight + // produce a single fragment from the beginning + start := 0 + end := start + used := 0 + for end < len(orig) && used < s.fragmentSize { + r, size := utf8.DecodeRune(orig[end:]) + if r == utf8.RuneError { + break + } + end += size + used++ + } + rv = append(rv, &highlight.Fragment{Orig: orig, Start: start, End: end}) + } + + return rv +} + +func Constructor(config map[string]interface{}, cache *registry.Cache) (highlight.Fragmenter, error) { + size := defaultFragmentSize + sizeVal, ok := config["size"].(float64) + if ok { + size = int(sizeVal) + } + return NewFragmenter(size), nil +} + +func init() { + registry.RegisterFragmenter(Name, Constructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/highlighter.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/highlighter.go new file mode 100644 index 0000000000..3dd9ce0531 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/highlighter.go @@ -0,0 +1,64 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package highlight + +import ( + "github.com/blevesearch/bleve/v2/search" + index "github.com/blevesearch/bleve_index_api" +) + +type Fragment struct { + Orig []byte + ArrayPositions []uint64 + Start int + End int + Score float64 + Index int // used by heap +} + +func (f *Fragment) Overlaps(other *Fragment) bool { + if other.Start >= f.Start && other.Start < f.End { + return true + } else if f.Start >= other.Start && f.Start < other.End { + return true + } + return false +} + +type Fragmenter interface { + Fragment([]byte, TermLocations) []*Fragment +} + +type FragmentFormatter interface { + Format(f *Fragment, orderedTermLocations TermLocations) string +} + +type FragmentScorer interface { + Score(f *Fragment) float64 +} + +type Highlighter interface { + Fragmenter() Fragmenter + SetFragmenter(Fragmenter) + + FragmentFormatter() FragmentFormatter + SetFragmentFormatter(FragmentFormatter) + + Separator() string + SetSeparator(string) + + BestFragmentInField(*search.DocumentMatch, index.Document, string) string + BestFragmentsInField(*search.DocumentMatch, index.Document, string, int) []string +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/highlighter/html/html.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/highlighter/html/html.go new file mode 100644 index 0000000000..ceb686dce5 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/highlighter/html/html.go @@ -0,0 +1,50 @@ +// Copyright (c) 2015 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package html + +import ( + "fmt" + + "github.com/blevesearch/bleve/v2/registry" + "github.com/blevesearch/bleve/v2/search/highlight" + htmlFormatter "github.com/blevesearch/bleve/v2/search/highlight/format/html" + simpleFragmenter "github.com/blevesearch/bleve/v2/search/highlight/fragmenter/simple" + simpleHighlighter "github.com/blevesearch/bleve/v2/search/highlight/highlighter/simple" +) + +const Name = "html" + +func Constructor(config map[string]interface{}, cache *registry.Cache) (highlight.Highlighter, error) { + + fragmenter, err := cache.FragmenterNamed(simpleFragmenter.Name) + if err != nil { + return nil, fmt.Errorf("error building fragmenter: %v", err) + } + + formatter, err := cache.FragmentFormatterNamed(htmlFormatter.Name) + if err != nil { + return nil, fmt.Errorf("error building fragment formatter: %v", err) + } + + return simpleHighlighter.NewHighlighter( + fragmenter, + formatter, + simpleHighlighter.DefaultSeparator), + nil +} + +func init() { + registry.RegisterHighlighter(Name, Constructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/highlighter/simple/fragment_scorer_simple.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/highlighter/simple/fragment_scorer_simple.go new file mode 100644 index 0000000000..786e33cb3a --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/highlighter/simple/fragment_scorer_simple.go @@ -0,0 +1,49 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package simple + +import ( + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/highlight" +) + +// FragmentScorer will score fragments by how many +// unique terms occur in the fragment with no regard for +// any boost values used in the original query +type FragmentScorer struct { + tlm search.TermLocationMap +} + +func NewFragmentScorer(tlm search.TermLocationMap) *FragmentScorer { + return &FragmentScorer{ + tlm: tlm, + } +} + +func (s *FragmentScorer) Score(f *highlight.Fragment) { + score := 0.0 +OUTER: + for _, locations := range s.tlm { + for _, location := range locations { + if location.ArrayPositions.Equals(f.ArrayPositions) && int(location.Start) >= f.Start && int(location.End) <= f.End { + score += 1.0 + // once we find a term in the fragment + // don't care about additional matches + continue OUTER + } + } + } + f.Score = score +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/highlighter/simple/highlighter_simple.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/highlighter/simple/highlighter_simple.go new file mode 100644 index 0000000000..19949687d2 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/highlighter/simple/highlighter_simple.go @@ -0,0 +1,221 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package simple + +import ( + "container/heap" + "fmt" + index "github.com/blevesearch/bleve_index_api" + + "github.com/blevesearch/bleve/v2/registry" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/highlight" +) + +const Name = "simple" +const DefaultSeparator = "…" + +type Highlighter struct { + fragmenter highlight.Fragmenter + formatter highlight.FragmentFormatter + sep string +} + +func NewHighlighter(fragmenter highlight.Fragmenter, formatter highlight.FragmentFormatter, separator string) *Highlighter { + return &Highlighter{ + fragmenter: fragmenter, + formatter: formatter, + sep: separator, + } +} + +func (s *Highlighter) Fragmenter() highlight.Fragmenter { + return s.fragmenter +} + +func (s *Highlighter) SetFragmenter(f highlight.Fragmenter) { + s.fragmenter = f +} + +func (s *Highlighter) FragmentFormatter() highlight.FragmentFormatter { + return s.formatter +} + +func (s *Highlighter) SetFragmentFormatter(f highlight.FragmentFormatter) { + s.formatter = f +} + +func (s *Highlighter) Separator() string { + return s.sep +} + +func (s *Highlighter) SetSeparator(sep string) { + s.sep = sep +} + +func (s *Highlighter) BestFragmentInField(dm *search.DocumentMatch, doc index.Document, field string) string { + fragments := s.BestFragmentsInField(dm, doc, field, 1) + if len(fragments) > 0 { + return fragments[0] + } + return "" +} + +func (s *Highlighter) BestFragmentsInField(dm *search.DocumentMatch, doc index.Document, field string, num int) []string { + tlm := dm.Locations[field] + orderedTermLocations := highlight.OrderTermLocations(tlm) + scorer := NewFragmentScorer(tlm) + + // score the fragments and put them into a priority queue ordered by score + fq := make(FragmentQueue, 0) + heap.Init(&fq) + doc.VisitFields(func(f index.Field) { + if f.Name() == field { + _, ok := f.(index.TextField) + if ok { + termLocationsSameArrayPosition := make(highlight.TermLocations, 0) + for _, otl := range orderedTermLocations { + if otl.ArrayPositions.Equals(f.ArrayPositions()) { + termLocationsSameArrayPosition = append(termLocationsSameArrayPosition, otl) + } + } + + fieldData := f.Value() + fragments := s.fragmenter.Fragment(fieldData, termLocationsSameArrayPosition) + for _, fragment := range fragments { + fragment.ArrayPositions = f.ArrayPositions() + scorer.Score(fragment) + heap.Push(&fq, fragment) + } + } + } + }) + + // now find the N best non-overlapping fragments + var bestFragments []*highlight.Fragment + if len(fq) > 0 { + candidate := heap.Pop(&fq) + OUTER: + for candidate != nil && len(bestFragments) < num { + // see if this overlaps with any of the best already identified + if len(bestFragments) > 0 { + for _, frag := range bestFragments { + if candidate.(*highlight.Fragment).Overlaps(frag) { + if len(fq) < 1 { + break OUTER + } + candidate = heap.Pop(&fq) + continue OUTER + } + } + bestFragments = append(bestFragments, candidate.(*highlight.Fragment)) + } else { + bestFragments = append(bestFragments, candidate.(*highlight.Fragment)) + } + + if len(fq) < 1 { + break + } + candidate = heap.Pop(&fq) + } + } + + // now that we have the best fragments, we can format them + orderedTermLocations.MergeOverlapping() + formattedFragments := make([]string, len(bestFragments)) + for i, fragment := range bestFragments { + formattedFragments[i] = "" + if fragment.Start != 0 { + formattedFragments[i] += s.sep + } + formattedFragments[i] += s.formatter.Format(fragment, orderedTermLocations) + if fragment.End != len(fragment.Orig) { + formattedFragments[i] += s.sep + } + } + + if dm.Fragments == nil { + dm.Fragments = make(search.FieldFragmentMap, 0) + } + if len(formattedFragments) > 0 { + dm.Fragments[field] = formattedFragments + } + + return formattedFragments +} + +// FragmentQueue implements heap.Interface and holds Items. +type FragmentQueue []*highlight.Fragment + +func (fq FragmentQueue) Len() int { return len(fq) } + +func (fq FragmentQueue) Less(i, j int) bool { + // We want Pop to give us the highest, not lowest, priority so we use greater-than here. + return fq[i].Score > fq[j].Score +} + +func (fq FragmentQueue) Swap(i, j int) { + fq[i], fq[j] = fq[j], fq[i] + fq[i].Index = i + fq[j].Index = j +} + +func (fq *FragmentQueue) Push(x interface{}) { + n := len(*fq) + item := x.(*highlight.Fragment) + item.Index = n + *fq = append(*fq, item) +} + +func (fq *FragmentQueue) Pop() interface{} { + old := *fq + n := len(old) + item := old[n-1] + item.Index = -1 // for safety + *fq = old[0 : n-1] + return item +} + +func Constructor(config map[string]interface{}, cache *registry.Cache) (highlight.Highlighter, error) { + separator := DefaultSeparator + separatorVal, ok := config["separator"].(string) + if ok { + separator = separatorVal + } + + fragmenterName, ok := config["fragmenter"].(string) + if !ok { + return nil, fmt.Errorf("must specify fragmenter") + } + fragmenter, err := cache.FragmenterNamed(fragmenterName) + if err != nil { + return nil, fmt.Errorf("error building fragmenter: %v", err) + } + + formatterName, ok := config["formatter"].(string) + if !ok { + return nil, fmt.Errorf("must specify formatter") + } + formatter, err := cache.FragmentFormatterNamed(formatterName) + if err != nil { + return nil, fmt.Errorf("error building fragment formatter: %v", err) + } + + return NewHighlighter(fragmenter, formatter, separator), nil +} + +func init() { + registry.RegisterHighlighter(Name, Constructor) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/term_locations.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/term_locations.go new file mode 100644 index 0000000000..6bf385c05c --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/highlight/term_locations.go @@ -0,0 +1,105 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package highlight + +import ( + "reflect" + "sort" + + "github.com/blevesearch/bleve/v2/search" +) + +type TermLocation struct { + Term string + ArrayPositions search.ArrayPositions + Pos int + Start int + End int +} + +func (tl *TermLocation) Overlaps(other *TermLocation) bool { + if reflect.DeepEqual(tl.ArrayPositions, other.ArrayPositions) { + if other.Start >= tl.Start && other.Start < tl.End { + return true + } else if tl.Start >= other.Start && tl.Start < other.End { + return true + } + } + return false +} + +type TermLocations []*TermLocation + +func (t TermLocations) Len() int { return len(t) } +func (t TermLocations) Swap(i, j int) { t[i], t[j] = t[j], t[i] } +func (t TermLocations) Less(i, j int) bool { + + shortestArrayPositions := len(t[i].ArrayPositions) + if len(t[j].ArrayPositions) < shortestArrayPositions { + shortestArrayPositions = len(t[j].ArrayPositions) + } + + // compare all the common array positions + for api := 0; api < shortestArrayPositions; api++ { + if t[i].ArrayPositions[api] < t[j].ArrayPositions[api] { + return true + } + if t[i].ArrayPositions[api] > t[j].ArrayPositions[api] { + return false + } + } + // all the common array positions are the same + if len(t[i].ArrayPositions) < len(t[j].ArrayPositions) { + return true // j array positions, longer so greater + } else if len(t[i].ArrayPositions) > len(t[j].ArrayPositions) { + return false // j array positions, shorter so less + } + + // array positions the same, compare starts + return t[i].Start < t[j].Start +} + +func (t TermLocations) MergeOverlapping() { + var lastTl *TermLocation + for i, tl := range t { + if lastTl == nil && tl != nil { + lastTl = tl + } else if lastTl != nil && tl != nil { + if lastTl.Overlaps(tl) { + // ok merge this with previous + lastTl.End = tl.End + t[i] = nil + } + } + } +} + +func OrderTermLocations(tlm search.TermLocationMap) TermLocations { + rv := make(TermLocations, 0) + for term, locations := range tlm { + for _, location := range locations { + tl := TermLocation{ + Term: term, + ArrayPositions: location.ArrayPositions, + Pos: int(location.Pos), + Start: int(location.Start), + End: int(location.End), + } + rv = append(rv, &tl) + } + } + sort.Sort(rv) + return rv +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/levenshtein.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/levenshtein.go new file mode 100644 index 0000000000..687608d3ff --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/levenshtein.go @@ -0,0 +1,114 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package search + +import ( + "math" +) + +func LevenshteinDistance(a, b string) int { + la := len(a) + lb := len(b) + d := make([]int, la+1) + var lastdiag, olddiag, temp int + + for i := 1; i <= la; i++ { + d[i] = i + } + for i := 1; i <= lb; i++ { + d[0] = i + lastdiag = i - 1 + for j := 1; j <= la; j++ { + olddiag = d[j] + min := d[j] + 1 + if (d[j-1] + 1) < min { + min = d[j-1] + 1 + } + if a[j-1] == b[i-1] { + temp = 0 + } else { + temp = 1 + } + if (lastdiag + temp) < min { + min = lastdiag + temp + } + d[j] = min + lastdiag = olddiag + } + } + return d[la] +} + +// LevenshteinDistanceMax same as LevenshteinDistance but +// attempts to bail early once we know the distance +// will be greater than max +// in which case the first return val will be the max +// and the second will be true, indicating max was exceeded +func LevenshteinDistanceMax(a, b string, max int) (int, bool) { + v, wasMax, _ := LevenshteinDistanceMaxReuseSlice(a, b, max, nil) + return v, wasMax +} + +func LevenshteinDistanceMaxReuseSlice(a, b string, max int, d []int) (int, bool, []int) { + la := len(a) + lb := len(b) + + ld := int(math.Abs(float64(la - lb))) + if ld > max { + return max, true, d + } + + if cap(d) < la+1 { + d = make([]int, la+1) + } + d = d[:la+1] + + var lastdiag, olddiag, temp int + + for i := 1; i <= la; i++ { + d[i] = i + } + for i := 1; i <= lb; i++ { + d[0] = i + lastdiag = i - 1 + rowmin := max + 1 + for j := 1; j <= la; j++ { + olddiag = d[j] + min := d[j] + 1 + if (d[j-1] + 1) < min { + min = d[j-1] + 1 + } + if a[j-1] == b[i-1] { + temp = 0 + } else { + temp = 1 + } + if (lastdiag + temp) < min { + min = lastdiag + temp + } + if min < rowmin { + rowmin = min + } + d[j] = min + + lastdiag = olddiag + } + // after each row if rowmin isn't less than max stop + if rowmin > max { + return max, true, d + } + } + return d[la], false, d +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/pool.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/pool.go new file mode 100644 index 0000000000..ba8be8fc27 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/pool.go @@ -0,0 +1,91 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package search + +import ( + "reflect" +) + +var reflectStaticSizeDocumentMatchPool int + +func init() { + var dmp DocumentMatchPool + reflectStaticSizeDocumentMatchPool = int(reflect.TypeOf(dmp).Size()) +} + +// DocumentMatchPoolTooSmall is a callback function that can be executed +// when the DocumentMatchPool does not have sufficient capacity +// By default we just perform just-in-time allocation, but you could log +// a message, or panic, etc. +type DocumentMatchPoolTooSmall func(p *DocumentMatchPool) *DocumentMatch + +// DocumentMatchPool manages use/re-use of DocumentMatch instances +// it pre-allocates space from a single large block with the expected +// number of instances. It is not thread-safe as currently all +// aspects of search take place in a single goroutine. +type DocumentMatchPool struct { + avail DocumentMatchCollection + TooSmall DocumentMatchPoolTooSmall +} + +func defaultDocumentMatchPoolTooSmall(p *DocumentMatchPool) *DocumentMatch { + return &DocumentMatch{} +} + +// NewDocumentMatchPool will build a DocumentMatchPool with memory +// pre-allocated to accommodate the requested number of DocumentMatch +// instances +func NewDocumentMatchPool(size, sortsize int) *DocumentMatchPool { + avail := make(DocumentMatchCollection, size) + // pre-allocate the expected number of instances + startBlock := make([]DocumentMatch, size) + startSorts := make([]string, size*sortsize) + // make these initial instances available + i, j := 0, 0 + for i < size { + avail[i] = &startBlock[i] + avail[i].Sort = startSorts[j:j] + i += 1 + j += sortsize + } + return &DocumentMatchPool{ + avail: avail, + TooSmall: defaultDocumentMatchPoolTooSmall, + } +} + +// Get returns an available DocumentMatch from the pool +// if the pool was not allocated with sufficient size, an allocation will +// occur to satisfy this request. As a side-effect this will grow the size +// of the pool. +func (p *DocumentMatchPool) Get() *DocumentMatch { + var rv *DocumentMatch + if len(p.avail) > 0 { + rv, p.avail = p.avail[len(p.avail)-1], p.avail[:len(p.avail)-1] + } else { + rv = p.TooSmall(p) + } + return rv +} + +// Put returns a DocumentMatch to the pool +func (p *DocumentMatchPool) Put(d *DocumentMatch) { + if d == nil { + return + } + // reset DocumentMatch before returning it to available pool + d.Reset() + p.avail = append(p.avail, d) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/bool_field.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/bool_field.go new file mode 100644 index 0000000000..5aa7bb8af7 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/bool_field.go @@ -0,0 +1,66 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type BoolFieldQuery struct { + Bool bool `json:"bool"` + FieldVal string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` +} + +// NewBoolFieldQuery creates a new Query for boolean fields +func NewBoolFieldQuery(val bool) *BoolFieldQuery { + return &BoolFieldQuery{ + Bool: val, + } +} + +func (q *BoolFieldQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *BoolFieldQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *BoolFieldQuery) SetField(f string) { + q.FieldVal = f +} + +func (q *BoolFieldQuery) Field() string { + return q.FieldVal +} + +func (q *BoolFieldQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + field := q.FieldVal + if q.FieldVal == "" { + field = m.DefaultSearchField() + } + term := "F" + if q.Bool { + term = "T" + } + return searcher.NewTermSearcher(ctx, i, term, field, q.BoostVal.Value(), options) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/boolean.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/boolean.go new file mode 100644 index 0000000000..b5e1fdc40d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/boolean.go @@ -0,0 +1,249 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type BooleanQuery struct { + Must Query `json:"must,omitempty"` + Should Query `json:"should,omitempty"` + MustNot Query `json:"must_not,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` + queryStringMode bool +} + +// NewBooleanQuery creates a compound Query composed +// of several other Query objects. +// Result documents must satisfy ALL of the +// must Queries. +// Result documents must satisfy NONE of the must not +// Queries. +// Result documents that ALSO satisfy any of the should +// Queries will score higher. +func NewBooleanQuery(must []Query, should []Query, mustNot []Query) *BooleanQuery { + + rv := BooleanQuery{} + if len(must) > 0 { + rv.Must = NewConjunctionQuery(must) + } + if len(should) > 0 { + rv.Should = NewDisjunctionQuery(should) + } + if len(mustNot) > 0 { + rv.MustNot = NewDisjunctionQuery(mustNot) + } + + return &rv +} + +func NewBooleanQueryForQueryString(must []Query, should []Query, mustNot []Query) *BooleanQuery { + rv := NewBooleanQuery(nil, nil, nil) + rv.queryStringMode = true + rv.AddMust(must...) + rv.AddShould(should...) + rv.AddMustNot(mustNot...) + return rv +} + +// SetMinShould requires that at least minShould of the +// should Queries must be satisfied. +func (q *BooleanQuery) SetMinShould(minShould float64) { + q.Should.(*DisjunctionQuery).SetMin(minShould) +} + +func (q *BooleanQuery) AddMust(m ...Query) { + if q.Must == nil { + tmp := NewConjunctionQuery([]Query{}) + tmp.queryStringMode = q.queryStringMode + q.Must = tmp + } + for _, mq := range m { + q.Must.(*ConjunctionQuery).AddQuery(mq) + } +} + +func (q *BooleanQuery) AddShould(m ...Query) { + if q.Should == nil { + tmp := NewDisjunctionQuery([]Query{}) + tmp.queryStringMode = q.queryStringMode + q.Should = tmp + } + for _, mq := range m { + q.Should.(*DisjunctionQuery).AddQuery(mq) + } +} + +func (q *BooleanQuery) AddMustNot(m ...Query) { + if q.MustNot == nil { + tmp := NewDisjunctionQuery([]Query{}) + tmp.queryStringMode = q.queryStringMode + q.MustNot = tmp + } + for _, mq := range m { + q.MustNot.(*DisjunctionQuery).AddQuery(mq) + } +} + +func (q *BooleanQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *BooleanQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *BooleanQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + var err error + var mustNotSearcher search.Searcher + if q.MustNot != nil { + mustNotSearcher, err = q.MustNot.Searcher(ctx, i, m, options) + if err != nil { + return nil, err + } + // if must not is MatchNone, reset it to nil + if _, ok := mustNotSearcher.(*searcher.MatchNoneSearcher); ok { + mustNotSearcher = nil + } + } + + var mustSearcher search.Searcher + if q.Must != nil { + mustSearcher, err = q.Must.Searcher(ctx, i, m, options) + if err != nil { + return nil, err + } + // if must searcher is MatchNone, reset it to nil + if _, ok := mustSearcher.(*searcher.MatchNoneSearcher); ok { + mustSearcher = nil + } + } + + var shouldSearcher search.Searcher + if q.Should != nil { + shouldSearcher, err = q.Should.Searcher(ctx, i, m, options) + if err != nil { + return nil, err + } + // if should searcher is MatchNone, reset it to nil + if _, ok := shouldSearcher.(*searcher.MatchNoneSearcher); ok { + shouldSearcher = nil + } + } + + // if all 3 are nil, return MatchNone + if mustSearcher == nil && shouldSearcher == nil && mustNotSearcher == nil { + return searcher.NewMatchNoneSearcher(i) + } + + // if only mustNotSearcher, start with MatchAll + if mustSearcher == nil && shouldSearcher == nil && mustNotSearcher != nil { + mustSearcher, err = searcher.NewMatchAllSearcher(ctx, i, 1.0, options) + if err != nil { + return nil, err + } + } + + // optimization, if only should searcher, just return it instead + if mustSearcher == nil && shouldSearcher != nil && mustNotSearcher == nil { + return shouldSearcher, nil + } + + return searcher.NewBooleanSearcher(ctx, i, mustSearcher, shouldSearcher, mustNotSearcher, options) +} + +func (q *BooleanQuery) Validate() error { + if qm, ok := q.Must.(ValidatableQuery); ok { + err := qm.Validate() + if err != nil { + return err + } + } + if qs, ok := q.Should.(ValidatableQuery); ok { + err := qs.Validate() + if err != nil { + return err + } + } + if qmn, ok := q.MustNot.(ValidatableQuery); ok { + err := qmn.Validate() + if err != nil { + return err + } + } + if q.Must == nil && q.Should == nil && q.MustNot == nil { + return fmt.Errorf("boolean query must contain at least one must or should or not must clause") + } + return nil +} + +func (q *BooleanQuery) UnmarshalJSON(data []byte) error { + tmp := struct { + Must json.RawMessage `json:"must,omitempty"` + Should json.RawMessage `json:"should,omitempty"` + MustNot json.RawMessage `json:"must_not,omitempty"` + Boost *Boost `json:"boost,omitempty"` + }{} + err := json.Unmarshal(data, &tmp) + if err != nil { + return err + } + + if tmp.Must != nil { + q.Must, err = ParseQuery(tmp.Must) + if err != nil { + return err + } + _, isConjunctionQuery := q.Must.(*ConjunctionQuery) + if !isConjunctionQuery { + return fmt.Errorf("must clause must be conjunction") + } + } + + if tmp.Should != nil { + q.Should, err = ParseQuery(tmp.Should) + if err != nil { + return err + } + _, isDisjunctionQuery := q.Should.(*DisjunctionQuery) + if !isDisjunctionQuery { + return fmt.Errorf("should clause must be disjunction") + } + } + + if tmp.MustNot != nil { + q.MustNot, err = ParseQuery(tmp.MustNot) + if err != nil { + return err + } + _, isDisjunctionQuery := q.MustNot.(*DisjunctionQuery) + if !isDisjunctionQuery { + return fmt.Errorf("must not clause must be disjunction") + } + } + + q.BoostVal = tmp.Boost + + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/boost.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/boost.go new file mode 100644 index 0000000000..13659945db --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/boost.go @@ -0,0 +1,33 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import "fmt" + +type Boost float64 + +func (b *Boost) Value() float64 { + if b == nil { + return 1.0 + } + return float64(*b) +} + +func (b *Boost) GoString() string { + if b == nil { + return "boost unspecified" + } + return fmt.Sprintf("%f", *b) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/conjunction.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/conjunction.go new file mode 100644 index 0000000000..27bec7d61c --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/conjunction.go @@ -0,0 +1,113 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "encoding/json" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type ConjunctionQuery struct { + Conjuncts []Query `json:"conjuncts"` + BoostVal *Boost `json:"boost,omitempty"` + queryStringMode bool +} + +// NewConjunctionQuery creates a new compound Query. +// Result documents must satisfy all of the queries. +func NewConjunctionQuery(conjuncts []Query) *ConjunctionQuery { + return &ConjunctionQuery{ + Conjuncts: conjuncts, + } +} + +func (q *ConjunctionQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *ConjunctionQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *ConjunctionQuery) AddQuery(aq ...Query) { + for _, aaq := range aq { + q.Conjuncts = append(q.Conjuncts, aaq) + } +} + +func (q *ConjunctionQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + ss := make([]search.Searcher, 0, len(q.Conjuncts)) + for _, conjunct := range q.Conjuncts { + sr, err := conjunct.Searcher(ctx, i, m, options) + if err != nil { + for _, searcher := range ss { + if searcher != nil { + _ = searcher.Close() + } + } + return nil, err + } + if _, ok := sr.(*searcher.MatchNoneSearcher); ok && q.queryStringMode { + // in query string mode, skip match none + continue + } + ss = append(ss, sr) + } + + if len(ss) < 1 { + return searcher.NewMatchNoneSearcher(i) + } + + return searcher.NewConjunctionSearcher(ctx, i, ss, options) +} + +func (q *ConjunctionQuery) Validate() error { + for _, q := range q.Conjuncts { + if q, ok := q.(ValidatableQuery); ok { + err := q.Validate() + if err != nil { + return err + } + } + } + return nil +} + +func (q *ConjunctionQuery) UnmarshalJSON(data []byte) error { + tmp := struct { + Conjuncts []json.RawMessage `json:"conjuncts"` + Boost *Boost `json:"boost,omitempty"` + }{} + err := json.Unmarshal(data, &tmp) + if err != nil { + return err + } + q.Conjuncts = make([]Query, len(tmp.Conjuncts)) + for i, term := range tmp.Conjuncts { + query, err := ParseQuery(term) + if err != nil { + return err + } + q.Conjuncts[i] = query + } + q.BoostVal = tmp.Boost + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/date_range.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/date_range.go new file mode 100644 index 0000000000..ef18f2fb8d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/date_range.go @@ -0,0 +1,192 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "encoding/json" + "fmt" + "math" + "time" + + "github.com/blevesearch/bleve/v2/analysis/datetime/optional" + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/numeric" + "github.com/blevesearch/bleve/v2/registry" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +// QueryDateTimeParser controls the default query date time parser +var QueryDateTimeParser = optional.Name + +// QueryDateTimeFormat controls the format when Marshaling to JSON +var QueryDateTimeFormat = time.RFC3339 + +var cache = registry.NewCache() + +type BleveQueryTime struct { + time.Time +} + +var MinRFC3339CompatibleTime time.Time +var MaxRFC3339CompatibleTime time.Time + +func init() { + MinRFC3339CompatibleTime, _ = time.Parse(time.RFC3339, "1677-12-01T00:00:00Z") + MaxRFC3339CompatibleTime, _ = time.Parse(time.RFC3339, "2262-04-11T11:59:59Z") +} + +func queryTimeFromString(t string) (time.Time, error) { + dateTimeParser, err := cache.DateTimeParserNamed(QueryDateTimeParser) + if err != nil { + return time.Time{}, err + } + rv, err := dateTimeParser.ParseDateTime(t) + if err != nil { + return time.Time{}, err + } + return rv, nil +} + +func (t *BleveQueryTime) MarshalJSON() ([]byte, error) { + tt := time.Time(t.Time) + return []byte("\"" + tt.Format(QueryDateTimeFormat) + "\""), nil +} + +func (t *BleveQueryTime) UnmarshalJSON(data []byte) error { + var timeString string + err := json.Unmarshal(data, &timeString) + if err != nil { + return err + } + dateTimeParser, err := cache.DateTimeParserNamed(QueryDateTimeParser) + if err != nil { + return err + } + t.Time, err = dateTimeParser.ParseDateTime(timeString) + if err != nil { + return err + } + return nil +} + +type DateRangeQuery struct { + Start BleveQueryTime `json:"start,omitempty"` + End BleveQueryTime `json:"end,omitempty"` + InclusiveStart *bool `json:"inclusive_start,omitempty"` + InclusiveEnd *bool `json:"inclusive_end,omitempty"` + FieldVal string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` +} + +// NewDateRangeQuery creates a new Query for ranges +// of date values. +// Date strings are parsed using the DateTimeParser configured in the +// top-level config.QueryDateTimeParser +// Either, but not both endpoints can be nil. +func NewDateRangeQuery(start, end time.Time) *DateRangeQuery { + return NewDateRangeInclusiveQuery(start, end, nil, nil) +} + +// NewDateRangeInclusiveQuery creates a new Query for ranges +// of date values. +// Date strings are parsed using the DateTimeParser configured in the +// top-level config.QueryDateTimeParser +// Either, but not both endpoints can be nil. +// startInclusive and endInclusive control inclusion of the endpoints. +func NewDateRangeInclusiveQuery(start, end time.Time, startInclusive, endInclusive *bool) *DateRangeQuery { + return &DateRangeQuery{ + Start: BleveQueryTime{start}, + End: BleveQueryTime{end}, + InclusiveStart: startInclusive, + InclusiveEnd: endInclusive, + } +} + +func (q *DateRangeQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *DateRangeQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *DateRangeQuery) SetField(f string) { + q.FieldVal = f +} + +func (q *DateRangeQuery) Field() string { + return q.FieldVal +} + +func (q *DateRangeQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + min, max, err := q.parseEndpoints() + if err != nil { + return nil, err + } + + field := q.FieldVal + if q.FieldVal == "" { + field = m.DefaultSearchField() + } + + return searcher.NewNumericRangeSearcher(ctx, i, min, max, q.InclusiveStart, q.InclusiveEnd, field, q.BoostVal.Value(), options) +} + +func (q *DateRangeQuery) parseEndpoints() (*float64, *float64, error) { + min := math.Inf(-1) + max := math.Inf(1) + if !q.Start.IsZero() { + if !isDatetimeCompatible(q.Start) { + // overflow + return nil, nil, fmt.Errorf("invalid/unsupported date range, start: %v", q.Start) + } + startInt64 := q.Start.UnixNano() + min = numeric.Int64ToFloat64(startInt64) + } + if !q.End.IsZero() { + if !isDatetimeCompatible(q.End) { + // overflow + return nil, nil, fmt.Errorf("invalid/unsupported date range, end: %v", q.End) + } + endInt64 := q.End.UnixNano() + max = numeric.Int64ToFloat64(endInt64) + } + + return &min, &max, nil +} + +func (q *DateRangeQuery) Validate() error { + if q.Start.IsZero() && q.End.IsZero() { + return fmt.Errorf("must specify start or end") + } + _, _, err := q.parseEndpoints() + if err != nil { + return err + } + return nil +} + +func isDatetimeCompatible(t BleveQueryTime) bool { + if QueryDateTimeFormat == time.RFC3339 && + (t.Before(MinRFC3339CompatibleTime) || t.After(MaxRFC3339CompatibleTime)) { + return false + } + + return true +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/disjunction.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/disjunction.go new file mode 100644 index 0000000000..c6cc0d737e --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/disjunction.go @@ -0,0 +1,125 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type DisjunctionQuery struct { + Disjuncts []Query `json:"disjuncts"` + BoostVal *Boost `json:"boost,omitempty"` + Min float64 `json:"min"` + queryStringMode bool +} + +// NewDisjunctionQuery creates a new compound Query. +// Result documents satisfy at least one Query. +func NewDisjunctionQuery(disjuncts []Query) *DisjunctionQuery { + return &DisjunctionQuery{ + Disjuncts: disjuncts, + } +} + +func (q *DisjunctionQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *DisjunctionQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *DisjunctionQuery) AddQuery(aq ...Query) { + for _, aaq := range aq { + q.Disjuncts = append(q.Disjuncts, aaq) + } +} + +func (q *DisjunctionQuery) SetMin(m float64) { + q.Min = m +} + +func (q *DisjunctionQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, + options search.SearcherOptions) (search.Searcher, error) { + ss := make([]search.Searcher, 0, len(q.Disjuncts)) + for _, disjunct := range q.Disjuncts { + sr, err := disjunct.Searcher(ctx, i, m, options) + if err != nil { + for _, searcher := range ss { + if searcher != nil { + _ = searcher.Close() + } + } + return nil, err + } + if _, ok := sr.(*searcher.MatchNoneSearcher); ok && q.queryStringMode { + // in query string mode, skip match none + continue + } + ss = append(ss, sr) + } + + if len(ss) < 1 { + return searcher.NewMatchNoneSearcher(i) + } + + return searcher.NewDisjunctionSearcher(ctx, i, ss, q.Min, options) +} + +func (q *DisjunctionQuery) Validate() error { + if int(q.Min) > len(q.Disjuncts) { + return fmt.Errorf("disjunction query has fewer than the minimum number of clauses to satisfy") + } + for _, q := range q.Disjuncts { + if q, ok := q.(ValidatableQuery); ok { + err := q.Validate() + if err != nil { + return err + } + } + } + return nil +} + +func (q *DisjunctionQuery) UnmarshalJSON(data []byte) error { + tmp := struct { + Disjuncts []json.RawMessage `json:"disjuncts"` + Boost *Boost `json:"boost,omitempty"` + Min float64 `json:"min"` + }{} + err := json.Unmarshal(data, &tmp) + if err != nil { + return err + } + q.Disjuncts = make([]Query, len(tmp.Disjuncts)) + for i, term := range tmp.Disjuncts { + query, err := ParseQuery(term) + if err != nil { + return err + } + q.Disjuncts[i] = query + } + q.BoostVal = tmp.Boost + q.Min = tmp.Min + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/docid.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/docid.go new file mode 100644 index 0000000000..7116f3913d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/docid.go @@ -0,0 +1,51 @@ +// Copyright (c) 2015 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type DocIDQuery struct { + IDs []string `json:"ids"` + BoostVal *Boost `json:"boost,omitempty"` +} + +// NewDocIDQuery creates a new Query object returning indexed documents among +// the specified set. Combine it with ConjunctionQuery to restrict the scope of +// other queries output. +func NewDocIDQuery(ids []string) *DocIDQuery { + return &DocIDQuery{ + IDs: ids, + } +} + +func (q *DocIDQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *DocIDQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *DocIDQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + return searcher.NewDocIDSearcher(ctx, i, q.IDs, q.BoostVal.Value(), options) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/fuzzy.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/fuzzy.go new file mode 100644 index 0000000000..f24eb0c20c --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/fuzzy.go @@ -0,0 +1,79 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type FuzzyQuery struct { + Term string `json:"term"` + Prefix int `json:"prefix_length"` + Fuzziness int `json:"fuzziness"` + FieldVal string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` +} + +// NewFuzzyQuery creates a new Query which finds +// documents containing terms within a specific +// fuzziness of the specified term. +// The default fuzziness is 1. +// +// The current implementation uses Levenshtein edit +// distance as the fuzziness metric. +func NewFuzzyQuery(term string) *FuzzyQuery { + return &FuzzyQuery{ + Term: term, + Fuzziness: 1, + } +} + +func (q *FuzzyQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *FuzzyQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *FuzzyQuery) SetField(f string) { + q.FieldVal = f +} + +func (q *FuzzyQuery) Field() string { + return q.FieldVal +} + +func (q *FuzzyQuery) SetFuzziness(f int) { + q.Fuzziness = f +} + +func (q *FuzzyQuery) SetPrefix(p int) { + q.Prefix = p +} + +func (q *FuzzyQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + field := q.FieldVal + if q.FieldVal == "" { + field = m.DefaultSearchField() + } + return searcher.NewFuzzySearcher(ctx, i, q.Term, q.Prefix, q.Fuzziness, field, q.BoostVal.Value(), options) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/geo_boundingbox.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/geo_boundingbox.go new file mode 100644 index 0000000000..ac9125393b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/geo_boundingbox.go @@ -0,0 +1,114 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/blevesearch/bleve/v2/geo" + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type GeoBoundingBoxQuery struct { + TopLeft []float64 `json:"top_left,omitempty"` + BottomRight []float64 `json:"bottom_right,omitempty"` + FieldVal string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` +} + +func NewGeoBoundingBoxQuery(topLeftLon, topLeftLat, bottomRightLon, bottomRightLat float64) *GeoBoundingBoxQuery { + return &GeoBoundingBoxQuery{ + TopLeft: []float64{topLeftLon, topLeftLat}, + BottomRight: []float64{bottomRightLon, bottomRightLat}, + } +} + +func (q *GeoBoundingBoxQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *GeoBoundingBoxQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *GeoBoundingBoxQuery) SetField(f string) { + q.FieldVal = f +} + +func (q *GeoBoundingBoxQuery) Field() string { + return q.FieldVal +} + +func (q *GeoBoundingBoxQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + field := q.FieldVal + if q.FieldVal == "" { + field = m.DefaultSearchField() + } + + if q.BottomRight[0] < q.TopLeft[0] { + // cross date line, rewrite as two parts + + leftSearcher, err := searcher.NewGeoBoundingBoxSearcher(ctx, i, -180, q.BottomRight[1], q.BottomRight[0], q.TopLeft[1], field, q.BoostVal.Value(), options, true) + if err != nil { + return nil, err + } + rightSearcher, err := searcher.NewGeoBoundingBoxSearcher(ctx, i, q.TopLeft[0], q.BottomRight[1], 180, q.TopLeft[1], field, q.BoostVal.Value(), options, true) + if err != nil { + _ = leftSearcher.Close() + return nil, err + } + + return searcher.NewDisjunctionSearcher(ctx, i, []search.Searcher{leftSearcher, rightSearcher}, 0, options) + } + + return searcher.NewGeoBoundingBoxSearcher(ctx, i, q.TopLeft[0], q.BottomRight[1], q.BottomRight[0], q.TopLeft[1], field, q.BoostVal.Value(), options, true) +} + +func (q *GeoBoundingBoxQuery) Validate() error { + return nil +} + +func (q *GeoBoundingBoxQuery) UnmarshalJSON(data []byte) error { + tmp := struct { + TopLeft interface{} `json:"top_left,omitempty"` + BottomRight interface{} `json:"bottom_right,omitempty"` + FieldVal string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` + }{} + err := json.Unmarshal(data, &tmp) + if err != nil { + return err + } + // now use our generic point parsing code from the geo package + lon, lat, found := geo.ExtractGeoPoint(tmp.TopLeft) + if !found { + return fmt.Errorf("geo location top_left not in a valid format") + } + q.TopLeft = []float64{lon, lat} + lon, lat, found = geo.ExtractGeoPoint(tmp.BottomRight) + if !found { + return fmt.Errorf("geo location bottom_right not in a valid format") + } + q.BottomRight = []float64{lon, lat} + q.FieldVal = tmp.FieldVal + q.BoostVal = tmp.BoostVal + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/geo_boundingpolygon.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/geo_boundingpolygon.go new file mode 100644 index 0000000000..467f39b28d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/geo_boundingpolygon.go @@ -0,0 +1,95 @@ +// Copyright (c) 2019 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/blevesearch/bleve/v2/geo" + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type GeoBoundingPolygonQuery struct { + Points []geo.Point `json:"polygon_points"` + FieldVal string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` +} + +func NewGeoBoundingPolygonQuery(points []geo.Point) *GeoBoundingPolygonQuery { + return &GeoBoundingPolygonQuery{ + Points: points} +} + +func (q *GeoBoundingPolygonQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *GeoBoundingPolygonQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *GeoBoundingPolygonQuery) SetField(f string) { + q.FieldVal = f +} + +func (q *GeoBoundingPolygonQuery) Field() string { + return q.FieldVal +} + +func (q *GeoBoundingPolygonQuery) Searcher(ctx context.Context, i index.IndexReader, + m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + field := q.FieldVal + if q.FieldVal == "" { + field = m.DefaultSearchField() + } + + return searcher.NewGeoBoundedPolygonSearcher(ctx, i, q.Points, field, q.BoostVal.Value(), options) +} + +func (q *GeoBoundingPolygonQuery) Validate() error { + return nil +} + +func (q *GeoBoundingPolygonQuery) UnmarshalJSON(data []byte) error { + tmp := struct { + Points []interface{} `json:"polygon_points"` + FieldVal string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` + }{} + err := json.Unmarshal(data, &tmp) + if err != nil { + return err + } + + q.Points = make([]geo.Point, 0, len(tmp.Points)) + for _, i := range tmp.Points { + // now use our generic point parsing code from the geo package + lon, lat, found := geo.ExtractGeoPoint(i) + if !found { + return fmt.Errorf("geo polygon point: %v is not in a valid format", i) + } + q.Points = append(q.Points, geo.Point{Lon: lon, Lat: lat}) + } + + q.FieldVal = tmp.FieldVal + q.BoostVal = tmp.BoostVal + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/geo_distance.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/geo_distance.go new file mode 100644 index 0000000000..f05bf67234 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/geo_distance.go @@ -0,0 +1,101 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/blevesearch/bleve/v2/geo" + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type GeoDistanceQuery struct { + Location []float64 `json:"location,omitempty"` + Distance string `json:"distance,omitempty"` + FieldVal string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` +} + +func NewGeoDistanceQuery(lon, lat float64, distance string) *GeoDistanceQuery { + return &GeoDistanceQuery{ + Location: []float64{lon, lat}, + Distance: distance, + } +} + +func (q *GeoDistanceQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *GeoDistanceQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *GeoDistanceQuery) SetField(f string) { + q.FieldVal = f +} + +func (q *GeoDistanceQuery) Field() string { + return q.FieldVal +} + +func (q *GeoDistanceQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, + options search.SearcherOptions) (search.Searcher, error) { + field := q.FieldVal + if q.FieldVal == "" { + field = m.DefaultSearchField() + } + + dist, err := geo.ParseDistance(q.Distance) + if err != nil { + return nil, err + } + + return searcher.NewGeoPointDistanceSearcher(ctx, i, q.Location[0], q.Location[1], + dist, field, q.BoostVal.Value(), options) +} + +func (q *GeoDistanceQuery) Validate() error { + return nil +} + +func (q *GeoDistanceQuery) UnmarshalJSON(data []byte) error { + tmp := struct { + Location interface{} `json:"location,omitempty"` + Distance string `json:"distance,omitempty"` + FieldVal string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` + }{} + err := json.Unmarshal(data, &tmp) + if err != nil { + return err + } + // now use our generic point parsing code from the geo package + lon, lat, found := geo.ExtractGeoPoint(tmp.Location) + if !found { + return fmt.Errorf("geo location not in a valid format") + } + q.Location = []float64{lon, lat} + q.Distance = tmp.Distance + q.FieldVal = tmp.FieldVal + q.BoostVal = tmp.BoostVal + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/geo_shape.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/geo_shape.go new file mode 100644 index 0000000000..a63ec80f7e --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/geo_shape.go @@ -0,0 +1,135 @@ +// Copyright (c) 2022 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "encoding/json" + + "github.com/blevesearch/bleve/v2/geo" + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type Geometry struct { + Shape index.GeoJSON `json:"shape"` + Relation string `json:"relation"` +} + +type GeoShapeQuery struct { + Geometry Geometry `json:"geometry"` + FieldVal string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` +} + +// NewGeoShapeQuery creates a geoshape query for the +// given shape type. This method can be used for +// creating geoshape queries for shape types like: point, +// linestring, polygon, multipoint, multilinestring, +// multipolygon and envelope. +func NewGeoShapeQuery(coordinates [][][][]float64, typ, + relation string) (*GeoShapeQuery, error) { + s, _, err := geo.NewGeoJsonShape(coordinates, typ) + if err != nil { + return nil, err + } + + return &GeoShapeQuery{Geometry: Geometry{Shape: s, + Relation: relation}}, nil +} + +// NewGeoShapeCircleQuery creates a geoshape query for the +// given center point and the radius. Radius formats supported: +// "5in" "5inch" "7yd" "7yards" "9ft" "9feet" "11km" "11kilometers" +// "3nm" "3nauticalmiles" "13mm" "13millimeters" "15cm" "15centimeters" +// "17mi" "17miles" "19m" "19meters" If the unit cannot be determined, +// the entire string is parsed and the unit of meters is assumed. +func NewGeoShapeCircleQuery(coordinates []float64, radius, + relation string) (*GeoShapeQuery, error) { + + s, _, err := geo.NewGeoCircleShape(coordinates, radius) + if err != nil { + return nil, err + } + + return &GeoShapeQuery{Geometry: Geometry{Shape: s, + Relation: relation}}, nil +} + +// NewGeometryCollectionQuery creates a geoshape query for the +// given geometrycollection coordinates and types. +func NewGeometryCollectionQuery(coordinates [][][][][]float64, types []string, + relation string) (*GeoShapeQuery, error) { + s, _, err := geo.NewGeometryCollection(coordinates, types) + if err != nil { + return nil, err + } + + return &GeoShapeQuery{Geometry: Geometry{Shape: s, + Relation: relation}}, nil +} + +func (q *GeoShapeQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *GeoShapeQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *GeoShapeQuery) SetField(f string) { + q.FieldVal = f +} + +func (q *GeoShapeQuery) Field() string { + return q.FieldVal +} + +func (q *GeoShapeQuery) Searcher(ctx context.Context, i index.IndexReader, + m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + field := q.FieldVal + if q.FieldVal == "" { + field = m.DefaultSearchField() + } + + return searcher.NewGeoShapeSearcher(ctx, i, q.Geometry.Shape, q.Geometry.Relation, field, + q.BoostVal.Value(), options) +} + +func (q *GeoShapeQuery) Validate() error { + return nil +} + +func (q *Geometry) UnmarshalJSON(data []byte) error { + tmp := struct { + Shape json.RawMessage `json:"shape"` + Relation string `json:"relation"` + }{} + + err := json.Unmarshal(data, &tmp) + if err != nil { + return err + } + + q.Shape, err = geo.ParseGeoJSONShape(tmp.Shape) + if err != nil { + return err + } + q.Relation = tmp.Relation + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/ip_range.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/ip_range.go new file mode 100644 index 0000000000..ba46f0b255 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/ip_range.go @@ -0,0 +1,85 @@ +// Copyright (c) 2021 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "fmt" + "net" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type IPRangeQuery struct { + CIDR string `json:"cidr, omitempty"` + FieldVal string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` +} + +func NewIPRangeQuery(cidr string) *IPRangeQuery { + return &IPRangeQuery{ + CIDR: cidr, + } +} + +func (q *IPRangeQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *IPRangeQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *IPRangeQuery) SetField(f string) { + q.FieldVal = f +} + +func (q *IPRangeQuery) Field() string { + return q.FieldVal +} + +func (q *IPRangeQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + field := q.FieldVal + if q.FieldVal == "" { + field = m.DefaultSearchField() + } + _, ipNet, err := net.ParseCIDR(q.CIDR) + if err != nil { + ip := net.ParseIP(q.CIDR) + if ip == nil { + return nil, err + } + // If we are searching for a specific ip rather than members of a network, just use a term search. + return searcher.NewTermSearcherBytes(ctx, i, ip.To16(), field, q.BoostVal.Value(), options) + } + return searcher.NewIPRangeSearcher(ctx, i, ipNet, field, q.BoostVal.Value(), options) +} + +func (q *IPRangeQuery) Validate() error { + _, _, err := net.ParseCIDR(q.CIDR) + if err == nil { + return nil + } + // We also allow search for a specific IP. + ip := net.ParseIP(q.CIDR) + if ip != nil { + return nil // we have a valid ip + } + return fmt.Errorf("IPRangeQuery must be for a network or ip address, %q", q.CIDR) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/match.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/match.go new file mode 100644 index 0000000000..61c00a0033 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/match.go @@ -0,0 +1,177 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + index "github.com/blevesearch/bleve_index_api" +) + +type MatchQuery struct { + Match string `json:"match"` + FieldVal string `json:"field,omitempty"` + Analyzer string `json:"analyzer,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` + Prefix int `json:"prefix_length"` + Fuzziness int `json:"fuzziness"` + Operator MatchQueryOperator `json:"operator,omitempty"` +} + +type MatchQueryOperator int + +const ( + // Document must satisfy AT LEAST ONE of term searches. + MatchQueryOperatorOr = MatchQueryOperator(0) + // Document must satisfy ALL of term searches. + MatchQueryOperatorAnd = MatchQueryOperator(1) +) + +func (o MatchQueryOperator) MarshalJSON() ([]byte, error) { + switch o { + case MatchQueryOperatorOr: + return json.Marshal("or") + case MatchQueryOperatorAnd: + return json.Marshal("and") + default: + return nil, fmt.Errorf("cannot marshal match operator %d to JSON", o) + } +} + +func (o *MatchQueryOperator) UnmarshalJSON(data []byte) error { + var operatorString string + err := json.Unmarshal(data, &operatorString) + if err != nil { + return err + } + + switch operatorString { + case "or": + *o = MatchQueryOperatorOr + return nil + case "and": + *o = MatchQueryOperatorAnd + return nil + default: + return fmt.Errorf("cannot unmarshal match operator '%v' from JSON", o) + } +} + +// NewMatchQuery creates a Query for matching text. +// An Analyzer is chosen based on the field. +// Input text is analyzed using this analyzer. +// Token terms resulting from this analysis are +// used to perform term searches. Result documents +// must satisfy at least one of these term searches. +func NewMatchQuery(match string) *MatchQuery { + return &MatchQuery{ + Match: match, + Operator: MatchQueryOperatorOr, + } +} + +func (q *MatchQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *MatchQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *MatchQuery) SetField(f string) { + q.FieldVal = f +} + +func (q *MatchQuery) Field() string { + return q.FieldVal +} + +func (q *MatchQuery) SetFuzziness(f int) { + q.Fuzziness = f +} + +func (q *MatchQuery) SetPrefix(p int) { + q.Prefix = p +} + +func (q *MatchQuery) SetOperator(operator MatchQueryOperator) { + q.Operator = operator +} + +func (q *MatchQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + + field := q.FieldVal + if q.FieldVal == "" { + field = m.DefaultSearchField() + } + + analyzerName := "" + if q.Analyzer != "" { + analyzerName = q.Analyzer + } else { + analyzerName = m.AnalyzerNameForPath(field) + } + analyzer := m.AnalyzerNamed(analyzerName) + + if analyzer == nil { + return nil, fmt.Errorf("no analyzer named '%s' registered", q.Analyzer) + } + + tokens := analyzer.Analyze([]byte(q.Match)) + if len(tokens) > 0 { + + tqs := make([]Query, len(tokens)) + if q.Fuzziness != 0 { + for i, token := range tokens { + query := NewFuzzyQuery(string(token.Term)) + query.SetFuzziness(q.Fuzziness) + query.SetPrefix(q.Prefix) + query.SetField(field) + query.SetBoost(q.BoostVal.Value()) + tqs[i] = query + } + } else { + for i, token := range tokens { + tq := NewTermQuery(string(token.Term)) + tq.SetField(field) + tq.SetBoost(q.BoostVal.Value()) + tqs[i] = tq + } + } + + switch q.Operator { + case MatchQueryOperatorOr: + shouldQuery := NewDisjunctionQuery(tqs) + shouldQuery.SetMin(1) + shouldQuery.SetBoost(q.BoostVal.Value()) + return shouldQuery.Searcher(ctx, i, m, options) + + case MatchQueryOperatorAnd: + mustQuery := NewConjunctionQuery(tqs) + mustQuery.SetBoost(q.BoostVal.Value()) + return mustQuery.Searcher(ctx, i, m, options) + + default: + return nil, fmt.Errorf("unhandled operator %d", q.Operator) + } + } + noneQuery := NewMatchNoneQuery() + return noneQuery.Searcher(ctx, i, m, options) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/match_all.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/match_all.go new file mode 100644 index 0000000000..e88825ae47 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/match_all.go @@ -0,0 +1,56 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "encoding/json" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type MatchAllQuery struct { + BoostVal *Boost `json:"boost,omitempty"` +} + +// NewMatchAllQuery creates a Query which will +// match all documents in the index. +func NewMatchAllQuery() *MatchAllQuery { + return &MatchAllQuery{} +} + +func (q *MatchAllQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *MatchAllQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *MatchAllQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + return searcher.NewMatchAllSearcher(ctx, i, q.BoostVal.Value(), options) +} + +func (q *MatchAllQuery) MarshalJSON() ([]byte, error) { + tmp := map[string]interface{}{ + "boost": q.BoostVal, + "match_all": map[string]interface{}{}, + } + return json.Marshal(tmp) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/match_none.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/match_none.go new file mode 100644 index 0000000000..cb65a725f8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/match_none.go @@ -0,0 +1,56 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "encoding/json" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type MatchNoneQuery struct { + BoostVal *Boost `json:"boost,omitempty"` +} + +// NewMatchNoneQuery creates a Query which will not +// match any documents in the index. +func NewMatchNoneQuery() *MatchNoneQuery { + return &MatchNoneQuery{} +} + +func (q *MatchNoneQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *MatchNoneQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *MatchNoneQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + return searcher.NewMatchNoneSearcher(i) +} + +func (q *MatchNoneQuery) MarshalJSON() ([]byte, error) { + tmp := map[string]interface{}{ + "boost": q.BoostVal, + "match_none": map[string]interface{}{}, + } + return json.Marshal(tmp) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/match_phrase.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/match_phrase.go new file mode 100644 index 0000000000..fa8ac720b3 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/match_phrase.go @@ -0,0 +1,114 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "fmt" + + "github.com/blevesearch/bleve/v2/analysis" + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + index "github.com/blevesearch/bleve_index_api" +) + +type MatchPhraseQuery struct { + MatchPhrase string `json:"match_phrase"` + FieldVal string `json:"field,omitempty"` + Analyzer string `json:"analyzer,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` +} + +// NewMatchPhraseQuery creates a new Query object +// for matching phrases in the index. +// An Analyzer is chosen based on the field. +// Input text is analyzed using this analyzer. +// Token terms resulting from this analysis are +// used to build a search phrase. Result documents +// must match this phrase. Queried field must have been indexed with +// IncludeTermVectors set to true. +func NewMatchPhraseQuery(matchPhrase string) *MatchPhraseQuery { + return &MatchPhraseQuery{ + MatchPhrase: matchPhrase, + } +} + +func (q *MatchPhraseQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *MatchPhraseQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *MatchPhraseQuery) SetField(f string) { + q.FieldVal = f +} + +func (q *MatchPhraseQuery) Field() string { + return q.FieldVal +} + +func (q *MatchPhraseQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + field := q.FieldVal + if q.FieldVal == "" { + field = m.DefaultSearchField() + } + + analyzerName := "" + if q.Analyzer != "" { + analyzerName = q.Analyzer + } else { + analyzerName = m.AnalyzerNameForPath(field) + } + analyzer := m.AnalyzerNamed(analyzerName) + if analyzer == nil { + return nil, fmt.Errorf("no analyzer named '%s' registered", q.Analyzer) + } + + tokens := analyzer.Analyze([]byte(q.MatchPhrase)) + if len(tokens) > 0 { + phrase := tokenStreamToPhrase(tokens) + phraseQuery := NewMultiPhraseQuery(phrase, field) + phraseQuery.SetBoost(q.BoostVal.Value()) + return phraseQuery.Searcher(ctx, i, m, options) + } + noneQuery := NewMatchNoneQuery() + return noneQuery.Searcher(ctx, i, m, options) +} + +func tokenStreamToPhrase(tokens analysis.TokenStream) [][]string { + firstPosition := int(^uint(0) >> 1) + lastPosition := 0 + for _, token := range tokens { + if token.Position < firstPosition { + firstPosition = token.Position + } + if token.Position > lastPosition { + lastPosition = token.Position + } + } + phraseLen := lastPosition - firstPosition + 1 + if phraseLen > 0 { + rv := make([][]string, phraseLen) + for _, token := range tokens { + pos := token.Position - firstPosition + rv[pos] = append(rv[pos], string(token.Term)) + } + return rv + } + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/multi_phrase.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/multi_phrase.go new file mode 100644 index 0000000000..2887be16a4 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/multi_phrase.go @@ -0,0 +1,81 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type MultiPhraseQuery struct { + Terms [][]string `json:"terms"` + Field string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` +} + +// NewMultiPhraseQuery creates a new Query for finding +// term phrases in the index. +// It is like PhraseQuery, but each position in the +// phrase may be satisfied by a list of terms +// as opposed to just one. +// At least one of the terms must exist in the correct +// order, at the correct index offsets, in the +// specified field. Queried field must have been indexed with +// IncludeTermVectors set to true. +func NewMultiPhraseQuery(terms [][]string, field string) *MultiPhraseQuery { + return &MultiPhraseQuery{ + Terms: terms, + Field: field, + } +} + +func (q *MultiPhraseQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *MultiPhraseQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *MultiPhraseQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + return searcher.NewMultiPhraseSearcher(ctx, i, q.Terms, q.Field, options) +} + +func (q *MultiPhraseQuery) Validate() error { + if len(q.Terms) < 1 { + return fmt.Errorf("phrase query must contain at least one term") + } + return nil +} + +func (q *MultiPhraseQuery) UnmarshalJSON(data []byte) error { + type _mphraseQuery MultiPhraseQuery + tmp := _mphraseQuery{} + err := json.Unmarshal(data, &tmp) + if err != nil { + return err + } + q.Terms = tmp.Terms + q.Field = tmp.Field + q.BoostVal = tmp.BoostVal + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/numeric_range.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/numeric_range.go new file mode 100644 index 0000000000..ad24741677 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/numeric_range.go @@ -0,0 +1,88 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "fmt" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type NumericRangeQuery struct { + Min *float64 `json:"min,omitempty"` + Max *float64 `json:"max,omitempty"` + InclusiveMin *bool `json:"inclusive_min,omitempty"` + InclusiveMax *bool `json:"inclusive_max,omitempty"` + FieldVal string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` +} + +// NewNumericRangeQuery creates a new Query for ranges +// of numeric values. +// Either, but not both endpoints can be nil. +// The minimum value is inclusive. +// The maximum value is exclusive. +func NewNumericRangeQuery(min, max *float64) *NumericRangeQuery { + return NewNumericRangeInclusiveQuery(min, max, nil, nil) +} + +// NewNumericRangeInclusiveQuery creates a new Query for ranges +// of numeric values. +// Either, but not both endpoints can be nil. +// Control endpoint inclusion with inclusiveMin, inclusiveMax. +func NewNumericRangeInclusiveQuery(min, max *float64, minInclusive, maxInclusive *bool) *NumericRangeQuery { + return &NumericRangeQuery{ + Min: min, + Max: max, + InclusiveMin: minInclusive, + InclusiveMax: maxInclusive, + } +} + +func (q *NumericRangeQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *NumericRangeQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *NumericRangeQuery) SetField(f string) { + q.FieldVal = f +} + +func (q *NumericRangeQuery) Field() string { + return q.FieldVal +} + +func (q *NumericRangeQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + field := q.FieldVal + if q.FieldVal == "" { + field = m.DefaultSearchField() + } + return searcher.NewNumericRangeSearcher(ctx, i, q.Min, q.Max, q.InclusiveMin, q.InclusiveMax, field, q.BoostVal.Value(), options) +} + +func (q *NumericRangeQuery) Validate() error { + if q.Min == nil && q.Min == q.Max { + return fmt.Errorf("numeric range query must specify min or max") + } + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/phrase.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/phrase.go new file mode 100644 index 0000000000..207e66b176 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/phrase.go @@ -0,0 +1,78 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type PhraseQuery struct { + Terms []string `json:"terms"` + Field string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` +} + +// NewPhraseQuery creates a new Query for finding +// exact term phrases in the index. +// The provided terms must exist in the correct +// order, at the correct index offsets, in the +// specified field. Queried field must have been indexed with +// IncludeTermVectors set to true. +func NewPhraseQuery(terms []string, field string) *PhraseQuery { + return &PhraseQuery{ + Terms: terms, + Field: field, + } +} + +func (q *PhraseQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *PhraseQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *PhraseQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + return searcher.NewPhraseSearcher(ctx, i, q.Terms, q.Field, options) +} + +func (q *PhraseQuery) Validate() error { + if len(q.Terms) < 1 { + return fmt.Errorf("phrase query must contain at least one term") + } + return nil +} + +func (q *PhraseQuery) UnmarshalJSON(data []byte) error { + type _phraseQuery PhraseQuery + tmp := _phraseQuery{} + err := json.Unmarshal(data, &tmp) + if err != nil { + return err + } + q.Terms = tmp.Terms + q.Field = tmp.Field + q.BoostVal = tmp.BoostVal + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/prefix.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/prefix.go new file mode 100644 index 0000000000..debbbc1e3d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/prefix.go @@ -0,0 +1,64 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type PrefixQuery struct { + Prefix string `json:"prefix"` + FieldVal string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` +} + +// NewPrefixQuery creates a new Query which finds +// documents containing terms that start with the +// specified prefix. +func NewPrefixQuery(prefix string) *PrefixQuery { + return &PrefixQuery{ + Prefix: prefix, + } +} + +func (q *PrefixQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *PrefixQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *PrefixQuery) SetField(f string) { + q.FieldVal = f +} + +func (q *PrefixQuery) Field() string { + return q.FieldVal +} + +func (q *PrefixQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + field := q.FieldVal + if q.FieldVal == "" { + field = m.DefaultSearchField() + } + return searcher.NewTermPrefixSearcher(ctx, i, q.Prefix, field, q.BoostVal.Value(), options) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/query.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/query.go new file mode 100644 index 0000000000..df560534b4 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/query.go @@ -0,0 +1,383 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "log" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + index "github.com/blevesearch/bleve_index_api" +) + +var logger = log.New(ioutil.Discard, "bleve mapping ", log.LstdFlags) + +// SetLog sets the logger used for logging +// by default log messages are sent to ioutil.Discard +func SetLog(l *log.Logger) { + logger = l +} + +// A Query represents a description of the type +// and parameters for a query into the index. +type Query interface { + Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, + options search.SearcherOptions) (search.Searcher, error) +} + +// A BoostableQuery represents a Query which can be boosted +// relative to other queries. +type BoostableQuery interface { + Query + SetBoost(b float64) + Boost() float64 +} + +// A FieldableQuery represents a Query which can be restricted +// to a single field. +type FieldableQuery interface { + Query + SetField(f string) + Field() string +} + +// A ValidatableQuery represents a Query which can be validated +// prior to execution. +type ValidatableQuery interface { + Query + Validate() error +} + +// ParseQuery deserializes a JSON representation of +// a Query object. +func ParseQuery(input []byte) (Query, error) { + var tmp map[string]interface{} + err := json.Unmarshal(input, &tmp) + if err != nil { + return nil, err + } + _, isMatchQuery := tmp["match"] + _, hasFuzziness := tmp["fuzziness"] + if hasFuzziness && !isMatchQuery { + var rv FuzzyQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + _, isTermQuery := tmp["term"] + if isTermQuery { + var rv TermQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + if isMatchQuery { + var rv MatchQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + _, isMatchPhraseQuery := tmp["match_phrase"] + if isMatchPhraseQuery { + var rv MatchPhraseQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + _, hasMust := tmp["must"] + _, hasShould := tmp["should"] + _, hasMustNot := tmp["must_not"] + if hasMust || hasShould || hasMustNot { + var rv BooleanQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + _, hasTerms := tmp["terms"] + if hasTerms { + var rv PhraseQuery + err := json.Unmarshal(input, &rv) + if err != nil { + // now try multi-phrase + var rv2 MultiPhraseQuery + err = json.Unmarshal(input, &rv2) + if err != nil { + return nil, err + } + return &rv2, nil + } + return &rv, nil + } + _, hasConjuncts := tmp["conjuncts"] + if hasConjuncts { + var rv ConjunctionQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + _, hasDisjuncts := tmp["disjuncts"] + if hasDisjuncts { + var rv DisjunctionQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + + _, hasSyntaxQuery := tmp["query"] + if hasSyntaxQuery { + var rv QueryStringQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + _, hasMin := tmp["min"].(float64) + _, hasMax := tmp["max"].(float64) + if hasMin || hasMax { + var rv NumericRangeQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + _, hasMinStr := tmp["min"].(string) + _, hasMaxStr := tmp["max"].(string) + if hasMinStr || hasMaxStr { + var rv TermRangeQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + _, hasStart := tmp["start"] + _, hasEnd := tmp["end"] + if hasStart || hasEnd { + var rv DateRangeQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + _, hasPrefix := tmp["prefix"] + if hasPrefix { + var rv PrefixQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + _, hasRegexp := tmp["regexp"] + if hasRegexp { + var rv RegexpQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + _, hasWildcard := tmp["wildcard"] + if hasWildcard { + var rv WildcardQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + _, hasMatchAll := tmp["match_all"] + if hasMatchAll { + var rv MatchAllQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + _, hasMatchNone := tmp["match_none"] + if hasMatchNone { + var rv MatchNoneQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + _, hasDocIds := tmp["ids"] + if hasDocIds { + var rv DocIDQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + _, hasBool := tmp["bool"] + if hasBool { + var rv BoolFieldQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + _, hasTopLeft := tmp["top_left"] + _, hasBottomRight := tmp["bottom_right"] + if hasTopLeft && hasBottomRight { + var rv GeoBoundingBoxQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + _, hasDistance := tmp["distance"] + if hasDistance { + var rv GeoDistanceQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + _, hasPoints := tmp["polygon_points"] + if hasPoints { + var rv GeoBoundingPolygonQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + + _, hasGeo := tmp["geometry"] + if hasGeo { + var rv GeoShapeQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + + _, hasCIDR := tmp["cidr"] + if hasCIDR { + var rv IPRangeQuery + err := json.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + } + + return nil, fmt.Errorf("unknown query type") +} + +// expandQuery traverses the input query tree and returns a new tree where +// query string queries have been expanded into base queries. Returned tree may +// reference queries from the input tree or new queries. +func expandQuery(m mapping.IndexMapping, query Query) (Query, error) { + var expand func(query Query) (Query, error) + var expandSlice func(queries []Query) ([]Query, error) + + expandSlice = func(queries []Query) ([]Query, error) { + expanded := []Query{} + for _, q := range queries { + exp, err := expand(q) + if err != nil { + return nil, err + } + expanded = append(expanded, exp) + } + return expanded, nil + } + + expand = func(query Query) (Query, error) { + switch q := query.(type) { + case *QueryStringQuery: + parsed, err := parseQuerySyntax(q.Query) + if err != nil { + return nil, fmt.Errorf("could not parse '%s': %s", q.Query, err) + } + return expand(parsed) + case *ConjunctionQuery: + children, err := expandSlice(q.Conjuncts) + if err != nil { + return nil, err + } + q.Conjuncts = children + return q, nil + case *DisjunctionQuery: + children, err := expandSlice(q.Disjuncts) + if err != nil { + return nil, err + } + q.Disjuncts = children + return q, nil + case *BooleanQuery: + var err error + q.Must, err = expand(q.Must) + if err != nil { + return nil, err + } + q.Should, err = expand(q.Should) + if err != nil { + return nil, err + } + q.MustNot, err = expand(q.MustNot) + if err != nil { + return nil, err + } + return q, nil + default: + return query, nil + } + } + return expand(query) +} + +// DumpQuery returns a string representation of the query tree, where query +// string queries have been expanded into base queries. The output format is +// meant for debugging purpose and may change in the future. +func DumpQuery(m mapping.IndexMapping, query Query) (string, error) { + q, err := expandQuery(m, query) + if err != nil { + return "", err + } + data, err := json.MarshalIndent(q, "", " ") + return string(data), err +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string.go new file mode 100644 index 0000000000..42bb598bb0 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string.go @@ -0,0 +1,69 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + index "github.com/blevesearch/bleve_index_api" +) + +type QueryStringQuery struct { + Query string `json:"query"` + BoostVal *Boost `json:"boost,omitempty"` +} + +// NewQueryStringQuery creates a new Query used for +// finding documents that satisfy a query string. The +// query string is a small query language for humans. +func NewQueryStringQuery(query string) *QueryStringQuery { + return &QueryStringQuery{ + Query: query, + } +} + +func (q *QueryStringQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *QueryStringQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *QueryStringQuery) Parse() (Query, error) { + return parseQuerySyntax(q.Query) +} + +func (q *QueryStringQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + newQuery, err := parseQuerySyntax(q.Query) + if err != nil { + return nil, err + } + return newQuery.Searcher(ctx, i, m, options) +} + +func (q *QueryStringQuery) Validate() error { + newQuery, err := parseQuerySyntax(q.Query) + if err != nil { + return err + } + if newQuery, ok := newQuery.(ValidatableQuery); ok { + return newQuery.Validate() + } + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string.y b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string.y new file mode 100644 index 0000000000..aeec85600b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string.y @@ -0,0 +1,338 @@ +%{ +package query +import ( + "fmt" + "strconv" + "strings" + "time" +) + +func logDebugGrammar(format string, v ...interface{}) { + if debugParser { + logger.Printf(format, v...) + } +} +%} + +%union { +s string +n int +f float64 +q Query +pf *float64} + +%token tSTRING tPHRASE tPLUS tMINUS tCOLON tBOOST tNUMBER tSTRING tGREATER tLESS +tEQUAL tTILDE + +%type tSTRING +%type tPHRASE +%type tNUMBER +%type posOrNegNumber +%type fieldName +%type tTILDE +%type tBOOST +%type searchBase +%type searchSuffix +%type searchPrefix + +%% + +input: +searchParts { + logDebugGrammar("INPUT") +}; + +searchParts: +searchPart searchParts { + logDebugGrammar("SEARCH PARTS") +} +| +searchPart { + logDebugGrammar("SEARCH PART") +}; + +searchPart: +searchPrefix searchBase searchSuffix { + query := $2 + if $3 != nil { + if query, ok := query.(BoostableQuery); ok { + query.SetBoost(*$3) + } + } + switch($1) { + case queryShould: + yylex.(*lexerWrapper).query.AddShould(query) + case queryMust: + yylex.(*lexerWrapper).query.AddMust(query) + case queryMustNot: + yylex.(*lexerWrapper).query.AddMustNot(query) + } +}; + + +searchPrefix: +/* empty */ { + $$ = queryShould +} +| +tPLUS { + logDebugGrammar("PLUS") + $$ = queryMust +} +| +tMINUS { + logDebugGrammar("MINUS") + $$ = queryMustNot +}; + +searchBase: +tSTRING { + str := $1 + logDebugGrammar("STRING - %s", str) + var q FieldableQuery + if strings.HasPrefix(str, "/") && strings.HasSuffix(str, "/") { + q = NewRegexpQuery(str[1:len(str)-1]) + } else if strings.ContainsAny(str, "*?"){ + q = NewWildcardQuery(str) + } else { + q = NewMatchQuery(str) + } + $$ = q +} +| +tSTRING tTILDE { + str := $1 + fuzziness, err := strconv.ParseFloat($2, 64) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("invalid fuzziness value: %v", err)) + } + logDebugGrammar("FUZZY STRING - %s %f", str, fuzziness) + q := NewMatchQuery(str) + q.SetFuzziness(int(fuzziness)) + $$ = q +} +| +fieldName tCOLON tSTRING tTILDE { + field := $1 + str := $3 + fuzziness, err := strconv.ParseFloat($4, 64) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("invalid fuzziness value: %v", err)) + } + logDebugGrammar("FIELD - %s FUZZY STRING - %s %f", field, str, fuzziness) + q := NewMatchQuery(str) + q.SetFuzziness(int(fuzziness)) + q.SetField(field) + $$ = q +} +| +tNUMBER { + str := $1 + logDebugGrammar("STRING - %s", str) + q1 := NewMatchQuery(str) + val, err := strconv.ParseFloat($1, 64) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("error parsing number: %v", err)) + } + inclusive := true + q2 := NewNumericRangeInclusiveQuery(&val, &val, &inclusive, &inclusive) + q := NewDisjunctionQuery([]Query{q1,q2}) + q.queryStringMode = true + $$ = q +} +| +tPHRASE { + phrase := $1 + logDebugGrammar("PHRASE - %s", phrase) + q := NewMatchPhraseQuery(phrase) + $$ = q +} +| +fieldName tCOLON tSTRING { + field := $1 + str := $3 + logDebugGrammar("FIELD - %s STRING - %s", field, str) + var q FieldableQuery + if strings.HasPrefix(str, "/") && strings.HasSuffix(str, "/") { + q = NewRegexpQuery(str[1:len(str)-1]) + } else if strings.ContainsAny(str, "*?"){ + q = NewWildcardQuery(str) + } else { + q = NewMatchQuery(str) + } + q.SetField(field) + $$ = q +} +| +fieldName tCOLON posOrNegNumber { + field := $1 + str := $3 + logDebugGrammar("FIELD - %s STRING - %s", field, str) + q1 := NewMatchQuery(str) + q1.SetField(field) + val, err := strconv.ParseFloat($3, 64) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("error parsing number: %v", err)) + } + inclusive := true + q2 := NewNumericRangeInclusiveQuery(&val, &val, &inclusive, &inclusive) + q2.SetField(field) + q := NewDisjunctionQuery([]Query{q1,q2}) + q.queryStringMode = true + $$ = q +} +| +fieldName tCOLON tPHRASE { + field := $1 + phrase := $3 + logDebugGrammar("FIELD - %s PHRASE - %s", field, phrase) + q := NewMatchPhraseQuery(phrase) + q.SetField(field) + $$ = q +} +| +fieldName tCOLON tGREATER posOrNegNumber { + field := $1 + min, err := strconv.ParseFloat($4, 64) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("error parsing number: %v", err)) + } + minInclusive := false + logDebugGrammar("FIELD - GREATER THAN %f", min) + q := NewNumericRangeInclusiveQuery(&min, nil, &minInclusive, nil) + q.SetField(field) + $$ = q +} +| +fieldName tCOLON tGREATER tEQUAL posOrNegNumber { + field := $1 + min, err := strconv.ParseFloat($5, 64) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("error parsing number: %v", err)) + } + minInclusive := true + logDebugGrammar("FIELD - GREATER THAN OR EQUAL %f", min) + q := NewNumericRangeInclusiveQuery(&min, nil, &minInclusive, nil) + q.SetField(field) + $$ = q +} +| +fieldName tCOLON tLESS posOrNegNumber { + field := $1 + max, err := strconv.ParseFloat($4, 64) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("error parsing number: %v", err)) + } + maxInclusive := false + logDebugGrammar("FIELD - LESS THAN %f", max) + q := NewNumericRangeInclusiveQuery(nil, &max, nil, &maxInclusive) + q.SetField(field) + $$ = q +} +| +fieldName tCOLON tLESS tEQUAL posOrNegNumber { + field := $1 + max, err := strconv.ParseFloat($5, 64) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("error parsing number: %v", err)) + } + maxInclusive := true + logDebugGrammar("FIELD - LESS THAN OR EQUAL %f", max) + q := NewNumericRangeInclusiveQuery(nil, &max, nil, &maxInclusive) + q.SetField(field) + $$ = q +} +| +fieldName tCOLON tGREATER tPHRASE { + field := $1 + minInclusive := false + phrase := $4 + + logDebugGrammar("FIELD - GREATER THAN DATE %s", phrase) + minTime, err := queryTimeFromString(phrase) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("invalid time: %v", err)) + } + q := NewDateRangeInclusiveQuery(minTime, time.Time{}, &minInclusive, nil) + q.SetField(field) + $$ = q +} +| +fieldName tCOLON tGREATER tEQUAL tPHRASE { + field := $1 + minInclusive := true + phrase := $5 + + logDebugGrammar("FIELD - GREATER THAN OR EQUAL DATE %s", phrase) + minTime, err := queryTimeFromString(phrase) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("invalid time: %v", err)) + } + q := NewDateRangeInclusiveQuery(minTime, time.Time{}, &minInclusive, nil) + q.SetField(field) + $$ = q +} +| +fieldName tCOLON tLESS tPHRASE { + field := $1 + maxInclusive := false + phrase := $4 + + logDebugGrammar("FIELD - LESS THAN DATE %s", phrase) + maxTime, err := queryTimeFromString(phrase) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("invalid time: %v", err)) + } + q := NewDateRangeInclusiveQuery(time.Time{}, maxTime, nil, &maxInclusive) + q.SetField(field) + $$ = q +} +| +fieldName tCOLON tLESS tEQUAL tPHRASE { + field := $1 + maxInclusive := true + phrase := $5 + + logDebugGrammar("FIELD - LESS THAN OR EQUAL DATE %s", phrase) + maxTime, err := queryTimeFromString(phrase) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("invalid time: %v", err)) + } + q := NewDateRangeInclusiveQuery(time.Time{}, maxTime, nil, &maxInclusive) + q.SetField(field) + $$ = q +}; + +searchSuffix: +/* empty */ { + $$ = nil +} +| +tBOOST { + $$ = nil + boost, err := strconv.ParseFloat($1, 64) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("invalid boost value: %v", err)) + } else { + $$ = &boost + } + logDebugGrammar("BOOST %f", boost) +}; + +posOrNegNumber: +tNUMBER { + $$ = $1 +} +| +tMINUS tNUMBER { + $$ = "-" + $2 +}; + +fieldName: +tPHRASE { + $$ = $1 +} +| +tSTRING { + $$ = $1 +}; diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string.y.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string.y.go new file mode 100644 index 0000000000..3a2abc1320 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string.y.go @@ -0,0 +1,833 @@ +// Code generated by goyacc -o query_string.y.go query_string.y. DO NOT EDIT. + +//line query_string.y:2 +package query + +import __yyfmt__ "fmt" + +//line query_string.y:2 +import ( + "fmt" + "strconv" + "strings" + "time" +) + +func logDebugGrammar(format string, v ...interface{}) { + if debugParser { + logger.Printf(format, v...) + } +} + +//line query_string.y:17 +type yySymType struct { + yys int + s string + n int + f float64 + q Query + pf *float64 +} + +const tSTRING = 57346 +const tPHRASE = 57347 +const tPLUS = 57348 +const tMINUS = 57349 +const tCOLON = 57350 +const tBOOST = 57351 +const tNUMBER = 57352 +const tGREATER = 57353 +const tLESS = 57354 +const tEQUAL = 57355 +const tTILDE = 57356 + +var yyToknames = [...]string{ + "$end", + "error", + "$unk", + "tSTRING", + "tPHRASE", + "tPLUS", + "tMINUS", + "tCOLON", + "tBOOST", + "tNUMBER", + "tGREATER", + "tLESS", + "tEQUAL", + "tTILDE", +} + +var yyStatenames = [...]string{} + +const yyEofCode = 1 +const yyErrCode = 2 +const yyInitialStackSize = 16 + +//line yacctab:1 +var yyExca = [...]int{ + -1, 1, + 1, -1, + -2, 0, + -1, 3, + 1, 3, + -2, 5, + -1, 9, + 8, 29, + -2, 8, + -1, 12, + 8, 28, + -2, 12, +} + +const yyPrivate = 57344 + +const yyLast = 43 + +var yyAct = [...]int{ + 18, 17, 19, 24, 23, 15, 31, 22, 20, 21, + 30, 27, 23, 23, 3, 22, 22, 14, 29, 26, + 16, 25, 28, 35, 33, 23, 23, 32, 22, 22, + 34, 9, 12, 1, 5, 6, 2, 11, 4, 13, + 7, 8, 10, +} + +var yyPact = [...]int{ + 28, -1000, -1000, 28, 27, -1000, -1000, -1000, 8, -9, + 12, -1000, -1000, -1000, -1000, -1000, -3, -11, -1000, -1000, + 6, 5, -1000, -4, -1000, -1000, 19, -1000, -1000, 18, + -1000, -1000, -1000, -1000, -1000, -1000, +} + +var yyPgo = [...]int{ + 0, 0, 42, 41, 39, 38, 33, 36, 14, +} + +var yyR1 = [...]int{ + 0, 6, 7, 7, 8, 5, 5, 5, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 4, 4, 1, 1, 2, 2, +} + +var yyR2 = [...]int{ + 0, 1, 2, 1, 3, 0, 1, 1, 1, 2, + 4, 1, 1, 3, 3, 3, 4, 5, 4, 5, + 4, 5, 4, 5, 0, 1, 1, 2, 1, 1, +} + +var yyChk = [...]int{ + -1000, -6, -7, -8, -5, 6, 7, -7, -3, 4, + -2, 10, 5, -4, 9, 14, 8, 4, -1, 5, + 11, 12, 10, 7, 14, -1, 13, 5, -1, 13, + 5, 10, -1, 5, -1, 5, +} + +var yyDef = [...]int{ + 5, -2, 1, -2, 0, 6, 7, 2, 24, -2, + 0, 11, -2, 4, 25, 9, 0, 13, 14, 15, + 0, 0, 26, 0, 10, 16, 0, 20, 18, 0, + 22, 27, 17, 21, 19, 23, +} + +var yyTok1 = [...]int{ + 1, +} + +var yyTok2 = [...]int{ + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, +} + +var yyTok3 = [...]int{ + 0, +} + +var yyErrorMessages = [...]struct { + state int + token int + msg string +}{} + +//line yaccpar:1 + +/* parser for yacc output */ + +var ( + yyDebug = 0 + yyErrorVerbose = false +) + +type yyLexer interface { + Lex(lval *yySymType) int + Error(s string) +} + +type yyParser interface { + Parse(yyLexer) int + Lookahead() int +} + +type yyParserImpl struct { + lval yySymType + stack [yyInitialStackSize]yySymType + char int +} + +func (p *yyParserImpl) Lookahead() int { + return p.char +} + +func yyNewParser() yyParser { + return &yyParserImpl{} +} + +const yyFlag = -1000 + +func yyTokname(c int) string { + if c >= 1 && c-1 < len(yyToknames) { + if yyToknames[c-1] != "" { + return yyToknames[c-1] + } + } + return __yyfmt__.Sprintf("tok-%v", c) +} + +func yyStatname(s int) string { + if s >= 0 && s < len(yyStatenames) { + if yyStatenames[s] != "" { + return yyStatenames[s] + } + } + return __yyfmt__.Sprintf("state-%v", s) +} + +func yyErrorMessage(state, lookAhead int) string { + const TOKSTART = 4 + + if !yyErrorVerbose { + return "syntax error" + } + + for _, e := range yyErrorMessages { + if e.state == state && e.token == lookAhead { + return "syntax error: " + e.msg + } + } + + res := "syntax error: unexpected " + yyTokname(lookAhead) + + // To match Bison, suggest at most four expected tokens. + expected := make([]int, 0, 4) + + // Look for shiftable tokens. + base := yyPact[state] + for tok := TOKSTART; tok-1 < len(yyToknames); tok++ { + if n := base + tok; n >= 0 && n < yyLast && yyChk[yyAct[n]] == tok { + if len(expected) == cap(expected) { + return res + } + expected = append(expected, tok) + } + } + + if yyDef[state] == -2 { + i := 0 + for yyExca[i] != -1 || yyExca[i+1] != state { + i += 2 + } + + // Look for tokens that we accept or reduce. + for i += 2; yyExca[i] >= 0; i += 2 { + tok := yyExca[i] + if tok < TOKSTART || yyExca[i+1] == 0 { + continue + } + if len(expected) == cap(expected) { + return res + } + expected = append(expected, tok) + } + + // If the default action is to accept or reduce, give up. + if yyExca[i+1] != 0 { + return res + } + } + + for i, tok := range expected { + if i == 0 { + res += ", expecting " + } else { + res += " or " + } + res += yyTokname(tok) + } + return res +} + +func yylex1(lex yyLexer, lval *yySymType) (char, token int) { + token = 0 + char = lex.Lex(lval) + if char <= 0 { + token = yyTok1[0] + goto out + } + if char < len(yyTok1) { + token = yyTok1[char] + goto out + } + if char >= yyPrivate { + if char < yyPrivate+len(yyTok2) { + token = yyTok2[char-yyPrivate] + goto out + } + } + for i := 0; i < len(yyTok3); i += 2 { + token = yyTok3[i+0] + if token == char { + token = yyTok3[i+1] + goto out + } + } + +out: + if token == 0 { + token = yyTok2[1] /* unknown char */ + } + if yyDebug >= 3 { + __yyfmt__.Printf("lex %s(%d)\n", yyTokname(token), uint(char)) + } + return char, token +} + +func yyParse(yylex yyLexer) int { + return yyNewParser().Parse(yylex) +} + +func (yyrcvr *yyParserImpl) Parse(yylex yyLexer) int { + var yyn int + var yyVAL yySymType + var yyDollar []yySymType + _ = yyDollar // silence set and not used + yyS := yyrcvr.stack[:] + + Nerrs := 0 /* number of errors */ + Errflag := 0 /* error recovery flag */ + yystate := 0 + yyrcvr.char = -1 + yytoken := -1 // yyrcvr.char translated into internal numbering + defer func() { + // Make sure we report no lookahead when not parsing. + yystate = -1 + yyrcvr.char = -1 + yytoken = -1 + }() + yyp := -1 + goto yystack + +ret0: + return 0 + +ret1: + return 1 + +yystack: + /* put a state and value onto the stack */ + if yyDebug >= 4 { + __yyfmt__.Printf("char %v in %v\n", yyTokname(yytoken), yyStatname(yystate)) + } + + yyp++ + if yyp >= len(yyS) { + nyys := make([]yySymType, len(yyS)*2) + copy(nyys, yyS) + yyS = nyys + } + yyS[yyp] = yyVAL + yyS[yyp].yys = yystate + +yynewstate: + yyn = yyPact[yystate] + if yyn <= yyFlag { + goto yydefault /* simple state */ + } + if yyrcvr.char < 0 { + yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval) + } + yyn += yytoken + if yyn < 0 || yyn >= yyLast { + goto yydefault + } + yyn = yyAct[yyn] + if yyChk[yyn] == yytoken { /* valid shift */ + yyrcvr.char = -1 + yytoken = -1 + yyVAL = yyrcvr.lval + yystate = yyn + if Errflag > 0 { + Errflag-- + } + goto yystack + } + +yydefault: + /* default state action */ + yyn = yyDef[yystate] + if yyn == -2 { + if yyrcvr.char < 0 { + yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval) + } + + /* look through exception table */ + xi := 0 + for { + if yyExca[xi+0] == -1 && yyExca[xi+1] == yystate { + break + } + xi += 2 + } + for xi += 2; ; xi += 2 { + yyn = yyExca[xi+0] + if yyn < 0 || yyn == yytoken { + break + } + } + yyn = yyExca[xi+1] + if yyn < 0 { + goto ret0 + } + } + if yyn == 0 { + /* error ... attempt to resume parsing */ + switch Errflag { + case 0: /* brand new error */ + yylex.Error(yyErrorMessage(yystate, yytoken)) + Nerrs++ + if yyDebug >= 1 { + __yyfmt__.Printf("%s", yyStatname(yystate)) + __yyfmt__.Printf(" saw %s\n", yyTokname(yytoken)) + } + fallthrough + + case 1, 2: /* incompletely recovered error ... try again */ + Errflag = 3 + + /* find a state where "error" is a legal shift action */ + for yyp >= 0 { + yyn = yyPact[yyS[yyp].yys] + yyErrCode + if yyn >= 0 && yyn < yyLast { + yystate = yyAct[yyn] /* simulate a shift of "error" */ + if yyChk[yystate] == yyErrCode { + goto yystack + } + } + + /* the current p has no shift on "error", pop stack */ + if yyDebug >= 2 { + __yyfmt__.Printf("error recovery pops state %d\n", yyS[yyp].yys) + } + yyp-- + } + /* there is no state on the stack with an error shift ... abort */ + goto ret1 + + case 3: /* no shift yet; clobber input char */ + if yyDebug >= 2 { + __yyfmt__.Printf("error recovery discards %s\n", yyTokname(yytoken)) + } + if yytoken == yyEofCode { + goto ret1 + } + yyrcvr.char = -1 + yytoken = -1 + goto yynewstate /* try again in the same state */ + } + } + + /* reduction by production yyn */ + if yyDebug >= 2 { + __yyfmt__.Printf("reduce %v in:\n\t%v\n", yyn, yyStatname(yystate)) + } + + yynt := yyn + yypt := yyp + _ = yypt // guard against "declared and not used" + + yyp -= yyR2[yyn] + // yyp is now the index of $0. Perform the default action. Iff the + // reduced production is ε, $1 is possibly out of range. + if yyp+1 >= len(yyS) { + nyys := make([]yySymType, len(yyS)*2) + copy(nyys, yyS) + yyS = nyys + } + yyVAL = yyS[yyp+1] + + /* consult goto table to find next state */ + yyn = yyR1[yyn] + yyg := yyPgo[yyn] + yyj := yyg + yyS[yyp].yys + 1 + + if yyj >= yyLast { + yystate = yyAct[yyg] + } else { + yystate = yyAct[yyj] + if yyChk[yystate] != -yyn { + yystate = yyAct[yyg] + } + } + // dummy call; replaced with literal code + switch yynt { + + case 1: + yyDollar = yyS[yypt-1 : yypt+1] +//line query_string.y:41 + { + logDebugGrammar("INPUT") + } + case 2: + yyDollar = yyS[yypt-2 : yypt+1] +//line query_string.y:46 + { + logDebugGrammar("SEARCH PARTS") + } + case 3: + yyDollar = yyS[yypt-1 : yypt+1] +//line query_string.y:50 + { + logDebugGrammar("SEARCH PART") + } + case 4: + yyDollar = yyS[yypt-3 : yypt+1] +//line query_string.y:55 + { + query := yyDollar[2].q + if yyDollar[3].pf != nil { + if query, ok := query.(BoostableQuery); ok { + query.SetBoost(*yyDollar[3].pf) + } + } + switch yyDollar[1].n { + case queryShould: + yylex.(*lexerWrapper).query.AddShould(query) + case queryMust: + yylex.(*lexerWrapper).query.AddMust(query) + case queryMustNot: + yylex.(*lexerWrapper).query.AddMustNot(query) + } + } + case 5: + yyDollar = yyS[yypt-0 : yypt+1] +//line query_string.y:74 + { + yyVAL.n = queryShould + } + case 6: + yyDollar = yyS[yypt-1 : yypt+1] +//line query_string.y:78 + { + logDebugGrammar("PLUS") + yyVAL.n = queryMust + } + case 7: + yyDollar = yyS[yypt-1 : yypt+1] +//line query_string.y:83 + { + logDebugGrammar("MINUS") + yyVAL.n = queryMustNot + } + case 8: + yyDollar = yyS[yypt-1 : yypt+1] +//line query_string.y:89 + { + str := yyDollar[1].s + logDebugGrammar("STRING - %s", str) + var q FieldableQuery + if strings.HasPrefix(str, "/") && strings.HasSuffix(str, "/") { + q = NewRegexpQuery(str[1 : len(str)-1]) + } else if strings.ContainsAny(str, "*?") { + q = NewWildcardQuery(str) + } else { + q = NewMatchQuery(str) + } + yyVAL.q = q + } + case 9: + yyDollar = yyS[yypt-2 : yypt+1] +//line query_string.y:103 + { + str := yyDollar[1].s + fuzziness, err := strconv.ParseFloat(yyDollar[2].s, 64) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("invalid fuzziness value: %v", err)) + } + logDebugGrammar("FUZZY STRING - %s %f", str, fuzziness) + q := NewMatchQuery(str) + q.SetFuzziness(int(fuzziness)) + yyVAL.q = q + } + case 10: + yyDollar = yyS[yypt-4 : yypt+1] +//line query_string.y:115 + { + field := yyDollar[1].s + str := yyDollar[3].s + fuzziness, err := strconv.ParseFloat(yyDollar[4].s, 64) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("invalid fuzziness value: %v", err)) + } + logDebugGrammar("FIELD - %s FUZZY STRING - %s %f", field, str, fuzziness) + q := NewMatchQuery(str) + q.SetFuzziness(int(fuzziness)) + q.SetField(field) + yyVAL.q = q + } + case 11: + yyDollar = yyS[yypt-1 : yypt+1] +//line query_string.y:129 + { + str := yyDollar[1].s + logDebugGrammar("STRING - %s", str) + q1 := NewMatchQuery(str) + val, err := strconv.ParseFloat(yyDollar[1].s, 64) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("error parsing number: %v", err)) + } + inclusive := true + q2 := NewNumericRangeInclusiveQuery(&val, &val, &inclusive, &inclusive) + q := NewDisjunctionQuery([]Query{q1, q2}) + q.queryStringMode = true + yyVAL.q = q + } + case 12: + yyDollar = yyS[yypt-1 : yypt+1] +//line query_string.y:144 + { + phrase := yyDollar[1].s + logDebugGrammar("PHRASE - %s", phrase) + q := NewMatchPhraseQuery(phrase) + yyVAL.q = q + } + case 13: + yyDollar = yyS[yypt-3 : yypt+1] +//line query_string.y:151 + { + field := yyDollar[1].s + str := yyDollar[3].s + logDebugGrammar("FIELD - %s STRING - %s", field, str) + var q FieldableQuery + if strings.HasPrefix(str, "/") && strings.HasSuffix(str, "/") { + q = NewRegexpQuery(str[1 : len(str)-1]) + } else if strings.ContainsAny(str, "*?") { + q = NewWildcardQuery(str) + } else { + q = NewMatchQuery(str) + } + q.SetField(field) + yyVAL.q = q + } + case 14: + yyDollar = yyS[yypt-3 : yypt+1] +//line query_string.y:167 + { + field := yyDollar[1].s + str := yyDollar[3].s + logDebugGrammar("FIELD - %s STRING - %s", field, str) + q1 := NewMatchQuery(str) + q1.SetField(field) + val, err := strconv.ParseFloat(yyDollar[3].s, 64) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("error parsing number: %v", err)) + } + inclusive := true + q2 := NewNumericRangeInclusiveQuery(&val, &val, &inclusive, &inclusive) + q2.SetField(field) + q := NewDisjunctionQuery([]Query{q1, q2}) + q.queryStringMode = true + yyVAL.q = q + } + case 15: + yyDollar = yyS[yypt-3 : yypt+1] +//line query_string.y:185 + { + field := yyDollar[1].s + phrase := yyDollar[3].s + logDebugGrammar("FIELD - %s PHRASE - %s", field, phrase) + q := NewMatchPhraseQuery(phrase) + q.SetField(field) + yyVAL.q = q + } + case 16: + yyDollar = yyS[yypt-4 : yypt+1] +//line query_string.y:194 + { + field := yyDollar[1].s + min, err := strconv.ParseFloat(yyDollar[4].s, 64) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("error parsing number: %v", err)) + } + minInclusive := false + logDebugGrammar("FIELD - GREATER THAN %f", min) + q := NewNumericRangeInclusiveQuery(&min, nil, &minInclusive, nil) + q.SetField(field) + yyVAL.q = q + } + case 17: + yyDollar = yyS[yypt-5 : yypt+1] +//line query_string.y:207 + { + field := yyDollar[1].s + min, err := strconv.ParseFloat(yyDollar[5].s, 64) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("error parsing number: %v", err)) + } + minInclusive := true + logDebugGrammar("FIELD - GREATER THAN OR EQUAL %f", min) + q := NewNumericRangeInclusiveQuery(&min, nil, &minInclusive, nil) + q.SetField(field) + yyVAL.q = q + } + case 18: + yyDollar = yyS[yypt-4 : yypt+1] +//line query_string.y:220 + { + field := yyDollar[1].s + max, err := strconv.ParseFloat(yyDollar[4].s, 64) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("error parsing number: %v", err)) + } + maxInclusive := false + logDebugGrammar("FIELD - LESS THAN %f", max) + q := NewNumericRangeInclusiveQuery(nil, &max, nil, &maxInclusive) + q.SetField(field) + yyVAL.q = q + } + case 19: + yyDollar = yyS[yypt-5 : yypt+1] +//line query_string.y:233 + { + field := yyDollar[1].s + max, err := strconv.ParseFloat(yyDollar[5].s, 64) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("error parsing number: %v", err)) + } + maxInclusive := true + logDebugGrammar("FIELD - LESS THAN OR EQUAL %f", max) + q := NewNumericRangeInclusiveQuery(nil, &max, nil, &maxInclusive) + q.SetField(field) + yyVAL.q = q + } + case 20: + yyDollar = yyS[yypt-4 : yypt+1] +//line query_string.y:246 + { + field := yyDollar[1].s + minInclusive := false + phrase := yyDollar[4].s + + logDebugGrammar("FIELD - GREATER THAN DATE %s", phrase) + minTime, err := queryTimeFromString(phrase) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("invalid time: %v", err)) + } + q := NewDateRangeInclusiveQuery(minTime, time.Time{}, &minInclusive, nil) + q.SetField(field) + yyVAL.q = q + } + case 21: + yyDollar = yyS[yypt-5 : yypt+1] +//line query_string.y:261 + { + field := yyDollar[1].s + minInclusive := true + phrase := yyDollar[5].s + + logDebugGrammar("FIELD - GREATER THAN OR EQUAL DATE %s", phrase) + minTime, err := queryTimeFromString(phrase) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("invalid time: %v", err)) + } + q := NewDateRangeInclusiveQuery(minTime, time.Time{}, &minInclusive, nil) + q.SetField(field) + yyVAL.q = q + } + case 22: + yyDollar = yyS[yypt-4 : yypt+1] +//line query_string.y:276 + { + field := yyDollar[1].s + maxInclusive := false + phrase := yyDollar[4].s + + logDebugGrammar("FIELD - LESS THAN DATE %s", phrase) + maxTime, err := queryTimeFromString(phrase) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("invalid time: %v", err)) + } + q := NewDateRangeInclusiveQuery(time.Time{}, maxTime, nil, &maxInclusive) + q.SetField(field) + yyVAL.q = q + } + case 23: + yyDollar = yyS[yypt-5 : yypt+1] +//line query_string.y:291 + { + field := yyDollar[1].s + maxInclusive := true + phrase := yyDollar[5].s + + logDebugGrammar("FIELD - LESS THAN OR EQUAL DATE %s", phrase) + maxTime, err := queryTimeFromString(phrase) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("invalid time: %v", err)) + } + q := NewDateRangeInclusiveQuery(time.Time{}, maxTime, nil, &maxInclusive) + q.SetField(field) + yyVAL.q = q + } + case 24: + yyDollar = yyS[yypt-0 : yypt+1] +//line query_string.y:307 + { + yyVAL.pf = nil + } + case 25: + yyDollar = yyS[yypt-1 : yypt+1] +//line query_string.y:311 + { + yyVAL.pf = nil + boost, err := strconv.ParseFloat(yyDollar[1].s, 64) + if err != nil { + yylex.(*lexerWrapper).lex.Error(fmt.Sprintf("invalid boost value: %v", err)) + } else { + yyVAL.pf = &boost + } + logDebugGrammar("BOOST %f", boost) + } + case 26: + yyDollar = yyS[yypt-1 : yypt+1] +//line query_string.y:323 + { + yyVAL.s = yyDollar[1].s + } + case 27: + yyDollar = yyS[yypt-2 : yypt+1] +//line query_string.y:327 + { + yyVAL.s = "-" + yyDollar[2].s + } + case 28: + yyDollar = yyS[yypt-1 : yypt+1] +//line query_string.y:332 + { + yyVAL.s = yyDollar[1].s + } + case 29: + yyDollar = yyS[yypt-1 : yypt+1] +//line query_string.y:336 + { + yyVAL.s = yyDollar[1].s + } + } + goto yystack /* stack new state and value */ +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string_lex.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string_lex.go new file mode 100644 index 0000000000..c01fa6fc29 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string_lex.go @@ -0,0 +1,329 @@ +// Copyright (c) 2016 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "bufio" + "io" + "strings" + "unicode" +) + +const reservedChars = "+-=&|>', '<', '=': + l.buf += string(next) + return singleCharOpState, true + case '^': + return inBoostState, true + case '~': + return inTildeState, true + } + + switch { + case !l.inEscape && next == '\\': + l.inEscape = true + return startState, true + case unicode.IsDigit(next): + l.buf += string(next) + return inNumOrStrState, true + case !unicode.IsSpace(next): + l.buf += string(next) + return inStrState, true + } + + // doesn't look like anything, just eat it and stay here + l.reset() + return startState, true +} + +func inPhraseState(l *queryStringLex, next rune, eof bool) (lexState, bool) { + // unterminated phrase eats the phrase + if eof { + l.Error("unterminated quote") + return nil, false + } + + // only a non-escaped " ends the phrase + if !l.inEscape && next == '"' { + // end phrase + l.nextTokenType = tPHRASE + l.nextToken = &yySymType{ + s: l.buf, + } + logDebugTokens("PHRASE - '%s'", l.nextToken.s) + l.reset() + return startState, true + } else if !l.inEscape && next == '\\' { + l.inEscape = true + } else if l.inEscape { + // if in escape, end it + l.inEscape = false + l.buf += unescape(string(next)) + } else { + l.buf += string(next) + } + + return inPhraseState, true +} + +func singleCharOpState(l *queryStringLex, next rune, eof bool) (lexState, bool) { + l.nextToken = &yySymType{} + + switch l.buf { + case "+": + l.nextTokenType = tPLUS + logDebugTokens("PLUS") + case "-": + l.nextTokenType = tMINUS + logDebugTokens("MINUS") + case ":": + l.nextTokenType = tCOLON + logDebugTokens("COLON") + case ">": + l.nextTokenType = tGREATER + logDebugTokens("GREATER") + case "<": + l.nextTokenType = tLESS + logDebugTokens("LESS") + case "=": + l.nextTokenType = tEQUAL + logDebugTokens("EQUAL") + } + + l.reset() + return startState, false +} + +func inBoostState(l *queryStringLex, next rune, eof bool) (lexState, bool) { + + // only a non-escaped space ends the boost (or eof) + if eof || (!l.inEscape && next == ' ') { + // end boost + l.nextTokenType = tBOOST + if l.buf == "" { + l.buf = "1" + } + l.nextToken = &yySymType{ + s: l.buf, + } + logDebugTokens("BOOST - '%s'", l.nextToken.s) + l.reset() + return startState, true + } else if !l.inEscape && next == '\\' { + l.inEscape = true + } else if l.inEscape { + // if in escape, end it + l.inEscape = false + l.buf += unescape(string(next)) + } else { + l.buf += string(next) + } + + return inBoostState, true +} + +func inTildeState(l *queryStringLex, next rune, eof bool) (lexState, bool) { + + // only a non-escaped space ends the tilde (or eof) + if eof || (!l.inEscape && next == ' ') { + // end tilde + l.nextTokenType = tTILDE + if l.buf == "" { + l.buf = "1" + } + l.nextToken = &yySymType{ + s: l.buf, + } + logDebugTokens("TILDE - '%s'", l.nextToken.s) + l.reset() + return startState, true + } else if !l.inEscape && next == '\\' { + l.inEscape = true + } else if l.inEscape { + // if in escape, end it + l.inEscape = false + l.buf += unescape(string(next)) + } else { + l.buf += string(next) + } + + return inTildeState, true +} + +func inNumOrStrState(l *queryStringLex, next rune, eof bool) (lexState, bool) { + // end on non-escaped space, colon, tilde, boost (or eof) + if eof || (!l.inEscape && (next == ' ' || next == ':' || next == '^' || next == '~')) { + // end number + l.nextTokenType = tNUMBER + l.nextToken = &yySymType{ + s: l.buf, + } + logDebugTokens("NUMBER - '%s'", l.nextToken.s) + l.reset() + + consumed := true + if !eof && (next == ':' || next == '^' || next == '~') { + consumed = false + } + + return startState, consumed + } else if !l.inEscape && next == '\\' { + l.inEscape = true + return inNumOrStrState, true + } else if l.inEscape { + // if in escape, end it + l.inEscape = false + l.buf += unescape(string(next)) + // go directly to string, no successfully or unsuccessfully + // escaped string results in a valid number + return inStrState, true + } + + // see where to go + if !l.seenDot && next == '.' { + // stay in this state + l.seenDot = true + l.buf += string(next) + return inNumOrStrState, true + } else if unicode.IsDigit(next) { + l.buf += string(next) + return inNumOrStrState, true + } + + // doesn't look like an number, transition + l.buf += string(next) + return inStrState, true +} + +func inStrState(l *queryStringLex, next rune, eof bool) (lexState, bool) { + // end on non-escaped space, colon, tilde, boost (or eof) + if eof || (!l.inEscape && (next == ' ' || next == ':' || next == '^' || next == '~')) { + // end string + l.nextTokenType = tSTRING + l.nextToken = &yySymType{ + s: l.buf, + } + logDebugTokens("STRING - '%s'", l.nextToken.s) + l.reset() + + consumed := true + if !eof && (next == ':' || next == '^' || next == '~') { + consumed = false + } + + return startState, consumed + } else if !l.inEscape && next == '\\' { + l.inEscape = true + } else if l.inEscape { + // if in escape, end it + l.inEscape = false + l.buf += unescape(string(next)) + } else { + l.buf += string(next) + } + + return inStrState, true +} + +func logDebugTokens(format string, v ...interface{}) { + if debugLexer { + logger.Printf(format, v...) + } +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string_parser.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string_parser.go new file mode 100644 index 0000000000..3fb7731b88 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/query_string_parser.go @@ -0,0 +1,85 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// as of Go 1.8 this requires the goyacc external tool +// available from golang.org/x/tools/cmd/goyacc + +//go:generate goyacc -o query_string.y.go query_string.y +//go:generate sed -i.tmp -e 1d query_string.y.go +//go:generate rm query_string.y.go.tmp + +// note: OSX sed and gnu sed handle the -i (in-place) option differently. +// using -i.tmp works on both, at the expense of having to remove +// the unsightly .tmp files + +package query + +import ( + "fmt" + "strings" +) + +var debugParser bool +var debugLexer bool + +func parseQuerySyntax(query string) (rq Query, err error) { + if query == "" { + return NewMatchNoneQuery(), nil + } + lex := newLexerWrapper(newQueryStringLex(strings.NewReader(query))) + doParse(lex) + + if len(lex.errs) > 0 { + return nil, fmt.Errorf(strings.Join(lex.errs, "\n")) + } + return lex.query, nil +} + +func doParse(lex *lexerWrapper) { + defer func() { + r := recover() + if r != nil { + lex.errs = append(lex.errs, fmt.Sprintf("parse error: %v", r)) + } + }() + + yyParse(lex) +} + +const ( + queryShould = iota + queryMust + queryMustNot +) + +type lexerWrapper struct { + lex yyLexer + errs []string + query *BooleanQuery +} + +func newLexerWrapper(lex yyLexer) *lexerWrapper { + return &lexerWrapper{ + lex: lex, + query: NewBooleanQueryForQueryString(nil, nil, nil), + } +} + +func (l *lexerWrapper) Lex(lval *yySymType) int { + return l.lex.Lex(lval) +} + +func (l *lexerWrapper) Error(s string) { + l.errs = append(l.errs, s) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/regexp.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/regexp.go new file mode 100644 index 0000000000..6b3da9554b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/regexp.go @@ -0,0 +1,82 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "strings" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type RegexpQuery struct { + Regexp string `json:"regexp"` + FieldVal string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` +} + +// NewRegexpQuery creates a new Query which finds +// documents containing terms that match the +// specified regular expression. The regexp pattern +// SHOULD NOT include ^ or $ modifiers, the search +// will only match entire terms even without them. +func NewRegexpQuery(regexp string) *RegexpQuery { + return &RegexpQuery{ + Regexp: regexp, + } +} + +func (q *RegexpQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *RegexpQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *RegexpQuery) SetField(f string) { + q.FieldVal = f +} + +func (q *RegexpQuery) Field() string { + return q.FieldVal +} + +func (q *RegexpQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + field := q.FieldVal + if q.FieldVal == "" { + field = m.DefaultSearchField() + } + + // require that pattern NOT be anchored to start and end of term. + // do not attempt to remove trailing $, its presence is not + // known to interfere with LiteralPrefix() the way ^ does + // and removing $ introduces possible ambiguities with escaped \$, \\$, etc + actualRegexp := q.Regexp + if strings.HasPrefix(actualRegexp, "^") { + actualRegexp = actualRegexp[1:] // remove leading ^ + } + + return searcher.NewRegexpStringSearcher(ctx, i, actualRegexp, field, + q.BoostVal.Value(), options) +} + +func (q *RegexpQuery) Validate() error { + return nil // real validation delayed until searcher constructor +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/term.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/term.go new file mode 100644 index 0000000000..5c6af3962e --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/term.go @@ -0,0 +1,63 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type TermQuery struct { + Term string `json:"term"` + FieldVal string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` +} + +// NewTermQuery creates a new Query for finding an +// exact term match in the index. +func NewTermQuery(term string) *TermQuery { + return &TermQuery{ + Term: term, + } +} + +func (q *TermQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *TermQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *TermQuery) SetField(f string) { + q.FieldVal = f +} + +func (q *TermQuery) Field() string { + return q.FieldVal +} + +func (q *TermQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + field := q.FieldVal + if q.FieldVal == "" { + field = m.DefaultSearchField() + } + return searcher.NewTermSearcher(ctx, i, q.Term, field, q.BoostVal.Value(), options) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/term_range.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/term_range.go new file mode 100644 index 0000000000..4dc3a34b7f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/term_range.go @@ -0,0 +1,96 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "fmt" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +type TermRangeQuery struct { + Min string `json:"min,omitempty"` + Max string `json:"max,omitempty"` + InclusiveMin *bool `json:"inclusive_min,omitempty"` + InclusiveMax *bool `json:"inclusive_max,omitempty"` + FieldVal string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` +} + +// NewTermRangeQuery creates a new Query for ranges +// of text term values. +// Either, but not both endpoints can be nil. +// The minimum value is inclusive. +// The maximum value is exclusive. +func NewTermRangeQuery(min, max string) *TermRangeQuery { + return NewTermRangeInclusiveQuery(min, max, nil, nil) +} + +// NewTermRangeInclusiveQuery creates a new Query for ranges +// of numeric values. +// Either, but not both endpoints can be nil. +// Control endpoint inclusion with inclusiveMin, inclusiveMax. +func NewTermRangeInclusiveQuery(min, max string, minInclusive, maxInclusive *bool) *TermRangeQuery { + return &TermRangeQuery{ + Min: min, + Max: max, + InclusiveMin: minInclusive, + InclusiveMax: maxInclusive, + } +} + +func (q *TermRangeQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *TermRangeQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *TermRangeQuery) SetField(f string) { + q.FieldVal = f +} + +func (q *TermRangeQuery) Field() string { + return q.FieldVal +} + +func (q *TermRangeQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + field := q.FieldVal + if q.FieldVal == "" { + field = m.DefaultSearchField() + } + var minTerm []byte + if q.Min != "" { + minTerm = []byte(q.Min) + } + var maxTerm []byte + if q.Max != "" { + maxTerm = []byte(q.Max) + } + return searcher.NewTermRangeSearcher(ctx, i, minTerm, maxTerm, q.InclusiveMin, q.InclusiveMax, field, q.BoostVal.Value(), options) +} + +func (q *TermRangeQuery) Validate() error { + if q.Min == "" && q.Min == q.Max { + return fmt.Errorf("term range query must specify min or max") + } + return nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/query/wildcard.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/wildcard.go new file mode 100644 index 0000000000..f04f3f2edc --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/query/wildcard.go @@ -0,0 +1,94 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "context" + "strings" + + "github.com/blevesearch/bleve/v2/mapping" + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/searcher" + index "github.com/blevesearch/bleve_index_api" +) + +var wildcardRegexpReplacer = strings.NewReplacer( + // characters in the wildcard that must + // be escaped in the regexp + "+", `\+`, + "(", `\(`, + ")", `\)`, + "^", `\^`, + "$", `\$`, + ".", `\.`, + "{", `\{`, + "}", `\}`, + "[", `\[`, + "]", `\]`, + `|`, `\|`, + `\`, `\\`, + // wildcard characters + "*", ".*", + "?", ".") + +type WildcardQuery struct { + Wildcard string `json:"wildcard"` + FieldVal string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` +} + +// NewWildcardQuery creates a new Query which finds +// documents containing terms that match the +// specified wildcard. In the wildcard pattern '*' +// will match any sequence of 0 or more characters, +// and '?' will match any single character. +func NewWildcardQuery(wildcard string) *WildcardQuery { + return &WildcardQuery{ + Wildcard: wildcard, + } +} + +func (q *WildcardQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *WildcardQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *WildcardQuery) SetField(f string) { + q.FieldVal = f +} + +func (q *WildcardQuery) Field() string { + return q.FieldVal +} + +func (q *WildcardQuery) Searcher(ctx context.Context, i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + field := q.FieldVal + if q.FieldVal == "" { + field = m.DefaultSearchField() + } + + regexpString := wildcardRegexpReplacer.Replace(q.Wildcard) + + return searcher.NewRegexpStringSearcher(ctx, i, regexpString, field, + q.BoostVal.Value(), options) +} + +func (q *WildcardQuery) Validate() error { + return nil // real validation delayed until searcher constructor +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/scorer_conjunction.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/scorer_conjunction.go new file mode 100644 index 0000000000..f3c81a78c8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/scorer_conjunction.go @@ -0,0 +1,72 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorer + +import ( + "reflect" + + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/size" +) + +var reflectStaticSizeConjunctionQueryScorer int + +func init() { + var cqs ConjunctionQueryScorer + reflectStaticSizeConjunctionQueryScorer = int(reflect.TypeOf(cqs).Size()) +} + +type ConjunctionQueryScorer struct { + options search.SearcherOptions +} + +func (s *ConjunctionQueryScorer) Size() int { + return reflectStaticSizeConjunctionQueryScorer + size.SizeOfPtr +} + +func NewConjunctionQueryScorer(options search.SearcherOptions) *ConjunctionQueryScorer { + return &ConjunctionQueryScorer{ + options: options, + } +} + +func (s *ConjunctionQueryScorer) Score(ctx *search.SearchContext, constituents []*search.DocumentMatch) *search.DocumentMatch { + var sum float64 + var childrenExplanations []*search.Explanation + if s.options.Explain { + childrenExplanations = make([]*search.Explanation, len(constituents)) + } + + for i, docMatch := range constituents { + sum += docMatch.Score + if s.options.Explain { + childrenExplanations[i] = docMatch.Expl + } + } + newScore := sum + var newExpl *search.Explanation + if s.options.Explain { + newExpl = &search.Explanation{Value: sum, Message: "sum of:", Children: childrenExplanations} + } + + // reuse constituents[0] as the return value + rv := constituents[0] + rv.Score = newScore + rv.Expl = newExpl + rv.FieldTermLocations = search.MergeFieldTermLocations( + rv.FieldTermLocations, constituents[1:]) + + return rv +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/scorer_constant.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/scorer_constant.go new file mode 100644 index 0000000000..fc36fd5bfa --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/scorer_constant.go @@ -0,0 +1,127 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorer + +import ( + "fmt" + "reflect" + + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeConstantScorer int + +func init() { + var cs ConstantScorer + reflectStaticSizeConstantScorer = int(reflect.TypeOf(cs).Size()) +} + +type ConstantScorer struct { + constant float64 + boost float64 + options search.SearcherOptions + queryNorm float64 + queryWeight float64 + queryWeightExplanation *search.Explanation +} + +func (s *ConstantScorer) Size() int { + sizeInBytes := reflectStaticSizeConstantScorer + size.SizeOfPtr + + if s.queryWeightExplanation != nil { + sizeInBytes += s.queryWeightExplanation.Size() + } + + return sizeInBytes +} + +func NewConstantScorer(constant float64, boost float64, options search.SearcherOptions) *ConstantScorer { + rv := ConstantScorer{ + options: options, + queryWeight: 1.0, + constant: constant, + boost: boost, + } + + return &rv +} + +func (s *ConstantScorer) Weight() float64 { + sum := s.boost + return sum * sum +} + +func (s *ConstantScorer) SetQueryNorm(qnorm float64) { + s.queryNorm = qnorm + + // update the query weight + s.queryWeight = s.boost * s.queryNorm + + if s.options.Explain { + childrenExplanations := make([]*search.Explanation, 2) + childrenExplanations[0] = &search.Explanation{ + Value: s.boost, + Message: "boost", + } + childrenExplanations[1] = &search.Explanation{ + Value: s.queryNorm, + Message: "queryNorm", + } + s.queryWeightExplanation = &search.Explanation{ + Value: s.queryWeight, + Message: fmt.Sprintf("ConstantScore()^%f, product of:", s.boost), + Children: childrenExplanations, + } + } +} + +func (s *ConstantScorer) Score(ctx *search.SearchContext, id index.IndexInternalID) *search.DocumentMatch { + var scoreExplanation *search.Explanation + + score := s.constant + + if s.options.Explain { + scoreExplanation = &search.Explanation{ + Value: score, + Message: fmt.Sprintf("ConstantScore()"), + } + } + + // if the query weight isn't 1, multiply + if s.queryWeight != 1.0 { + score = score * s.queryWeight + if s.options.Explain { + childExplanations := make([]*search.Explanation, 2) + childExplanations[0] = s.queryWeightExplanation + childExplanations[1] = scoreExplanation + scoreExplanation = &search.Explanation{ + Value: score, + Message: fmt.Sprintf("weight(^%f), product of:", s.boost), + Children: childExplanations, + } + } + } + + rv := ctx.DocumentMatchPool.Get() + rv.IndexInternalID = id + rv.Score = score + if s.options.Explain { + rv.Expl = scoreExplanation + } + + return rv +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/scorer_disjunction.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/scorer_disjunction.go new file mode 100644 index 0000000000..054e76fd42 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/scorer_disjunction.go @@ -0,0 +1,83 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorer + +import ( + "fmt" + "reflect" + + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/size" +) + +var reflectStaticSizeDisjunctionQueryScorer int + +func init() { + var dqs DisjunctionQueryScorer + reflectStaticSizeDisjunctionQueryScorer = int(reflect.TypeOf(dqs).Size()) +} + +type DisjunctionQueryScorer struct { + options search.SearcherOptions +} + +func (s *DisjunctionQueryScorer) Size() int { + return reflectStaticSizeDisjunctionQueryScorer + size.SizeOfPtr +} + +func NewDisjunctionQueryScorer(options search.SearcherOptions) *DisjunctionQueryScorer { + return &DisjunctionQueryScorer{ + options: options, + } +} + +func (s *DisjunctionQueryScorer) Score(ctx *search.SearchContext, constituents []*search.DocumentMatch, countMatch, countTotal int) *search.DocumentMatch { + var sum float64 + var childrenExplanations []*search.Explanation + if s.options.Explain { + childrenExplanations = make([]*search.Explanation, len(constituents)) + } + + for i, docMatch := range constituents { + sum += docMatch.Score + if s.options.Explain { + childrenExplanations[i] = docMatch.Expl + } + } + + var rawExpl *search.Explanation + if s.options.Explain { + rawExpl = &search.Explanation{Value: sum, Message: "sum of:", Children: childrenExplanations} + } + + coord := float64(countMatch) / float64(countTotal) + newScore := sum * coord + var newExpl *search.Explanation + if s.options.Explain { + ce := make([]*search.Explanation, 2) + ce[0] = rawExpl + ce[1] = &search.Explanation{Value: coord, Message: fmt.Sprintf("coord(%d/%d)", countMatch, countTotal)} + newExpl = &search.Explanation{Value: newScore, Message: "product of:", Children: ce} + } + + // reuse constituents[0] as the return value + rv := constituents[0] + rv.Score = newScore + rv.Expl = newExpl + rv.FieldTermLocations = search.MergeFieldTermLocations( + rv.FieldTermLocations, constituents[1:]) + + return rv +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/scorer_term.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/scorer_term.go new file mode 100644 index 0000000000..7b60eda4ed --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/scorer_term.go @@ -0,0 +1,202 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorer + +import ( + "fmt" + "math" + "reflect" + + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeTermQueryScorer int + +func init() { + var tqs TermQueryScorer + reflectStaticSizeTermQueryScorer = int(reflect.TypeOf(tqs).Size()) +} + +type TermQueryScorer struct { + queryTerm string + queryField string + queryBoost float64 + docTerm uint64 + docTotal uint64 + idf float64 + options search.SearcherOptions + idfExplanation *search.Explanation + includeScore bool + queryNorm float64 + queryWeight float64 + queryWeightExplanation *search.Explanation +} + +func (s *TermQueryScorer) Size() int { + sizeInBytes := reflectStaticSizeTermQueryScorer + size.SizeOfPtr + + len(s.queryTerm) + len(s.queryField) + + if s.idfExplanation != nil { + sizeInBytes += s.idfExplanation.Size() + } + + if s.queryWeightExplanation != nil { + sizeInBytes += s.queryWeightExplanation.Size() + } + + return sizeInBytes +} + +func NewTermQueryScorer(queryTerm []byte, queryField string, queryBoost float64, docTotal, docTerm uint64, options search.SearcherOptions) *TermQueryScorer { + rv := TermQueryScorer{ + queryTerm: string(queryTerm), + queryField: queryField, + queryBoost: queryBoost, + docTerm: docTerm, + docTotal: docTotal, + idf: 1.0 + math.Log(float64(docTotal)/float64(docTerm+1.0)), + options: options, + queryWeight: 1.0, + includeScore: options.Score != "none", + } + + if options.Explain { + rv.idfExplanation = &search.Explanation{ + Value: rv.idf, + Message: fmt.Sprintf("idf(docFreq=%d, maxDocs=%d)", docTerm, docTotal), + } + } + + return &rv +} + +func (s *TermQueryScorer) Weight() float64 { + sum := s.queryBoost * s.idf + return sum * sum +} + +func (s *TermQueryScorer) SetQueryNorm(qnorm float64) { + s.queryNorm = qnorm + + // update the query weight + s.queryWeight = s.queryBoost * s.idf * s.queryNorm + + if s.options.Explain { + childrenExplanations := make([]*search.Explanation, 3) + childrenExplanations[0] = &search.Explanation{ + Value: s.queryBoost, + Message: "boost", + } + childrenExplanations[1] = s.idfExplanation + childrenExplanations[2] = &search.Explanation{ + Value: s.queryNorm, + Message: "queryNorm", + } + s.queryWeightExplanation = &search.Explanation{ + Value: s.queryWeight, + Message: fmt.Sprintf("queryWeight(%s:%s^%f), product of:", s.queryField, s.queryTerm, s.queryBoost), + Children: childrenExplanations, + } + } +} + +func (s *TermQueryScorer) Score(ctx *search.SearchContext, termMatch *index.TermFieldDoc) *search.DocumentMatch { + rv := ctx.DocumentMatchPool.Get() + // perform any score computations only when needed + if s.includeScore || s.options.Explain { + var scoreExplanation *search.Explanation + var tf float64 + if termMatch.Freq < MaxSqrtCache { + tf = SqrtCache[int(termMatch.Freq)] + } else { + tf = math.Sqrt(float64(termMatch.Freq)) + } + score := tf * termMatch.Norm * s.idf + + if s.options.Explain { + childrenExplanations := make([]*search.Explanation, 3) + childrenExplanations[0] = &search.Explanation{ + Value: tf, + Message: fmt.Sprintf("tf(termFreq(%s:%s)=%d", s.queryField, s.queryTerm, termMatch.Freq), + } + childrenExplanations[1] = &search.Explanation{ + Value: termMatch.Norm, + Message: fmt.Sprintf("fieldNorm(field=%s, doc=%s)", s.queryField, termMatch.ID), + } + childrenExplanations[2] = s.idfExplanation + scoreExplanation = &search.Explanation{ + Value: score, + Message: fmt.Sprintf("fieldWeight(%s:%s in %s), product of:", s.queryField, s.queryTerm, termMatch.ID), + Children: childrenExplanations, + } + } + + // if the query weight isn't 1, multiply + if s.queryWeight != 1.0 { + score = score * s.queryWeight + if s.options.Explain { + childExplanations := make([]*search.Explanation, 2) + childExplanations[0] = s.queryWeightExplanation + childExplanations[1] = scoreExplanation + scoreExplanation = &search.Explanation{ + Value: score, + Message: fmt.Sprintf("weight(%s:%s^%f in %s), product of:", s.queryField, s.queryTerm, s.queryBoost, termMatch.ID), + Children: childExplanations, + } + } + } + + if s.includeScore { + rv.Score = score + } + + if s.options.Explain { + rv.Expl = scoreExplanation + } + } + + rv.IndexInternalID = append(rv.IndexInternalID, termMatch.ID...) + + if len(termMatch.Vectors) > 0 { + if cap(rv.FieldTermLocations) < len(termMatch.Vectors) { + rv.FieldTermLocations = make([]search.FieldTermLocation, 0, len(termMatch.Vectors)) + } + + for _, v := range termMatch.Vectors { + var ap search.ArrayPositions + if len(v.ArrayPositions) > 0 { + n := len(rv.FieldTermLocations) + if n < cap(rv.FieldTermLocations) { // reuse ap slice if available + ap = rv.FieldTermLocations[:n+1][n].Location.ArrayPositions[:0] + } + ap = append(ap, v.ArrayPositions...) + } + rv.FieldTermLocations = + append(rv.FieldTermLocations, search.FieldTermLocation{ + Field: v.Field, + Term: s.queryTerm, + Location: search.Location{ + Pos: v.Pos, + Start: v.Start, + End: v.End, + ArrayPositions: ap, + }, + }) + } + } + return rv +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/sqrt_cache.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/sqrt_cache.go new file mode 100644 index 0000000000..e26d33d93d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/scorer/sqrt_cache.go @@ -0,0 +1,30 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scorer + +import ( + "math" +) + +var SqrtCache []float64 + +const MaxSqrtCache = 64 + +func init() { + SqrtCache = make([]float64, MaxSqrtCache) + for i := 0; i < MaxSqrtCache; i++ { + SqrtCache[i] = math.Sqrt(float64(i)) + } +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/search.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/search.go new file mode 100644 index 0000000000..69d8945f9c --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/search.go @@ -0,0 +1,382 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package search + +import ( + "fmt" + "reflect" + "sort" + + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeDocumentMatch int +var reflectStaticSizeSearchContext int +var reflectStaticSizeLocation int + +const SearchIOStatsCallbackKey = "_search_io_stats_callback_key" + +type SearchIOStatsCallbackFunc func(uint64) + +func init() { + var dm DocumentMatch + reflectStaticSizeDocumentMatch = int(reflect.TypeOf(dm).Size()) + var sc SearchContext + reflectStaticSizeSearchContext = int(reflect.TypeOf(sc).Size()) + var l Location + reflectStaticSizeLocation = int(reflect.TypeOf(l).Size()) +} + +type ArrayPositions []uint64 + +func (ap ArrayPositions) Equals(other ArrayPositions) bool { + if len(ap) != len(other) { + return false + } + for i := range ap { + if ap[i] != other[i] { + return false + } + } + return true +} + +func (ap ArrayPositions) Compare(other ArrayPositions) int { + for i, p := range ap { + if i >= len(other) { + return 1 + } + if p < other[i] { + return -1 + } + if p > other[i] { + return 1 + } + } + if len(ap) < len(other) { + return -1 + } + return 0 +} + +type Location struct { + // Pos is the position of the term within the field, starting at 1 + Pos uint64 `json:"pos"` + + // Start and End are the byte offsets of the term in the field + Start uint64 `json:"start"` + End uint64 `json:"end"` + + // ArrayPositions contains the positions of the term within any elements. + ArrayPositions ArrayPositions `json:"array_positions"` +} + +func (l *Location) Size() int { + return reflectStaticSizeLocation + size.SizeOfPtr + + len(l.ArrayPositions)*size.SizeOfUint64 +} + +type Locations []*Location + +func (p Locations) Len() int { return len(p) } +func (p Locations) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +func (p Locations) Less(i, j int) bool { + c := p[i].ArrayPositions.Compare(p[j].ArrayPositions) + if c < 0 { + return true + } + if c > 0 { + return false + } + return p[i].Pos < p[j].Pos +} + +func (p Locations) Dedupe() Locations { // destructive! + if len(p) <= 1 { + return p + } + + sort.Sort(p) + + slow := 0 + + for _, pfast := range p { + pslow := p[slow] + if pslow.Pos == pfast.Pos && + pslow.Start == pfast.Start && + pslow.End == pfast.End && + pslow.ArrayPositions.Equals(pfast.ArrayPositions) { + continue // duplicate, so only move fast ahead + } + + slow++ + + p[slow] = pfast + } + + return p[:slow+1] +} + +type TermLocationMap map[string]Locations + +func (t TermLocationMap) AddLocation(term string, location *Location) { + t[term] = append(t[term], location) +} + +type FieldTermLocationMap map[string]TermLocationMap + +type FieldTermLocation struct { + Field string + Term string + Location Location +} + +type FieldFragmentMap map[string][]string + +type DocumentMatch struct { + Index string `json:"index,omitempty"` + ID string `json:"id"` + IndexInternalID index.IndexInternalID `json:"-"` + Score float64 `json:"score"` + Expl *Explanation `json:"explanation,omitempty"` + Locations FieldTermLocationMap `json:"locations,omitempty"` + Fragments FieldFragmentMap `json:"fragments,omitempty"` + Sort []string `json:"sort,omitempty"` + + // Fields contains the values for document fields listed in + // SearchRequest.Fields. Text fields are returned as strings, numeric + // fields as float64s and date fields as time.RFC3339 formatted strings. + Fields map[string]interface{} `json:"fields,omitempty"` + + // used to maintain natural index order + HitNumber uint64 `json:"-"` + + // used to temporarily hold field term location information during + // search processing in an efficient, recycle-friendly manner, to + // be later incorporated into the Locations map when search + // results are completed + FieldTermLocations []FieldTermLocation `json:"-"` +} + +func (dm *DocumentMatch) AddFieldValue(name string, value interface{}) { + if dm.Fields == nil { + dm.Fields = make(map[string]interface{}) + } + existingVal, ok := dm.Fields[name] + if !ok { + dm.Fields[name] = value + return + } + + valSlice, ok := existingVal.([]interface{}) + if ok { + // already a slice, append to it + valSlice = append(valSlice, value) + } else { + // create a slice + valSlice = []interface{}{existingVal, value} + } + dm.Fields[name] = valSlice +} + +// Reset allows an already allocated DocumentMatch to be reused +func (dm *DocumentMatch) Reset() *DocumentMatch { + // remember the []byte used for the IndexInternalID + indexInternalID := dm.IndexInternalID + // remember the []interface{} used for sort + sort := dm.Sort + // remember the FieldTermLocations backing array + ftls := dm.FieldTermLocations + for i := range ftls { // recycle the ArrayPositions of each location + ftls[i].Location.ArrayPositions = ftls[i].Location.ArrayPositions[:0] + } + // idiom to copy over from empty DocumentMatch (0 allocations) + *dm = DocumentMatch{} + // reuse the []byte already allocated (and reset len to 0) + dm.IndexInternalID = indexInternalID[:0] + // reuse the []interface{} already allocated (and reset len to 0) + dm.Sort = sort[:0] + // reuse the FieldTermLocations already allocated (and reset len to 0) + dm.FieldTermLocations = ftls[:0] + return dm +} + +func (dm *DocumentMatch) Size() int { + sizeInBytes := reflectStaticSizeDocumentMatch + size.SizeOfPtr + + len(dm.Index) + + len(dm.ID) + + len(dm.IndexInternalID) + + if dm.Expl != nil { + sizeInBytes += dm.Expl.Size() + } + + for k, v := range dm.Locations { + sizeInBytes += size.SizeOfString + len(k) + for k1, v1 := range v { + sizeInBytes += size.SizeOfString + len(k1) + + size.SizeOfSlice + for _, entry := range v1 { + sizeInBytes += entry.Size() + } + } + } + + for k, v := range dm.Fragments { + sizeInBytes += size.SizeOfString + len(k) + + size.SizeOfSlice + + for _, entry := range v { + sizeInBytes += size.SizeOfString + len(entry) + } + } + + for _, entry := range dm.Sort { + sizeInBytes += size.SizeOfString + len(entry) + } + + for k, _ := range dm.Fields { + sizeInBytes += size.SizeOfString + len(k) + + size.SizeOfPtr + } + + return sizeInBytes +} + +// Complete performs final preparation & transformation of the +// DocumentMatch at the end of search processing, also allowing the +// caller to provide an optional preallocated locations slice +func (dm *DocumentMatch) Complete(prealloc []Location) []Location { + // transform the FieldTermLocations slice into the Locations map + nlocs := len(dm.FieldTermLocations) + if nlocs > 0 { + if cap(prealloc) < nlocs { + prealloc = make([]Location, nlocs) + } + prealloc = prealloc[:nlocs] + + var lastField string + var tlm TermLocationMap + var needsDedupe bool + + for i, ftl := range dm.FieldTermLocations { + if i == 0 || lastField != ftl.Field { + lastField = ftl.Field + + if dm.Locations == nil { + dm.Locations = make(FieldTermLocationMap) + } + + tlm = dm.Locations[ftl.Field] + if tlm == nil { + tlm = make(TermLocationMap) + dm.Locations[ftl.Field] = tlm + } + } + + loc := &prealloc[i] + *loc = ftl.Location + + if len(loc.ArrayPositions) > 0 { // copy + loc.ArrayPositions = append(ArrayPositions(nil), loc.ArrayPositions...) + } + + locs := tlm[ftl.Term] + + // if the loc is before or at the last location, then there + // might be duplicates that need to be deduplicated + if !needsDedupe && len(locs) > 0 { + last := locs[len(locs)-1] + cmp := loc.ArrayPositions.Compare(last.ArrayPositions) + if cmp < 0 || (cmp == 0 && loc.Pos <= last.Pos) { + needsDedupe = true + } + } + + tlm[ftl.Term] = append(locs, loc) + + dm.FieldTermLocations[i] = FieldTermLocation{ // recycle + Location: Location{ + ArrayPositions: ftl.Location.ArrayPositions[:0], + }, + } + } + + if needsDedupe { + for _, tlm := range dm.Locations { + for term, locs := range tlm { + tlm[term] = locs.Dedupe() + } + } + } + } + + dm.FieldTermLocations = dm.FieldTermLocations[:0] // recycle + + return prealloc +} + +func (dm *DocumentMatch) String() string { + return fmt.Sprintf("[%s-%f]", string(dm.IndexInternalID), dm.Score) +} + +type DocumentMatchCollection []*DocumentMatch + +func (c DocumentMatchCollection) Len() int { return len(c) } +func (c DocumentMatchCollection) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +func (c DocumentMatchCollection) Less(i, j int) bool { return c[i].Score > c[j].Score } + +type Searcher interface { + Next(ctx *SearchContext) (*DocumentMatch, error) + Advance(ctx *SearchContext, ID index.IndexInternalID) (*DocumentMatch, error) + Close() error + Weight() float64 + SetQueryNorm(float64) + Count() uint64 + Min() int + Size() int + + DocumentMatchPoolSize() int +} + +type SearcherOptions struct { + Explain bool + IncludeTermVectors bool + Score string +} + +// SearchContext represents the context around a single search +type SearchContext struct { + DocumentMatchPool *DocumentMatchPool + Collector Collector + IndexReader index.IndexReader +} + +func (sc *SearchContext) Size() int { + sizeInBytes := reflectStaticSizeSearchContext + size.SizeOfPtr + + reflectStaticSizeDocumentMatchPool + size.SizeOfPtr + + if sc.DocumentMatchPool != nil { + for _, entry := range sc.DocumentMatchPool.avail { + if entry != nil { + sizeInBytes += entry.Size() + } + } + } + + return sizeInBytes +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/ordered_searchers_list.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/ordered_searchers_list.go new file mode 100644 index 0000000000..f3e646e9da --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/ordered_searchers_list.go @@ -0,0 +1,35 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "github.com/blevesearch/bleve/v2/search" +) + +type OrderedSearcherList []search.Searcher + +// sort.Interface + +func (otrl OrderedSearcherList) Len() int { + return len(otrl) +} + +func (otrl OrderedSearcherList) Less(i, j int) bool { + return otrl[i].Count() < otrl[j].Count() +} + +func (otrl OrderedSearcherList) Swap(i, j int) { + otrl[i], otrl[j] = otrl[j], otrl[i] +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_boolean.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_boolean.go new file mode 100644 index 0000000000..bf207f8100 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_boolean.go @@ -0,0 +1,451 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "context" + "math" + "reflect" + + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/scorer" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeBooleanSearcher int + +func init() { + var bs BooleanSearcher + reflectStaticSizeBooleanSearcher = int(reflect.TypeOf(bs).Size()) +} + +type BooleanSearcher struct { + indexReader index.IndexReader + mustSearcher search.Searcher + shouldSearcher search.Searcher + mustNotSearcher search.Searcher + queryNorm float64 + currMust *search.DocumentMatch + currShould *search.DocumentMatch + currMustNot *search.DocumentMatch + currentID index.IndexInternalID + min uint64 + scorer *scorer.ConjunctionQueryScorer + matches []*search.DocumentMatch + initialized bool + done bool +} + +func NewBooleanSearcher(ctx context.Context, indexReader index.IndexReader, mustSearcher search.Searcher, shouldSearcher search.Searcher, mustNotSearcher search.Searcher, options search.SearcherOptions) (*BooleanSearcher, error) { + // build our searcher + rv := BooleanSearcher{ + indexReader: indexReader, + mustSearcher: mustSearcher, + shouldSearcher: shouldSearcher, + mustNotSearcher: mustNotSearcher, + scorer: scorer.NewConjunctionQueryScorer(options), + matches: make([]*search.DocumentMatch, 2), + } + rv.computeQueryNorm() + return &rv, nil +} + +func (s *BooleanSearcher) Size() int { + sizeInBytes := reflectStaticSizeBooleanSearcher + size.SizeOfPtr + + if s.mustSearcher != nil { + sizeInBytes += s.mustSearcher.Size() + } + + if s.shouldSearcher != nil { + sizeInBytes += s.shouldSearcher.Size() + } + + if s.mustNotSearcher != nil { + sizeInBytes += s.mustNotSearcher.Size() + } + + sizeInBytes += s.scorer.Size() + + for _, entry := range s.matches { + if entry != nil { + sizeInBytes += entry.Size() + } + } + + return sizeInBytes +} + +func (s *BooleanSearcher) computeQueryNorm() { + // first calculate sum of squared weights + sumOfSquaredWeights := 0.0 + if s.mustSearcher != nil { + sumOfSquaredWeights += s.mustSearcher.Weight() + } + if s.shouldSearcher != nil { + sumOfSquaredWeights += s.shouldSearcher.Weight() + } + + // now compute query norm from this + s.queryNorm = 1.0 / math.Sqrt(sumOfSquaredWeights) + // finally tell all the downstream searchers the norm + if s.mustSearcher != nil { + s.mustSearcher.SetQueryNorm(s.queryNorm) + } + if s.shouldSearcher != nil { + s.shouldSearcher.SetQueryNorm(s.queryNorm) + } +} + +func (s *BooleanSearcher) initSearchers(ctx *search.SearchContext) error { + var err error + // get all searchers pointing at their first match + if s.mustSearcher != nil { + if s.currMust != nil { + ctx.DocumentMatchPool.Put(s.currMust) + } + s.currMust, err = s.mustSearcher.Next(ctx) + if err != nil { + return err + } + } + + if s.shouldSearcher != nil { + if s.currShould != nil { + ctx.DocumentMatchPool.Put(s.currShould) + } + s.currShould, err = s.shouldSearcher.Next(ctx) + if err != nil { + return err + } + } + + if s.mustNotSearcher != nil { + if s.currMustNot != nil { + ctx.DocumentMatchPool.Put(s.currMustNot) + } + s.currMustNot, err = s.mustNotSearcher.Next(ctx) + if err != nil { + return err + } + } + + if s.mustSearcher != nil && s.currMust != nil { + s.currentID = s.currMust.IndexInternalID + } else if s.mustSearcher == nil && s.currShould != nil { + s.currentID = s.currShould.IndexInternalID + } else { + s.currentID = nil + } + + s.initialized = true + return nil +} + +func (s *BooleanSearcher) advanceNextMust(ctx *search.SearchContext, skipReturn *search.DocumentMatch) error { + var err error + + if s.mustSearcher != nil { + if s.currMust != skipReturn { + ctx.DocumentMatchPool.Put(s.currMust) + } + s.currMust, err = s.mustSearcher.Next(ctx) + if err != nil { + return err + } + } else { + if s.currShould != skipReturn { + ctx.DocumentMatchPool.Put(s.currShould) + } + s.currShould, err = s.shouldSearcher.Next(ctx) + if err != nil { + return err + } + } + + if s.mustSearcher != nil && s.currMust != nil { + s.currentID = s.currMust.IndexInternalID + } else if s.mustSearcher == nil && s.currShould != nil { + s.currentID = s.currShould.IndexInternalID + } else { + s.currentID = nil + } + return nil +} + +func (s *BooleanSearcher) Weight() float64 { + var rv float64 + if s.mustSearcher != nil { + rv += s.mustSearcher.Weight() + } + if s.shouldSearcher != nil { + rv += s.shouldSearcher.Weight() + } + + return rv +} + +func (s *BooleanSearcher) SetQueryNorm(qnorm float64) { + if s.mustSearcher != nil { + s.mustSearcher.SetQueryNorm(qnorm) + } + if s.shouldSearcher != nil { + s.shouldSearcher.SetQueryNorm(qnorm) + } +} + +func (s *BooleanSearcher) Next(ctx *search.SearchContext) (*search.DocumentMatch, error) { + + if s.done { + return nil, nil + } + + if !s.initialized { + err := s.initSearchers(ctx) + if err != nil { + return nil, err + } + } + + var err error + var rv *search.DocumentMatch + + for s.currentID != nil { + if s.currMustNot != nil { + cmp := s.currMustNot.IndexInternalID.Compare(s.currentID) + if cmp < 0 { + ctx.DocumentMatchPool.Put(s.currMustNot) + // advance must not searcher to our candidate entry + s.currMustNot, err = s.mustNotSearcher.Advance(ctx, s.currentID) + if err != nil { + return nil, err + } + if s.currMustNot != nil && s.currMustNot.IndexInternalID.Equals(s.currentID) { + // the candidate is excluded + err = s.advanceNextMust(ctx, nil) + if err != nil { + return nil, err + } + continue + } + } else if cmp == 0 { + // the candidate is excluded + err = s.advanceNextMust(ctx, nil) + if err != nil { + return nil, err + } + continue + } + } + + shouldCmpOrNil := 1 // NOTE: shouldCmp will also be 1 when currShould == nil. + if s.currShould != nil { + shouldCmpOrNil = s.currShould.IndexInternalID.Compare(s.currentID) + } + + if shouldCmpOrNil < 0 { + ctx.DocumentMatchPool.Put(s.currShould) + // advance should searcher to our candidate entry + s.currShould, err = s.shouldSearcher.Advance(ctx, s.currentID) + if err != nil { + return nil, err + } + if s.currShould != nil && s.currShould.IndexInternalID.Equals(s.currentID) { + // score bonus matches should + var cons []*search.DocumentMatch + if s.currMust != nil { + cons = s.matches + cons[0] = s.currMust + cons[1] = s.currShould + } else { + cons = s.matches[0:1] + cons[0] = s.currShould + } + rv = s.scorer.Score(ctx, cons) + err = s.advanceNextMust(ctx, rv) + if err != nil { + return nil, err + } + break + } else if s.shouldSearcher.Min() == 0 { + // match is OK anyway + cons := s.matches[0:1] + cons[0] = s.currMust + rv = s.scorer.Score(ctx, cons) + err = s.advanceNextMust(ctx, rv) + if err != nil { + return nil, err + } + break + } + } else if shouldCmpOrNil == 0 { + // score bonus matches should + var cons []*search.DocumentMatch + if s.currMust != nil { + cons = s.matches + cons[0] = s.currMust + cons[1] = s.currShould + } else { + cons = s.matches[0:1] + cons[0] = s.currShould + } + rv = s.scorer.Score(ctx, cons) + err = s.advanceNextMust(ctx, rv) + if err != nil { + return nil, err + } + break + } else if s.shouldSearcher == nil || s.shouldSearcher.Min() == 0 { + // match is OK anyway + cons := s.matches[0:1] + cons[0] = s.currMust + rv = s.scorer.Score(ctx, cons) + err = s.advanceNextMust(ctx, rv) + if err != nil { + return nil, err + } + break + } + + err = s.advanceNextMust(ctx, nil) + if err != nil { + return nil, err + } + } + + if rv == nil { + s.done = true + } + + return rv, nil +} + +func (s *BooleanSearcher) Advance(ctx *search.SearchContext, ID index.IndexInternalID) (*search.DocumentMatch, error) { + + if s.done { + return nil, nil + } + + if !s.initialized { + err := s.initSearchers(ctx) + if err != nil { + return nil, err + } + } + + // Advance the searcher only if the cursor is trailing the lookup ID + if s.currentID == nil || s.currentID.Compare(ID) < 0 { + var err error + if s.mustSearcher != nil { + if s.currMust != nil { + ctx.DocumentMatchPool.Put(s.currMust) + } + s.currMust, err = s.mustSearcher.Advance(ctx, ID) + if err != nil { + return nil, err + } + } + + if s.shouldSearcher != nil { + if s.currShould != nil { + ctx.DocumentMatchPool.Put(s.currShould) + } + s.currShould, err = s.shouldSearcher.Advance(ctx, ID) + if err != nil { + return nil, err + } + } + + if s.mustNotSearcher != nil { + // Additional check for mustNotSearcher, whose cursor isn't tracked by + // currentID to prevent it from moving when the searcher's tracked + // position is already ahead of or at the requested ID. + if s.currMustNot == nil || s.currMustNot.IndexInternalID.Compare(ID) < 0 { + if s.currMustNot != nil { + ctx.DocumentMatchPool.Put(s.currMustNot) + } + s.currMustNot, err = s.mustNotSearcher.Advance(ctx, ID) + if err != nil { + return nil, err + } + } + } + + if s.mustSearcher != nil && s.currMust != nil { + s.currentID = s.currMust.IndexInternalID + } else if s.mustSearcher == nil && s.currShould != nil { + s.currentID = s.currShould.IndexInternalID + } else { + s.currentID = nil + } + } + + return s.Next(ctx) +} + +func (s *BooleanSearcher) Count() uint64 { + + // for now return a worst case + var sum uint64 + if s.mustSearcher != nil { + sum += s.mustSearcher.Count() + } + if s.shouldSearcher != nil { + sum += s.shouldSearcher.Count() + } + return sum +} + +func (s *BooleanSearcher) Close() error { + var err0, err1, err2 error + if s.mustSearcher != nil { + err0 = s.mustSearcher.Close() + } + if s.shouldSearcher != nil { + err1 = s.shouldSearcher.Close() + } + if s.mustNotSearcher != nil { + err2 = s.mustNotSearcher.Close() + } + if err0 != nil { + return err0 + } + if err1 != nil { + return err1 + } + if err2 != nil { + return err2 + } + return nil +} + +func (s *BooleanSearcher) Min() int { + return 0 +} + +func (s *BooleanSearcher) DocumentMatchPoolSize() int { + rv := 3 + if s.mustSearcher != nil { + rv += s.mustSearcher.DocumentMatchPoolSize() + } + if s.shouldSearcher != nil { + rv += s.shouldSearcher.DocumentMatchPoolSize() + } + if s.mustNotSearcher != nil { + rv += s.mustNotSearcher.DocumentMatchPoolSize() + } + return rv +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_conjunction.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_conjunction.go new file mode 100644 index 0000000000..19ef199ac4 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_conjunction.go @@ -0,0 +1,286 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "context" + "math" + "reflect" + "sort" + + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/scorer" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeConjunctionSearcher int + +func init() { + var cs ConjunctionSearcher + reflectStaticSizeConjunctionSearcher = int(reflect.TypeOf(cs).Size()) +} + +type ConjunctionSearcher struct { + indexReader index.IndexReader + searchers OrderedSearcherList + queryNorm float64 + currs []*search.DocumentMatch + maxIDIdx int + scorer *scorer.ConjunctionQueryScorer + initialized bool + options search.SearcherOptions + bytesRead uint64 +} + +func NewConjunctionSearcher(ctx context.Context, indexReader index.IndexReader, + qsearchers []search.Searcher, options search.SearcherOptions) ( + search.Searcher, error) { + // build the sorted downstream searchers + searchers := make(OrderedSearcherList, len(qsearchers)) + for i, searcher := range qsearchers { + searchers[i] = searcher + } + sort.Sort(searchers) + + // attempt the "unadorned" conjunction optimization only when we + // do not need extra information like freq-norm's or term vectors + if len(searchers) > 1 && + options.Score == "none" && !options.IncludeTermVectors { + rv, err := optimizeCompositeSearcher(ctx, "conjunction:unadorned", + indexReader, searchers, options) + if err != nil || rv != nil { + return rv, err + } + } + + // build our searcher + rv := ConjunctionSearcher{ + indexReader: indexReader, + options: options, + searchers: searchers, + currs: make([]*search.DocumentMatch, len(searchers)), + scorer: scorer.NewConjunctionQueryScorer(options), + } + rv.computeQueryNorm() + + // attempt push-down conjunction optimization when there's >1 searchers + if len(searchers) > 1 { + rv, err := optimizeCompositeSearcher(ctx, "conjunction", + indexReader, searchers, options) + if err != nil || rv != nil { + return rv, err + } + } + + return &rv, nil +} + +func (s *ConjunctionSearcher) Size() int { + sizeInBytes := reflectStaticSizeConjunctionSearcher + size.SizeOfPtr + + s.scorer.Size() + + for _, entry := range s.searchers { + sizeInBytes += entry.Size() + } + + for _, entry := range s.currs { + if entry != nil { + sizeInBytes += entry.Size() + } + } + + return sizeInBytes +} + +func (s *ConjunctionSearcher) computeQueryNorm() { + // first calculate sum of squared weights + sumOfSquaredWeights := 0.0 + for _, searcher := range s.searchers { + sumOfSquaredWeights += searcher.Weight() + } + // now compute query norm from this + s.queryNorm = 1.0 / math.Sqrt(sumOfSquaredWeights) + // finally tell all the downstream searchers the norm + for _, searcher := range s.searchers { + searcher.SetQueryNorm(s.queryNorm) + } +} + +func (s *ConjunctionSearcher) initSearchers(ctx *search.SearchContext) error { + var err error + // get all searchers pointing at their first match + for i, searcher := range s.searchers { + if s.currs[i] != nil { + ctx.DocumentMatchPool.Put(s.currs[i]) + } + s.currs[i], err = searcher.Next(ctx) + if err != nil { + return err + } + } + s.initialized = true + return nil +} + +func (s *ConjunctionSearcher) Weight() float64 { + var rv float64 + for _, searcher := range s.searchers { + rv += searcher.Weight() + } + return rv +} + +func (s *ConjunctionSearcher) SetQueryNorm(qnorm float64) { + for _, searcher := range s.searchers { + searcher.SetQueryNorm(qnorm) + } +} + +func (s *ConjunctionSearcher) Next(ctx *search.SearchContext) (*search.DocumentMatch, error) { + if !s.initialized { + err := s.initSearchers(ctx) + if err != nil { + return nil, err + } + } + var rv *search.DocumentMatch + var err error +OUTER: + for s.maxIDIdx < len(s.currs) && s.currs[s.maxIDIdx] != nil { + maxID := s.currs[s.maxIDIdx].IndexInternalID + + i := 0 + for i < len(s.currs) { + if s.currs[i] == nil { + return nil, nil + } + + if i == s.maxIDIdx { + i++ + continue + } + + cmp := maxID.Compare(s.currs[i].IndexInternalID) + if cmp == 0 { + i++ + continue + } + + if cmp < 0 { + // maxID < currs[i], so we found a new maxIDIdx + s.maxIDIdx = i + + // advance the positions where [0 <= x < i], since we + // know they were equal to the former max entry + maxID = s.currs[s.maxIDIdx].IndexInternalID + for x := 0; x < i; x++ { + err = s.advanceChild(ctx, x, maxID) + if err != nil { + return nil, err + } + } + + continue OUTER + } + + // maxID > currs[i], so need to advance searchers[i] + err = s.advanceChild(ctx, i, maxID) + if err != nil { + return nil, err + } + + // don't bump i, so that we'll examine the just-advanced + // currs[i] again + } + + // if we get here, a doc matched all readers, so score and add it + rv = s.scorer.Score(ctx, s.currs) + + // we know all the searchers are pointing at the same thing + // so they all need to be bumped + for i, searcher := range s.searchers { + if s.currs[i] != rv { + ctx.DocumentMatchPool.Put(s.currs[i]) + } + s.currs[i], err = searcher.Next(ctx) + if err != nil { + return nil, err + } + } + + // don't continue now, wait for the next call to Next() + break + } + return rv, nil +} + +func (s *ConjunctionSearcher) Advance(ctx *search.SearchContext, ID index.IndexInternalID) (*search.DocumentMatch, error) { + if !s.initialized { + err := s.initSearchers(ctx) + if err != nil { + return nil, err + } + } + for i := range s.searchers { + if s.currs[i] != nil && s.currs[i].IndexInternalID.Compare(ID) >= 0 { + continue + } + err := s.advanceChild(ctx, i, ID) + if err != nil { + return nil, err + } + } + return s.Next(ctx) +} + +func (s *ConjunctionSearcher) advanceChild(ctx *search.SearchContext, i int, ID index.IndexInternalID) (err error) { + if s.currs[i] != nil { + ctx.DocumentMatchPool.Put(s.currs[i]) + } + s.currs[i], err = s.searchers[i].Advance(ctx, ID) + return err +} + +func (s *ConjunctionSearcher) Count() uint64 { + // for now return a worst case + var sum uint64 + for _, searcher := range s.searchers { + sum += searcher.Count() + } + return sum +} + +func (s *ConjunctionSearcher) Close() (rv error) { + for _, searcher := range s.searchers { + err := searcher.Close() + if err != nil && rv == nil { + rv = err + } + } + return rv +} + +func (s *ConjunctionSearcher) Min() int { + return 0 +} + +func (s *ConjunctionSearcher) DocumentMatchPoolSize() int { + rv := len(s.currs) + for _, s := range s.searchers { + rv += s.DocumentMatchPoolSize() + } + return rv +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_disjunction.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_disjunction.go new file mode 100644 index 0000000000..606a157aed --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_disjunction.go @@ -0,0 +1,115 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "context" + "fmt" + + "github.com/blevesearch/bleve/v2/search" + index "github.com/blevesearch/bleve_index_api" +) + +// DisjunctionMaxClauseCount is a compile time setting that applications can +// adjust to non-zero value to cause the DisjunctionSearcher to return an +// error instead of exeucting searches when the size exceeds this value. +var DisjunctionMaxClauseCount = 0 + +// DisjunctionHeapTakeover is a compile time setting that applications can +// adjust to control when the DisjunctionSearcher will switch from a simple +// slice implementation to a heap implementation. +var DisjunctionHeapTakeover = 10 + +func NewDisjunctionSearcher(ctx context.Context, indexReader index.IndexReader, + qsearchers []search.Searcher, min float64, options search.SearcherOptions) ( + search.Searcher, error) { + return newDisjunctionSearcher(ctx, indexReader, qsearchers, min, options, true) +} + +func optionsDisjunctionOptimizable(options search.SearcherOptions) bool { + rv := options.Score == "none" && !options.IncludeTermVectors + return rv +} + +func newDisjunctionSearcher(ctx context.Context, indexReader index.IndexReader, + qsearchers []search.Searcher, min float64, options search.SearcherOptions, + limit bool) (search.Searcher, error) { + // attempt the "unadorned" disjunction optimization only when we + // do not need extra information like freq-norm's or term vectors + // and the requested min is simple + if len(qsearchers) > 1 && min <= 1 && + optionsDisjunctionOptimizable(options) { + rv, err := optimizeCompositeSearcher(ctx, "disjunction:unadorned", + indexReader, qsearchers, options) + if err != nil || rv != nil { + return rv, err + } + } + + if len(qsearchers) > DisjunctionHeapTakeover { + return newDisjunctionHeapSearcher(ctx, indexReader, qsearchers, min, options, + limit) + } + return newDisjunctionSliceSearcher(ctx, indexReader, qsearchers, min, options, + limit) +} + +func optimizeCompositeSearcher(ctx context.Context, optimizationKind string, + indexReader index.IndexReader, qsearchers []search.Searcher, + options search.SearcherOptions) (search.Searcher, error) { + var octx index.OptimizableContext + + for _, searcher := range qsearchers { + o, ok := searcher.(index.Optimizable) + if !ok { + return nil, nil + } + + var err error + octx, err = o.Optimize(optimizationKind, octx) + if err != nil { + return nil, err + } + + if octx == nil { + return nil, nil + } + } + + optimized, err := octx.Finish() + if err != nil || optimized == nil { + return nil, err + } + + tfr, ok := optimized.(index.TermFieldReader) + if !ok { + return nil, nil + } + + return newTermSearcherFromReader(indexReader, tfr, + []byte(optimizationKind), "*", 1.0, options) +} + +func tooManyClauses(count int) bool { + if DisjunctionMaxClauseCount != 0 && count > DisjunctionMaxClauseCount { + return true + } + return false +} + +func tooManyClausesErr(field string, count int) error { + return fmt.Errorf("TooManyClauses over field: `%s` [%d > maxClauseCount,"+ + " which is set to %d]", field, count, DisjunctionMaxClauseCount) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_disjunction_heap.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_disjunction_heap.go new file mode 100644 index 0000000000..0235838325 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_disjunction_heap.go @@ -0,0 +1,346 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "bytes" + "container/heap" + "context" + "math" + "reflect" + + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/scorer" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeDisjunctionHeapSearcher int +var reflectStaticSizeSearcherCurr int + +func init() { + var dhs DisjunctionHeapSearcher + reflectStaticSizeDisjunctionHeapSearcher = int(reflect.TypeOf(dhs).Size()) + + var sc SearcherCurr + reflectStaticSizeSearcherCurr = int(reflect.TypeOf(sc).Size()) +} + +type SearcherCurr struct { + searcher search.Searcher + curr *search.DocumentMatch +} + +type DisjunctionHeapSearcher struct { + indexReader index.IndexReader + + numSearchers int + scorer *scorer.DisjunctionQueryScorer + min int + queryNorm float64 + initialized bool + searchers []search.Searcher + heap []*SearcherCurr + + matching []*search.DocumentMatch + matchingCurrs []*SearcherCurr + + bytesRead uint64 +} + +func newDisjunctionHeapSearcher(ctx context.Context, indexReader index.IndexReader, + searchers []search.Searcher, min float64, options search.SearcherOptions, + limit bool) ( + *DisjunctionHeapSearcher, error) { + if limit && tooManyClauses(len(searchers)) { + return nil, tooManyClausesErr("", len(searchers)) + } + + // build our searcher + rv := DisjunctionHeapSearcher{ + indexReader: indexReader, + searchers: searchers, + numSearchers: len(searchers), + scorer: scorer.NewDisjunctionQueryScorer(options), + min: int(min), + matching: make([]*search.DocumentMatch, len(searchers)), + matchingCurrs: make([]*SearcherCurr, len(searchers)), + heap: make([]*SearcherCurr, 0, len(searchers)), + } + rv.computeQueryNorm() + return &rv, nil +} + +func (s *DisjunctionHeapSearcher) Size() int { + sizeInBytes := reflectStaticSizeDisjunctionHeapSearcher + size.SizeOfPtr + + s.scorer.Size() + + for _, entry := range s.searchers { + sizeInBytes += entry.Size() + } + + for _, entry := range s.matching { + if entry != nil { + sizeInBytes += entry.Size() + } + } + + // for matchingCurrs and heap, just use static size * len + // since searchers and document matches already counted above + sizeInBytes += len(s.matchingCurrs) * reflectStaticSizeSearcherCurr + sizeInBytes += len(s.heap) * reflectStaticSizeSearcherCurr + + return sizeInBytes +} + +func (s *DisjunctionHeapSearcher) computeQueryNorm() { + // first calculate sum of squared weights + sumOfSquaredWeights := 0.0 + for _, searcher := range s.searchers { + sumOfSquaredWeights += searcher.Weight() + } + // now compute query norm from this + s.queryNorm = 1.0 / math.Sqrt(sumOfSquaredWeights) + // finally tell all the downstream searchers the norm + for _, searcher := range s.searchers { + searcher.SetQueryNorm(s.queryNorm) + } +} + +func (s *DisjunctionHeapSearcher) initSearchers(ctx *search.SearchContext) error { + // alloc a single block of SearcherCurrs + block := make([]SearcherCurr, len(s.searchers)) + + // get all searchers pointing at their first match + for i, searcher := range s.searchers { + curr, err := searcher.Next(ctx) + if err != nil { + return err + } + if curr != nil { + block[i].searcher = searcher + block[i].curr = curr + heap.Push(s, &block[i]) + } + } + + err := s.updateMatches() + if err != nil { + return err + } + s.initialized = true + return nil +} + +func (s *DisjunctionHeapSearcher) updateMatches() error { + matching := s.matching[:0] + matchingCurrs := s.matchingCurrs[:0] + + if len(s.heap) > 0 { + + // top of the heap is our next hit + next := heap.Pop(s).(*SearcherCurr) + matching = append(matching, next.curr) + matchingCurrs = append(matchingCurrs, next) + + // now as long as top of heap matches, keep popping + for len(s.heap) > 0 && bytes.Compare(next.curr.IndexInternalID, s.heap[0].curr.IndexInternalID) == 0 { + next = heap.Pop(s).(*SearcherCurr) + matching = append(matching, next.curr) + matchingCurrs = append(matchingCurrs, next) + } + } + + s.matching = matching + s.matchingCurrs = matchingCurrs + + return nil +} + +func (s *DisjunctionHeapSearcher) Weight() float64 { + var rv float64 + for _, searcher := range s.searchers { + rv += searcher.Weight() + } + return rv +} + +func (s *DisjunctionHeapSearcher) SetQueryNorm(qnorm float64) { + for _, searcher := range s.searchers { + searcher.SetQueryNorm(qnorm) + } +} + +func (s *DisjunctionHeapSearcher) Next(ctx *search.SearchContext) ( + *search.DocumentMatch, error) { + if !s.initialized { + err := s.initSearchers(ctx) + if err != nil { + return nil, err + } + } + + var rv *search.DocumentMatch + found := false + for !found && len(s.matching) > 0 { + if len(s.matching) >= s.min { + found = true + // score this match + rv = s.scorer.Score(ctx, s.matching, len(s.matching), s.numSearchers) + } + + // invoke next on all the matching searchers + for _, matchingCurr := range s.matchingCurrs { + if matchingCurr.curr != rv { + ctx.DocumentMatchPool.Put(matchingCurr.curr) + } + curr, err := matchingCurr.searcher.Next(ctx) + if err != nil { + return nil, err + } + if curr != nil { + matchingCurr.curr = curr + heap.Push(s, matchingCurr) + } + } + + err := s.updateMatches() + if err != nil { + return nil, err + } + } + + return rv, nil +} + +func (s *DisjunctionHeapSearcher) Advance(ctx *search.SearchContext, + ID index.IndexInternalID) (*search.DocumentMatch, error) { + if !s.initialized { + err := s.initSearchers(ctx) + if err != nil { + return nil, err + } + } + + // if there is anything in matching, toss it back onto the heap + for _, matchingCurr := range s.matchingCurrs { + heap.Push(s, matchingCurr) + } + s.matching = s.matching[:0] + s.matchingCurrs = s.matchingCurrs[:0] + + // find all searchers that actually need to be advanced + // advance them, using s.matchingCurrs as temp storage + for len(s.heap) > 0 && bytes.Compare(s.heap[0].curr.IndexInternalID, ID) < 0 { + searcherCurr := heap.Pop(s).(*SearcherCurr) + ctx.DocumentMatchPool.Put(searcherCurr.curr) + curr, err := searcherCurr.searcher.Advance(ctx, ID) + if err != nil { + return nil, err + } + if curr != nil { + searcherCurr.curr = curr + s.matchingCurrs = append(s.matchingCurrs, searcherCurr) + } + } + // now all of the searchers that we advanced have to be pushed back + for _, matchingCurr := range s.matchingCurrs { + heap.Push(s, matchingCurr) + } + // reset our temp space + s.matchingCurrs = s.matchingCurrs[:0] + + err := s.updateMatches() + if err != nil { + return nil, err + } + + return s.Next(ctx) +} + +func (s *DisjunctionHeapSearcher) Count() uint64 { + // for now return a worst case + var sum uint64 + for _, searcher := range s.searchers { + sum += searcher.Count() + } + return sum +} + +func (s *DisjunctionHeapSearcher) Close() (rv error) { + for _, searcher := range s.searchers { + err := searcher.Close() + if err != nil && rv == nil { + rv = err + } + } + return rv +} + +func (s *DisjunctionHeapSearcher) Min() int { + return s.min +} + +func (s *DisjunctionHeapSearcher) DocumentMatchPoolSize() int { + rv := len(s.searchers) + for _, s := range s.searchers { + rv += s.DocumentMatchPoolSize() + } + return rv +} + +// a disjunction searcher implements the index.Optimizable interface +// but only activates on an edge case where the disjunction is a +// wrapper around a single Optimizable child searcher +func (s *DisjunctionHeapSearcher) Optimize(kind string, octx index.OptimizableContext) ( + index.OptimizableContext, error) { + if len(s.searchers) == 1 { + o, ok := s.searchers[0].(index.Optimizable) + if ok { + return o.Optimize(kind, octx) + } + } + + return nil, nil +} + +// heap impl + +func (s *DisjunctionHeapSearcher) Len() int { return len(s.heap) } + +func (s *DisjunctionHeapSearcher) Less(i, j int) bool { + if s.heap[i].curr == nil { + return true + } else if s.heap[j].curr == nil { + return false + } + return bytes.Compare(s.heap[i].curr.IndexInternalID, s.heap[j].curr.IndexInternalID) < 0 +} + +func (s *DisjunctionHeapSearcher) Swap(i, j int) { + s.heap[i], s.heap[j] = s.heap[j], s.heap[i] +} + +func (s *DisjunctionHeapSearcher) Push(x interface{}) { + s.heap = append(s.heap, x.(*SearcherCurr)) +} + +func (s *DisjunctionHeapSearcher) Pop() interface{} { + old := s.heap + n := len(old) + x := old[n-1] + s.heap = old[0 : n-1] + return x +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_disjunction_slice.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_disjunction_slice.go new file mode 100644 index 0000000000..6958cf492f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_disjunction_slice.go @@ -0,0 +1,299 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "context" + "math" + "reflect" + "sort" + + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/scorer" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeDisjunctionSliceSearcher int + +func init() { + var ds DisjunctionSliceSearcher + reflectStaticSizeDisjunctionSliceSearcher = int(reflect.TypeOf(ds).Size()) +} + +type DisjunctionSliceSearcher struct { + indexReader index.IndexReader + searchers OrderedSearcherList + numSearchers int + queryNorm float64 + currs []*search.DocumentMatch + scorer *scorer.DisjunctionQueryScorer + min int + matching []*search.DocumentMatch + matchingIdxs []int + initialized bool + bytesRead uint64 +} + +func newDisjunctionSliceSearcher(ctx context.Context, indexReader index.IndexReader, + qsearchers []search.Searcher, min float64, options search.SearcherOptions, + limit bool) ( + *DisjunctionSliceSearcher, error) { + if limit && tooManyClauses(len(qsearchers)) { + return nil, tooManyClausesErr("", len(qsearchers)) + } + // build the downstream searchers + searchers := make(OrderedSearcherList, len(qsearchers)) + for i, searcher := range qsearchers { + searchers[i] = searcher + } + // sort the searchers + sort.Sort(sort.Reverse(searchers)) + // build our searcher + rv := DisjunctionSliceSearcher{ + indexReader: indexReader, + searchers: searchers, + numSearchers: len(searchers), + currs: make([]*search.DocumentMatch, len(searchers)), + scorer: scorer.NewDisjunctionQueryScorer(options), + min: int(min), + matching: make([]*search.DocumentMatch, len(searchers)), + matchingIdxs: make([]int, len(searchers)), + } + rv.computeQueryNorm() + return &rv, nil +} + +func (s *DisjunctionSliceSearcher) Size() int { + sizeInBytes := reflectStaticSizeDisjunctionSliceSearcher + size.SizeOfPtr + + s.scorer.Size() + + for _, entry := range s.searchers { + sizeInBytes += entry.Size() + } + + for _, entry := range s.currs { + if entry != nil { + sizeInBytes += entry.Size() + } + } + + for _, entry := range s.matching { + if entry != nil { + sizeInBytes += entry.Size() + } + } + + sizeInBytes += len(s.matchingIdxs) * size.SizeOfInt + + return sizeInBytes +} + +func (s *DisjunctionSliceSearcher) computeQueryNorm() { + // first calculate sum of squared weights + sumOfSquaredWeights := 0.0 + for _, searcher := range s.searchers { + sumOfSquaredWeights += searcher.Weight() + } + // now compute query norm from this + s.queryNorm = 1.0 / math.Sqrt(sumOfSquaredWeights) + // finally tell all the downstream searchers the norm + for _, searcher := range s.searchers { + searcher.SetQueryNorm(s.queryNorm) + } +} + +func (s *DisjunctionSliceSearcher) initSearchers(ctx *search.SearchContext) error { + var err error + // get all searchers pointing at their first match + for i, searcher := range s.searchers { + if s.currs[i] != nil { + ctx.DocumentMatchPool.Put(s.currs[i]) + } + s.currs[i], err = searcher.Next(ctx) + if err != nil { + return err + } + } + + err = s.updateMatches() + if err != nil { + return err + } + + s.initialized = true + return nil +} + +func (s *DisjunctionSliceSearcher) updateMatches() error { + matching := s.matching[:0] + matchingIdxs := s.matchingIdxs[:0] + + for i := 0; i < len(s.currs); i++ { + curr := s.currs[i] + if curr == nil { + continue + } + + if len(matching) > 0 { + cmp := curr.IndexInternalID.Compare(matching[0].IndexInternalID) + if cmp > 0 { + continue + } + + if cmp < 0 { + matching = matching[:0] + matchingIdxs = matchingIdxs[:0] + } + } + matching = append(matching, curr) + matchingIdxs = append(matchingIdxs, i) + } + + s.matching = matching + s.matchingIdxs = matchingIdxs + + return nil +} + +func (s *DisjunctionSliceSearcher) Weight() float64 { + var rv float64 + for _, searcher := range s.searchers { + rv += searcher.Weight() + } + return rv +} + +func (s *DisjunctionSliceSearcher) SetQueryNorm(qnorm float64) { + for _, searcher := range s.searchers { + searcher.SetQueryNorm(qnorm) + } +} + +func (s *DisjunctionSliceSearcher) Next(ctx *search.SearchContext) ( + *search.DocumentMatch, error) { + if !s.initialized { + err := s.initSearchers(ctx) + if err != nil { + return nil, err + } + } + var err error + var rv *search.DocumentMatch + + found := false + for !found && len(s.matching) > 0 { + if len(s.matching) >= s.min { + found = true + // score this match + rv = s.scorer.Score(ctx, s.matching, len(s.matching), s.numSearchers) + } + + // invoke next on all the matching searchers + for _, i := range s.matchingIdxs { + searcher := s.searchers[i] + if s.currs[i] != rv { + ctx.DocumentMatchPool.Put(s.currs[i]) + } + s.currs[i], err = searcher.Next(ctx) + if err != nil { + return nil, err + } + } + + err = s.updateMatches() + if err != nil { + return nil, err + } + } + return rv, nil +} + +func (s *DisjunctionSliceSearcher) Advance(ctx *search.SearchContext, + ID index.IndexInternalID) (*search.DocumentMatch, error) { + if !s.initialized { + err := s.initSearchers(ctx) + if err != nil { + return nil, err + } + } + // get all searchers pointing at their first match + var err error + for i, searcher := range s.searchers { + if s.currs[i] != nil { + if s.currs[i].IndexInternalID.Compare(ID) >= 0 { + continue + } + ctx.DocumentMatchPool.Put(s.currs[i]) + } + s.currs[i], err = searcher.Advance(ctx, ID) + if err != nil { + return nil, err + } + } + + err = s.updateMatches() + if err != nil { + return nil, err + } + + return s.Next(ctx) +} + +func (s *DisjunctionSliceSearcher) Count() uint64 { + // for now return a worst case + var sum uint64 + for _, searcher := range s.searchers { + sum += searcher.Count() + } + return sum +} + +func (s *DisjunctionSliceSearcher) Close() (rv error) { + for _, searcher := range s.searchers { + err := searcher.Close() + if err != nil && rv == nil { + rv = err + } + } + return rv +} + +func (s *DisjunctionSliceSearcher) Min() int { + return s.min +} + +func (s *DisjunctionSliceSearcher) DocumentMatchPoolSize() int { + rv := len(s.currs) + for _, s := range s.searchers { + rv += s.DocumentMatchPoolSize() + } + return rv +} + +// a disjunction searcher implements the index.Optimizable interface +// but only activates on an edge case where the disjunction is a +// wrapper around a single Optimizable child searcher +func (s *DisjunctionSliceSearcher) Optimize(kind string, octx index.OptimizableContext) ( + index.OptimizableContext, error) { + if len(s.searchers) == 1 { + o, ok := s.searchers[0].(index.Optimizable) + if ok { + return o.Optimize(kind, octx) + } + } + + return nil, nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_docid.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_docid.go new file mode 100644 index 0000000000..720fd32330 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_docid.go @@ -0,0 +1,110 @@ +// Copyright (c) 2015 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "context" + "reflect" + + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/scorer" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeDocIDSearcher int + +func init() { + var ds DocIDSearcher + reflectStaticSizeDocIDSearcher = int(reflect.TypeOf(ds).Size()) +} + +// DocIDSearcher returns documents matching a predefined set of identifiers. +type DocIDSearcher struct { + reader index.DocIDReader + scorer *scorer.ConstantScorer + count int +} + +func NewDocIDSearcher(ctx context.Context, indexReader index.IndexReader, ids []string, boost float64, + options search.SearcherOptions) (searcher *DocIDSearcher, err error) { + + reader, err := indexReader.DocIDReaderOnly(ids) + if err != nil { + return nil, err + } + scorer := scorer.NewConstantScorer(1.0, boost, options) + return &DocIDSearcher{ + scorer: scorer, + reader: reader, + count: len(ids), + }, nil +} + +func (s *DocIDSearcher) Size() int { + return reflectStaticSizeDocIDSearcher + size.SizeOfPtr + + s.reader.Size() + + s.scorer.Size() +} + +func (s *DocIDSearcher) Count() uint64 { + return uint64(s.count) +} + +func (s *DocIDSearcher) Weight() float64 { + return s.scorer.Weight() +} + +func (s *DocIDSearcher) SetQueryNorm(qnorm float64) { + s.scorer.SetQueryNorm(qnorm) +} + +func (s *DocIDSearcher) Next(ctx *search.SearchContext) (*search.DocumentMatch, error) { + docidMatch, err := s.reader.Next() + if err != nil { + return nil, err + } + if docidMatch == nil { + return nil, nil + } + + docMatch := s.scorer.Score(ctx, docidMatch) + return docMatch, nil +} + +func (s *DocIDSearcher) Advance(ctx *search.SearchContext, ID index.IndexInternalID) (*search.DocumentMatch, error) { + docidMatch, err := s.reader.Advance(ID) + if err != nil { + return nil, err + } + if docidMatch == nil { + return nil, nil + } + + docMatch := s.scorer.Score(ctx, docidMatch) + return docMatch, nil +} + +func (s *DocIDSearcher) Close() error { + return s.reader.Close() +} + +func (s *DocIDSearcher) Min() int { + return 0 +} + +func (s *DocIDSearcher) DocumentMatchPoolSize() int { + return 1 +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_filter.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_filter.go new file mode 100644 index 0000000000..4e4dd5eae0 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_filter.go @@ -0,0 +1,104 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "context" + "reflect" + + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeFilteringSearcher int + +func init() { + var fs FilteringSearcher + reflectStaticSizeFilteringSearcher = int(reflect.TypeOf(fs).Size()) +} + +// FilterFunc defines a function which can filter documents +// returning true means keep the document +// returning false means do not keep the document +type FilterFunc func(d *search.DocumentMatch) bool + +// FilteringSearcher wraps any other searcher, but checks any Next/Advance +// call against the supplied FilterFunc +type FilteringSearcher struct { + child search.Searcher + accept FilterFunc +} + +func NewFilteringSearcher(ctx context.Context, s search.Searcher, filter FilterFunc) *FilteringSearcher { + return &FilteringSearcher{ + child: s, + accept: filter, + } +} + +func (f *FilteringSearcher) Size() int { + return reflectStaticSizeFilteringSearcher + size.SizeOfPtr + + f.child.Size() +} + +func (f *FilteringSearcher) Next(ctx *search.SearchContext) (*search.DocumentMatch, error) { + next, err := f.child.Next(ctx) + for next != nil && err == nil { + if f.accept(next) { + return next, nil + } + next, err = f.child.Next(ctx) + } + return nil, err +} + +func (f *FilteringSearcher) Advance(ctx *search.SearchContext, ID index.IndexInternalID) (*search.DocumentMatch, error) { + adv, err := f.child.Advance(ctx, ID) + if err != nil { + return nil, err + } + if adv == nil { + return nil, nil + } + if f.accept(adv) { + return adv, nil + } + return f.Next(ctx) +} + +func (f *FilteringSearcher) Close() error { + return f.child.Close() +} + +func (f *FilteringSearcher) Weight() float64 { + return f.child.Weight() +} + +func (f *FilteringSearcher) SetQueryNorm(n float64) { + f.child.SetQueryNorm(n) +} + +func (f *FilteringSearcher) Count() uint64 { + return f.child.Count() +} + +func (f *FilteringSearcher) Min() int { + return f.child.Min() +} + +func (f *FilteringSearcher) DocumentMatchPoolSize() int { + return f.child.DocumentMatchPoolSize() +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_fuzzy.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_fuzzy.go new file mode 100644 index 0000000000..9423b611e6 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_fuzzy.go @@ -0,0 +1,149 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "context" + "fmt" + + "github.com/blevesearch/bleve/v2/search" + index "github.com/blevesearch/bleve_index_api" +) + +var MaxFuzziness = 2 + +func NewFuzzySearcher(ctx context.Context, indexReader index.IndexReader, term string, + prefix, fuzziness int, field string, boost float64, + options search.SearcherOptions) (search.Searcher, error) { + + if fuzziness > MaxFuzziness { + return nil, fmt.Errorf("fuzziness exceeds max (%d)", MaxFuzziness) + } + + if fuzziness < 0 { + return nil, fmt.Errorf("invalid fuzziness, negative") + } + + // Note: we don't byte slice the term for a prefix because of runes. + prefixTerm := "" + for i, r := range term { + if i < prefix { + prefixTerm += string(r) + } else { + break + } + } + fuzzyCandidates, err := findFuzzyCandidateTerms(indexReader, term, fuzziness, + field, prefixTerm) + if err != nil { + return nil, err + } + + var candidates []string + var dictBytesRead uint64 + if fuzzyCandidates != nil { + candidates = fuzzyCandidates.candidates + dictBytesRead = fuzzyCandidates.bytesRead + } + + if ctx != nil { + reportIOStats(dictBytesRead, ctx) + } + + return NewMultiTermSearcher(ctx, indexReader, candidates, field, + boost, options, true) +} + +type fuzzyCandidates struct { + candidates []string + bytesRead uint64 +} + +func reportIOStats(bytesRead uint64, ctx context.Context) { + // The fuzzy, regexp like queries essentially load a dictionary, + // which potentially incurs a cost that must be accounted by + // using the callback to report the value. + statsCallbackFn := ctx.Value(search.SearchIOStatsCallbackKey) + if statsCallbackFn != nil { + statsCallbackFn.(search.SearchIOStatsCallbackFunc)(bytesRead) + } +} + +func findFuzzyCandidateTerms(indexReader index.IndexReader, term string, + fuzziness int, field, prefixTerm string) (rv *fuzzyCandidates, err error) { + rv = &fuzzyCandidates{ + candidates: make([]string, 0), + } + + // in case of advanced reader implementations directly call + // the levenshtein automaton based iterator to collect the + // candidate terms + if ir, ok := indexReader.(index.IndexReaderFuzzy); ok { + fieldDict, err := ir.FieldDictFuzzy(field, term, fuzziness, prefixTerm) + if err != nil { + return nil, err + } + defer func() { + if cerr := fieldDict.Close(); cerr != nil && err == nil { + err = cerr + } + }() + tfd, err := fieldDict.Next() + for err == nil && tfd != nil { + rv.candidates = append(rv.candidates, tfd.Term) + if tooManyClauses(len(rv.candidates)) { + return nil, tooManyClausesErr(field, len(rv.candidates)) + } + tfd, err = fieldDict.Next() + } + + rv.bytesRead = fieldDict.BytesRead() + return rv, err + } + + var fieldDict index.FieldDict + if len(prefixTerm) > 0 { + fieldDict, err = indexReader.FieldDictPrefix(field, []byte(prefixTerm)) + } else { + fieldDict, err = indexReader.FieldDict(field) + } + if err != nil { + return nil, err + } + defer func() { + if cerr := fieldDict.Close(); cerr != nil && err == nil { + err = cerr + } + }() + + // enumerate terms and check levenshtein distance + var reuse []int + tfd, err := fieldDict.Next() + for err == nil && tfd != nil { + var ld int + var exceeded bool + ld, exceeded, reuse = search.LevenshteinDistanceMaxReuseSlice(term, tfd.Term, fuzziness, reuse) + if !exceeded && ld <= fuzziness { + rv.candidates = append(rv.candidates, tfd.Term) + if tooManyClauses(len(rv.candidates)) { + return nil, tooManyClausesErr(field, len(rv.candidates)) + } + } + tfd, err = fieldDict.Next() + } + + rv.bytesRead = fieldDict.BytesRead() + return rv, err +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_geoboundingbox.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_geoboundingbox.go new file mode 100644 index 0000000000..05ca1bf959 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_geoboundingbox.go @@ -0,0 +1,297 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "context" + + "github.com/blevesearch/bleve/v2/document" + "github.com/blevesearch/bleve/v2/geo" + "github.com/blevesearch/bleve/v2/numeric" + "github.com/blevesearch/bleve/v2/search" + index "github.com/blevesearch/bleve_index_api" +) + +type filterFunc func(key []byte) bool + +var GeoBitsShift1 = geo.GeoBits << 1 +var GeoBitsShift1Minus1 = GeoBitsShift1 - 1 + +func NewGeoBoundingBoxSearcher(ctx context.Context, indexReader index.IndexReader, minLon, minLat, + maxLon, maxLat float64, field string, boost float64, + options search.SearcherOptions, checkBoundaries bool) ( + search.Searcher, error) { + if tp, ok := indexReader.(index.SpatialIndexPlugin); ok { + sp, err := tp.GetSpatialAnalyzerPlugin("s2") + if err == nil { + terms := sp.GetQueryTokens(geo.NewBoundedRectangle(minLat, + minLon, maxLat, maxLon)) + boxSearcher, err := NewMultiTermSearcher(ctx, indexReader, + terms, field, boost, options, false) + if err != nil { + return nil, err + } + + dvReader, err := indexReader.DocValueReader([]string{field}) + if err != nil { + return nil, err + } + + return NewFilteringSearcher(ctx, boxSearcher, buildRectFilter(dvReader, + field, minLon, minLat, maxLon, maxLat)), nil + } + } + + // indexes without the spatial plugin override would continue here. + + // track list of opened searchers, for cleanup on early exit + var openedSearchers []search.Searcher + cleanupOpenedSearchers := func() { + for _, s := range openedSearchers { + _ = s.Close() + } + } + + // do math to produce list of terms needed for this search + onBoundaryTerms, notOnBoundaryTerms, err := ComputeGeoRange(nil, 0, GeoBitsShift1Minus1, + minLon, minLat, maxLon, maxLat, checkBoundaries, indexReader, field) + if err != nil { + return nil, err + } + + var onBoundarySearcher search.Searcher + dvReader, err := indexReader.DocValueReader([]string{field}) + if err != nil { + return nil, err + } + + if len(onBoundaryTerms) > 0 { + rawOnBoundarySearcher, err := NewMultiTermSearcherBytes(ctx, indexReader, + onBoundaryTerms, field, boost, options, false) + if err != nil { + return nil, err + } + // add filter to check points near the boundary + onBoundarySearcher = NewFilteringSearcher(ctx, rawOnBoundarySearcher, + buildRectFilter(dvReader, field, minLon, minLat, maxLon, maxLat)) + openedSearchers = append(openedSearchers, onBoundarySearcher) + } + + var notOnBoundarySearcher search.Searcher + if len(notOnBoundaryTerms) > 0 { + var err error + notOnBoundarySearcher, err = NewMultiTermSearcherBytes(ctx, indexReader, + notOnBoundaryTerms, field, boost, options, false) + if err != nil { + cleanupOpenedSearchers() + return nil, err + } + openedSearchers = append(openedSearchers, notOnBoundarySearcher) + } + + if onBoundarySearcher != nil && notOnBoundarySearcher != nil { + rv, err := NewDisjunctionSearcher(ctx, indexReader, + []search.Searcher{ + onBoundarySearcher, + notOnBoundarySearcher, + }, + 0, options) + if err != nil { + cleanupOpenedSearchers() + return nil, err + } + return rv, nil + } else if onBoundarySearcher != nil { + return onBoundarySearcher, nil + } else if notOnBoundarySearcher != nil { + return notOnBoundarySearcher, nil + } + + return NewMatchNoneSearcher(indexReader) +} + +var geoMaxShift = document.GeoPrecisionStep * 4 +var geoDetailLevel = ((geo.GeoBits << 1) - geoMaxShift) / 2 + +type closeFunc func() error + +func ComputeGeoRange(ctx context.Context, term uint64, shift uint, + sminLon, sminLat, smaxLon, smaxLat float64, checkBoundaries bool, + indexReader index.IndexReader, field string) ( + onBoundary [][]byte, notOnBoundary [][]byte, err error) { + + isIndexed, closeF, err := buildIsIndexedFunc(ctx, indexReader, field) + if closeF != nil { + defer func() { + cerr := closeF() + if cerr != nil { + err = cerr + } + }() + } + + grc := &geoRangeCompute{ + preallocBytesLen: 32, + preallocBytes: make([]byte, 32), + sminLon: sminLon, + sminLat: sminLat, + smaxLon: smaxLon, + smaxLat: smaxLat, + checkBoundaries: checkBoundaries, + isIndexed: isIndexed, + } + + grc.computeGeoRange(term, shift) + + return grc.onBoundary, grc.notOnBoundary, nil +} + +func buildIsIndexedFunc(ctx context.Context, indexReader index.IndexReader, field string) (isIndexed filterFunc, closeF closeFunc, err error) { + if irr, ok := indexReader.(index.IndexReaderContains); ok { + fieldDict, err := irr.FieldDictContains(field) + if err != nil { + return nil, nil, err + } + + isIndexed = func(term []byte) bool { + found, err := fieldDict.Contains(term) + return err == nil && found + } + + closeF = func() error { + if fd, ok := fieldDict.(index.FieldDict); ok { + err := fd.Close() + if err != nil { + return err + } + } + return nil + } + } else if indexReader != nil { + isIndexed = func(term []byte) bool { + reader, err := indexReader.TermFieldReader(ctx, term, field, false, false, false) + if err != nil || reader == nil { + return false + } + if reader.Count() == 0 { + _ = reader.Close() + return false + } + _ = reader.Close() + return true + } + + } else { + isIndexed = func([]byte) bool { + return true + } + } + return isIndexed, closeF, err +} + +func buildRectFilter(dvReader index.DocValueReader, field string, + minLon, minLat, maxLon, maxLat float64) FilterFunc { + return func(d *search.DocumentMatch) bool { + // check geo matches against all numeric type terms indexed + var lons, lats []float64 + var found bool + err := dvReader.VisitDocValues(d.IndexInternalID, func(field string, term []byte) { + // only consider the values which are shifted 0 + prefixCoded := numeric.PrefixCoded(term) + shift, err := prefixCoded.Shift() + if err == nil && shift == 0 { + var i64 int64 + i64, err = prefixCoded.Int64() + if err == nil { + lons = append(lons, geo.MortonUnhashLon(uint64(i64))) + lats = append(lats, geo.MortonUnhashLat(uint64(i64))) + found = true + } + } + }) + if err == nil && found { + for i := range lons { + if geo.BoundingBoxContains(lons[i], lats[i], + minLon, minLat, maxLon, maxLat) { + return true + } + } + } + return false + } +} + +type geoRangeCompute struct { + preallocBytesLen int + preallocBytes []byte + sminLon, sminLat, smaxLon, smaxLat float64 + checkBoundaries bool + onBoundary, notOnBoundary [][]byte + isIndexed func(term []byte) bool +} + +func (grc *geoRangeCompute) makePrefixCoded(in int64, shift uint) (rv numeric.PrefixCoded) { + if len(grc.preallocBytes) <= 0 { + grc.preallocBytesLen = grc.preallocBytesLen * 2 + grc.preallocBytes = make([]byte, grc.preallocBytesLen) + } + + rv, grc.preallocBytes, _ = + numeric.NewPrefixCodedInt64Prealloc(in, shift, grc.preallocBytes) + + return rv +} + +func (grc *geoRangeCompute) computeGeoRange(term uint64, shift uint) { + split := term | uint64(0x1)<> 1 + + within := res%document.GeoPrecisionStep == 0 && + geo.RectWithin(minLon, minLat, maxLon, maxLat, + grc.sminLon, grc.sminLat, grc.smaxLon, grc.smaxLat) + if within || (level == geoDetailLevel && + geo.RectIntersects(minLon, minLat, maxLon, maxLat, + grc.sminLon, grc.sminLat, grc.smaxLon, grc.smaxLat)) { + codedTerm := grc.makePrefixCoded(int64(start), res) + if grc.isIndexed(codedTerm) { + if !within && grc.checkBoundaries { + grc.onBoundary = append(grc.onBoundary, codedTerm) + } else { + grc.notOnBoundary = append(grc.notOnBoundary, codedTerm) + } + } + } else if level < geoDetailLevel && + geo.RectIntersects(minLon, minLat, maxLon, maxLat, + grc.sminLon, grc.sminLat, grc.smaxLon, grc.smaxLat) { + grc.computeGeoRange(start, res-1) + } +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_geopointdistance.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_geopointdistance.go new file mode 100644 index 0000000000..01ed209299 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_geopointdistance.go @@ -0,0 +1,146 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "context" + + "github.com/blevesearch/bleve/v2/geo" + "github.com/blevesearch/bleve/v2/numeric" + "github.com/blevesearch/bleve/v2/search" + index "github.com/blevesearch/bleve_index_api" +) + +func NewGeoPointDistanceSearcher(ctx context.Context, indexReader index.IndexReader, centerLon, + centerLat, dist float64, field string, boost float64, + options search.SearcherOptions) (search.Searcher, error) { + var rectSearcher search.Searcher + if tp, ok := indexReader.(index.SpatialIndexPlugin); ok { + sp, err := tp.GetSpatialAnalyzerPlugin("s2") + if err == nil { + terms := sp.GetQueryTokens(geo.NewPointDistance(centerLat, + centerLon, dist)) + rectSearcher, err = NewMultiTermSearcher(ctx, indexReader, terms, + field, boost, options, false) + if err != nil { + return nil, err + } + } + } + + // indexes without the spatial plugin override would get + // initialized here. + if rectSearcher == nil { + // compute bounding box containing the circle + topLeftLon, topLeftLat, bottomRightLon, bottomRightLat, err := + geo.RectFromPointDistance(centerLon, centerLat, dist) + if err != nil { + return nil, err + } + + // build a searcher for the box + rectSearcher, err = boxSearcher(ctx, indexReader, + topLeftLon, topLeftLat, bottomRightLon, bottomRightLat, + field, boost, options, false) + if err != nil { + return nil, err + } + } + + dvReader, err := indexReader.DocValueReader([]string{field}) + if err != nil { + return nil, err + } + + // wrap it in a filtering searcher which checks the actual distance + return NewFilteringSearcher(ctx, rectSearcher, + buildDistFilter(dvReader, field, centerLon, centerLat, dist)), nil +} + +// boxSearcher builds a searcher for the described bounding box +// if the desired box crosses the dateline, it is automatically split into +// two boxes joined through a disjunction searcher +func boxSearcher(ctx context.Context, indexReader index.IndexReader, + topLeftLon, topLeftLat, bottomRightLon, bottomRightLat float64, + field string, boost float64, options search.SearcherOptions, checkBoundaries bool) ( + search.Searcher, error) { + if bottomRightLon < topLeftLon { + // cross date line, rewrite as two parts + + leftSearcher, err := NewGeoBoundingBoxSearcher(ctx, indexReader, + -180, bottomRightLat, bottomRightLon, topLeftLat, + field, boost, options, checkBoundaries) + if err != nil { + return nil, err + } + rightSearcher, err := NewGeoBoundingBoxSearcher(ctx, indexReader, + topLeftLon, bottomRightLat, 180, topLeftLat, field, boost, options, + checkBoundaries) + if err != nil { + _ = leftSearcher.Close() + return nil, err + } + + boxSearcher, err := NewDisjunctionSearcher(ctx, indexReader, + []search.Searcher{leftSearcher, rightSearcher}, 0, options) + if err != nil { + _ = leftSearcher.Close() + _ = rightSearcher.Close() + return nil, err + } + return boxSearcher, nil + } + + // build geoboundingbox searcher for that bounding box + boxSearcher, err := NewGeoBoundingBoxSearcher(ctx, indexReader, + topLeftLon, bottomRightLat, bottomRightLon, topLeftLat, field, boost, + options, checkBoundaries) + if err != nil { + return nil, err + } + return boxSearcher, nil +} + +func buildDistFilter(dvReader index.DocValueReader, field string, + centerLon, centerLat, maxDist float64) FilterFunc { + return func(d *search.DocumentMatch) bool { + // check geo matches against all numeric type terms indexed + var lons, lats []float64 + var found bool + + err := dvReader.VisitDocValues(d.IndexInternalID, func(field string, term []byte) { + // only consider the values which are shifted 0 + prefixCoded := numeric.PrefixCoded(term) + shift, err := prefixCoded.Shift() + if err == nil && shift == 0 { + i64, err := prefixCoded.Int64() + if err == nil { + lons = append(lons, geo.MortonUnhashLon(uint64(i64))) + lats = append(lats, geo.MortonUnhashLat(uint64(i64))) + found = true + } + } + }) + if err == nil && found { + for i := range lons { + dist := geo.Haversin(lons[i], lats[i], centerLon, centerLat) + if dist <= maxDist/1000 { + return true + } + } + } + return false + } +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_geopolygon.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_geopolygon.go new file mode 100644 index 0000000000..1d6538adf0 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_geopolygon.go @@ -0,0 +1,144 @@ +// Copyright (c) 2019 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "context" + "fmt" + "math" + + "github.com/blevesearch/bleve/v2/geo" + "github.com/blevesearch/bleve/v2/numeric" + "github.com/blevesearch/bleve/v2/search" + index "github.com/blevesearch/bleve_index_api" +) + +func NewGeoBoundedPolygonSearcher(ctx context.Context, indexReader index.IndexReader, + coordinates []geo.Point, field string, boost float64, + options search.SearcherOptions) (search.Searcher, error) { + if len(coordinates) < 3 { + return nil, fmt.Errorf("Too few points specified for the polygon boundary") + } + + var rectSearcher search.Searcher + if sr, ok := indexReader.(index.SpatialIndexPlugin); ok { + tp, err := sr.GetSpatialAnalyzerPlugin("s2") + if err == nil { + terms := tp.GetQueryTokens(geo.NewBoundedPolygon(coordinates)) + rectSearcher, err = NewMultiTermSearcher(ctx, indexReader, terms, + field, boost, options, false) + if err != nil { + return nil, err + } + } + } + + // indexes without the spatial plugin override would get + // initialized here. + if rectSearcher == nil { + // compute the bounding box enclosing the polygon + topLeftLon, topLeftLat, bottomRightLon, bottomRightLat, err := + geo.BoundingRectangleForPolygon(coordinates) + if err != nil { + return nil, err + } + + // build a searcher for the bounding box on the polygon + rectSearcher, err = boxSearcher(ctx, indexReader, + topLeftLon, topLeftLat, bottomRightLon, bottomRightLat, + field, boost, options, true) + if err != nil { + return nil, err + } + } + + dvReader, err := indexReader.DocValueReader([]string{field}) + if err != nil { + return nil, err + } + + // wrap it in a filtering searcher that checks for the polygon inclusivity + return NewFilteringSearcher(ctx, rectSearcher, + buildPolygonFilter(dvReader, field, coordinates)), nil +} + +const float64EqualityThreshold = 1e-6 + +func almostEqual(a, b float64) bool { + return math.Abs(a-b) <= float64EqualityThreshold +} + +// buildPolygonFilter returns true if the point lies inside the +// polygon. It is based on the ray-casting technique as referred +// here: https://wrf.ecse.rpi.edu/nikola/pubdetails/pnpoly.html +func buildPolygonFilter(dvReader index.DocValueReader, field string, + coordinates []geo.Point) FilterFunc { + return func(d *search.DocumentMatch) bool { + // check geo matches against all numeric type terms indexed + var lons, lats []float64 + var found bool + + err := dvReader.VisitDocValues(d.IndexInternalID, func(field string, term []byte) { + // only consider the values which are shifted 0 + prefixCoded := numeric.PrefixCoded(term) + shift, err := prefixCoded.Shift() + if err == nil && shift == 0 { + i64, err := prefixCoded.Int64() + if err == nil { + lons = append(lons, geo.MortonUnhashLon(uint64(i64))) + lats = append(lats, geo.MortonUnhashLat(uint64(i64))) + found = true + } + } + }) + + // Note: this approach works for points which are strictly inside + // the polygon. ie it might fail for certain points on the polygon boundaries. + if err == nil && found { + nVertices := len(coordinates) + if len(coordinates) < 3 { + return false + } + rayIntersectsSegment := func(point, a, b geo.Point) bool { + return (a.Lat > point.Lat) != (b.Lat > point.Lat) && + point.Lon < (b.Lon-a.Lon)*(point.Lat-a.Lat)/(b.Lat-a.Lat)+a.Lon + } + + for i := range lons { + pt := geo.Point{Lon: lons[i], Lat: lats[i]} + inside := rayIntersectsSegment(pt, coordinates[len(coordinates)-1], coordinates[0]) + // check for a direct vertex match + if almostEqual(coordinates[0].Lat, lats[i]) && + almostEqual(coordinates[0].Lon, lons[i]) { + return true + } + + for j := 1; j < nVertices; j++ { + if almostEqual(coordinates[j].Lat, lats[i]) && + almostEqual(coordinates[j].Lon, lons[i]) { + return true + } + if rayIntersectsSegment(pt, coordinates[j-1], coordinates[j]) { + inside = !inside + } + } + if inside { + return true + } + } + } + return false + } +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_geoshape.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_geoshape.go new file mode 100644 index 0000000000..d2c6b1c55d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_geoshape.go @@ -0,0 +1,124 @@ +// Copyright (c) 2022 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "bytes" + "context" + + "github.com/blevesearch/bleve/v2/geo" + "github.com/blevesearch/bleve/v2/search" + index "github.com/blevesearch/bleve_index_api" + "github.com/blevesearch/geo/geojson" +) + +func NewGeoShapeSearcher(ctx context.Context, indexReader index.IndexReader, shape index.GeoJSON, + relation string, field string, boost float64, + options search.SearcherOptions) (search.Searcher, error) { + var err error + var spatialPlugin index.SpatialAnalyzerPlugin + + // check for the spatial plugin from the index. + if sr, ok := indexReader.(index.SpatialIndexPlugin); ok { + spatialPlugin, _ = sr.GetSpatialAnalyzerPlugin("s2") + } + + if spatialPlugin == nil { + // fallback to the default spatial plugin(s2). + spatialPlugin = geo.GetSpatialAnalyzerPlugin("s2") + } + + // obtain the query tokens. + terms := spatialPlugin.GetQueryTokens(shape) + mSearcher, err := NewMultiTermSearcher(ctx, indexReader, terms, + field, boost, options, false) + if err != nil { + return nil, err + } + + dvReader, err := indexReader.DocValueReader([]string{field}) + if err != nil { + return nil, err + } + + return NewFilteringSearcher(ctx, mSearcher, + buildRelationFilterOnShapes(dvReader, field, relation, shape)), nil + +} + +// Using the same term splitter slice used in the doc values in zap. +// TODO: This needs to be revisited whenever we change the zap +// implementation of doc values. +var termSeparatorSplitSlice = []byte{0xff} + +func buildRelationFilterOnShapes(dvReader index.DocValueReader, field string, + relation string, shape index.GeoJSON) FilterFunc { + // this is for accumulating the shape's actual complete value + // spread across multiple docvalue visitor callbacks. + var dvShapeValue []byte + var startReading, finishReading bool + var reader *bytes.Reader + return func(d *search.DocumentMatch) bool { + var found bool + + err := dvReader.VisitDocValues(d.IndexInternalID, + func(field string, term []byte) { + + // only consider the values which are GlueBytes prefixed or + // if it had already started reading the shape bytes from previous callbacks. + if startReading || len(term) > geo.GlueBytesOffset { + + if !startReading && bytes.Equal(geo.GlueBytes, term[:geo.GlueBytesOffset]) { + startReading = true + + if bytes.Equal(geo.GlueBytes, term[len(term)-geo.GlueBytesOffset:]) { + term = term[:len(term)-geo.GlueBytesOffset] + finishReading = true + } + + dvShapeValue = append(dvShapeValue, term[geo.GlueBytesOffset:]...) + + } else if startReading && !finishReading { + if len(term) > geo.GlueBytesOffset && + bytes.Equal(geo.GlueBytes, term[len(term)-geo.GlueBytesOffset:]) { + term = term[:len(term)-geo.GlueBytesOffset] + finishReading = true + } + + term = append(termSeparatorSplitSlice, term...) + dvShapeValue = append(dvShapeValue, term...) + } + + // apply the filter once the entire docvalue is finished reading. + if finishReading { + v, err := geojson.FilterGeoShapesOnRelation(shape, + dvShapeValue, relation, &reader) + if err == nil && v { + found = true + } + dvShapeValue = dvShapeValue[:0] + startReading = false + finishReading = false + } + } + }) + + if err == nil && found { + return found + } + + return false + } +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_ip_range.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_ip_range.go new file mode 100644 index 0000000000..3826620628 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_ip_range.go @@ -0,0 +1,68 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "context" + "net" + + "github.com/blevesearch/bleve/v2/search" + index "github.com/blevesearch/bleve_index_api" +) + +// netLimits returns the lo and hi bounds inside the network. +func netLimits(n *net.IPNet) (lo net.IP, hi net.IP) { + ones, bits := n.Mask.Size() + netNum := n.IP + if bits == net.IPv4len*8 { + netNum = netNum.To16() + ones += 8 * (net.IPv6len - net.IPv4len) + } + mask := net.CIDRMask(ones, 8*net.IPv6len) + lo = make(net.IP, net.IPv6len) + hi = make(net.IP, net.IPv6len) + for i := 0; i < net.IPv6len; i++ { + lo[i] = netNum[i] & mask[i] + hi[i] = lo[i] | ^mask[i] + } + return lo, hi +} + +func NewIPRangeSearcher(ctx context.Context, indexReader index.IndexReader, ipNet *net.IPNet, + field string, boost float64, options search.SearcherOptions) ( + search.Searcher, error) { + + lo, hi := netLimits(ipNet) + fieldDict, err := indexReader.FieldDictRange(field, lo, hi) + if err != nil { + return nil, err + } + defer fieldDict.Close() + + var terms []string + tfd, err := fieldDict.Next() + for err == nil && tfd != nil { + terms = append(terms, tfd.Term) + if tooManyClauses(len(terms)) { + return nil, tooManyClausesErr(field, len(terms)) + } + tfd, err = fieldDict.Next() + } + if err != nil { + return nil, err + } + + return NewMultiTermSearcher(ctx, indexReader, terms, field, boost, options, true) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_match_all.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_match_all.go new file mode 100644 index 0000000000..57d8d07279 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_match_all.go @@ -0,0 +1,123 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "context" + "reflect" + + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/scorer" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeMatchAllSearcher int + +func init() { + var mas MatchAllSearcher + reflectStaticSizeMatchAllSearcher = int(reflect.TypeOf(mas).Size()) +} + +type MatchAllSearcher struct { + indexReader index.IndexReader + reader index.DocIDReader + scorer *scorer.ConstantScorer + count uint64 +} + +func NewMatchAllSearcher(ctx context.Context, indexReader index.IndexReader, boost float64, options search.SearcherOptions) (*MatchAllSearcher, error) { + reader, err := indexReader.DocIDReaderAll() + if err != nil { + return nil, err + } + count, err := indexReader.DocCount() + if err != nil { + _ = reader.Close() + return nil, err + } + scorer := scorer.NewConstantScorer(1.0, boost, options) + + return &MatchAllSearcher{ + indexReader: indexReader, + reader: reader, + scorer: scorer, + count: count, + }, nil +} + +func (s *MatchAllSearcher) Size() int { + return reflectStaticSizeMatchAllSearcher + size.SizeOfPtr + + s.reader.Size() + + s.scorer.Size() +} + +func (s *MatchAllSearcher) Count() uint64 { + return s.count +} + +func (s *MatchAllSearcher) Weight() float64 { + return s.scorer.Weight() +} + +func (s *MatchAllSearcher) SetQueryNorm(qnorm float64) { + s.scorer.SetQueryNorm(qnorm) +} + +func (s *MatchAllSearcher) Next(ctx *search.SearchContext) (*search.DocumentMatch, error) { + id, err := s.reader.Next() + if err != nil { + return nil, err + } + + if id == nil { + return nil, nil + } + + // score match + docMatch := s.scorer.Score(ctx, id) + // return doc match + return docMatch, nil + +} + +func (s *MatchAllSearcher) Advance(ctx *search.SearchContext, ID index.IndexInternalID) (*search.DocumentMatch, error) { + id, err := s.reader.Advance(ID) + if err != nil { + return nil, err + } + + if id == nil { + return nil, nil + } + + // score match + docMatch := s.scorer.Score(ctx, id) + + // return doc match + return docMatch, nil +} + +func (s *MatchAllSearcher) Close() error { + return s.reader.Close() +} + +func (s *MatchAllSearcher) Min() int { + return 0 +} + +func (s *MatchAllSearcher) DocumentMatchPoolSize() int { + return 1 +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_match_none.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_match_none.go new file mode 100644 index 0000000000..b7f76941ec --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_match_none.go @@ -0,0 +1,76 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "reflect" + + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeMatchNoneSearcher int + +func init() { + var mns MatchNoneSearcher + reflectStaticSizeMatchNoneSearcher = int(reflect.TypeOf(mns).Size()) +} + +type MatchNoneSearcher struct { + indexReader index.IndexReader +} + +func NewMatchNoneSearcher(indexReader index.IndexReader) (*MatchNoneSearcher, error) { + return &MatchNoneSearcher{ + indexReader: indexReader, + }, nil +} + +func (s *MatchNoneSearcher) Size() int { + return reflectStaticSizeMatchNoneSearcher + size.SizeOfPtr +} + +func (s *MatchNoneSearcher) Count() uint64 { + return uint64(0) +} + +func (s *MatchNoneSearcher) Weight() float64 { + return 0.0 +} + +func (s *MatchNoneSearcher) SetQueryNorm(qnorm float64) { + +} + +func (s *MatchNoneSearcher) Next(ctx *search.SearchContext) (*search.DocumentMatch, error) { + return nil, nil +} + +func (s *MatchNoneSearcher) Advance(ctx *search.SearchContext, ID index.IndexInternalID) (*search.DocumentMatch, error) { + return nil, nil +} + +func (s *MatchNoneSearcher) Close() error { + return nil +} + +func (s *MatchNoneSearcher) Min() int { + return 0 +} + +func (s *MatchNoneSearcher) DocumentMatchPoolSize() int { + return 0 +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_multi_term.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_multi_term.go new file mode 100644 index 0000000000..913f99f55c --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_multi_term.go @@ -0,0 +1,217 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "context" + "fmt" + + "github.com/blevesearch/bleve/v2/search" + index "github.com/blevesearch/bleve_index_api" +) + +func NewMultiTermSearcher(ctx context.Context, indexReader index.IndexReader, terms []string, + field string, boost float64, options search.SearcherOptions, limit bool) ( + search.Searcher, error) { + + if tooManyClauses(len(terms)) { + if optionsDisjunctionOptimizable(options) { + return optimizeMultiTermSearcher(ctx, indexReader, terms, field, boost, options) + } + if limit { + return nil, tooManyClausesErr(field, len(terms)) + } + } + + qsearchers, err := makeBatchSearchers(ctx, indexReader, terms, field, boost, options) + if err != nil { + return nil, err + } + + // build disjunction searcher of these ranges + return newMultiTermSearcherInternal(ctx, indexReader, qsearchers, field, boost, + options, limit) +} + +func NewMultiTermSearcherBytes(ctx context.Context, indexReader index.IndexReader, terms [][]byte, + field string, boost float64, options search.SearcherOptions, limit bool) ( + search.Searcher, error) { + + if tooManyClauses(len(terms)) { + if optionsDisjunctionOptimizable(options) { + return optimizeMultiTermSearcherBytes(ctx, indexReader, terms, field, boost, options) + } + + if limit { + return nil, tooManyClausesErr(field, len(terms)) + } + } + + qsearchers, err := makeBatchSearchersBytes(ctx, indexReader, terms, field, boost, options) + if err != nil { + return nil, err + } + + // build disjunction searcher of these ranges + return newMultiTermSearcherInternal(ctx, indexReader, qsearchers, field, boost, + options, limit) +} + +func newMultiTermSearcherInternal(ctx context.Context, indexReader index.IndexReader, + searchers []search.Searcher, field string, boost float64, + options search.SearcherOptions, limit bool) ( + search.Searcher, error) { + + // build disjunction searcher of these ranges + searcher, err := newDisjunctionSearcher(ctx, indexReader, searchers, 0, options, + limit) + if err != nil { + for _, s := range searchers { + _ = s.Close() + } + return nil, err + } + + return searcher, nil +} + +func optimizeMultiTermSearcher(ctx context.Context, indexReader index.IndexReader, terms []string, + field string, boost float64, options search.SearcherOptions) ( + search.Searcher, error) { + var finalSearcher search.Searcher + for len(terms) > 0 { + var batchTerms []string + if len(terms) > DisjunctionMaxClauseCount { + batchTerms = terms[:DisjunctionMaxClauseCount] + terms = terms[DisjunctionMaxClauseCount:] + } else { + batchTerms = terms + terms = nil + } + batch, err := makeBatchSearchers(ctx, indexReader, batchTerms, field, boost, options) + if err != nil { + return nil, err + } + if finalSearcher != nil { + batch = append(batch, finalSearcher) + } + cleanup := func() { + for _, searcher := range batch { + if searcher != nil { + _ = searcher.Close() + } + } + } + finalSearcher, err = optimizeCompositeSearcher(ctx, "disjunction:unadorned", + indexReader, batch, options) + // all searchers in batch should be closed, regardless of error or optimization failure + // either we're returning, or continuing and only finalSearcher is needed for next loop + cleanup() + if err != nil { + return nil, err + } + if finalSearcher == nil { + return nil, fmt.Errorf("unable to optimize") + } + } + return finalSearcher, nil +} + +func makeBatchSearchers(ctx context.Context, indexReader index.IndexReader, terms []string, field string, + boost float64, options search.SearcherOptions) ([]search.Searcher, error) { + + qsearchers := make([]search.Searcher, len(terms)) + qsearchersClose := func() { + for _, searcher := range qsearchers { + if searcher != nil { + _ = searcher.Close() + } + } + } + for i, term := range terms { + var err error + qsearchers[i], err = NewTermSearcher(ctx, indexReader, term, field, boost, options) + if err != nil { + qsearchersClose() + return nil, err + } + } + return qsearchers, nil +} + +func optimizeMultiTermSearcherBytes(ctx context.Context, indexReader index.IndexReader, terms [][]byte, + field string, boost float64, options search.SearcherOptions) ( + search.Searcher, error) { + + var finalSearcher search.Searcher + for len(terms) > 0 { + var batchTerms [][]byte + if len(terms) > DisjunctionMaxClauseCount { + batchTerms = terms[:DisjunctionMaxClauseCount] + terms = terms[DisjunctionMaxClauseCount:] + } else { + batchTerms = terms + terms = nil + } + batch, err := makeBatchSearchersBytes(ctx, indexReader, batchTerms, field, boost, options) + if err != nil { + return nil, err + } + if finalSearcher != nil { + batch = append(batch, finalSearcher) + } + cleanup := func() { + for _, searcher := range batch { + if searcher != nil { + _ = searcher.Close() + } + } + } + finalSearcher, err = optimizeCompositeSearcher(ctx, "disjunction:unadorned", + indexReader, batch, options) + // all searchers in batch should be closed, regardless of error or optimization failure + // either we're returning, or continuing and only finalSearcher is needed for next loop + cleanup() + if err != nil { + return nil, err + } + if finalSearcher == nil { + return nil, fmt.Errorf("unable to optimize") + } + } + return finalSearcher, nil +} + +func makeBatchSearchersBytes(ctx context.Context, indexReader index.IndexReader, terms [][]byte, field string, + boost float64, options search.SearcherOptions) ([]search.Searcher, error) { + + qsearchers := make([]search.Searcher, len(terms)) + qsearchersClose := func() { + for _, searcher := range qsearchers { + if searcher != nil { + _ = searcher.Close() + } + } + } + for i, term := range terms { + var err error + qsearchers[i], err = NewTermSearcherBytes(ctx, indexReader, term, field, boost, options) + if err != nil { + qsearchersClose() + return nil, err + } + } + return qsearchers, nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_numeric_range.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_numeric_range.go new file mode 100644 index 0000000000..68728c94c4 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_numeric_range.go @@ -0,0 +1,256 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "bytes" + "context" + "math" + "sort" + + "github.com/blevesearch/bleve/v2/numeric" + "github.com/blevesearch/bleve/v2/search" + index "github.com/blevesearch/bleve_index_api" +) + +func NewNumericRangeSearcher(ctx context.Context, indexReader index.IndexReader, + min *float64, max *float64, inclusiveMin, inclusiveMax *bool, field string, + boost float64, options search.SearcherOptions) (search.Searcher, error) { + // account for unbounded edges + if min == nil { + negInf := math.Inf(-1) + min = &negInf + } + if max == nil { + Inf := math.Inf(1) + max = &Inf + } + if inclusiveMin == nil { + defaultInclusiveMin := true + inclusiveMin = &defaultInclusiveMin + } + if inclusiveMax == nil { + defaultInclusiveMax := false + inclusiveMax = &defaultInclusiveMax + } + // find all the ranges + minInt64 := numeric.Float64ToInt64(*min) + if !*inclusiveMin && minInt64 != math.MaxInt64 { + minInt64++ + } + maxInt64 := numeric.Float64ToInt64(*max) + if !*inclusiveMax && maxInt64 != math.MinInt64 { + maxInt64-- + } + + var fieldDict index.FieldDictContains + var dictBytesRead uint64 + var isIndexed filterFunc + var err error + if irr, ok := indexReader.(index.IndexReaderContains); ok { + fieldDict, err = irr.FieldDictContains(field) + if err != nil { + return nil, err + } + + isIndexed = func(term []byte) bool { + found, err := fieldDict.Contains(term) + return err == nil && found + } + + dictBytesRead = fieldDict.BytesRead() + } + + // FIXME hard-coded precision, should match field declaration + termRanges := splitInt64Range(minInt64, maxInt64, 4) + terms := termRanges.Enumerate(isIndexed) + if fieldDict != nil { + if fd, ok := fieldDict.(index.FieldDict); ok { + if err = fd.Close(); err != nil { + return nil, err + } + } + } + + if len(terms) < 1 { + // reporting back the IO stats with respect to the dictionary + // loaded, using the context + if ctx != nil { + reportIOStats(dictBytesRead, ctx) + } + + // cannot return MatchNoneSearcher because of interaction with + // commit f391b991c20f02681bacd197afc6d8aed444e132 + return NewMultiTermSearcherBytes(ctx, indexReader, terms, field, + boost, options, true) + } + + // for upside_down + if isIndexed == nil { + terms, err = filterCandidateTerms(indexReader, terms, field) + if err != nil { + return nil, err + } + } + + if tooManyClauses(len(terms)) { + return nil, tooManyClausesErr(field, len(terms)) + } + + if ctx != nil { + reportIOStats(dictBytesRead, ctx) + } + + return NewMultiTermSearcherBytes(ctx, indexReader, terms, field, + boost, options, true) +} + +func filterCandidateTerms(indexReader index.IndexReader, + terms [][]byte, field string) (rv [][]byte, err error) { + + fieldDict, err := indexReader.FieldDictRange(field, terms[0], terms[len(terms)-1]) + if err != nil { + return nil, err + } + + // enumerate the terms and check against list of terms + tfd, err := fieldDict.Next() + for err == nil && tfd != nil { + termBytes := []byte(tfd.Term) + i := sort.Search(len(terms), func(i int) bool { return bytes.Compare(terms[i], termBytes) >= 0 }) + if i < len(terms) && bytes.Compare(terms[i], termBytes) == 0 { + rv = append(rv, terms[i]) + } + terms = terms[i:] + tfd, err = fieldDict.Next() + } + + if cerr := fieldDict.Close(); cerr != nil && err == nil { + err = cerr + } + + return rv, err +} + +type termRange struct { + startTerm []byte + endTerm []byte +} + +func (t *termRange) Enumerate(filter filterFunc) [][]byte { + var rv [][]byte + next := t.startTerm + for bytes.Compare(next, t.endTerm) <= 0 { + if filter != nil { + if filter(next) { + rv = append(rv, next) + } + } else { + rv = append(rv, next) + } + next = incrementBytes(next) + } + return rv +} + +func incrementBytes(in []byte) []byte { + rv := make([]byte, len(in)) + copy(rv, in) + for i := len(rv) - 1; i >= 0; i-- { + rv[i] = rv[i] + 1 + if rv[i] != 0 { + // didn't overflow, so stop + break + } + } + return rv +} + +type termRanges []*termRange + +func (tr termRanges) Enumerate(filter filterFunc) [][]byte { + var rv [][]byte + for _, tri := range tr { + trie := tri.Enumerate(filter) + rv = append(rv, trie...) + } + return rv +} + +func splitInt64Range(minBound, maxBound int64, precisionStep uint) termRanges { + rv := make(termRanges, 0) + if minBound > maxBound { + return rv + } + + for shift := uint(0); ; shift += precisionStep { + + diff := int64(1) << (shift + precisionStep) + mask := ((int64(1) << precisionStep) - int64(1)) << shift + hasLower := (minBound & mask) != int64(0) + hasUpper := (maxBound & mask) != mask + + var nextMinBound int64 + if hasLower { + nextMinBound = (minBound + diff) &^ mask + } else { + nextMinBound = minBound &^ mask + } + var nextMaxBound int64 + if hasUpper { + nextMaxBound = (maxBound - diff) &^ mask + } else { + nextMaxBound = maxBound &^ mask + } + + lowerWrapped := nextMinBound < minBound + upperWrapped := nextMaxBound > maxBound + + if shift+precisionStep >= 64 || nextMinBound > nextMaxBound || + lowerWrapped || upperWrapped { + // We are in the lowest precision or the next precision is not available. + rv = append(rv, newRange(minBound, maxBound, shift)) + // exit the split recursion loop + break + } + + if hasLower { + rv = append(rv, newRange(minBound, minBound|mask, shift)) + } + if hasUpper { + rv = append(rv, newRange(maxBound&^mask, maxBound, shift)) + } + + // recurse to next precision + minBound = nextMinBound + maxBound = nextMaxBound + } + + return rv +} + +func newRange(minBound, maxBound int64, shift uint) *termRange { + maxBound |= (int64(1) << shift) - int64(1) + minBytes := numeric.MustNewPrefixCodedInt64(minBound, shift) + maxBytes := numeric.MustNewPrefixCodedInt64(maxBound, shift) + return newRangeBytes(minBytes, maxBytes) +} + +func newRangeBytes(minBytes, maxBytes []byte) *termRange { + return &termRange{ + startTerm: minBytes, + endTerm: maxBytes, + } +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_phrase.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_phrase.go new file mode 100644 index 0000000000..087ad768cb --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_phrase.go @@ -0,0 +1,438 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "context" + "fmt" + "math" + "reflect" + + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizePhraseSearcher int + +func init() { + var ps PhraseSearcher + reflectStaticSizePhraseSearcher = int(reflect.TypeOf(ps).Size()) +} + +type PhraseSearcher struct { + mustSearcher search.Searcher + queryNorm float64 + currMust *search.DocumentMatch + terms [][]string + path phrasePath + paths []phrasePath + locations []search.Location + initialized bool +} + +func (s *PhraseSearcher) Size() int { + sizeInBytes := reflectStaticSizePhraseSearcher + size.SizeOfPtr + + if s.mustSearcher != nil { + sizeInBytes += s.mustSearcher.Size() + } + + if s.currMust != nil { + sizeInBytes += s.currMust.Size() + } + + for _, entry := range s.terms { + sizeInBytes += size.SizeOfSlice + for _, entry1 := range entry { + sizeInBytes += size.SizeOfString + len(entry1) + } + } + + return sizeInBytes +} + +func NewPhraseSearcher(ctx context.Context, indexReader index.IndexReader, terms []string, field string, options search.SearcherOptions) (*PhraseSearcher, error) { + // turn flat terms []string into [][]string + mterms := make([][]string, len(terms)) + for i, term := range terms { + mterms[i] = []string{term} + } + return NewMultiPhraseSearcher(ctx, indexReader, mterms, field, options) +} + +func NewMultiPhraseSearcher(ctx context.Context, indexReader index.IndexReader, terms [][]string, field string, options search.SearcherOptions) (*PhraseSearcher, error) { + options.IncludeTermVectors = true + var termPositionSearchers []search.Searcher + for _, termPos := range terms { + if len(termPos) == 1 && termPos[0] != "" { + // single term + ts, err := NewTermSearcher(ctx, indexReader, termPos[0], field, 1.0, options) + if err != nil { + // close any searchers already opened + for _, ts := range termPositionSearchers { + _ = ts.Close() + } + return nil, fmt.Errorf("phrase searcher error building term searcher: %v", err) + } + termPositionSearchers = append(termPositionSearchers, ts) + } else if len(termPos) > 1 { + // multiple terms + var termSearchers []search.Searcher + for _, term := range termPos { + if term == "" { + continue + } + ts, err := NewTermSearcher(ctx, indexReader, term, field, 1.0, options) + if err != nil { + // close any searchers already opened + for _, ts := range termPositionSearchers { + _ = ts.Close() + } + return nil, fmt.Errorf("phrase searcher error building term searcher: %v", err) + } + termSearchers = append(termSearchers, ts) + } + disjunction, err := NewDisjunctionSearcher(ctx, indexReader, termSearchers, 1, options) + if err != nil { + // close any searchers already opened + for _, ts := range termPositionSearchers { + _ = ts.Close() + } + return nil, fmt.Errorf("phrase searcher error building term position disjunction searcher: %v", err) + } + termPositionSearchers = append(termPositionSearchers, disjunction) + } + } + + mustSearcher, err := NewConjunctionSearcher(ctx, indexReader, termPositionSearchers, options) + if err != nil { + // close any searchers already opened + for _, ts := range termPositionSearchers { + _ = ts.Close() + } + return nil, fmt.Errorf("phrase searcher error building conjunction searcher: %v", err) + } + + // build our searcher + rv := PhraseSearcher{ + mustSearcher: mustSearcher, + terms: terms, + } + rv.computeQueryNorm() + return &rv, nil +} + +func (s *PhraseSearcher) computeQueryNorm() { + // first calculate sum of squared weights + sumOfSquaredWeights := 0.0 + if s.mustSearcher != nil { + sumOfSquaredWeights += s.mustSearcher.Weight() + } + + // now compute query norm from this + s.queryNorm = 1.0 / math.Sqrt(sumOfSquaredWeights) + // finally tell all the downstream searchers the norm + if s.mustSearcher != nil { + s.mustSearcher.SetQueryNorm(s.queryNorm) + } +} + +func (s *PhraseSearcher) initSearchers(ctx *search.SearchContext) error { + err := s.advanceNextMust(ctx) + if err != nil { + return err + } + + s.initialized = true + return nil +} + +func (s *PhraseSearcher) advanceNextMust(ctx *search.SearchContext) error { + var err error + + if s.mustSearcher != nil { + if s.currMust != nil { + ctx.DocumentMatchPool.Put(s.currMust) + } + s.currMust, err = s.mustSearcher.Next(ctx) + if err != nil { + return err + } + } + + return nil +} + +func (s *PhraseSearcher) Weight() float64 { + return s.mustSearcher.Weight() +} + +func (s *PhraseSearcher) SetQueryNorm(qnorm float64) { + s.mustSearcher.SetQueryNorm(qnorm) +} + +func (s *PhraseSearcher) Next(ctx *search.SearchContext) (*search.DocumentMatch, error) { + if !s.initialized { + err := s.initSearchers(ctx) + if err != nil { + return nil, err + } + } + + for s.currMust != nil { + // check this match against phrase constraints + rv := s.checkCurrMustMatch(ctx) + + // prepare for next iteration (either loop or subsequent call to Next()) + err := s.advanceNextMust(ctx) + if err != nil { + return nil, err + } + + // if match satisfied phrase constraints return it as a hit + if rv != nil { + return rv, nil + } + } + + return nil, nil +} + +// checkCurrMustMatch is solely concerned with determining if the DocumentMatch +// pointed to by s.currMust (which satisifies the pre-condition searcher) +// also satisfies the phase constraints. if so, it returns a DocumentMatch +// for this document, otherwise nil +func (s *PhraseSearcher) checkCurrMustMatch(ctx *search.SearchContext) *search.DocumentMatch { + s.locations = s.currMust.Complete(s.locations) + + locations := s.currMust.Locations + s.currMust.Locations = nil + + ftls := s.currMust.FieldTermLocations + + // typically we would expect there to only actually be results in + // one field, but we allow for this to not be the case + // but, we note that phrase constraints can only be satisfied within + // a single field, so we can check them each independently + for field, tlm := range locations { + ftls = s.checkCurrMustMatchField(ctx, field, tlm, ftls) + } + + if len(ftls) > 0 { + // return match + rv := s.currMust + s.currMust = nil + rv.FieldTermLocations = ftls + return rv + } + + return nil +} + +// checkCurrMustMatchField is solely concerned with determining if one +// particular field within the currMust DocumentMatch Locations +// satisfies the phase constraints (possibly more than once). if so, +// the matching field term locations are appended to the provided +// slice +func (s *PhraseSearcher) checkCurrMustMatchField(ctx *search.SearchContext, + field string, tlm search.TermLocationMap, + ftls []search.FieldTermLocation) []search.FieldTermLocation { + if s.path == nil { + s.path = make(phrasePath, 0, len(s.terms)) + } + s.paths = findPhrasePaths(0, nil, s.terms, tlm, s.path[:0], 0, s.paths[:0]) + for _, p := range s.paths { + for _, pp := range p { + ftls = append(ftls, search.FieldTermLocation{ + Field: field, + Term: pp.term, + Location: search.Location{ + Pos: pp.loc.Pos, + Start: pp.loc.Start, + End: pp.loc.End, + ArrayPositions: pp.loc.ArrayPositions, + }, + }) + } + } + return ftls +} + +type phrasePart struct { + term string + loc *search.Location +} + +func (p *phrasePart) String() string { + return fmt.Sprintf("[%s %v]", p.term, p.loc) +} + +type phrasePath []phrasePart + +func (p phrasePath) MergeInto(in search.TermLocationMap) { + for _, pp := range p { + in[pp.term] = append(in[pp.term], pp.loc) + } +} + +func (p phrasePath) String() string { + rv := "[" + for i, pp := range p { + if i > 0 { + rv += ", " + } + rv += pp.String() + } + rv += "]" + return rv +} + +// findPhrasePaths is a function to identify phase matches from a set +// of known term locations. it recursive so care must be taken with +// arguments and return values. +// +// prevPos - the previous location, 0 on first invocation +// ap - array positions of the first candidate phrase part to +// which further recursive phrase parts must match, +// nil on initial invocation or when there are no array positions +// phraseTerms - slice containing the phrase terms, +// may contain empty string as placeholder (don't care) +// tlm - the Term Location Map containing all relevant term locations +// p - the current path being explored (appended to in recursive calls) +// this is the primary state being built during the traversal +// remainingSlop - amount of sloppiness that's allowed, which is the +// sum of the editDistances from each matching phrase part, +// where 0 means no sloppiness allowed (all editDistances must be 0), +// decremented during recursion +// rv - the final result being appended to by all the recursive calls +// +// returns slice of paths, or nil if invocation did not find any successul paths +func findPhrasePaths(prevPos uint64, ap search.ArrayPositions, phraseTerms [][]string, + tlm search.TermLocationMap, p phrasePath, remainingSlop int, rv []phrasePath) []phrasePath { + // no more terms + if len(phraseTerms) < 1 { + // snapshot or copy the recursively built phrasePath p and + // append it to the rv, also optimizing by checking if next + // phrasePath item in the rv (which we're about to overwrite) + // is available for reuse + var pcopy phrasePath + if len(rv) < cap(rv) { + pcopy = rv[:len(rv)+1][len(rv)][:0] + } + return append(rv, append(pcopy, p...)) + } + + car := phraseTerms[0] + cdr := phraseTerms[1:] + + // empty term is treated as match (continue) + if len(car) == 0 || (len(car) == 1 && car[0] == "") { + nextPos := prevPos + 1 + if prevPos == 0 { + // if prevPos was 0, don't set it to 1 (as thats not a real abs pos) + nextPos = 0 // don't advance nextPos if prevPos was 0 + } + return findPhrasePaths(nextPos, ap, cdr, tlm, p, remainingSlop, rv) + } + + // locations for this term + for _, carTerm := range car { + locations := tlm[carTerm] + LOCATIONS_LOOP: + for _, loc := range locations { + if prevPos != 0 && !loc.ArrayPositions.Equals(ap) { + // if the array positions are wrong, can't match, try next location + continue + } + + // compute distance from previous phrase term + dist := 0 + if prevPos != 0 { + dist = editDistance(prevPos+1, loc.Pos) + } + + // if enough slop remaining, continue recursively + if prevPos == 0 || (remainingSlop-dist) >= 0 { + // skip if we've already used this term+loc already + for _, ppart := range p { + if ppart.term == carTerm && ppart.loc == loc { + continue LOCATIONS_LOOP + } + } + + // this location works, add it to the path (but not for empty term) + px := append(p, phrasePart{term: carTerm, loc: loc}) + rv = findPhrasePaths(loc.Pos, loc.ArrayPositions, cdr, tlm, px, remainingSlop-dist, rv) + } + } + } + return rv +} + +func editDistance(p1, p2 uint64) int { + dist := int(p1 - p2) + if dist < 0 { + return -dist + } + return dist +} + +func (s *PhraseSearcher) Advance(ctx *search.SearchContext, ID index.IndexInternalID) (*search.DocumentMatch, error) { + if !s.initialized { + err := s.initSearchers(ctx) + if err != nil { + return nil, err + } + } + if s.currMust != nil { + if s.currMust.IndexInternalID.Compare(ID) >= 0 { + return s.Next(ctx) + } + ctx.DocumentMatchPool.Put(s.currMust) + } + if s.currMust == nil { + return nil, nil + } + var err error + s.currMust, err = s.mustSearcher.Advance(ctx, ID) + if err != nil { + return nil, err + } + return s.Next(ctx) +} + +func (s *PhraseSearcher) Count() uint64 { + // for now return a worst case + return s.mustSearcher.Count() +} + +func (s *PhraseSearcher) Close() error { + if s.mustSearcher != nil { + err := s.mustSearcher.Close() + if err != nil { + return err + } + } + return nil +} + +func (s *PhraseSearcher) Min() int { + return 0 +} + +func (s *PhraseSearcher) DocumentMatchPoolSize() int { + return s.mustSearcher.DocumentMatchPoolSize() + 1 +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_regexp.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_regexp.go new file mode 100644 index 0000000000..b419d54707 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_regexp.go @@ -0,0 +1,148 @@ +// Copyright (c) 2015 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "context" + "regexp" + + "github.com/blevesearch/bleve/v2/search" + index "github.com/blevesearch/bleve_index_api" +) + +// The Regexp interface defines the subset of the regexp.Regexp API +// methods that are used by bleve indexes, allowing callers to pass in +// alternate implementations. +type Regexp interface { + FindStringIndex(s string) (loc []int) + + LiteralPrefix() (prefix string, complete bool) + + String() string +} + +// NewRegexpStringSearcher is similar to NewRegexpSearcher, but +// additionally optimizes for index readers that handle regexp's. +func NewRegexpStringSearcher(ctx context.Context, indexReader index.IndexReader, pattern string, + field string, boost float64, options search.SearcherOptions) ( + search.Searcher, error) { + ir, ok := indexReader.(index.IndexReaderRegexp) + if !ok { + r, err := regexp.Compile(pattern) + if err != nil { + return nil, err + } + + return NewRegexpSearcher(ctx, indexReader, r, field, boost, options) + } + + fieldDict, err := ir.FieldDictRegexp(field, pattern) + if err != nil { + return nil, err + } + defer func() { + if cerr := fieldDict.Close(); cerr != nil && err == nil { + err = cerr + } + }() + + var candidateTerms []string + + tfd, err := fieldDict.Next() + for err == nil && tfd != nil { + candidateTerms = append(candidateTerms, tfd.Term) + tfd, err = fieldDict.Next() + } + if err != nil { + return nil, err + } + + return NewMultiTermSearcher(ctx, indexReader, candidateTerms, field, boost, + options, true) +} + +// NewRegexpSearcher creates a searcher which will match documents that +// contain terms which match the pattern regexp. The match must be EXACT +// matching the entire term. The provided regexp SHOULD NOT start with ^ +// or end with $ as this can intefere with the implementation. Separately, +// matches will be checked to ensure they match the entire term. +func NewRegexpSearcher(ctx context.Context, indexReader index.IndexReader, pattern Regexp, + field string, boost float64, options search.SearcherOptions) ( + search.Searcher, error) { + var candidateTerms []string + var regexpCandidates *regexpCandidates + prefixTerm, complete := pattern.LiteralPrefix() + if complete { + // there is no pattern + candidateTerms = []string{prefixTerm} + } else { + var err error + regexpCandidates, err = findRegexpCandidateTerms(indexReader, pattern, field, + prefixTerm) + if err != nil { + return nil, err + } + } + var dictBytesRead uint64 + if regexpCandidates != nil { + candidateTerms = regexpCandidates.candidates + dictBytesRead = regexpCandidates.bytesRead + } + + if ctx != nil { + reportIOStats(dictBytesRead, ctx) + } + + return NewMultiTermSearcher(ctx, indexReader, candidateTerms, field, boost, + options, true) +} + +type regexpCandidates struct { + candidates []string + bytesRead uint64 +} + +func findRegexpCandidateTerms(indexReader index.IndexReader, + pattern Regexp, field, prefixTerm string) (rv *regexpCandidates, err error) { + rv = ®expCandidates{ + candidates: make([]string, 0), + } + var fieldDict index.FieldDict + if len(prefixTerm) > 0 { + fieldDict, err = indexReader.FieldDictPrefix(field, []byte(prefixTerm)) + } else { + fieldDict, err = indexReader.FieldDict(field) + } + defer func() { + if cerr := fieldDict.Close(); cerr != nil && err == nil { + err = cerr + } + }() + + // enumerate the terms and check against regexp + tfd, err := fieldDict.Next() + for err == nil && tfd != nil { + matchPos := pattern.FindStringIndex(tfd.Term) + if matchPos != nil && matchPos[0] == 0 && matchPos[1] == len(tfd.Term) { + rv.candidates = append(rv.candidates, tfd.Term) + if tooManyClauses(len(rv.candidates)) { + return rv, tooManyClausesErr(field, len(rv.candidates)) + } + } + tfd, err = fieldDict.Next() + } + rv.bytesRead = fieldDict.BytesRead() + return rv, err +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_term.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_term.go new file mode 100644 index 0000000000..db18e5376f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_term.go @@ -0,0 +1,142 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "context" + "reflect" + + "github.com/blevesearch/bleve/v2/search" + "github.com/blevesearch/bleve/v2/search/scorer" + "github.com/blevesearch/bleve/v2/size" + index "github.com/blevesearch/bleve_index_api" +) + +var reflectStaticSizeTermSearcher int + +func init() { + var ts TermSearcher + reflectStaticSizeTermSearcher = int(reflect.TypeOf(ts).Size()) +} + +type TermSearcher struct { + indexReader index.IndexReader + reader index.TermFieldReader + scorer *scorer.TermQueryScorer + tfd index.TermFieldDoc +} + +func NewTermSearcher(ctx context.Context, indexReader index.IndexReader, term string, field string, boost float64, options search.SearcherOptions) (*TermSearcher, error) { + return NewTermSearcherBytes(ctx, indexReader, []byte(term), field, boost, options) +} + +func NewTermSearcherBytes(ctx context.Context, indexReader index.IndexReader, term []byte, field string, boost float64, options search.SearcherOptions) (*TermSearcher, error) { + needFreqNorm := options.Score != "none" + reader, err := indexReader.TermFieldReader(ctx, term, field, needFreqNorm, needFreqNorm, options.IncludeTermVectors) + if err != nil { + return nil, err + } + return newTermSearcherFromReader(indexReader, reader, term, field, boost, options) +} + +func newTermSearcherFromReader(indexReader index.IndexReader, reader index.TermFieldReader, + term []byte, field string, boost float64, options search.SearcherOptions) (*TermSearcher, error) { + count, err := indexReader.DocCount() + if err != nil { + _ = reader.Close() + return nil, err + } + scorer := scorer.NewTermQueryScorer(term, field, boost, count, reader.Count(), options) + return &TermSearcher{ + indexReader: indexReader, + reader: reader, + scorer: scorer, + }, nil +} + +func (s *TermSearcher) Size() int { + return reflectStaticSizeTermSearcher + size.SizeOfPtr + + s.reader.Size() + + s.tfd.Size() + + s.scorer.Size() +} + +func (s *TermSearcher) Count() uint64 { + return s.reader.Count() +} + +func (s *TermSearcher) Weight() float64 { + return s.scorer.Weight() +} + +func (s *TermSearcher) SetQueryNorm(qnorm float64) { + s.scorer.SetQueryNorm(qnorm) +} + +func (s *TermSearcher) Next(ctx *search.SearchContext) (*search.DocumentMatch, error) { + termMatch, err := s.reader.Next(s.tfd.Reset()) + if err != nil { + return nil, err + } + + if termMatch == nil { + return nil, nil + } + + // score match + docMatch := s.scorer.Score(ctx, termMatch) + // return doc match + return docMatch, nil + +} + +func (s *TermSearcher) Advance(ctx *search.SearchContext, ID index.IndexInternalID) (*search.DocumentMatch, error) { + termMatch, err := s.reader.Advance(ID, s.tfd.Reset()) + if err != nil { + return nil, err + } + + if termMatch == nil { + return nil, nil + } + + // score match + docMatch := s.scorer.Score(ctx, termMatch) + + // return doc match + return docMatch, nil +} + +func (s *TermSearcher) Close() error { + return s.reader.Close() +} + +func (s *TermSearcher) Min() int { + return 0 +} + +func (s *TermSearcher) DocumentMatchPoolSize() int { + return 1 +} + +func (s *TermSearcher) Optimize(kind string, octx index.OptimizableContext) ( + index.OptimizableContext, error) { + o, ok := s.reader.(index.Optimizable) + if ok { + return o.Optimize(kind, octx) + } + + return nil, nil +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_term_prefix.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_term_prefix.go new file mode 100644 index 0000000000..89f836a50c --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_term_prefix.go @@ -0,0 +1,56 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "context" + + "github.com/blevesearch/bleve/v2/search" + index "github.com/blevesearch/bleve_index_api" +) + +func NewTermPrefixSearcher(ctx context.Context, indexReader index.IndexReader, prefix string, + field string, boost float64, options search.SearcherOptions) ( + search.Searcher, error) { + // find the terms with this prefix + fieldDict, err := indexReader.FieldDictPrefix(field, []byte(prefix)) + if err != nil { + return nil, err + } + defer func() { + if cerr := fieldDict.Close(); cerr != nil && err == nil { + err = cerr + } + }() + + var terms []string + tfd, err := fieldDict.Next() + for err == nil && tfd != nil { + terms = append(terms, tfd.Term) + if tooManyClauses(len(terms)) { + return nil, tooManyClausesErr(field, len(terms)) + } + tfd, err = fieldDict.Next() + } + if err != nil { + return nil, err + } + + if ctx != nil { + reportIOStats(fieldDict.BytesRead(), ctx) + } + + return NewMultiTermSearcher(ctx, indexReader, terms, field, boost, options, true) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_term_range.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_term_range.go new file mode 100644 index 0000000000..a2fb4e9939 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/searcher/search_term_range.go @@ -0,0 +1,91 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package searcher + +import ( + "context" + + "github.com/blevesearch/bleve/v2/search" + index "github.com/blevesearch/bleve_index_api" +) + +func NewTermRangeSearcher(ctx context.Context, indexReader index.IndexReader, + min, max []byte, inclusiveMin, inclusiveMax *bool, field string, + boost float64, options search.SearcherOptions) (search.Searcher, error) { + + if inclusiveMin == nil { + defaultInclusiveMin := true + inclusiveMin = &defaultInclusiveMin + } + if inclusiveMax == nil { + defaultInclusiveMax := false + inclusiveMax = &defaultInclusiveMax + } + + if min == nil { + min = []byte{} + } + + rangeMax := max + if rangeMax != nil { + // the term dictionary range end has an unfortunate implementation + rangeMax = append(rangeMax, 0) + } + + // find the terms with this prefix + fieldDict, err := indexReader.FieldDictRange(field, min, rangeMax) + if err != nil { + return nil, err + } + + defer func() { + if cerr := fieldDict.Close(); cerr != nil && err == nil { + err = cerr + } + }() + + var terms []string + tfd, err := fieldDict.Next() + for err == nil && tfd != nil { + terms = append(terms, tfd.Term) + tfd, err = fieldDict.Next() + } + if err != nil { + return nil, err + } + + if len(terms) < 1 { + return NewMatchNoneSearcher(indexReader) + } + + if !*inclusiveMin && min != nil && string(min) == terms[0] { + terms = terms[1:] + // check again, as we might have removed only entry + if len(terms) < 1 { + return NewMatchNoneSearcher(indexReader) + } + } + + // if our term list included the max, it would be the last item + if !*inclusiveMax && max != nil && string(max) == terms[len(terms)-1] { + terms = terms[:len(terms)-1] + } + + if ctx != nil { + reportIOStats(fieldDict.BytesRead(), ctx) + } + + return NewMultiTermSearcher(ctx, indexReader, terms, field, boost, options, true) +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/sort.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/sort.go new file mode 100644 index 0000000000..3a744af992 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/sort.go @@ -0,0 +1,749 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package search + +import ( + "bytes" + "encoding/json" + "fmt" + "math" + "sort" + "strings" + "unicode/utf8" + + "github.com/blevesearch/bleve/v2/geo" + "github.com/blevesearch/bleve/v2/numeric" +) + +var HighTerm = strings.Repeat(string(utf8.MaxRune), 3) +var LowTerm = string([]byte{0x00}) + +type SearchSort interface { + UpdateVisitor(field string, term []byte) + Value(a *DocumentMatch) string + Descending() bool + + RequiresDocID() bool + RequiresScoring() bool + RequiresFields() []string + + Reverse() + + Copy() SearchSort +} + +func ParseSearchSortObj(input map[string]interface{}) (SearchSort, error) { + descending, ok := input["desc"].(bool) + by, ok := input["by"].(string) + if !ok { + return nil, fmt.Errorf("search sort must specify by") + } + switch by { + case "id": + return &SortDocID{ + Desc: descending, + }, nil + case "score": + return &SortScore{ + Desc: descending, + }, nil + case "geo_distance": + field, ok := input["field"].(string) + if !ok { + return nil, fmt.Errorf("search sort mode geo_distance must specify field") + } + lon, lat, foundLocation := geo.ExtractGeoPoint(input["location"]) + if !foundLocation { + return nil, fmt.Errorf("unable to parse geo_distance location") + } + rvd := &SortGeoDistance{ + Field: field, + Desc: descending, + Lon: lon, + Lat: lat, + unitMult: 1.0, + } + if distUnit, ok := input["unit"].(string); ok { + var err error + rvd.unitMult, err = geo.ParseDistanceUnit(distUnit) + if err != nil { + return nil, err + } + rvd.Unit = distUnit + } + return rvd, nil + case "field": + field, ok := input["field"].(string) + if !ok { + return nil, fmt.Errorf("search sort mode field must specify field") + } + rv := &SortField{ + Field: field, + Desc: descending, + } + typ, ok := input["type"].(string) + if ok { + switch typ { + case "auto": + rv.Type = SortFieldAuto + case "string": + rv.Type = SortFieldAsString + case "number": + rv.Type = SortFieldAsNumber + case "date": + rv.Type = SortFieldAsDate + default: + return nil, fmt.Errorf("unknown sort field type: %s", typ) + } + } + mode, ok := input["mode"].(string) + if ok { + switch mode { + case "default": + rv.Mode = SortFieldDefault + case "min": + rv.Mode = SortFieldMin + case "max": + rv.Mode = SortFieldMax + default: + return nil, fmt.Errorf("unknown sort field mode: %s", mode) + } + } + missing, ok := input["missing"].(string) + if ok { + switch missing { + case "first": + rv.Missing = SortFieldMissingFirst + case "last": + rv.Missing = SortFieldMissingLast + default: + return nil, fmt.Errorf("unknown sort field missing: %s", missing) + } + } + return rv, nil + } + + return nil, fmt.Errorf("unknown search sort by: %s", by) +} + +func ParseSearchSortString(input string) SearchSort { + descending := false + if strings.HasPrefix(input, "-") { + descending = true + input = input[1:] + } else if strings.HasPrefix(input, "+") { + input = input[1:] + } + if input == "_id" { + return &SortDocID{ + Desc: descending, + } + } else if input == "_score" { + return &SortScore{ + Desc: descending, + } + } + return &SortField{ + Field: input, + Desc: descending, + } +} + +func ParseSearchSortJSON(input json.RawMessage) (SearchSort, error) { + // first try to parse it as string + var sortString string + err := json.Unmarshal(input, &sortString) + if err != nil { + var sortObj map[string]interface{} + err = json.Unmarshal(input, &sortObj) + if err != nil { + return nil, err + } + return ParseSearchSortObj(sortObj) + } + return ParseSearchSortString(sortString), nil +} + +func ParseSortOrderStrings(in []string) SortOrder { + rv := make(SortOrder, 0, len(in)) + for _, i := range in { + ss := ParseSearchSortString(i) + rv = append(rv, ss) + } + return rv +} + +func ParseSortOrderJSON(in []json.RawMessage) (SortOrder, error) { + rv := make(SortOrder, 0, len(in)) + for _, i := range in { + ss, err := ParseSearchSortJSON(i) + if err != nil { + return nil, err + } + rv = append(rv, ss) + } + return rv, nil +} + +type SortOrder []SearchSort + +func (so SortOrder) Value(doc *DocumentMatch) { + for _, soi := range so { + doc.Sort = append(doc.Sort, soi.Value(doc)) + } +} + +func (so SortOrder) UpdateVisitor(field string, term []byte) { + for _, soi := range so { + soi.UpdateVisitor(field, term) + } +} + +func (so SortOrder) Copy() SortOrder { + rv := make(SortOrder, len(so)) + for i, soi := range so { + rv[i] = soi.Copy() + } + return rv +} + +// Compare will compare two document matches using the specified sort order +// if both are numbers, we avoid converting back to term +func (so SortOrder) Compare(cachedScoring, cachedDesc []bool, i, j *DocumentMatch) int { + // compare the documents on all search sorts until a differences is found + for x := range so { + c := 0 + if cachedScoring[x] { + if i.Score < j.Score { + c = -1 + } else if i.Score > j.Score { + c = 1 + } + } else { + iVal := i.Sort[x] + jVal := j.Sort[x] + if iVal < jVal { + c = -1 + } else if iVal > jVal { + c = 1 + } + } + + if c == 0 { + continue + } + if cachedDesc[x] { + c = -c + } + return c + } + // if they are the same at this point, impose order based on index natural sort order + if i.HitNumber == j.HitNumber { + return 0 + } else if i.HitNumber > j.HitNumber { + return 1 + } + return -1 +} + +func (so SortOrder) RequiresScore() bool { + for _, soi := range so { + if soi.RequiresScoring() { + return true + } + } + return false +} + +func (so SortOrder) RequiresDocID() bool { + for _, soi := range so { + if soi.RequiresDocID() { + return true + } + } + return false +} + +func (so SortOrder) RequiredFields() []string { + var rv []string + for _, soi := range so { + rv = append(rv, soi.RequiresFields()...) + } + return rv +} + +func (so SortOrder) CacheIsScore() []bool { + rv := make([]bool, 0, len(so)) + for _, soi := range so { + rv = append(rv, soi.RequiresScoring()) + } + return rv +} + +func (so SortOrder) CacheDescending() []bool { + rv := make([]bool, 0, len(so)) + for _, soi := range so { + rv = append(rv, soi.Descending()) + } + return rv +} + +func (so SortOrder) Reverse() { + for _, soi := range so { + soi.Reverse() + } +} + +// SortFieldType lets you control some internal sort behavior +// normally leaving this to the zero-value of SortFieldAuto is fine +type SortFieldType int + +const ( + // SortFieldAuto applies heuristics attempt to automatically sort correctly + SortFieldAuto SortFieldType = iota + // SortFieldAsString forces sort as string (no prefix coded terms removed) + SortFieldAsString + // SortFieldAsNumber forces sort as string (prefix coded terms with shift > 0 removed) + SortFieldAsNumber + // SortFieldAsDate forces sort as string (prefix coded terms with shift > 0 removed) + SortFieldAsDate +) + +// SortFieldMode describes the behavior if the field has multiple values +type SortFieldMode int + +const ( + // SortFieldDefault uses the first (or only) value, this is the default zero-value + SortFieldDefault SortFieldMode = iota // FIXME name is confusing + // SortFieldMin uses the minimum value + SortFieldMin + // SortFieldMax uses the maximum value + SortFieldMax +) + +// SortFieldMissing controls where documents missing a field value should be sorted +type SortFieldMissing int + +const ( + // SortFieldMissingLast sorts documents missing a field at the end + SortFieldMissingLast SortFieldMissing = iota + + // SortFieldMissingFirst sorts documents missing a field at the beginning + SortFieldMissingFirst +) + +// SortField will sort results by the value of a stored field +// +// Field is the name of the field +// Descending reverse the sort order (default false) +// Type allows forcing of string/number/date behavior (default auto) +// Mode controls behavior for multi-values fields (default first) +// Missing controls behavior of missing values (default last) +type SortField struct { + Field string + Desc bool + Type SortFieldType + Mode SortFieldMode + Missing SortFieldMissing + values [][]byte + tmp [][]byte +} + +// UpdateVisitor notifies this sort field that in this document +// this field has the specified term +func (s *SortField) UpdateVisitor(field string, term []byte) { + if field == s.Field { + s.values = append(s.values, term) + } +} + +// Value returns the sort value of the DocumentMatch +// it also resets the state of this SortField for +// processing the next document +func (s *SortField) Value(i *DocumentMatch) string { + iTerms := s.filterTermsByType(s.values) + iTerm := s.filterTermsByMode(iTerms) + s.values = s.values[:0] + return iTerm +} + +// Descending determines the order of the sort +func (s *SortField) Descending() bool { + return s.Desc +} + +func (s *SortField) filterTermsByMode(terms [][]byte) string { + if len(terms) == 1 || (len(terms) > 1 && s.Mode == SortFieldDefault) { + return string(terms[0]) + } else if len(terms) > 1 { + switch s.Mode { + case SortFieldMin: + sort.Sort(BytesSlice(terms)) + return string(terms[0]) + case SortFieldMax: + sort.Sort(BytesSlice(terms)) + return string(terms[len(terms)-1]) + } + } + + // handle missing terms + if s.Missing == SortFieldMissingLast { + if s.Desc { + return LowTerm + } + return HighTerm + } + if s.Desc { + return HighTerm + } + return LowTerm +} + +// filterTermsByType attempts to make one pass on the terms +// if we are in auto-mode AND all the terms look like prefix-coded numbers +// return only the terms which had shift of 0 +// if we are in explicit number or date mode, return only valid +// prefix coded numbers with shift of 0 +func (s *SortField) filterTermsByType(terms [][]byte) [][]byte { + stype := s.Type + if stype == SortFieldAuto { + allTermsPrefixCoded := true + termsWithShiftZero := s.tmp[:0] + for _, term := range terms { + valid, shift := numeric.ValidPrefixCodedTermBytes(term) + if valid && shift == 0 { + termsWithShiftZero = append(termsWithShiftZero, term) + } else if !valid { + allTermsPrefixCoded = false + } + } + // reset the terms only when valid zero shift terms are found. + if allTermsPrefixCoded && len(termsWithShiftZero) > 0 { + terms = termsWithShiftZero + s.tmp = termsWithShiftZero[:0] + } + } else if stype == SortFieldAsNumber || stype == SortFieldAsDate { + termsWithShiftZero := s.tmp[:0] + for _, term := range terms { + valid, shift := numeric.ValidPrefixCodedTermBytes(term) + if valid && shift == 0 { + termsWithShiftZero = append(termsWithShiftZero, term) + } + } + terms = termsWithShiftZero + s.tmp = termsWithShiftZero[:0] + } + return terms +} + +// RequiresDocID says this SearchSort does not require the DocID be loaded +func (s *SortField) RequiresDocID() bool { return false } + +// RequiresScoring says this SearchStore does not require scoring +func (s *SortField) RequiresScoring() bool { return false } + +// RequiresFields says this SearchStore requires the specified stored field +func (s *SortField) RequiresFields() []string { return []string{s.Field} } + +func (s *SortField) MarshalJSON() ([]byte, error) { + // see if simple format can be used + if s.Missing == SortFieldMissingLast && + s.Mode == SortFieldDefault && + s.Type == SortFieldAuto { + if s.Desc { + return json.Marshal("-" + s.Field) + } + return json.Marshal(s.Field) + } + sfm := map[string]interface{}{ + "by": "field", + "field": s.Field, + } + if s.Desc { + sfm["desc"] = true + } + if s.Missing > SortFieldMissingLast { + switch s.Missing { + case SortFieldMissingFirst: + sfm["missing"] = "first" + } + } + if s.Mode > SortFieldDefault { + switch s.Mode { + case SortFieldMin: + sfm["mode"] = "min" + case SortFieldMax: + sfm["mode"] = "max" + } + } + if s.Type > SortFieldAuto { + switch s.Type { + case SortFieldAsString: + sfm["type"] = "string" + case SortFieldAsNumber: + sfm["type"] = "number" + case SortFieldAsDate: + sfm["type"] = "date" + } + } + + return json.Marshal(sfm) +} + +func (s *SortField) Copy() SearchSort { + rv := *s + return &rv +} + +func (s *SortField) Reverse() { + s.Desc = !s.Desc + if s.Missing == SortFieldMissingFirst { + s.Missing = SortFieldMissingLast + } else { + s.Missing = SortFieldMissingFirst + } +} + +// SortDocID will sort results by the document identifier +type SortDocID struct { + Desc bool +} + +// UpdateVisitor is a no-op for SortDocID as it's value +// is not dependent on any field terms +func (s *SortDocID) UpdateVisitor(field string, term []byte) { +} + +// Value returns the sort value of the DocumentMatch +func (s *SortDocID) Value(i *DocumentMatch) string { + return i.ID +} + +// Descending determines the order of the sort +func (s *SortDocID) Descending() bool { + return s.Desc +} + +// RequiresDocID says this SearchSort does require the DocID be loaded +func (s *SortDocID) RequiresDocID() bool { return true } + +// RequiresScoring says this SearchStore does not require scoring +func (s *SortDocID) RequiresScoring() bool { return false } + +// RequiresFields says this SearchStore does not require any stored fields +func (s *SortDocID) RequiresFields() []string { return nil } + +func (s *SortDocID) MarshalJSON() ([]byte, error) { + if s.Desc { + return json.Marshal("-_id") + } + return json.Marshal("_id") +} + +func (s *SortDocID) Copy() SearchSort { + rv := *s + return &rv +} + +func (s *SortDocID) Reverse() { + s.Desc = !s.Desc +} + +// SortScore will sort results by the document match score +type SortScore struct { + Desc bool +} + +// UpdateVisitor is a no-op for SortScore as it's value +// is not dependent on any field terms +func (s *SortScore) UpdateVisitor(field string, term []byte) { +} + +// Value returns the sort value of the DocumentMatch +func (s *SortScore) Value(i *DocumentMatch) string { + return "_score" +} + +// Descending determines the order of the sort +func (s *SortScore) Descending() bool { + return s.Desc +} + +// RequiresDocID says this SearchSort does not require the DocID be loaded +func (s *SortScore) RequiresDocID() bool { return false } + +// RequiresScoring says this SearchStore does require scoring +func (s *SortScore) RequiresScoring() bool { return true } + +// RequiresFields says this SearchStore does not require any store fields +func (s *SortScore) RequiresFields() []string { return nil } + +func (s *SortScore) MarshalJSON() ([]byte, error) { + if s.Desc { + return json.Marshal("-_score") + } + return json.Marshal("_score") +} + +func (s *SortScore) Copy() SearchSort { + rv := *s + return &rv +} + +func (s *SortScore) Reverse() { + s.Desc = !s.Desc +} + +var maxDistance = string(numeric.MustNewPrefixCodedInt64(math.MaxInt64, 0)) + +// NewSortGeoDistance creates SearchSort instance for sorting documents by +// their distance from the specified point. +func NewSortGeoDistance(field, unit string, lon, lat float64, desc bool) ( + *SortGeoDistance, error) { + rv := &SortGeoDistance{ + Field: field, + Desc: desc, + Unit: unit, + Lon: lon, + Lat: lat, + } + var err error + rv.unitMult, err = geo.ParseDistanceUnit(unit) + if err != nil { + return nil, err + } + return rv, nil +} + +// SortGeoDistance will sort results by the distance of an +// indexed geo point, from the provided location. +// +// Field is the name of the field +// Descending reverse the sort order (default false) +type SortGeoDistance struct { + Field string + Desc bool + Unit string + values []string + Lon float64 + Lat float64 + unitMult float64 +} + +// UpdateVisitor notifies this sort field that in this document +// this field has the specified term +func (s *SortGeoDistance) UpdateVisitor(field string, term []byte) { + if field == s.Field { + s.values = append(s.values, string(term)) + } +} + +// Value returns the sort value of the DocumentMatch +// it also resets the state of this SortField for +// processing the next document +func (s *SortGeoDistance) Value(i *DocumentMatch) string { + iTerms := s.filterTermsByType(s.values) + iTerm := s.filterTermsByMode(iTerms) + s.values = s.values[:0] + + if iTerm == "" { + return maxDistance + } + + i64, err := numeric.PrefixCoded(iTerm).Int64() + if err != nil { + return maxDistance + } + docLon := geo.MortonUnhashLon(uint64(i64)) + docLat := geo.MortonUnhashLat(uint64(i64)) + + dist := geo.Haversin(s.Lon, s.Lat, docLon, docLat) + // dist is returned in km, so convert to m + dist *= 1000 + if s.unitMult != 0 { + dist /= s.unitMult + } + distInt64 := numeric.Float64ToInt64(dist) + return string(numeric.MustNewPrefixCodedInt64(distInt64, 0)) +} + +// Descending determines the order of the sort +func (s *SortGeoDistance) Descending() bool { + return s.Desc +} + +func (s *SortGeoDistance) filterTermsByMode(terms []string) string { + if len(terms) >= 1 { + return terms[0] + } + + return "" +} + +// filterTermsByType attempts to make one pass on the terms +// return only valid prefix coded numbers with shift of 0 +func (s *SortGeoDistance) filterTermsByType(terms []string) []string { + var termsWithShiftZero []string + for _, term := range terms { + valid, shift := numeric.ValidPrefixCodedTerm(term) + if valid && shift == 0 { + termsWithShiftZero = append(termsWithShiftZero, term) + } + } + return termsWithShiftZero +} + +// RequiresDocID says this SearchSort does not require the DocID be loaded +func (s *SortGeoDistance) RequiresDocID() bool { return false } + +// RequiresScoring says this SearchStore does not require scoring +func (s *SortGeoDistance) RequiresScoring() bool { return false } + +// RequiresFields says this SearchStore requires the specified stored field +func (s *SortGeoDistance) RequiresFields() []string { return []string{s.Field} } + +func (s *SortGeoDistance) MarshalJSON() ([]byte, error) { + sfm := map[string]interface{}{ + "by": "geo_distance", + "field": s.Field, + "location": map[string]interface{}{ + "lon": s.Lon, + "lat": s.Lat, + }, + } + if s.Unit != "" { + sfm["unit"] = s.Unit + } + if s.Desc { + sfm["desc"] = true + } + + return json.Marshal(sfm) +} + +func (s *SortGeoDistance) Copy() SearchSort { + rv := *s + return &rv +} + +func (s *SortGeoDistance) Reverse() { + s.Desc = !s.Desc +} + +type BytesSlice [][]byte + +func (p BytesSlice) Len() int { return len(p) } +func (p BytesSlice) Less(i, j int) bool { return bytes.Compare(p[i], p[j]) < 0 } +func (p BytesSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/search/util.go b/backend/vendor/github.com/blevesearch/bleve/v2/search/util.go new file mode 100644 index 0000000000..19dd5d68bd --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/search/util.go @@ -0,0 +1,69 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package search + +func MergeLocations(locations []FieldTermLocationMap) FieldTermLocationMap { + rv := locations[0] + + for i := 1; i < len(locations); i++ { + nextLocations := locations[i] + for field, termLocationMap := range nextLocations { + rvTermLocationMap, rvHasField := rv[field] + if rvHasField { + rv[field] = MergeTermLocationMaps(rvTermLocationMap, termLocationMap) + } else { + rv[field] = termLocationMap + } + } + } + + return rv +} + +func MergeTermLocationMaps(rv, other TermLocationMap) TermLocationMap { + for term, locationMap := range other { + // for a given term/document there cannot be different locations + // if they came back from different clauses, overwrite is ok + rv[term] = locationMap + } + return rv +} + +func MergeFieldTermLocations(dest []FieldTermLocation, matches []*DocumentMatch) []FieldTermLocation { + n := len(dest) + for _, dm := range matches { + n += len(dm.FieldTermLocations) + } + if cap(dest) < n { + dest = append(make([]FieldTermLocation, 0, n), dest...) + } + + for _, dm := range matches { + for _, ftl := range dm.FieldTermLocations { + dest = append(dest, FieldTermLocation{ + Field: ftl.Field, + Term: ftl.Term, + Location: Location{ + Pos: ftl.Location.Pos, + Start: ftl.Location.Start, + End: ftl.Location.End, + ArrayPositions: append(ArrayPositions(nil), ftl.Location.ArrayPositions...), + }, + }) + } + } + + return dest +} diff --git a/backend/vendor/github.com/blevesearch/bleve/v2/size/sizes.go b/backend/vendor/github.com/blevesearch/bleve/v2/size/sizes.go new file mode 100644 index 0000000000..0990bf86ec --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve/v2/size/sizes.go @@ -0,0 +1,59 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package size + +import ( + "reflect" +) + +func init() { + var b bool + SizeOfBool = int(reflect.TypeOf(b).Size()) + var f32 float32 + SizeOfFloat32 = int(reflect.TypeOf(f32).Size()) + var f64 float64 + SizeOfFloat64 = int(reflect.TypeOf(f64).Size()) + var i int + SizeOfInt = int(reflect.TypeOf(i).Size()) + var m map[int]int + SizeOfMap = int(reflect.TypeOf(m).Size()) + var ptr *int + SizeOfPtr = int(reflect.TypeOf(ptr).Size()) + var slice []int + SizeOfSlice = int(reflect.TypeOf(slice).Size()) + var str string + SizeOfString = int(reflect.TypeOf(str).Size()) + var u8 uint8 + SizeOfUint8 = int(reflect.TypeOf(u8).Size()) + var u16 uint16 + SizeOfUint16 = int(reflect.TypeOf(u16).Size()) + var u32 uint32 + SizeOfUint32 = int(reflect.TypeOf(u32).Size()) + var u64 uint64 + SizeOfUint64 = int(reflect.TypeOf(u64).Size()) +} + +var SizeOfBool int +var SizeOfFloat32 int +var SizeOfFloat64 int +var SizeOfInt int +var SizeOfMap int +var SizeOfPtr int +var SizeOfSlice int +var SizeOfString int +var SizeOfUint8 int +var SizeOfUint16 int +var SizeOfUint32 int +var SizeOfUint64 int diff --git a/backend/vendor/github.com/blevesearch/bleve_index_api/.golangci.yml b/backend/vendor/github.com/blevesearch/bleve_index_api/.golangci.yml new file mode 100644 index 0000000000..a00f6c57e4 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve_index_api/.golangci.yml @@ -0,0 +1,37 @@ +linters: + # please, do not use `enable-all`: it's deprecated and will be removed soon. + # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint + disable-all: true + enable: + - bodyclose + - deadcode + - depguard + - dogsled + - dupl + - errcheck + - goconst + - gocritic + - gocyclo + - gofmt + - goimports + - gomnd + - goprintffuncname + - gosimple + - govet + - ineffassign + - interfacer + - lll + - misspell + - nakedret + - nolintlint + - rowserrcheck + - scopelint + - staticcheck + - structcheck + - stylecheck + - typecheck + - unconvert + - unparam + - unused + - varcheck + - whitespace diff --git a/backend/vendor/github.com/blevesearch/bleve_index_api/LICENSE b/backend/vendor/github.com/blevesearch/bleve_index_api/LICENSE new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve_index_api/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/backend/vendor/github.com/blevesearch/bleve_index_api/README.md b/backend/vendor/github.com/blevesearch/bleve_index_api/README.md new file mode 100644 index 0000000000..46daa68322 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve_index_api/README.md @@ -0,0 +1,11 @@ +# Bleve Index API + +[![PkgGoDev](https://pkg.go.dev/badge/github.com/blevesearch/bleve_index_api)](https://pkg.go.dev/github.com/blevesearch/bleve_index_api) +[![Tests](https://github.com/blevesearch/bleve_index_api/workflows/Tests/badge.svg?branch=master&event=push)](https://github.com/blevesearch/bleve_index_api/actions?query=workflow%3ATests+event%3Apush+branch%3Amaster) +[![Lint](https://github.com/blevesearch/bleve_index_api/workflows/Lint/badge.svg?branch=master&event=push)](https://github.com/blevesearch/bleve_index_api/actions?query=workflow%3ALint+event%3Apush+branch%3Amaster) + +Bleve supports a pluggable Index interface. + +By placing these interfaces in their own, *hopefully* slowly evolving module, it frees up Bleve and the underlying index to each introduce new major versions without interfering with one another. + +With that in mind, we anticipate introducing non-breaking changes only to this module, and keeping the major version at 1.x for some time. \ No newline at end of file diff --git a/backend/vendor/github.com/blevesearch/bleve_index_api/analysis.go b/backend/vendor/github.com/blevesearch/bleve_index_api/analysis.go new file mode 100644 index 0000000000..5ab616c1a0 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve_index_api/analysis.go @@ -0,0 +1,53 @@ +// Copyright (c) 2015 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package index + +type AnalysisWork func() + +type AnalysisQueue struct { + queue chan AnalysisWork + done chan struct{} +} + +func (q *AnalysisQueue) Queue(work AnalysisWork) { + q.queue <- work +} + +func (q *AnalysisQueue) Close() { + close(q.done) +} + +func NewAnalysisQueue(numWorkers int) *AnalysisQueue { + rv := AnalysisQueue{ + queue: make(chan AnalysisWork), + done: make(chan struct{}), + } + for i := 0; i < numWorkers; i++ { + go AnalysisWorker(rv) + } + return &rv +} + +func AnalysisWorker(q AnalysisQueue) { + // read work off the queue + for { + select { + case <-q.done: + return + case w := <-q.queue: + w() + } + } +} diff --git a/backend/vendor/github.com/blevesearch/bleve_index_api/batch.go b/backend/vendor/github.com/blevesearch/bleve_index_api/batch.go new file mode 100644 index 0000000000..ff1eaf6c6e --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve_index_api/batch.go @@ -0,0 +1,101 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package index + +import "fmt" + +type BatchCallback func(error) + +type Batch struct { + IndexOps map[string]Document + InternalOps map[string][]byte + persistedCallback BatchCallback +} + +func NewBatch() *Batch { + return &Batch{ + IndexOps: make(map[string]Document), + InternalOps: make(map[string][]byte), + } +} + +func (b *Batch) Update(doc Document) { + b.IndexOps[doc.ID()] = doc +} + +func (b *Batch) Delete(id string) { + b.IndexOps[id] = nil +} + +func (b *Batch) SetInternal(key, val []byte) { + b.InternalOps[string(key)] = val +} + +func (b *Batch) DeleteInternal(key []byte) { + b.InternalOps[string(key)] = nil +} + +func (b *Batch) SetPersistedCallback(f BatchCallback) { + b.persistedCallback = f +} + +func (b *Batch) PersistedCallback() BatchCallback { + return b.persistedCallback +} + +func (b *Batch) String() string { + rv := fmt.Sprintf("Batch (%d ops, %d internal ops)\n", len(b.IndexOps), len(b.InternalOps)) + for k, v := range b.IndexOps { + if v != nil { + rv += fmt.Sprintf("\tINDEX - '%s'\n", k) + } else { + rv += fmt.Sprintf("\tDELETE - '%s'\n", k) + } + } + for k, v := range b.InternalOps { + if v != nil { + rv += fmt.Sprintf("\tSET INTERNAL - '%s'\n", k) + } else { + rv += fmt.Sprintf("\tDELETE INTERNAL - '%s'\n", k) + } + } + return rv +} + +func (b *Batch) Reset() { + b.IndexOps = make(map[string]Document) + b.InternalOps = make(map[string][]byte) + b.persistedCallback = nil +} + +func (b *Batch) Merge(o *Batch) { + for k, v := range o.IndexOps { + b.IndexOps[k] = v + } + for k, v := range o.InternalOps { + b.InternalOps[k] = v + } +} + +func (b *Batch) TotalDocSize() int { + var s int + for k, v := range b.IndexOps { + if v != nil { + s += v.Size() + sizeOfString + } + s += len(k) + } + return s +} diff --git a/backend/vendor/github.com/blevesearch/bleve_index_api/directory.go b/backend/vendor/github.com/blevesearch/bleve_index_api/directory.go new file mode 100644 index 0000000000..709a384565 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve_index_api/directory.go @@ -0,0 +1,23 @@ +// Copyright (c) 2021 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package index + +import ( + "io" +) + +type Directory interface { + GetWriter(filePath string) (io.WriteCloser, error) +} diff --git a/backend/vendor/github.com/blevesearch/bleve_index_api/document.go b/backend/vendor/github.com/blevesearch/bleve_index_api/document.go new file mode 100644 index 0000000000..416d701297 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve_index_api/document.go @@ -0,0 +1,93 @@ +// Copyright (c) 2015 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package index + +import "time" + +type Document interface { + ID() string + Size() int + + VisitFields(visitor FieldVisitor) + VisitComposite(visitor CompositeFieldVisitor) + HasComposite() bool + + NumPlainTextBytes() uint64 + + AddIDField() + + StoredFieldsBytes() uint64 +} + +type FieldVisitor func(Field) + +type Field interface { + Name() string + Value() []byte + ArrayPositions() []uint64 + + EncodedFieldType() byte + + Analyze() + + Options() FieldIndexingOptions + + AnalyzedLength() int + AnalyzedTokenFrequencies() TokenFrequencies + + NumPlainTextBytes() uint64 +} + +type CompositeFieldVisitor func(field CompositeField) + +type CompositeField interface { + Field + + Compose(field string, length int, freq TokenFrequencies) +} + +type TextField interface { + Text() string +} + +type NumericField interface { + Number() (float64, error) +} + +type DateTimeField interface { + DateTime() (time.Time, error) +} + +type BooleanField interface { + Boolean() (bool, error) +} + +type GeoPointField interface { + Lon() (float64, error) + Lat() (float64, error) +} + +type GeoShapeField interface { + GeoShape() (GeoJSON, error) +} + +// TokenizableSpatialField is an optional interface for fields that +// supports pluggable custom hierarchial spatial token generation. +type TokenizableSpatialField interface { + // SetSpatialAnalyzerPlugin lets the index implementations to + // initialise relevant spatial analyzer plugins for the field + // to override the spatial token generations during the analysis phase. + SetSpatialAnalyzerPlugin(SpatialAnalyzerPlugin) +} diff --git a/backend/vendor/github.com/blevesearch/bleve_index_api/freq.go b/backend/vendor/github.com/blevesearch/bleve_index_api/freq.go new file mode 100644 index 0000000000..5b6c7e1d82 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve_index_api/freq.go @@ -0,0 +1,106 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package index + +import "reflect" + +var reflectStaticSizeTokenLocation int +var reflectStaticSizeTokenFreq int + +func init() { + var tl TokenLocation + reflectStaticSizeTokenLocation = int(reflect.TypeOf(tl).Size()) + var tf TokenFreq + reflectStaticSizeTokenFreq = int(reflect.TypeOf(tf).Size()) +} + +// TokenLocation represents one occurrence of a term at a particular location in +// a field. Start, End and Position have the same meaning as in analysis.Token. +// Field and ArrayPositions identify the field value in the source document. +// See document.Field for details. +type TokenLocation struct { + Field string + ArrayPositions []uint64 + Start int + End int + Position int +} + +func (tl *TokenLocation) Size() int { + rv := reflectStaticSizeTokenLocation + rv += len(tl.ArrayPositions) * sizeOfUint64 + return rv +} + +// TokenFreq represents all the occurrences of a term in all fields of a +// document. +type TokenFreq struct { + Term []byte + Locations []*TokenLocation + frequency int +} + +func (tf *TokenFreq) Size() int { + rv := reflectStaticSizeTokenFreq + rv += len(tf.Term) + for _, loc := range tf.Locations { + rv += loc.Size() + } + return rv +} + +func (tf *TokenFreq) Frequency() int { + return tf.frequency +} + +func (tf *TokenFreq) SetFrequency(frequency int) { + tf.frequency = frequency +} + +// TokenFrequencies maps document terms to their combined frequencies from all +// fields. +type TokenFrequencies map[string]*TokenFreq + +func (tfs TokenFrequencies) Size() int { + rv := sizeOfMap + rv += len(tfs) * (sizeOfString + sizeOfPtr) + for k, v := range tfs { + rv += len(k) + rv += v.Size() + } + return rv +} + +func (tfs TokenFrequencies) MergeAll(remoteField string, other TokenFrequencies) { + // walk the new token frequencies + for tfk, tf := range other { + // set the remoteField value in incoming token freqs + for _, l := range tf.Locations { + l.Field = remoteField + } + existingTf, exists := tfs[tfk] + if exists { + existingTf.Locations = append(existingTf.Locations, tf.Locations...) + existingTf.frequency += tf.frequency + } else { + tfs[tfk] = &TokenFreq{ + Term: tf.Term, + frequency: tf.frequency, + Locations: make([]*TokenLocation, len(tf.Locations)), + } + copy(tfs[tfk].Locations, tf.Locations) + } + } +} diff --git a/backend/vendor/github.com/blevesearch/bleve_index_api/index.go b/backend/vendor/github.com/blevesearch/bleve_index_api/index.go new file mode 100644 index 0000000000..4c916d5c20 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve_index_api/index.go @@ -0,0 +1,227 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package index + +import ( + "bytes" + "context" + "reflect" +) + +var reflectStaticSizeTermFieldDoc int +var reflectStaticSizeTermFieldVector int + +func init() { + var tfd TermFieldDoc + reflectStaticSizeTermFieldDoc = int(reflect.TypeOf(tfd).Size()) + var tfv TermFieldVector + reflectStaticSizeTermFieldVector = int(reflect.TypeOf(tfv).Size()) +} + +type Index interface { + Open() error + Close() error + + Update(doc Document) error + Delete(id string) error + Batch(batch *Batch) error + + SetInternal(key, val []byte) error + DeleteInternal(key []byte) error + + // Reader returns a low-level accessor on the index data. Close it to + // release associated resources. + Reader() (IndexReader, error) + + StatsMap() map[string]interface{} +} + +type IndexReader interface { + TermFieldReader(ctx context.Context, term []byte, field string, includeFreq, includeNorm, includeTermVectors bool) (TermFieldReader, error) + + // DocIDReader returns an iterator over all doc ids + // The caller must close returned instance to release associated resources. + DocIDReaderAll() (DocIDReader, error) + + DocIDReaderOnly(ids []string) (DocIDReader, error) + + FieldDict(field string) (FieldDict, error) + + // FieldDictRange is currently defined to include the start and end terms + FieldDictRange(field string, startTerm []byte, endTerm []byte) (FieldDict, error) + FieldDictPrefix(field string, termPrefix []byte) (FieldDict, error) + + Document(id string) (Document, error) + + DocValueReader(fields []string) (DocValueReader, error) + + Fields() ([]string, error) + + GetInternal(key []byte) ([]byte, error) + + DocCount() (uint64, error) + + ExternalID(id IndexInternalID) (string, error) + InternalID(id string) (IndexInternalID, error) + + Close() error +} + +type IndexReaderRegexp interface { + FieldDictRegexp(field string, regex string) (FieldDict, error) +} + +type IndexReaderFuzzy interface { + FieldDictFuzzy(field string, term string, fuzziness int, prefix string) (FieldDict, error) +} + +type IndexReaderContains interface { + FieldDictContains(field string) (FieldDictContains, error) +} + +// SpatialIndexPlugin is an optional interface for exposing the +// support for any custom analyzer plugins that are capable of +// generating hierarchial spatial tokens for both indexing and +// query purposes from the geo location data. +type SpatialIndexPlugin interface { + GetSpatialAnalyzerPlugin(typ string) (SpatialAnalyzerPlugin, error) +} + +type TermFieldVector struct { + Field string + ArrayPositions []uint64 + Pos uint64 + Start uint64 + End uint64 +} + +func (tfv *TermFieldVector) Size() int { + return reflectStaticSizeTermFieldVector + sizeOfPtr + + len(tfv.Field) + len(tfv.ArrayPositions)*sizeOfUint64 +} + +// IndexInternalID is an opaque document identifier interal to the index impl +type IndexInternalID []byte + +func (id IndexInternalID) Equals(other IndexInternalID) bool { + return id.Compare(other) == 0 +} + +func (id IndexInternalID) Compare(other IndexInternalID) int { + return bytes.Compare(id, other) +} + +type TermFieldDoc struct { + Term string + ID IndexInternalID + Freq uint64 + Norm float64 + Vectors []*TermFieldVector +} + +func (tfd *TermFieldDoc) Size() int { + sizeInBytes := reflectStaticSizeTermFieldDoc + sizeOfPtr + + len(tfd.Term) + len(tfd.ID) + + for _, entry := range tfd.Vectors { + sizeInBytes += entry.Size() + } + + return sizeInBytes +} + +// Reset allows an already allocated TermFieldDoc to be reused +func (tfd *TermFieldDoc) Reset() *TermFieldDoc { + // remember the []byte used for the ID + id := tfd.ID + vectors := tfd.Vectors + // idiom to copy over from empty TermFieldDoc (0 allocations) + *tfd = TermFieldDoc{} + // reuse the []byte already allocated (and reset len to 0) + tfd.ID = id[:0] + tfd.Vectors = vectors[:0] + return tfd +} + +// TermFieldReader is the interface exposing the enumeration of documents +// containing a given term in a given field. Documents are returned in byte +// lexicographic order over their identifiers. +type TermFieldReader interface { + // Next returns the next document containing the term in this field, or nil + // when it reaches the end of the enumeration. The preAlloced TermFieldDoc + // is optional, and when non-nil, will be used instead of allocating memory. + Next(preAlloced *TermFieldDoc) (*TermFieldDoc, error) + + // Advance resets the enumeration at specified document or its immediate + // follower. + Advance(ID IndexInternalID, preAlloced *TermFieldDoc) (*TermFieldDoc, error) + + // Count returns the number of documents contains the term in this field. + Count() uint64 + Close() error + + Size() int +} + +type DictEntry struct { + Term string + Count uint64 +} + +type FieldDict interface { + Next() (*DictEntry, error) + Close() error + + BytesRead() uint64 +} + +type FieldDictContains interface { + Contains(key []byte) (bool, error) + + BytesRead() uint64 +} + +// DocIDReader is the interface exposing enumeration of documents identifiers. +// Close the reader to release associated resources. +type DocIDReader interface { + // Next returns the next document internal identifier in the natural + // index order, nil when the end of the sequence is reached. + Next() (IndexInternalID, error) + + // Advance resets the iteration to the first internal identifier greater than + // or equal to ID. If ID is smaller than the start of the range, the iteration + // will start there instead. If ID is greater than or equal to the end of + // the range, Next() call will return io.EOF. + Advance(ID IndexInternalID) (IndexInternalID, error) + + Size() int + + Close() error +} + +type DocValueVisitor func(field string, term []byte) + +type DocValueReader interface { + VisitDocValues(id IndexInternalID, visitor DocValueVisitor) error + + BytesRead() uint64 +} + +// IndexBuilder is an interface supported by some index schemes +// to allow direct write-only index building +type IndexBuilder interface { + Index(doc Document) error + Close() error +} diff --git a/backend/vendor/github.com/blevesearch/bleve_index_api/indexing_options.go b/backend/vendor/github.com/blevesearch/bleve_index_api/indexing_options.go new file mode 100644 index 0000000000..9724ccae07 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve_index_api/indexing_options.go @@ -0,0 +1,77 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package index + +type FieldIndexingOptions int + +const ( + IndexField FieldIndexingOptions = 1 << iota + StoreField + IncludeTermVectors + DocValues + SkipFreqNorm +) + +func (o FieldIndexingOptions) IsIndexed() bool { + return o&IndexField != 0 +} + +func (o FieldIndexingOptions) IsStored() bool { + return o&StoreField != 0 +} + +func (o FieldIndexingOptions) IncludeTermVectors() bool { + return o&IncludeTermVectors != 0 +} + +func (o FieldIndexingOptions) IncludeDocValues() bool { + return o&DocValues != 0 +} + +func (o FieldIndexingOptions) SkipFreqNorm() bool { + return o&SkipFreqNorm != 0 +} + +func (o FieldIndexingOptions) String() string { + rv := "" + if o.IsIndexed() { + rv += "INDEXED" + } + if o.IsStored() { + if rv != "" { + rv += ", " + } + rv += "STORE" + } + if o.IncludeTermVectors() { + if rv != "" { + rv += ", " + } + rv += "TV" + } + if o.IncludeDocValues() { + if rv != "" { + rv += ", " + } + rv += "DV" + } + if !o.SkipFreqNorm() { + if rv != "" { + rv += ", " + } + rv += "FN" + } + return rv +} diff --git a/backend/vendor/github.com/blevesearch/bleve_index_api/optimize.go b/backend/vendor/github.com/blevesearch/bleve_index_api/optimize.go new file mode 100644 index 0000000000..2b4e1244c4 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve_index_api/optimize.go @@ -0,0 +1,39 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package index + +// Optimizable represents an optional interface that implementable by +// optimizable resources (e.g., TermFieldReaders, Searchers). These +// optimizable resources are provided the same OptimizableContext +// instance, so that they can coordinate via dynamic interface +// casting. +type Optimizable interface { + Optimize(kind string, octx OptimizableContext) (OptimizableContext, error) +} + +// Represents a result of optimization -- see the Finish() method. +type Optimized interface{} + +type OptimizableContext interface { + // Once all the optimzable resources have been provided the same + // OptimizableContext instance, the optimization preparations are + // finished or completed via the Finish() method. + // + // Depending on the optimization being performed, the Finish() + // method might return a non-nil Optimized instance. For example, + // the Optimized instance might represent an optimized + // TermFieldReader instance. + Finish() (Optimized, error) +} diff --git a/backend/vendor/github.com/blevesearch/bleve_index_api/sizes.go b/backend/vendor/github.com/blevesearch/bleve_index_api/sizes.go new file mode 100644 index 0000000000..65c2dd0000 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve_index_api/sizes.go @@ -0,0 +1,35 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package index + +import ( + "reflect" +) + +func init() { + var m map[int]int + sizeOfMap = int(reflect.TypeOf(m).Size()) + var ptr *int + sizeOfPtr = int(reflect.TypeOf(ptr).Size()) + var str string + sizeOfString = int(reflect.TypeOf(str).Size()) + var u64 uint64 + sizeOfUint64 = int(reflect.TypeOf(u64).Size()) +} + +var sizeOfMap int +var sizeOfPtr int +var sizeOfString int +var sizeOfUint64 int diff --git a/backend/vendor/github.com/blevesearch/bleve_index_api/spatial_plugin.go b/backend/vendor/github.com/blevesearch/bleve_index_api/spatial_plugin.go new file mode 100644 index 0000000000..bee0476989 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/bleve_index_api/spatial_plugin.go @@ -0,0 +1,47 @@ +// Copyright (c) 2022 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package index + +// SpatialAnalyzerPlugin is an interface for the custom spatial +// tokenizer implementations that supports the generation of spatial +// hierarchial tokens for both indexing and querying of geoJSON data. +type SpatialAnalyzerPlugin interface { + // Type returns the plugin type. eg: "s2". + Type() string + + // GetIndexTokens returns the tokens to be indexed for the + // given GeoJSON type data in the document. + GetIndexTokens(GeoJSON) []string + + // GetQueryTokens returns the tokens to be queried for the + // given GeoJSON type data in the document. + GetQueryTokens(GeoJSON) []string +} + +// GeoJSON is generic interface for any geoJSON shapes like +// points, polygon etc. +type GeoJSON interface { + // Returns the type of geoJSON shape. + Type() string + + // Checks whether the given shape intersects with current shape. + Intersects(GeoJSON) (bool, error) + + // Checks whether the given shape resides within the current shape. + Contains(GeoJSON) (bool, error) + + // Value returns the byte value for the shape. + Value() ([]byte, error) +} diff --git a/backend/vendor/github.com/blevesearch/geo/LICENSE b/backend/vendor/github.com/blevesearch/geo/LICENSE new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/backend/vendor/github.com/blevesearch/geo/geojson/geojson_s2_util.go b/backend/vendor/github.com/blevesearch/geo/geojson/geojson_s2_util.go new file mode 100644 index 0000000000..60d9aa89e9 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/geojson/geojson_s2_util.go @@ -0,0 +1,319 @@ +// Copyright (c) 2022 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package geojson + +import ( + "strconv" + "strings" + + index "github.com/blevesearch/bleve_index_api" + "github.com/blevesearch/geo/s2" + "github.com/golang/geo/s1" +) + +// ------------------------------------------------------------------------ + +func polylineIntersectsPoint(pls []*s2.Polyline, + point *s2.Point) bool { + s2cell := s2.CellFromPoint(*point) + + for _, pl := range pls { + if pl.IntersectsCell(s2cell) { + return true + } + } + + return false +} + +func polylineIntersectsPolygons(pls []*s2.Polyline, + s2pgns []*s2.Polygon) bool { + // Early exit if the polygon contains any of the line's vertices. + for _, pl := range pls { + for i := 0; i < pl.NumEdges(); i++ { + edge := pl.Edge(i) + for _, s2pgn := range s2pgns { + if s2pgn.IntersectsCell(s2.CellFromPoint(edge.V0)) || + s2pgn.IntersectsCell(s2.CellFromPoint(edge.V1)) { + return true + } + } + } + } + + for _, pl := range pls { + for _, s2pgn := range s2pgns { + for i := 0; i < pl.NumEdges(); i++ { + for i := 0; i < s2pgn.NumEdges(); i++ { + edgeB := s2pgn.Edge(i) + latLng1 := s2.LatLngFromPoint(edgeB.V0) + latLng2 := s2.LatLngFromPoint(edgeB.V1) + pl2 := s2.PolylineFromLatLngs([]s2.LatLng{latLng1, latLng2}) + + if pl.Intersects(pl2) { + return true + } + } + } + } + } + + return false +} + +func geometryCollectionIntersectsShape(gc *GeometryCollection, + shapeIn index.GeoJSON) bool { + for _, shape := range gc.Members() { + intersects, err := shapeIn.Intersects(shape) + if err == nil && intersects { + return true + } + } + return false +} + +func polygonsContainsLineStrings(s2pgns []*s2.Polygon, + pls []*s2.Polyline) bool { + linesWithIn := make(map[int]struct{}) + checker := s2.NewCrossingEdgeQuery(s2.NewShapeIndex()) +nextLine: + for lineIndex, pl := range pls { + for i := 0; i < len(*pl)-1; i++ { + start := (*pl)[i] + end := (*pl)[i+1] + + for _, s2pgn := range s2pgns { + containsStart := s2pgn.ContainsPoint(start) + containsEnd := s2pgn.ContainsPoint(end) + if containsStart && containsEnd { + crossings := checker.Crossings(start, end, s2pgn, s2.CrossingTypeInterior) + if len(crossings) > 0 { + continue nextLine + } + linesWithIn[lineIndex] = struct{}{} + continue nextLine + } else { + for _, loop := range s2pgn.Loops() { + for i := 0; i < loop.NumVertices(); i++ { + if !containsStart && start.ApproxEqual(loop.Vertex(i)) { + containsStart = true + } else if !containsEnd && end.ApproxEqual(loop.Vertex(i)) { + containsEnd = true + } + if containsStart && containsEnd { + linesWithIn[lineIndex] = struct{}{} + continue nextLine + } + } + } + } + } + } + } + + return len(pls) == len(linesWithIn) +} + +func rectangleIntersectsWithPolygons(s2rect *s2.Rect, + s2pgns []*s2.Polygon) bool { + s2pgnFromRect := s2PolygonFromS2Rectangle(s2rect) + for _, s2pgn := range s2pgns { + if s2pgn.Intersects(s2pgnFromRect) { + return true + } + } + + return false +} + +func rectangleIntersectsWithLineStrings(s2rect *s2.Rect, + polylines []*s2.Polyline) bool { + // Early exit path if the envelope contains any of the linestring's vertices. + for _, pl := range polylines { + for i := 0; i < pl.NumEdges(); i++ { + edge := pl.Edge(i) + if s2rect.IntersectsCell(s2.CellFromPoint(edge.V0)) || + s2rect.IntersectsCell(s2.CellFromPoint(edge.V1)) { + return true + } + } + } + + for _, pl := range polylines { + for i := 0; i < pl.NumEdges(); i++ { + for j := 0; j < 4; j++ { + pl2 := s2.PolylineFromLatLngs([]s2.LatLng{s2rect.Vertex(j), + s2rect.Vertex((j + 1) % 4)}) + + if pl.Intersects(pl2) { + return true + } + } + } + } + + return false +} + +func s2PolygonFromCoordinates(coordinates [][][]float64) *s2.Polygon { + loops := make([]*s2.Loop, 0, len(coordinates)) + for _, loop := range coordinates { + var points []s2.Point + if loop[0][0] == loop[len(loop)-1][0] && loop[0][1] == loop[len(loop)-1][1] { + loop = loop[:len(loop)-1] + } + for _, point := range loop { + p := s2.PointFromLatLng(s2.LatLngFromDegrees(point[1], point[0])) + points = append(points, p) + } + s2loop := s2.LoopFromPoints(points) + loops = append(loops, s2loop) + } + + rv := s2.PolygonFromOrientedLoops(loops) + return rv +} + +func s2PolygonFromS2Rectangle(s2rect *s2.Rect) *s2.Polygon { + loops := make([]*s2.Loop, 0, 1) + var points []s2.Point + for j := 0; j < 4; j++ { + points = append(points, s2.PointFromLatLng(s2rect.Vertex(j%4))) + } + + loops = append(loops, s2.LoopFromPoints(points)) + return s2.PolygonFromLoops(loops) +} + +func DeduplicateTerms(terms []string) []string { + var rv []string + hash := make(map[string]struct{}, len(terms)) + for _, term := range terms { + if _, exists := hash[term]; !exists { + rv = append(rv, term) + hash[term] = struct{}{} + } + } + + return rv +} + +//---------------------------------------------------------------------- + +var earthRadiusInMeter = 6378137.0 + +func radiusInMetersToS1Angle(radius float64) s1.Angle { + return s1.Angle(radius / earthRadiusInMeter) +} + +func s2PolylinesFromCoordinates(coordinates [][][]float64) []*s2.Polyline { + var polylines []*s2.Polyline + for _, lines := range coordinates { + var latlngs []s2.LatLng + for _, line := range lines { + v := s2.LatLngFromDegrees(line[1], line[0]) + latlngs = append(latlngs, v) + } + polylines = append(polylines, s2.PolylineFromLatLngs(latlngs)) + } + return polylines +} + +func s2RectFromBounds(topLeft, bottomRight []float64) *s2.Rect { + rect := s2.EmptyRect() + rect = rect.AddPoint(s2.LatLngFromDegrees(topLeft[1], topLeft[0])) + rect = rect.AddPoint(s2.LatLngFromDegrees(bottomRight[1], bottomRight[0])) + return &rect +} + +func s2Cap(vertices []float64, radiusInMeter float64) *s2.Cap { + cp := s2.PointFromLatLng(s2.LatLngFromDegrees(vertices[1], vertices[0])) + angle := radiusInMetersToS1Angle(float64(radiusInMeter)) + cap := s2.CapFromCenterAngle(cp, angle) + return &cap +} + +func max(a, b float64) float64 { + if a >= b { + return a + } + return b +} + +func min(a, b float64) float64 { + if a >= b { + return b + } + return a +} + +func StripCoveringTerms(terms []string) []string { + rv := make([]string, 0, len(terms)) + for _, term := range terms { + if strings.HasPrefix(term, "$") { + rv = append(rv, term[1:]) + continue + } + rv = append(rv, term) + } + return DeduplicateTerms(rv) +} + +type distanceUnit struct { + conv float64 + suffixes []string +} + +var inch = distanceUnit{0.0254, []string{"in", "inch"}} +var yard = distanceUnit{0.9144, []string{"yd", "yards"}} +var feet = distanceUnit{0.3048, []string{"ft", "feet"}} +var kilom = distanceUnit{1000, []string{"km", "kilometers"}} +var nauticalm = distanceUnit{1852.0, []string{"nm", "nauticalmiles"}} +var millim = distanceUnit{0.001, []string{"mm", "millimeters"}} +var centim = distanceUnit{0.01, []string{"cm", "centimeters"}} +var miles = distanceUnit{1609.344, []string{"mi", "miles"}} +var meters = distanceUnit{1, []string{"m", "meters"}} + +var distanceUnits = []*distanceUnit{ + &inch, &yard, &feet, &kilom, &nauticalm, &millim, ¢im, &miles, &meters, +} + +// ParseDistance attempts to parse a distance string and return distance in +// meters. Example formats supported: +// "5in" "5inch" "7yd" "7yards" "9ft" "9feet" "11km" "11kilometers" +// "3nm" "3nauticalmiles" "13mm" "13millimeters" "15cm" "15centimeters" +// "17mi" "17miles" "19m" "19meters" +// If the unit cannot be determined, the entire string is parsed and the +// unit of meters is assumed. +// If the number portion cannot be parsed, 0 and the parse error are returned. +func ParseDistance(d string) (float64, error) { + for _, unit := range distanceUnits { + for _, unitSuffix := range unit.suffixes { + if strings.HasSuffix(d, unitSuffix) { + parsedNum, err := strconv.ParseFloat(d[0:len(d)-len(unitSuffix)], 64) + if err != nil { + return 0, err + } + return parsedNum * unit.conv, nil + } + } + } + // no unit matched, try assuming meters? + parsedNum, err := strconv.ParseFloat(d, 64) + if err != nil { + return 0, err + } + return parsedNum, nil +} diff --git a/backend/vendor/github.com/blevesearch/geo/geojson/geojson_shapes_impl.go b/backend/vendor/github.com/blevesearch/geo/geojson/geojson_shapes_impl.go new file mode 100644 index 0000000000..39734589cb --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/geojson/geojson_shapes_impl.go @@ -0,0 +1,1861 @@ +// Copyright (c) 2022 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package geojson + +import ( + "bufio" + "bytes" + "encoding/binary" + "encoding/json" + "fmt" + "strings" + + index "github.com/blevesearch/bleve_index_api" + + "github.com/blevesearch/geo/s2" +) + +// s2Serializable is an optional interface for implementations +// supporting custom serialisation of data based out of s2's +// encode method. +type s2Serializable interface { + // Marshal implementation should encode the shape using the + // s2's encode methods with appropriate prefix bytes to + // identify the type of the contents. + Marshal() ([]byte, error) +} + +const ( + PointType = "point" + MultiPointType = "multipoint" + LineStringType = "linestring" + MultiLineStringType = "multilinestring" + PolygonType = "polygon" + MultiPolygonType = "multipolygon" + GeometryCollectionType = "geometrycollection" + CircleType = "circle" + EnvelopeType = "envelope" +) + +// These are the byte prefixes for identifying the +// shape contained within the doc values byte slice +// while decoding the contents during the query +// filtering phase. +const ( + PointTypePrefix = byte(1) + MultiPointTypePrefix = byte(2) + LineStringTypePrefix = byte(3) + MultiLineStringTypePrefix = byte(4) + PolygonTypePrefix = byte(5) + MultiPolygonTypePrefix = byte(6) + GeometryCollectionTypePrefix = byte(7) + CircleTypePrefix = byte(8) + EnvelopeTypePrefix = byte(9) +) + +// compositeShape is an optional interface for the +// composite geoJSON shapes which is composed of +// multiple spatial shapes within it. Composite shapes +// like multipoint, multilinestring, multipolygon and +// geometrycollection shapes are supposed to implement +// this interface. +type compositeShape interface { + // Members implementation returns the + // geoJSON shapes composed within the shape. + Members() []index.GeoJSON +} + +// -------------------------------------------------------- +// Point represents the geoJSON point type and it +// implements the index.GeoJSON interface. +type Point struct { + Typ string `json:"type"` + Vertices []float64 `json:"coordinates"` + s2point *s2.Point +} + +func (p *Point) Type() string { + return strings.ToLower(p.Typ) +} + +func (p *Point) Value() ([]byte, error) { + return jsoniter.Marshal(p) +} + +func NewGeoJsonPoint(v []float64) index.GeoJSON { + rv := &Point{Typ: PointType, Vertices: v} + rv.init() + return rv +} + +func (p *Point) init() { + if p.s2point == nil { + s2point := s2.PointFromLatLng(s2.LatLngFromDegrees( + p.Vertices[1], p.Vertices[0])) + p.s2point = &s2point + } +} + +func (p *Point) Marshal() ([]byte, error) { + p.init() + + var b bytes.Buffer + b.Grow(32) + w := bufio.NewWriter(&b) + err := p.s2point.Encode(w) + if err != nil { + return nil, err + } + + w.Flush() + return append([]byte{PointTypePrefix}, b.Bytes()...), nil +} + +func (p *Point) Intersects(other index.GeoJSON) (bool, error) { + p.init() + s2cell := s2.CellFromPoint(*p.s2point) + + return checkCellIntersectsShape(&s2cell, p, other) +} + +func (p *Point) Contains(other index.GeoJSON) (bool, error) { + p.init() + s2cell := s2.CellFromPoint(*p.s2point) + + return checkCellContainsShape([]*s2.Cell{&s2cell}, other) +} + +func (p *Point) Coordinates() []float64 { + return p.Vertices +} + +// -------------------------------------------------------- +// MultiPoint represents the geoJSON multipoint type and it +// implements the index.GeoJSON interface as well as the +// compositeShap interface. +type MultiPoint struct { + Typ string `json:"type"` + Vertices [][]float64 `json:"coordinates"` + s2points []*s2.Point +} + +func NewGeoJsonMultiPoint(v [][]float64) index.GeoJSON { + rv := &MultiPoint{Typ: MultiPointType, Vertices: v} + rv.init() + return rv +} + +func (mp *MultiPoint) init() { + if mp.s2points == nil { + mp.s2points = make([]*s2.Point, len(mp.Vertices)) + for i, point := range mp.Vertices { + s2point := s2.PointFromLatLng(s2.LatLngFromDegrees( + point[1], point[0])) + mp.s2points[i] = &s2point + } + } +} + +func (p *MultiPoint) Marshal() ([]byte, error) { + p.init() + + var b bytes.Buffer + b.Grow(64) + w := bufio.NewWriter(&b) + + // first write the number of points. + count := int32(len(p.s2points)) + err := binary.Write(w, binary.BigEndian, count) + if err != nil { + return nil, err + } + // write the points. + for _, s2point := range p.s2points { + err := s2point.Encode(w) + if err != nil { + return nil, err + } + } + + w.Flush() + return append([]byte{MultiPointTypePrefix}, b.Bytes()...), nil +} + +func (p *MultiPoint) Type() string { + return strings.ToLower(p.Typ) +} + +func (mp *MultiPoint) Value() ([]byte, error) { + return jsoniter.Marshal(mp) +} + +func (p *MultiPoint) Intersects(other index.GeoJSON) (bool, error) { + p.init() + + for _, s2point := range p.s2points { + cell := s2.CellFromPoint(*s2point) + rv, err := checkCellIntersectsShape(&cell, p, other) + if rv && err == nil { + return rv, nil + } + } + + return false, nil +} + +func (p *MultiPoint) Contains(other index.GeoJSON) (bool, error) { + p.init() + s2cells := make([]*s2.Cell, 0, len(p.s2points)) + + for _, s2point := range p.s2points { + cell := s2.CellFromPoint(*s2point) + s2cells = append(s2cells, &cell) + } + + return checkCellContainsShape(s2cells, other) +} + +func (p *MultiPoint) Coordinates() [][]float64 { + return p.Vertices +} + +func (p *MultiPoint) Members() []index.GeoJSON { + if len(p.Vertices) > 0 && len(p.s2points) == 0 { + points := make([]index.GeoJSON, len(p.Vertices)) + for pos, vertices := range p.Vertices { + points[pos] = NewGeoJsonPoint(vertices) + } + return points + } + + points := make([]index.GeoJSON, len(p.s2points)) + for pos, point := range p.s2points { + points[pos] = &Point{s2point: point} + } + return points +} + +// -------------------------------------------------------- +// LineString represents the geoJSON linestring type and it +// implements the index.GeoJSON interface. +type LineString struct { + Typ string `json:"type"` + Vertices [][]float64 `json:"coordinates"` + pl *s2.Polyline +} + +func NewGeoJsonLinestring(points [][]float64) index.GeoJSON { + rv := &LineString{Typ: LineStringType, Vertices: points} + rv.init() + return rv +} + +func (ls *LineString) init() { + if ls.pl == nil { + latlngs := make([]s2.LatLng, len(ls.Vertices)) + for i, vertex := range ls.Vertices { + latlngs[i] = s2.LatLngFromDegrees(vertex[1], vertex[0]) + } + ls.pl = s2.PolylineFromLatLngs(latlngs) + } +} + +func (ls *LineString) Type() string { + return strings.ToLower(ls.Typ) +} + +func (ls *LineString) Value() ([]byte, error) { + return jsoniter.Marshal(ls) +} + +func (ls *LineString) Marshal() ([]byte, error) { + ls.init() + + var b bytes.Buffer + b.Grow(50) + w := bufio.NewWriter(&b) + err := ls.pl.Encode(w) + if err != nil { + return nil, err + } + + w.Flush() + return append([]byte{LineStringTypePrefix}, b.Bytes()...), nil +} + +func (ls *LineString) Intersects(other index.GeoJSON) (bool, error) { + ls.init() + + return checkLineStringsIntersectsShape([]*s2.Polyline{ls.pl}, ls, other) +} + +func (ls *LineString) Contains(other index.GeoJSON) (bool, error) { + return checkLineStringsContainsShape([]*s2.Polyline{ls.pl}, other) +} + +func (ls *LineString) Coordinates() [][]float64 { + return ls.Vertices +} + +// -------------------------------------------------------- +// MultiLineString represents the geoJSON multilinestring type +// and it implements the index.GeoJSON interface as well as the +// compositeShap interface. +type MultiLineString struct { + Typ string `json:"type"` + Vertices [][][]float64 `json:"coordinates"` + pls []*s2.Polyline +} + +func NewGeoJsonMultilinestring(points [][][]float64) index.GeoJSON { + rv := &MultiLineString{Typ: MultiLineStringType, Vertices: points} + rv.init() + return rv +} + +func (mls *MultiLineString) init() { + if mls.pls == nil { + mls.pls = s2PolylinesFromCoordinates(mls.Vertices) + } +} + +func (mls *MultiLineString) Type() string { + return strings.ToLower(mls.Typ) +} + +func (mls *MultiLineString) Value() ([]byte, error) { + return jsoniter.Marshal(mls) +} + +func (mls *MultiLineString) Marshal() ([]byte, error) { + mls.init() + + var b bytes.Buffer + b.Grow(256) + w := bufio.NewWriter(&b) + + // first write the number of linestrings. + count := int32(len(mls.pls)) + err := binary.Write(w, binary.BigEndian, count) + if err != nil { + return nil, err + } + // write the lines. + for _, ls := range mls.pls { + err := ls.Encode(w) + if err != nil { + return nil, err + } + } + + w.Flush() + return append([]byte{MultiLineStringTypePrefix}, b.Bytes()...), nil +} + +func (p *MultiLineString) Intersects(other index.GeoJSON) (bool, error) { + p.init() + return checkLineStringsIntersectsShape(p.pls, p, other) +} + +func (p *MultiLineString) Contains(other index.GeoJSON) (bool, error) { + return checkLineStringsContainsShape(p.pls, other) +} + +func (p *MultiLineString) Coordinates() [][][]float64 { + return p.Vertices +} + +func (p *MultiLineString) Members() []index.GeoJSON { + if len(p.Vertices) > 0 && len(p.pls) == 0 { + lines := make([]index.GeoJSON, len(p.Vertices)) + for pos, vertices := range p.Vertices { + lines[pos] = NewGeoJsonLinestring(vertices) + } + return lines + } + + lines := make([]index.GeoJSON, len(p.pls)) + for pos, pl := range p.pls { + lines[pos] = &LineString{pl: pl} + } + return lines +} + +// -------------------------------------------------------- +// Polygon represents the geoJSON polygon type +// and it implements the index.GeoJSON interface. +type Polygon struct { + Typ string `json:"type"` + Vertices [][][]float64 `json:"coordinates"` + s2pgn *s2.Polygon +} + +func NewGeoJsonPolygon(points [][][]float64) index.GeoJSON { + rv := &Polygon{Typ: PolygonType, Vertices: points} + rv.init() + return rv +} + +func (p *Polygon) init() { + if p.s2pgn == nil { + p.s2pgn = s2PolygonFromCoordinates(p.Vertices) + } +} + +func (p *Polygon) Type() string { + return strings.ToLower(p.Typ) +} + +func (p *Polygon) Value() ([]byte, error) { + return jsoniter.Marshal(p) +} + +func (p *Polygon) Marshal() ([]byte, error) { + p.init() + + var b bytes.Buffer + b.Grow(128) + w := bufio.NewWriter(&b) + err := p.s2pgn.Encode(w) + if err != nil { + return nil, err + } + + w.Flush() + return append([]byte{PolygonTypePrefix}, b.Bytes()...), nil +} + +func (p *Polygon) Intersects(other index.GeoJSON) (bool, error) { + // make an s2polygon for reuse. + p.init() + + return checkPolygonIntersectsShape(p.s2pgn, p, other) +} + +func (p *Polygon) Contains(other index.GeoJSON) (bool, error) { + // make an s2polygon for reuse. + p.init() + + return checkMultiPolygonContainsShape([]*s2.Polygon{p.s2pgn}, p, other) +} + +func (p *Polygon) Coordinates() [][][]float64 { + return p.Vertices +} + +// -------------------------------------------------------- +// MultiPolygon represents the geoJSON multipolygon type +// and it implements the index.GeoJSON interface as well as the +// compositeShap interface. +type MultiPolygon struct { + Typ string `json:"type"` + Vertices [][][][]float64 `json:"coordinates"` + s2pgns []*s2.Polygon +} + +func NewGeoJsonMultiPolygon(points [][][][]float64) index.GeoJSON { + rv := &MultiPolygon{Typ: MultiPolygonType, Vertices: points} + rv.init() + return rv +} + +func (p *MultiPolygon) init() { + if p.s2pgns == nil { + p.s2pgns = make([]*s2.Polygon, len(p.Vertices)) + for i, vertices := range p.Vertices { + pgn := s2PolygonFromCoordinates(vertices) + p.s2pgns[i] = pgn + } + } +} + +func (p *MultiPolygon) Type() string { + return strings.ToLower(p.Typ) +} + +func (p *MultiPolygon) Value() ([]byte, error) { + return jsoniter.Marshal(p) +} + +func (p *MultiPolygon) Marshal() ([]byte, error) { + p.init() + + var b bytes.Buffer + b.Grow(512) + w := bufio.NewWriter(&b) + + // first write the number of polygons. + count := int32(len(p.s2pgns)) + err := binary.Write(w, binary.BigEndian, count) + if err != nil { + return nil, err + } + // write the polygons. + for _, pgn := range p.s2pgns { + err := pgn.Encode(w) + if err != nil { + return nil, err + } + } + + w.Flush() + return append([]byte{MultiPolygonTypePrefix}, b.Bytes()...), nil +} + +func (p *MultiPolygon) Intersects(other index.GeoJSON) (bool, error) { + p.init() + + for _, pgn := range p.s2pgns { + rv, err := checkPolygonIntersectsShape(pgn, p, other) + if rv && err == nil { + return true, nil + } + } + + return false, nil +} + +func (p *MultiPolygon) Contains(other index.GeoJSON) (bool, error) { + p.init() + + return checkMultiPolygonContainsShape(p.s2pgns, p, other) +} + +func (p *MultiPolygon) Coordinates() [][][][]float64 { + return p.Vertices +} + +func (p *MultiPolygon) Members() []index.GeoJSON { + if len(p.Vertices) > 0 && len(p.s2pgns) == 0 { + polygons := make([]index.GeoJSON, len(p.Vertices)) + for pos, vertices := range p.Vertices { + polygons[pos] = NewGeoJsonPolygon(vertices) + } + return polygons + } + + polygons := make([]index.GeoJSON, len(p.s2pgns)) + for pos, pgn := range p.s2pgns { + polygons[pos] = &Polygon{s2pgn: pgn} + } + return polygons +} + +// -------------------------------------------------------- +// GeometryCollection represents the geoJSON geometryCollection type +// and it implements the index.GeoJSON interface as well as the +// compositeShap interface. +type GeometryCollection struct { + Typ string `json:"type"` + Shapes []index.GeoJSON `json:"geometries"` +} + +func (gc *GeometryCollection) Type() string { + return strings.ToLower(gc.Typ) +} + +func (gc *GeometryCollection) Value() ([]byte, error) { + return jsoniter.Marshal(gc) +} + +func (gc *GeometryCollection) Members() []index.GeoJSON { + shapes := make([]index.GeoJSON, 0, len(gc.Shapes)) + for _, shape := range gc.Shapes { + if cs, ok := shape.(compositeShape); ok { + shapes = append(shapes, cs.Members()...) + } else { + shapes = append(shapes, shape) + } + } + return shapes +} + +func (gc *GeometryCollection) Marshal() ([]byte, error) { + var b bytes.Buffer + b.Grow(512) + w := bufio.NewWriter(&b) + + // first write the number of shapes. + count := int32(len(gc.Shapes)) + err := binary.Write(w, binary.BigEndian, count) + if err != nil { + return nil, err + } + + var res []byte + for _, shape := range gc.Shapes { + if s, ok := shape.(s2Serializable); ok { + sb, err := s.Marshal() + if err != nil { + return nil, err + } + // write the length of each shape. + err = binary.Write(w, binary.BigEndian, int32(len(sb))) + if err != nil { + return nil, err + } + // track the shape contents. + res = append(res, sb...) + } + } + w.Flush() + + return append([]byte{GeometryCollectionTypePrefix}, append(b.Bytes(), res...)...), nil +} + +func (gc *GeometryCollection) Intersects(other index.GeoJSON) (bool, error) { + for _, shape := range gc.Members() { + + intersects, err := shape.Intersects(other) + if intersects && err == nil { + return true, nil + } + } + return false, nil +} + +func (gc *GeometryCollection) Contains(other index.GeoJSON) (bool, error) { + // handle composite target shapes explicitly + if cs, ok := other.(compositeShape); ok { + otherShapes := cs.Members() + shapesFoundWithIn := make(map[int]struct{}) + + nextShape: + for pos, shapeInDoc := range otherShapes { + for _, shape := range gc.Members() { + within, err := shape.Contains(shapeInDoc) + if within && err == nil { + shapesFoundWithIn[pos] = struct{}{} + continue nextShape + } + } + } + + return len(shapesFoundWithIn) == len(otherShapes), nil + } + + for _, shape := range gc.Members() { + within, err := shape.Contains(other) + if within && err == nil { + return true, nil + } + } + + return false, nil +} + +func (gc *GeometryCollection) UnmarshalJSON(data []byte) error { + tmp := struct { + Typ string `json:"type"` + Shapes []json.RawMessage `json:"geometries"` + }{} + + err := jsoniter.Unmarshal(data, &tmp) + if err != nil { + return err + } + gc.Typ = tmp.Typ + + for _, shape := range tmp.Shapes { + var t map[string]interface{} + err := jsoniter.Unmarshal(shape, &t) + if err != nil { + return err + } + + var typ string + + if val, ok := t["type"]; ok { + typ = strings.ToLower(val.(string)) + } else { + continue + } + + switch typ { + case PointType: + var p Point + err := jsoniter.Unmarshal(shape, &p) + if err != nil { + return err + } + p.init() + gc.Shapes = append(gc.Shapes, &p) + + case MultiPointType: + var mp MultiPoint + err := jsoniter.Unmarshal(shape, &mp) + if err != nil { + return err + } + mp.init() + gc.Shapes = append(gc.Shapes, &mp) + + case LineStringType: + var ls LineString + err := jsoniter.Unmarshal(shape, &ls) + if err != nil { + return err + } + ls.init() + gc.Shapes = append(gc.Shapes, &ls) + + case MultiLineStringType: + var mls MultiLineString + err := jsoniter.Unmarshal(shape, &mls) + if err != nil { + return err + } + mls.init() + gc.Shapes = append(gc.Shapes, &mls) + + case PolygonType: + var pgn Polygon + err := jsoniter.Unmarshal(shape, &pgn) + if err != nil { + return err + } + pgn.init() + gc.Shapes = append(gc.Shapes, &pgn) + + case MultiPolygonType: + var pgn MultiPolygon + err := jsoniter.Unmarshal(shape, &pgn) + if err != nil { + return err + } + pgn.init() + gc.Shapes = append(gc.Shapes, &pgn) + } + } + + return nil +} + +// -------------------------------------------------------- +// Circle represents a custom circle type and it +// implements the index.GeoJSON interface. +type Circle struct { + Typ string `json:"type"` + Vertices []float64 `json:"coordinates"` + Radius string `json:"radius"` + radiusInMeters float64 + s2cap *s2.Cap +} + +func NewGeoCircle(points []float64, + radius string) index.GeoJSON { + r, err := ParseDistance(radius) + if err != nil { + return nil + } + + return &Circle{Typ: CircleType, + Vertices: points, + Radius: radius, + radiusInMeters: r} +} + +func (c *Circle) Type() string { + return strings.ToLower(c.Typ) +} + +func (c *Circle) Value() ([]byte, error) { + return jsoniter.Marshal(c) +} + +func (c *Circle) init() { + if c.s2cap == nil { + c.s2cap = s2Cap(c.Vertices, c.radiusInMeters) + } +} + +func (c *Circle) Marshal() ([]byte, error) { + c.init() + + var b bytes.Buffer + b.Grow(40) + w := bufio.NewWriter(&b) + err := c.s2cap.Encode(w) + if err != nil { + return nil, err + } + + w.Flush() + return append([]byte{CircleTypePrefix}, b.Bytes()...), nil +} + +func (c *Circle) Intersects(other index.GeoJSON) (bool, error) { + c.init() + + return checkCircleIntersectsShape(c.s2cap, c, other) +} + +func (c *Circle) Contains(other index.GeoJSON) (bool, error) { + c.init() + return checkCircleContainsShape(c.s2cap, c, other) +} + +func (c *Circle) UnmarshalJSON(data []byte) error { + tmp := struct { + Typ string `json:"type"` + Vertices []float64 `json:"coordinates"` + Radius string `json:"radius"` + }{} + + err := jsoniter.Unmarshal(data, &tmp) + if err != nil { + return err + } + c.Typ = tmp.Typ + c.Vertices = tmp.Vertices + c.Radius = tmp.Radius + if tmp.Radius != "" { + c.radiusInMeters, err = ParseDistance(tmp.Radius) + } + + return err +} + +// -------------------------------------------------------- +// Envelope represents the envelope/bounding box type and it +// implements the index.GeoJSON interface. +type Envelope struct { + Typ string `json:"type"` + Vertices [][]float64 `json:"coordinates"` + r *s2.Rect +} + +func NewGeoEnvelope(points [][]float64) index.GeoJSON { + return &Envelope{Vertices: points, Typ: EnvelopeType} +} + +func (e *Envelope) Type() string { + return strings.ToLower(e.Typ) +} + +func (e *Envelope) Value() ([]byte, error) { + return jsoniter.Marshal(e) +} + +func (e *Envelope) init() { + if e.r == nil { + e.r = s2RectFromBounds(e.Vertices[0], e.Vertices[1]) + } +} + +func (e *Envelope) Marshal() ([]byte, error) { + e.init() + + var b bytes.Buffer + b.Grow(50) + w := bufio.NewWriter(&b) + err := e.r.Encode(w) + if err != nil { + return nil, err + } + + w.Flush() + return append([]byte{EnvelopeTypePrefix}, b.Bytes()...), nil +} + +func (e *Envelope) Intersects(other index.GeoJSON) (bool, error) { + e.init() + + return checkEnvelopeIntersectsShape(e.r, e, other) +} + +func (e *Envelope) Contains(other index.GeoJSON) (bool, error) { + e.init() + + return checkEnvelopeContainsShape(e.r, e, other) +} + +//-------------------------------------------------------- + +// checkCellIntersectsShape checks for intersection between +// the s2cell and the shape in the document. +func checkCellIntersectsShape(cell *s2.Cell, shapeIn, + other index.GeoJSON) (bool, error) { + // check if the other shape is a point. + if p2, ok := other.(*Point); ok { + s2cell := s2.CellFromPoint(*p2.s2point) + + if cell.IntersectsCell(s2cell) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a multipoint. + if p2, ok := other.(*MultiPoint); ok { + // check the intersection for any point in the array. + for _, point := range p2.s2points { + s2cell := s2.CellFromPoint(*point) + + if cell.IntersectsCell(s2cell) { + return true, nil + } + } + + return false, nil + } + + // check if the other shape is a polygon. + if p2, ok := other.(*Polygon); ok { + + if p2.s2pgn.IntersectsCell(*cell) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a multipolygon. + if p2, ok := other.(*MultiPolygon); ok { + // check the intersection for any polygon in the collection. + for _, s2pgn := range p2.s2pgns { + + if s2pgn.IntersectsCell(*cell) { + return true, nil + } + } + + return false, nil + } + + // check if the other shape is a linestring. + if p2, ok := other.(*LineString); ok { + for i := 0; i < p2.pl.NumEdges(); i++ { + edge := p2.pl.Edge(i) + start := s2.CellFromPoint(edge.V0) + end := s2.CellFromPoint(edge.V1) + if cell.IntersectsCell(start) || cell.IntersectsCell(end) { + return true, nil + } + } + + return false, nil + } + + // check if the other shape is a multilinestring. + if p2, ok := other.(*MultiLineString); ok { + // check the intersection for any linestring in the array. + for _, pl := range p2.pls { + for i := 0; i < pl.NumEdges(); i++ { + edge := pl.Edge(i) + start := s2.CellFromPoint(edge.V0) + end := s2.CellFromPoint(edge.V1) + if cell.IntersectsCell(start) || cell.IntersectsCell(end) { + return true, nil + } + } + } + + return false, nil + } + + // check if the other shape is a geometrycollection. + if gc, ok := other.(*GeometryCollection); ok { + // check for intersection across every member shape. + if geometryCollectionIntersectsShape(gc, shapeIn) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a circle. + if c, ok := other.(*Circle); ok { + + if c.s2cap.IntersectsCell(*cell) { + return true, nil + } + + return false, nil + } + + // check if the other shape is an envelope. + if e, ok := other.(*Envelope); ok { + + if e.r.IntersectsCell(*cell) { + return true, nil + } + + return false, nil + } + + return false, fmt.Errorf("unknown geojson type: %s "+ + " found in document", other.Type()) +} + +// checkCellContainsShape checks whether the given shape in +// in the document is contained with the s2cell. +func checkCellContainsShape(cells []*s2.Cell, + other index.GeoJSON) (bool, error) { + // check if the other shape is a point. + if p2, ok := other.(*Point); ok { + for _, cell := range cells { + + if cell.ContainsPoint(*p2.s2point) { + return true, nil + } + } + + return false, nil + } + + // check if the other shape is a multipoint, if so containment is + // checked for every point in the multipoint with every given cells. + if p2, ok := other.(*MultiPoint); ok { + // check the containment for every point in the collection. + lookup := make(map[int]struct{}) + for _, cell := range cells { + for pos, point := range p2.s2points { + if _, done := lookup[pos]; done { + continue + } + // already processed all the points in the multipoint. + if len(lookup) == len(p2.s2points) { + return true, nil + } + + if cell.ContainsPoint(*point) { + lookup[pos] = struct{}{} + } + } + } + + return len(lookup) == len(p2.s2points), nil + } + + // as point is a non closed shape, containment isn't feasible + // for other higher dimensions. + return false, nil +} + +// ------------------------------------------------------------------------ + +// checkLineStringsIntersectsShape checks whether the given linestrings +// intersects with the shape in the document. +func checkLineStringsIntersectsShape(pls []*s2.Polyline, shapeIn, + other index.GeoJSON) (bool, error) { + // check if the other shape is a point. + if p2, ok := other.(*Point); ok { + if polylineIntersectsPoint(pls, p2.s2point) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a multipoint. + if p2, ok := other.(*MultiPoint); ok { + // check the intersection for any point in the collection. + for _, point := range p2.s2points { + + if polylineIntersectsPoint(pls, point) { + return true, nil + } + } + + return false, nil + } + + // check if the other shape is a polygon. + if p2, ok := other.(*Polygon); ok { + if polylineIntersectsPolygons(pls, []*s2.Polygon{p2.s2pgn}) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a multipolygon. + if p2, ok := other.(*MultiPolygon); ok { + // check the intersection for any polygon in the collection. + if polylineIntersectsPolygons(pls, p2.s2pgns) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a linestring. + if ls, ok := other.(*LineString); ok { + for _, pl := range pls { + if ls.pl.Intersects(pl) { + return true, nil + } + } + + return false, nil + } + + // check if the other shape is a multilinestring. + if mls, ok := other.(*MultiLineString); ok { + for _, ls := range pls { + for _, docLineString := range mls.pls { + if ls.Intersects(docLineString) { + return true, nil + } + } + } + + return false, nil + } + + if gc, ok := other.(*GeometryCollection); ok { + // check whether the linestring intersects with any of the + // shapes Contains a geometrycollection. + if geometryCollectionIntersectsShape(gc, shapeIn) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a circle. + if c, ok := other.(*Circle); ok { + centre := c.s2cap.Center() + for _, pl := range pls { + for i := 0; i < pl.NumEdges(); i++ { + edge := pl.Edge(i) + distance := s2.DistanceFromSegment(centre, edge.V0, edge.V1) + return distance <= c.s2cap.Radius(), nil + } + } + + return false, nil + } + + // check if the other shape is a envelope. + if e, ok := other.(*Envelope); ok { + res := rectangleIntersectsWithLineStrings(e.r, pls) + + return res, nil + } + + return false, fmt.Errorf("unknown geojson type: %s "+ + "found in document", other.Type()) +} + +// checkLineStringsContainsShape checks the containment for +// points and multipoints for the linestring vertices. +func checkLineStringsContainsShape(pls []*s2.Polyline, + other index.GeoJSON) (bool, error) { + return false, nil +} + +// ------------------------------------------------------------------------ + +// checkPolygonIntersectsShape checks the intersection between the +// s2 polygon and the other shapes in the documents. +func checkPolygonIntersectsShape(s2pgn *s2.Polygon, shapeIn, + other index.GeoJSON) (bool, error) { + // check if the other shape is a point. + if p2, ok := other.(*Point); ok { + + s2cell := s2.CellFromPoint(*p2.s2point) + if s2pgn.IntersectsCell(s2cell) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a multipoint. + if p2, ok := other.(*MultiPoint); ok { + + for _, s2point := range p2.s2points { + s2cell := s2.CellFromPoint(*s2point) + if s2pgn.IntersectsCell(s2cell) { + return true, nil + } + } + + return false, nil + } + + // check if the other shape is a polygon. + if p2, ok := other.(*Polygon); ok { + + if s2pgn.Intersects(p2.s2pgn) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a multipolygon. + if p2, ok := other.(*MultiPolygon); ok { + // check the intersection for any polygon in the collection. + for _, s2pgn1 := range p2.s2pgns { + + if s2pgn.Intersects(s2pgn1) { + return true, nil + } + } + + return false, nil + } + + // check if the other shape is a linestring. + if ls, ok := other.(*LineString); ok { + + if polylineIntersectsPolygons([]*s2.Polyline{ls.pl}, + []*s2.Polygon{s2pgn}) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a multilinestring. + if mls, ok := other.(*MultiLineString); ok { + + if polylineIntersectsPolygons(mls.pls, []*s2.Polygon{s2pgn}) { + return true, nil + } + + return false, nil + } + + if gc, ok := other.(*GeometryCollection); ok { + // check whether the polygon intersects with any of the + // member shapes of the geometry collection. + if geometryCollectionIntersectsShape(gc, shapeIn) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a circle. + if c, ok := other.(*Circle); ok { + cp := c.s2cap.Center() + radius := c.s2cap.Radius() + + projected := s2pgn.Project(&cp) + distance := projected.Distance(cp) + + return distance <= radius, nil + } + + // check if the other shape is a envelope. + if e, ok := other.(*Envelope); ok { + + s2pgnInDoc := s2PolygonFromS2Rectangle(e.r) + if s2pgn.Intersects(s2pgnInDoc) { + return true, nil + } + return false, nil + } + + return false, fmt.Errorf("unknown geojson type: %s "+ + " found in document", other.Type()) +} + +// checkMultiPolygonContainsShape checks whether the given polygons +// collectively contains the shape in the document. +func checkMultiPolygonContainsShape(s2pgns []*s2.Polygon, + shapeIn, other index.GeoJSON) (bool, error) { + // check if the other shape is a point. + if p2, ok := other.(*Point); ok { + + for _, s2pgn := range s2pgns { + if s2pgn.ContainsPoint(*p2.s2point) { + return true, nil + } + } + + return false, nil + } + + // check if the other shape is a multipoint. + if p2, ok := other.(*MultiPoint); ok { + // check the containment for every point in the collection. + pointsWithIn := make(map[int]struct{}) + nextPoint: + for pointIndex, point := range p2.s2points { + + for _, s2pgn := range s2pgns { + if s2pgn.ContainsPoint(*point) { + pointsWithIn[pointIndex] = struct{}{} + continue nextPoint + } else { + // double check for containment with the vertices. + for _, loop := range s2pgn.Loops() { + for i := 0; i < loop.NumVertices(); i++ { + if point.ApproxEqual(loop.Vertex(i)) { + pointsWithIn[pointIndex] = struct{}{} + continue nextPoint + } + } + } + } + } + } + + return len(p2.s2points) == len(pointsWithIn), nil + } + + // check if the other shape is a polygon. + if p2, ok := other.(*Polygon); ok { + + for _, s2pgn := range s2pgns { + if s2pgn.Contains(p2.s2pgn) { + return true, nil + } + } + + return false, nil + } + + // check if the other shape is a multipolygon. + if p2, ok := other.(*MultiPolygon); ok { + // check the intersection for every polygon in the collection. + polygonsWithIn := make(map[int]struct{}) + + nextPolygon: + for pgnIndex, pgn := range p2.s2pgns { + for _, s2pgn := range s2pgns { + if s2pgn.Contains(pgn) { + polygonsWithIn[pgnIndex] = struct{}{} + continue nextPolygon + } + } + } + + return len(p2.s2pgns) == len(polygonsWithIn), nil + } + + // check if the other shape is a linestring. + if ls, ok := other.(*LineString); ok { + + if polygonsContainsLineStrings(s2pgns, + []*s2.Polyline{ls.pl}) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a multilinestring. + if mls, ok := other.(*MultiLineString); ok { + // check whether any of the linestring is inside the polygon. + if polygonsContainsLineStrings(s2pgns, mls.pls) { + return true, nil + } + + return false, nil + } + + if gc, ok := other.(*GeometryCollection); ok { + shapesWithIn := make(map[int]struct{}) + nextShape: + for pos, shape := range gc.Members() { + for _, s2pgn := range s2pgns { + contains, err := checkMultiPolygonContainsShape( + []*s2.Polygon{s2pgn}, shapeIn, shape) + if err == nil && contains { + shapesWithIn[pos] = struct{}{} + continue nextShape + } + } + } + return len(shapesWithIn) == len(gc.Members()), nil + } + + // check if the other shape is a circle. + if c, ok := other.(*Circle); ok { + cp := c.s2cap.Center() + radius := c.s2cap.Radius() + + for _, s2pgn := range s2pgns { + + if s2pgn.ContainsPoint(cp) { + projected := s2pgn.ProjectToBoundary(&cp) + distance := projected.Distance(cp) + if distance >= radius { + return true, nil + } + } + } + + return false, nil + } + + // check if the other shape is a envelope. + if e, ok := other.(*Envelope); ok { + // create a polygon from the rectangle and checks the containment. + s2pgnInDoc := s2PolygonFromS2Rectangle(e.r) + for _, s2pgn := range s2pgns { + if s2pgn.Contains(s2pgnInDoc) { + return true, nil + } + } + + return false, nil + } + + return false, fmt.Errorf("unknown geojson type: %s"+ + " found in document", other.Type()) +} + +// ------------------------------------------------------------------------ + +// checkCircleIntersectsShape checks for intersection of the +// shape in the document with the circle. +func checkCircleIntersectsShape(s2cap *s2.Cap, shapeIn, + other index.GeoJSON) (bool, error) { + // check if the other shape is a point. + if p2, ok := other.(*Point); ok { + s2cell := s2.CellFromPoint(*p2.s2point) + + if s2cap.IntersectsCell(s2cell) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a multipoint. + if p2, ok := other.(*MultiPoint); ok { + // check the intersection for any point in the collection. + for _, point := range p2.s2points { + s2cell := s2.CellFromPoint(*point) + + if s2cap.IntersectsCell(s2cell) { + return true, nil + } + } + + return false, nil + } + + // check if the other shape is a polygon. + if p2, ok := other.(*Polygon); ok { + centerPoint := s2cap.Center() + projected := p2.s2pgn.Project(¢erPoint) + distance := projected.Distance(centerPoint) + return distance <= s2cap.Radius(), nil + } + + // check if the other shape is a multipolygon. + if p2, ok := other.(*MultiPolygon); ok { + // check the intersection for any polygon in the collection. + for _, s2pgn := range p2.s2pgns { + centerPoint := s2cap.Center() + projected := s2pgn.Project(¢erPoint) + distance := projected.Distance(centerPoint) + return distance <= s2cap.Radius(), nil + } + + return false, nil + } + + // check if the other shape is a linestring. + if p2, ok := other.(*LineString); ok { + projected, _ := p2.pl.Project(s2cap.Center()) + distance := projected.Distance(s2cap.Center()) + return distance <= s2cap.Radius(), nil + } + + // check if the other shape is a multilinestring. + if p2, ok := other.(*MultiLineString); ok { + for _, pl := range p2.pls { + projected, _ := pl.Project(s2cap.Center()) + distance := projected.Distance(s2cap.Center()) + if distance <= s2cap.Radius() { + return true, nil + } + } + + return false, nil + } + + if gc, ok := other.(*GeometryCollection); ok { + // check whether the circle intersects with any of the + // member shapes Contains the geometrycollection. + if geometryCollectionIntersectsShape(gc, shapeIn) { + return true, nil + } + return false, nil + } + + // check if the other shape is a circle. + if c, ok := other.(*Circle); ok { + if s2cap.Intersects(*c.s2cap) { + return true, nil + } + return false, nil + } + + // check if the other shape is a envelope. + if e, ok := other.(*Envelope); ok { + + if e.r.ContainsPoint(s2cap.Center()) { + return true, nil + } + + latlngs := []s2.LatLng{e.r.Vertex(0), e.r.Vertex(1), + e.r.Vertex(2), e.r.Vertex(3), e.r.Vertex(0)} + pl := s2.PolylineFromLatLngs(latlngs) + projected, _ := pl.Project(s2cap.Center()) + distance := projected.Distance(s2cap.Center()) + if distance <= s2cap.Radius() { + return true, nil + } + + return false, nil + } + + return false, fmt.Errorf("unknown geojson type: %s"+ + " found in document", other.Type()) +} + +// checkCircleContainsShape checks for containment of the +// shape in the document with the circle. +func checkCircleContainsShape(s2cap *s2.Cap, + shapeIn, other index.GeoJSON) (bool, error) { + // check if the other shape is a point. + if p2, ok := other.(*Point); ok { + + if s2cap.ContainsPoint(*p2.s2point) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a multipoint. + if p2, ok := other.(*MultiPoint); ok { + // check the intersection for every point in the collection. + for _, point := range p2.s2points { + if !s2cap.ContainsPoint(*point) { + return false, nil + } + } + + return true, nil + } + + // check if the other shape is a polygon. + if p2, ok := other.(*Polygon); ok { + for i := 0; i < p2.s2pgn.NumEdges(); i++ { + edge := p2.s2pgn.Edge(i) + if !s2cap.ContainsPoint(edge.V0) || + !s2cap.ContainsPoint(edge.V1) { + return false, nil + } + } + return true, nil + } + + // check if the other shape is a multipolygon. + if p2, ok := other.(*MultiPolygon); ok { + // check the containment for every polygon in the collection. + for _, s2pgn := range p2.s2pgns { + for i := 0; i < s2pgn.NumEdges(); i++ { + edge := s2pgn.Edge(i) + if !s2cap.ContainsPoint(edge.V0) || + !s2cap.ContainsPoint(edge.V1) { + return false, nil + } + } + } + + return true, nil + } + + // check if the other shape is a linestring. + if p2, ok := other.(*LineString); ok { + for i := 0; i < p2.pl.NumEdges(); i++ { + edge := p2.pl.Edge(i) + // check whether both the end vertices are inside the circle. + if s2cap.ContainsPoint(edge.V0) && + s2cap.ContainsPoint(edge.V1) { + return true, nil + } + } + return false, nil + } + + // check if the other shape is a multilinestring. + if p2, ok := other.(*MultiLineString); ok { + for _, pl := range p2.pls { + for i := 0; i < pl.NumEdges(); i++ { + edge := pl.Edge(i) + // check whether both the end vertices are inside the circle. + if !(s2cap.ContainsPoint(edge.V0) && s2cap.ContainsPoint(edge.V1)) { + return false, nil + } + } + } + return true, nil + } + + if gc, ok := other.(*GeometryCollection); ok { + for _, shape := range gc.Members() { + contains, err := shapeIn.Contains(shape) + if err == nil && !contains { + return false, nil + } + } + return true, nil + } + + // check if the other shape is a circle. + if c, ok := other.(*Circle); ok { + + if s2cap.Contains(*c.s2cap) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a envelope. + if e, ok := other.(*Envelope); ok { + + for i := 0; i < 4; i++ { + if !s2cap.ContainsPoint( + s2.PointFromLatLng(e.r.Vertex(i))) { + return false, nil + } + } + + return true, nil + } + + return false, fmt.Errorf("unknown geojson type: %s"+ + " found in document", other.Type()) +} + +// ------------------------------------------------------------------------ + +// checkEnvelopeIntersectsShape checks whether the given shape in +// the document is intersecting Contains the envelope/rectangle. +func checkEnvelopeIntersectsShape(s2rect *s2.Rect, shapeIn, + other index.GeoJSON) (bool, error) { + // check if the other shape is a point. + if p2, ok := other.(*Point); ok { + s2cell := s2.CellFromPoint(*p2.s2point) + + if s2rect.IntersectsCell(s2cell) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a multipoint. + if p2, ok := other.(*MultiPoint); ok { + // check the intersection for any point in the collection. + for _, point := range p2.s2points { + s2cell := s2.CellFromPoint(*point) + + if s2rect.IntersectsCell(s2cell) { + return true, nil + } + } + + return false, nil + } + + // check if the other shape is a polygon. + if pgn, ok := other.(*Polygon); ok { + + if rectangleIntersectsWithPolygons(s2rect, + []*s2.Polygon{pgn.s2pgn}) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a multipolygon. + if mpgn, ok := other.(*MultiPolygon); ok { + // check the intersection for any polygon in the collection. + if rectangleIntersectsWithPolygons(s2rect, mpgn.s2pgns) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a linestring. + if ls, ok := other.(*LineString); ok { + + if rectangleIntersectsWithLineStrings(s2rect, + []*s2.Polyline{ls.pl}) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a multilinestring. + if mls, ok := other.(*MultiLineString); ok { + + if rectangleIntersectsWithLineStrings(s2rect, mls.pls) { + return true, nil + } + + return false, nil + } + + if gc, ok := other.(*GeometryCollection); ok { + // check for the intersection of every member shape + // within the geometrycollection. + if geometryCollectionIntersectsShape(gc, shapeIn) { + return true, nil + } + return false, nil + } + + // check if the other shape is a circle. + if c, ok := other.(*Circle); ok { + s2pgn := s2PolygonFromS2Rectangle(s2rect) + cp := c.s2cap.Center() + projected := s2pgn.Project(&cp) + distance := projected.Distance(cp) + return distance <= c.s2cap.Radius(), nil + } + + // check if the other shape is a envelope. + if e, ok := other.(*Envelope); ok { + + if s2rect.Intersects(*e.r) { + return true, nil + } + + return false, nil + } + + return false, fmt.Errorf("unknown geojson type: %s"+ + " found in document", other.Type()) +} + +// checkEnvelopeContainsShape checks whether the given shape in +// the document is contained Contains the envelope/rectangle. +func checkEnvelopeContainsShape(s2rect *s2.Rect, shapeIn, + other index.GeoJSON) (bool, error) { + // check if the other shape is a point. + if p2, ok := other.(*Point); ok { + s2LatLng := s2.LatLngFromPoint(*p2.s2point) + + if s2rect.ContainsLatLng(s2LatLng) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a multipoint. + if p2, ok := other.(*MultiPoint); ok { + // check the intersection for any point in the collection. + for _, point := range p2.s2points { + s2LatLng := s2.LatLngFromPoint(*point) + + if !s2rect.ContainsLatLng(s2LatLng) { + return false, nil + } + } + + return true, nil + } + + // check if the other shape is a polygon. + if p2, ok := other.(*Polygon); ok { + s2pgnRect := s2PolygonFromS2Rectangle(s2rect) + return s2pgnRect.Contains(p2.s2pgn), nil + } + + // check if the other shape is a multipolygon. + if p2, ok := other.(*MultiPolygon); ok { + s2pgnRect := s2PolygonFromS2Rectangle(s2rect) + + // check the containment for every polygon in the collection. + for _, s2pgn := range p2.s2pgns { + if !s2pgnRect.Contains(s2pgn) { + return false, nil + } + } + + return true, nil + } + + // check if the other shape is a linestring. + if p2, ok := other.(*LineString); ok { + for i := 0; i < p2.pl.NumEdges(); i++ { + edge := p2.pl.Edge(i) + if !s2rect.ContainsPoint(edge.V0) || + !s2rect.ContainsPoint(edge.V1) { + return false, nil + } + } + + return true, nil + } + + // check if the other shape is a multilinestring. + if p2, ok := other.(*MultiLineString); ok { + for _, pl := range p2.pls { + for i := 0; i < pl.NumEdges(); i++ { + edge := pl.Edge(i) + if !s2rect.ContainsPoint(edge.V0) || + !s2rect.ContainsPoint(edge.V1) { + return false, nil + } + } + } + return true, nil + } + + if gc, ok := other.(*GeometryCollection); ok { + for _, shape := range gc.Members() { + contains, err := shapeIn.Contains(shape) + if err == nil && !contains { + return false, nil + } + } + return true, nil + } + + // check if the other shape is a circle. + if c, ok := other.(*Circle); ok { + + if s2rect.Contains(c.s2cap.RectBound()) { + return true, nil + } + + return false, nil + } + + // check if the other shape is a envelope. + if e, ok := other.(*Envelope); ok { + + if s2rect.Contains(*e.r) { + return true, nil + } + + return false, nil + } + + return false, fmt.Errorf("unknown geojson type: %s"+ + " found in document", other.Type()) +} diff --git a/backend/vendor/github.com/blevesearch/geo/geojson/geojson_shapes_util.go b/backend/vendor/github.com/blevesearch/geo/geojson/geojson_shapes_util.go new file mode 100644 index 0000000000..a62f685cd3 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/geojson/geojson_shapes_util.go @@ -0,0 +1,586 @@ +// Copyright (c) 2022 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package geojson + +import ( + "bytes" + "encoding/binary" + "fmt" + "strings" + + index "github.com/blevesearch/bleve_index_api" + "github.com/blevesearch/geo/s2" + jsoniterator "github.com/json-iterator/go" +) + +var jsoniter = jsoniterator.ConfigCompatibleWithStandardLibrary + +// FilterGeoShapesOnRelation extracts the shapes in the document, apply +// the `relation` filter and confirms whether the shape in the document +// satisfies the given relation. +func FilterGeoShapesOnRelation(shape index.GeoJSON, targetShapeBytes []byte, + relation string, reader **bytes.Reader) (bool, error) { + + shapeInDoc, err := extractShapesFromBytes(targetShapeBytes, reader) + if err != nil { + return false, err + } + + return filterShapes(shape, shapeInDoc, relation) +} + +// extractShapesFromBytes unmarshal the bytes to retrieve the +// embedded geojson shape. +func extractShapesFromBytes(targetShapeBytes []byte, r **bytes.Reader) ( + index.GeoJSON, error) { + if (*r) == nil { + *r = bytes.NewReader(targetShapeBytes[1:]) + } else { + (*r).Reset(targetShapeBytes[1:]) + } + + switch targetShapeBytes[0] { + case PointTypePrefix: + point := &Point{s2point: &s2.Point{}} + err := point.s2point.Decode(*r) + if err != nil { + return nil, err + } + return point, nil + + case MultiPointTypePrefix: + var numPoints int32 + err := binary.Read(*r, binary.BigEndian, &numPoints) + if err != nil { + return nil, err + } + multipoint := &MultiPoint{ + s2points: make([]*s2.Point, 0, numPoints), + } + for i := 0; i < int(numPoints); i++ { + s2point := s2.Point{} + err := s2point.Decode((*r)) + if err != nil { + return nil, err + } + multipoint.s2points = append(multipoint.s2points, &s2point) + } + + return multipoint, nil + + case LineStringTypePrefix: + ls := &LineString{pl: &s2.Polyline{}} + err := ls.pl.Decode(*r) + if err != nil { + return nil, err + } + return ls, nil + + case MultiLineStringTypePrefix: + var numLineStrings int32 + err := binary.Read(*r, binary.BigEndian, &numLineStrings) + if err != nil { + return nil, err + } + + mls := &MultiLineString{pls: make([]*s2.Polyline, 0, numLineStrings)} + + for i := 0; i < int(numLineStrings); i++ { + pl := &s2.Polyline{} + err := pl.Decode(*r) + if err != nil { + return nil, err + } + mls.pls = append(mls.pls, pl) + } + + return mls, nil + + case PolygonTypePrefix: + pgn := &Polygon{s2pgn: &s2.Polygon{}} + err := pgn.s2pgn.Decode(*r) + if err != nil { + return nil, err + } + + return pgn, nil + + case MultiPolygonTypePrefix: + var numPolygons int32 + err := binary.Read(*r, binary.BigEndian, &numPolygons) + if err != nil { + return nil, err + } + mpgns := &MultiPolygon{s2pgns: make([]*s2.Polygon, 0, numPolygons)} + for i := 0; i < int(numPolygons); i++ { + pgn := &s2.Polygon{} + err := pgn.Decode(*r) + if err != nil { + return nil, err + } + mpgns.s2pgns = append(mpgns.s2pgns, pgn) + } + + return mpgns, nil + + case GeometryCollectionTypePrefix: + var numShapes int32 + err := binary.Read(*r, binary.BigEndian, &numShapes) + if err != nil { + return nil, err + } + + lengths := make([]int32, numShapes) + for i := int32(0); i < numShapes; i++ { + var length int32 + err := binary.Read(*r, binary.BigEndian, &length) + if err != nil { + return nil, err + } + lengths[i] = length + } + + inputBytes := targetShapeBytes[len(targetShapeBytes)-(*r).Len():] + gc := &GeometryCollection{Shapes: make([]index.GeoJSON, numShapes)} + + for i := int32(0); i < numShapes; i++ { + shape, err := extractShapesFromBytes(inputBytes[:lengths[i]], r) + if err != nil { + return nil, err + } + + gc.Shapes[i] = shape + inputBytes = inputBytes[lengths[i]:] + } + + return gc, nil + + case CircleTypePrefix: + c := &Circle{s2cap: &s2.Cap{}} + err := c.s2cap.Decode(*r) + if err != nil { + return nil, err + } + + return c, nil + + case EnvelopeTypePrefix: + e := &Envelope{r: &s2.Rect{}} + err := e.r.Decode(*r) + if err != nil { + return nil, err + } + + return e, nil + } + + return nil, fmt.Errorf("unknown geo shape type: %v", targetShapeBytes[0]) +} + +// filterShapes applies the given relation between the query shape +// and the shape in the document. +func filterShapes(shape index.GeoJSON, + shapeInDoc index.GeoJSON, relation string) (bool, error) { + + if relation == "intersects" { + return shape.Intersects(shapeInDoc) + } + + if relation == "contains" { + return shapeInDoc.Contains(shape) + } + + if relation == "within" { + return shape.Contains(shapeInDoc) + } + + if relation == "disjoint" { + intersects, err := shape.Intersects(shapeInDoc) + return !intersects, err + } + + return false, fmt.Errorf("unknown relation: %s", relation) +} + +// ParseGeoJSONShape unmarshals the geojson/circle/envelope shape +// embedded in the given bytes. +func ParseGeoJSONShape(input []byte) (index.GeoJSON, error) { + var sType string + var tmp struct { + Typ string `json:"type"` + } + err := jsoniter.Unmarshal(input, &tmp) + if err != nil { + return nil, err + } + + sType = strings.ToLower(tmp.Typ) + + switch sType { + case PolygonType: + var rv Polygon + err := jsoniter.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + rv.init() + return &rv, nil + + case MultiPolygonType: + var rv MultiPolygon + err := jsoniter.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + rv.init() + return &rv, nil + + case PointType: + var rv Point + err := jsoniter.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + rv.init() + return &rv, nil + + case MultiPointType: + var rv MultiPoint + err := jsoniter.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + rv.init() + return &rv, nil + + case LineStringType: + var rv LineString + err := jsoniter.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + rv.init() + return &rv, nil + + case MultiLineStringType: + var rv MultiLineString + err := jsoniter.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + rv.init() + return &rv, nil + + case GeometryCollectionType: + var rv GeometryCollection + err := jsoniter.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + return &rv, nil + + case CircleType: + var rv Circle + err := jsoniter.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + rv.init() + return &rv, nil + + case EnvelopeType: + var rv Envelope + err := jsoniter.Unmarshal(input, &rv) + if err != nil { + return nil, err + } + rv.init() + return &rv, nil + + default: + return nil, fmt.Errorf("unknown shape type: %s", sType) + } + + return nil, err +} + +// NewGeoJsonShape instantiate a geojson shape/circle or +// an envelope from the given coordinates and type. +func NewGeoJsonShape(coordinates [][][][]float64, typ string) ( + index.GeoJSON, []byte, error) { + if len(coordinates) == 0 { + return nil, nil, fmt.Errorf("missing coordinates") + } + + typ = strings.ToLower(typ) + + switch typ { + case PointType: + point := NewGeoJsonPoint(coordinates[0][0][0]) + value, err := point.(s2Serializable).Marshal() + if err != nil { + return nil, nil, err + } + return point, value, nil + + case MultiPointType: + multipoint := NewGeoJsonMultiPoint(coordinates[0][0]) + value, err := multipoint.(s2Serializable).Marshal() + if err != nil { + return nil, nil, err + } + return multipoint, value, nil + + case LineStringType: + linestring := NewGeoJsonLinestring(coordinates[0][0]) + value, err := linestring.(s2Serializable).Marshal() + if err != nil { + return nil, nil, err + } + return linestring, value, nil + + case MultiLineStringType: + multilinestring := NewGeoJsonMultilinestring(coordinates[0]) + value, err := multilinestring.(s2Serializable).Marshal() + if err != nil { + return nil, nil, err + } + return multilinestring, value, nil + + case PolygonType: + polygon := NewGeoJsonPolygon(coordinates[0]) + value, err := polygon.(s2Serializable).Marshal() + if err != nil { + return nil, nil, err + } + return polygon, value, nil + + case MultiPolygonType: + multipolygon := NewGeoJsonMultiPolygon(coordinates) + value, err := multipolygon.(s2Serializable).Marshal() + if err != nil { + return nil, nil, err + } + return multipolygon, value, nil + + case EnvelopeType: + envelope := NewGeoEnvelope(coordinates[0][0]) + value, err := envelope.(s2Serializable).Marshal() + if err != nil { + return nil, nil, err + } + return envelope, value, nil + } + + return nil, nil, fmt.Errorf("unknown shape type: %s", typ) +} + +// GlueBytes primarily for quicker filtering of docvalues +// during the filtering phase. +var GlueBytes = []byte("##") + +// NewGeometryCollection instantiate a geometrycollection +// and prefix the byte contents with certain glue bytes that +// can be used later while filering the doc values. +func NewGeometryCollection(coordinates [][][][][]float64, + typs []string) (index.GeoJSON, []byte, error) { + if typs == nil { + return nil, nil, fmt.Errorf("nil type information") + } + if len(typs) < len(coordinates) { + return nil, nil, fmt.Errorf("missing type information for some shapes") + } + shapes := make([]index.GeoJSON, 0, len(coordinates)) + for i, vertices := range coordinates { + s, _, err := NewGeoJsonShape(vertices, typs[i]) + if err != nil { + continue + } + shapes = append(shapes, s) + } + + var gc GeometryCollection + gc.Typ = GeometryCollectionType + gc.Shapes = shapes + vbytes, err := gc.Marshal() + if err != nil { + return nil, nil, err + } + + return &gc, vbytes, nil +} + +// NewGeoCircleShape instantiate a circle shape and +// prefix the byte contents with certain glue bytes that +// can be used later while filering the doc values. +func NewGeoCircleShape(cp []float64, + radius string) (*Circle, []byte, error) { + r, err := ParseDistance(radius) + if err != nil { + return nil, nil, err + } + rv := &Circle{Typ: CircleType, Vertices: cp, + Radius: radius, + radiusInMeters: r} + + vbytes, err := rv.Marshal() + if err != nil { + return nil, nil, err + } + + return rv, vbytes, nil +} + +// ------------------------------------------------------------------------ + +func (p *Point) IndexTokens(s *s2.RegionTermIndexer) []string { + p.init() + terms := s.GetIndexTermsForPoint(*p.s2point, "") + return StripCoveringTerms(terms) +} + +func (p *Point) QueryTokens(s *s2.RegionTermIndexer) []string { + p.init() + terms := s.GetQueryTermsForPoint(*p.s2point, "") + return StripCoveringTerms(terms) +} + +// ------------------------------------------------------------------------ + +func (mp *MultiPoint) IndexTokens(s *s2.RegionTermIndexer) []string { + mp.init() + var rv []string + for _, s2point := range mp.s2points { + terms := s.GetIndexTermsForPoint(*s2point, "") + rv = append(rv, terms...) + } + return StripCoveringTerms(rv) +} + +func (mp *MultiPoint) QueryTokens(s *s2.RegionTermIndexer) []string { + mp.init() + var rv []string + for _, s2point := range mp.s2points { + terms := s.GetQueryTermsForPoint(*s2point, "") + rv = append(rv, terms...) + } + + return StripCoveringTerms(rv) +} + +// ------------------------------------------------------------------------ + +func (ls *LineString) IndexTokens(s *s2.RegionTermIndexer) []string { + ls.init() + terms := s.GetIndexTermsForRegion(ls.pl.CapBound(), "") + return StripCoveringTerms(terms) +} + +func (ls *LineString) QueryTokens(s *s2.RegionTermIndexer) []string { + ls.init() + terms := s.GetQueryTermsForRegion(ls.pl.CapBound(), "") + return StripCoveringTerms(terms) +} + +// ------------------------------------------------------------------------ + +func (mls *MultiLineString) IndexTokens(s *s2.RegionTermIndexer) []string { + mls.init() + var rv []string + for _, ls := range mls.pls { + terms := s.GetIndexTermsForRegion(ls.CapBound(), "") + rv = append(rv, terms...) + } + + return StripCoveringTerms(rv) +} + +func (mls *MultiLineString) QueryTokens(s *s2.RegionTermIndexer) []string { + mls.init() + + var rv []string + for _, ls := range mls.pls { + terms := s.GetQueryTermsForRegion(ls.CapBound(), "") + rv = append(rv, terms...) + } + + return StripCoveringTerms(rv) +} + +// ------------------------------------------------------------------------ + +func (mp *MultiPolygon) IndexTokens(s *s2.RegionTermIndexer) []string { + mp.init() + + var rv []string + for _, s2pgn := range mp.s2pgns { + terms := s.GetIndexTermsForRegion(s2pgn.CapBound(), "") + rv = append(rv, terms...) + } + + return StripCoveringTerms(rv) +} + +func (mp *MultiPolygon) QueryTokens(s *s2.RegionTermIndexer) []string { + mp.init() + + var rv []string + for _, s2pgn := range mp.s2pgns { + terms := s.GetQueryTermsForRegion(s2pgn.CapBound(), "") + rv = append(rv, terms...) + } + + return StripCoveringTerms(rv) +} + +// ------------------------------------------------------------------------ + +func (pgn *Polygon) IndexTokens(s *s2.RegionTermIndexer) []string { + pgn.init() + terms := s.GetIndexTermsForRegion( + pgn.s2pgn.CapBound(), "") + return StripCoveringTerms(terms) +} + +func (pgn *Polygon) QueryTokens(s *s2.RegionTermIndexer) []string { + pgn.init() + terms := s.GetQueryTermsForRegion( + pgn.s2pgn.CapBound(), "") + return StripCoveringTerms(terms) +} + +// ------------------------------------------------------------------------ + +func (c *Circle) IndexTokens(s *s2.RegionTermIndexer) []string { + c.init() + return StripCoveringTerms(s.GetIndexTermsForRegion(c.s2cap.CapBound(), "")) +} + +func (c *Circle) QueryTokens(s *s2.RegionTermIndexer) []string { + c.init() + return StripCoveringTerms(s.GetQueryTermsForRegion(c.s2cap.CapBound(), "")) +} + +// ------------------------------------------------------------------------ + +func (e *Envelope) IndexTokens(s *s2.RegionTermIndexer) []string { + e.init() + return StripCoveringTerms(s.GetIndexTermsForRegion(e.r.CapBound(), "")) +} + +func (e *Envelope) QueryTokens(s *s2.RegionTermIndexer) []string { + e.init() + return StripCoveringTerms(s.GetQueryTermsForRegion(e.r.CapBound(), "")) +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/bits_go18.go b/backend/vendor/github.com/blevesearch/geo/s2/bits_go18.go new file mode 100644 index 0000000000..4b8bfef941 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/bits_go18.go @@ -0,0 +1,54 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !go1.9 +// +build !go1.9 + +package s2 + +// This file is for the bit manipulation code pre-Go 1.9. + +// findMSBSetNonZero64 returns the index (between 0 and 63) of the most +// significant set bit. Passing zero to this function returns zero. +func findMSBSetNonZero64(x uint64) int { + val := []uint64{0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000, 0xFFFFFFFF00000000} + shift := []uint64{1, 2, 4, 8, 16, 32} + var msbPos uint64 + for i := 5; i >= 0; i-- { + if x&val[i] != 0 { + x >>= shift[i] + msbPos |= shift[i] + } + } + return int(msbPos) +} + +const deBruijn64 = 0x03f79d71b4ca8b09 +const digitMask = uint64(1<<64 - 1) + +var deBruijn64Lookup = []byte{ + 0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4, + 62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5, + 63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11, + 54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6, +} + +// findLSBSetNonZero64 returns the index (between 0 and 63) of the least +// significant set bit. Passing zero to this function returns zero. +// +// This code comes from trailingZeroBits in https://golang.org/src/math/big/nat.go +// which references (Knuth, volume 4, section 7.3.1). +func findLSBSetNonZero64(x uint64) int { + return int(deBruijn64Lookup[((x&-x)*(deBruijn64&digitMask))>>58]) +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/bits_go19.go b/backend/vendor/github.com/blevesearch/geo/s2/bits_go19.go new file mode 100644 index 0000000000..0de1ac69b9 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/bits_go19.go @@ -0,0 +1,40 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build go1.9 +// +build go1.9 + +package s2 + +// This file is for the bit manipulation code post-Go 1.9. + +import "math/bits" + +// findMSBSetNonZero64 returns the index (between 0 and 63) of the most +// significant set bit. Passing zero to this function return zero. +func findMSBSetNonZero64(x uint64) int { + if x == 0 { + return 0 + } + return 63 - bits.LeadingZeros64(x) +} + +// findLSBSetNonZero64 returns the index (between 0 and 63) of the least +// significant set bit. Passing zero to this function return zero. +func findLSBSetNonZero64(x uint64) int { + if x == 0 { + return 0 + } + return bits.TrailingZeros64(x) +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/cap.go b/backend/vendor/github.com/blevesearch/geo/s2/cap.go new file mode 100644 index 0000000000..c4fb2e1e0d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/cap.go @@ -0,0 +1,519 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "fmt" + "io" + "math" + + "github.com/golang/geo/r1" + "github.com/golang/geo/s1" +) + +var ( + // centerPoint is the default center for Caps + centerPoint = PointFromCoords(1.0, 0, 0) +) + +// Cap represents a disc-shaped region defined by a center and radius. +// Technically this shape is called a "spherical cap" (rather than disc) +// because it is not planar; the cap represents a portion of the sphere that +// has been cut off by a plane. The boundary of the cap is the circle defined +// by the intersection of the sphere and the plane. For containment purposes, +// the cap is a closed set, i.e. it contains its boundary. +// +// For the most part, you can use a spherical cap wherever you would use a +// disc in planar geometry. The radius of the cap is measured along the +// surface of the sphere (rather than the straight-line distance through the +// interior). Thus a cap of radius π/2 is a hemisphere, and a cap of radius +// π covers the entire sphere. +// +// The center is a point on the surface of the unit sphere. (Hence the need for +// it to be of unit length.) +// +// A cap can also be defined by its center point and height. The height is the +// distance from the center point to the cutoff plane. There is also support for +// "empty" and "full" caps, which contain no points and all points respectively. +// +// Here are some useful relationships between the cap height (h), the cap +// radius (r), the maximum chord length from the cap's center (d), and the +// radius of cap's base (a). +// +// h = 1 - cos(r) +// = 2 * sin^2(r/2) +// d^2 = 2 * h +// = a^2 + h^2 +// +// The zero value of Cap is an invalid cap. Use EmptyCap to get a valid empty cap. +type Cap struct { + center Point + radius s1.ChordAngle +} + +// CapFromPoint constructs a cap containing a single point. +func CapFromPoint(p Point) Cap { + return CapFromCenterChordAngle(p, 0) +} + +// CapFromCenterAngle constructs a cap with the given center and angle. +func CapFromCenterAngle(center Point, angle s1.Angle) Cap { + return CapFromCenterChordAngle(center, s1.ChordAngleFromAngle(angle)) +} + +// CapFromCenterChordAngle constructs a cap where the angle is expressed as an +// s1.ChordAngle. This constructor is more efficient than using an s1.Angle. +func CapFromCenterChordAngle(center Point, radius s1.ChordAngle) Cap { + return Cap{ + center: center, + radius: radius, + } +} + +// CapFromCenterHeight constructs a cap with the given center and height. A +// negative height yields an empty cap; a height of 2 or more yields a full cap. +// The center should be unit length. +func CapFromCenterHeight(center Point, height float64) Cap { + return CapFromCenterChordAngle(center, s1.ChordAngleFromSquaredLength(2*height)) +} + +// CapFromCenterArea constructs a cap with the given center and surface area. +// Note that the area can also be interpreted as the solid angle subtended by the +// cap (because the sphere has unit radius). A negative area yields an empty cap; +// an area of 4*π or more yields a full cap. +func CapFromCenterArea(center Point, area float64) Cap { + return CapFromCenterChordAngle(center, s1.ChordAngleFromSquaredLength(area/math.Pi)) +} + +// EmptyCap returns a cap that contains no points. +func EmptyCap() Cap { + return CapFromCenterChordAngle(centerPoint, s1.NegativeChordAngle) +} + +// FullCap returns a cap that contains all points. +func FullCap() Cap { + return CapFromCenterChordAngle(centerPoint, s1.StraightChordAngle) +} + +// IsValid reports whether the Cap is considered valid. +func (c Cap) IsValid() bool { + return c.center.Vector.IsUnit() && c.radius <= s1.StraightChordAngle +} + +// IsEmpty reports whether the cap is empty, i.e. it contains no points. +func (c Cap) IsEmpty() bool { + return c.radius < 0 +} + +// IsFull reports whether the cap is full, i.e. it contains all points. +func (c Cap) IsFull() bool { + return c.radius == s1.StraightChordAngle +} + +// Center returns the cap's center point. +func (c Cap) Center() Point { + return c.center +} + +// Height returns the height of the cap. This is the distance from the center +// point to the cutoff plane. +func (c Cap) Height() float64 { + return float64(0.5 * c.radius) +} + +// Radius returns the cap radius as an s1.Angle. (Note that the cap angle +// is stored internally as a ChordAngle, so this method requires a trigonometric +// operation and may yield a slightly different result than the value passed +// to CapFromCenterAngle). +func (c Cap) Radius() s1.Angle { + return c.radius.Angle() +} + +// Area returns the surface area of the Cap on the unit sphere. +func (c Cap) Area() float64 { + return 2.0 * math.Pi * math.Max(0, c.Height()) +} + +// Contains reports whether this cap contains the other. +func (c Cap) Contains(other Cap) bool { + // In a set containment sense, every cap contains the empty cap. + if c.IsFull() || other.IsEmpty() { + return true + } + return c.radius >= ChordAngleBetweenPoints(c.center, other.center).Add(other.radius) +} + +// Intersects reports whether this cap intersects the other cap. +// i.e. whether they have any points in common. +func (c Cap) Intersects(other Cap) bool { + if c.IsEmpty() || other.IsEmpty() { + return false + } + + return c.radius.Add(other.radius) >= ChordAngleBetweenPoints(c.center, other.center) +} + +// InteriorIntersects reports whether this caps interior intersects the other cap. +func (c Cap) InteriorIntersects(other Cap) bool { + // Make sure this cap has an interior and the other cap is non-empty. + if c.radius <= 0 || other.IsEmpty() { + return false + } + + return c.radius.Add(other.radius) > ChordAngleBetweenPoints(c.center, other.center) +} + +// ContainsPoint reports whether this cap contains the point. +func (c Cap) ContainsPoint(p Point) bool { + return ChordAngleBetweenPoints(c.center, p) <= c.radius +} + +// InteriorContainsPoint reports whether the point is within the interior of this cap. +func (c Cap) InteriorContainsPoint(p Point) bool { + return c.IsFull() || ChordAngleBetweenPoints(c.center, p) < c.radius +} + +// Complement returns the complement of the interior of the cap. A cap and its +// complement have the same boundary but do not share any interior points. +// The complement operator is not a bijection because the complement of a +// singleton cap (containing a single point) is the same as the complement +// of an empty cap. +func (c Cap) Complement() Cap { + if c.IsFull() { + return EmptyCap() + } + if c.IsEmpty() { + return FullCap() + } + + return CapFromCenterChordAngle(Point{c.center.Mul(-1)}, s1.StraightChordAngle.Sub(c.radius)) +} + +// CapBound returns a bounding spherical cap. This is not guaranteed to be exact. +func (c Cap) CapBound() Cap { + return c +} + +// RectBound returns a bounding latitude-longitude rectangle. +// The bounds are not guaranteed to be tight. +func (c Cap) RectBound() Rect { + if c.IsEmpty() { + return EmptyRect() + } + + capAngle := c.Radius().Radians() + allLongitudes := false + lat := r1.Interval{ + Lo: latitude(c.center).Radians() - capAngle, + Hi: latitude(c.center).Radians() + capAngle, + } + lng := s1.FullInterval() + + // Check whether cap includes the south pole. + if lat.Lo <= -math.Pi/2 { + lat.Lo = -math.Pi / 2 + allLongitudes = true + } + + // Check whether cap includes the north pole. + if lat.Hi >= math.Pi/2 { + lat.Hi = math.Pi / 2 + allLongitudes = true + } + + if !allLongitudes { + // Compute the range of longitudes covered by the cap. We use the law + // of sines for spherical triangles. Consider the triangle ABC where + // A is the north pole, B is the center of the cap, and C is the point + // of tangency between the cap boundary and a line of longitude. Then + // C is a right angle, and letting a,b,c denote the sides opposite A,B,C, + // we have sin(a)/sin(A) = sin(c)/sin(C), or sin(A) = sin(a)/sin(c). + // Here "a" is the cap angle, and "c" is the colatitude (90 degrees + // minus the latitude). This formula also works for negative latitudes. + // + // The formula for sin(a) follows from the relationship h = 1 - cos(a). + sinA := c.radius.Sin() + sinC := math.Cos(latitude(c.center).Radians()) + if sinA <= sinC { + angleA := math.Asin(sinA / sinC) + lng.Lo = math.Remainder(longitude(c.center).Radians()-angleA, math.Pi*2) + lng.Hi = math.Remainder(longitude(c.center).Radians()+angleA, math.Pi*2) + } + } + return Rect{lat, lng} +} + +// Equal reports whether this cap is equal to the other cap. +func (c Cap) Equal(other Cap) bool { + return (c.radius == other.radius && c.center == other.center) || + (c.IsEmpty() && other.IsEmpty()) || + (c.IsFull() && other.IsFull()) +} + +// ApproxEqual reports whether this cap is equal to the other cap within the given tolerance. +func (c Cap) ApproxEqual(other Cap) bool { + const epsilon = 1e-14 + r2 := float64(c.radius) + otherR2 := float64(other.radius) + return c.center.ApproxEqual(other.center) && + math.Abs(r2-otherR2) <= epsilon || + c.IsEmpty() && otherR2 <= epsilon || + other.IsEmpty() && r2 <= epsilon || + c.IsFull() && otherR2 >= 2-epsilon || + other.IsFull() && r2 >= 2-epsilon +} + +// AddPoint increases the cap if necessary to include the given point. If this cap is empty, +// then the center is set to the point with a zero height. p must be unit-length. +func (c Cap) AddPoint(p Point) Cap { + if c.IsEmpty() { + c.center = p + c.radius = 0 + return c + } + + // After calling cap.AddPoint(p), cap.Contains(p) must be true. However + // we don't need to do anything special to achieve this because Contains() + // does exactly the same distance calculation that we do here. + if newRad := ChordAngleBetweenPoints(c.center, p); newRad > c.radius { + c.radius = newRad + } + return c +} + +// AddCap increases the cap height if necessary to include the other cap. If this cap is empty, +// it is set to the other cap. +func (c Cap) AddCap(other Cap) Cap { + if c.IsEmpty() { + return other + } + if other.IsEmpty() { + return c + } + + // We round up the distance to ensure that the cap is actually contained. + // TODO(roberts): Do some error analysis in order to guarantee this. + dist := ChordAngleBetweenPoints(c.center, other.center).Add(other.radius) + if newRad := dist.Expanded(dblEpsilon * float64(dist)); newRad > c.radius { + c.radius = newRad + } + return c +} + +// Expanded returns a new cap expanded by the given angle. If the cap is empty, +// it returns an empty cap. +func (c Cap) Expanded(distance s1.Angle) Cap { + if c.IsEmpty() { + return EmptyCap() + } + return CapFromCenterChordAngle(c.center, c.radius.Add(s1.ChordAngleFromAngle(distance))) +} + +func (c Cap) String() string { + return fmt.Sprintf("[Center=%v, Radius=%f]", c.center.Vector, c.Radius().Degrees()) +} + +// radiusToHeight converts an s1.Angle into the height of the cap. +func radiusToHeight(r s1.Angle) float64 { + if r.Radians() < 0 { + return float64(s1.NegativeChordAngle) + } + if r.Radians() >= math.Pi { + return float64(s1.RightChordAngle) + } + return float64(0.5 * s1.ChordAngleFromAngle(r)) + +} + +// ContainsCell reports whether the cap contains the given cell. +func (c Cap) ContainsCell(cell Cell) bool { + // If the cap does not contain all cell vertices, return false. + var vertices [4]Point + for k := 0; k < 4; k++ { + vertices[k] = cell.Vertex(k) + if !c.ContainsPoint(vertices[k]) { + return false + } + } + // Otherwise, return true if the complement of the cap does not intersect the cell. + return !c.Complement().intersects(cell, vertices) +} + +// IntersectsCell reports whether the cap intersects the cell. +func (c Cap) IntersectsCell(cell Cell) bool { + // If the cap contains any cell vertex, return true. + var vertices [4]Point + for k := 0; k < 4; k++ { + vertices[k] = cell.Vertex(k) + if c.ContainsPoint(vertices[k]) { + return true + } + } + return c.intersects(cell, vertices) +} + +// intersects reports whether the cap intersects any point of the cell excluding +// its vertices (which are assumed to already have been checked). +func (c Cap) intersects(cell Cell, vertices [4]Point) bool { + // If the cap is a hemisphere or larger, the cell and the complement of the cap + // are both convex. Therefore since no vertex of the cell is contained, no other + // interior point of the cell is contained either. + if c.radius >= s1.RightChordAngle { + return false + } + + // We need to check for empty caps due to the center check just below. + if c.IsEmpty() { + return false + } + + // Optimization: return true if the cell contains the cap center. This allows half + // of the edge checks below to be skipped. + if cell.ContainsPoint(c.center) { + return true + } + + // At this point we know that the cell does not contain the cap center, and the cap + // does not contain any cell vertex. The only way that they can intersect is if the + // cap intersects the interior of some edge. + sin2Angle := c.radius.Sin2() + for k := 0; k < 4; k++ { + edge := cell.Edge(k).Vector + dot := c.center.Vector.Dot(edge) + if dot > 0 { + // The center is in the interior half-space defined by the edge. We do not need + // to consider these edges, since if the cap intersects this edge then it also + // intersects the edge on the opposite side of the cell, because the center is + // not contained with the cell. + continue + } + + // The Norm2() factor is necessary because "edge" is not normalized. + if dot*dot > sin2Angle*edge.Norm2() { + return false + } + + // Otherwise, the great circle containing this edge intersects the interior of the cap. We just + // need to check whether the point of closest approach occurs between the two edge endpoints. + dir := edge.Cross(c.center.Vector) + if dir.Dot(vertices[k].Vector) < 0 && dir.Dot(vertices[(k+1)&3].Vector) > 0 { + return true + } + } + return false +} + +// CellUnionBound computes a covering of the Cap. In general the covering +// consists of at most 4 cells except for very large caps, which may need +// up to 6 cells. The output is not sorted. +func (c Cap) CellUnionBound() []CellID { + // TODO(roberts): The covering could be made quite a bit tighter by mapping + // the cap to a rectangle in (i,j)-space and finding a covering for that. + + // Find the maximum level such that the cap contains at most one cell vertex + // and such that CellID.AppendVertexNeighbors() can be called. + level := MinWidthMetric.MaxLevel(c.Radius().Radians()) - 1 + + // If level < 0, more than three face cells are required. + if level < 0 { + cellIDs := make([]CellID, 6) + for face := 0; face < 6; face++ { + cellIDs[face] = CellIDFromFace(face) + } + return cellIDs + } + // The covering consists of the 4 cells at the given level that share the + // cell vertex that is closest to the cap center. + return cellIDFromPoint(c.center).VertexNeighbors(level) +} + +// Centroid returns the true centroid of the cap multiplied by its surface area +// The result lies on the ray from the origin through the cap's center, but it +// is not unit length. Note that if you just want the "surface centroid", i.e. +// the normalized result, then it is simpler to call Center. +// +// The reason for multiplying the result by the cap area is to make it +// easier to compute the centroid of more complicated shapes. The centroid +// of a union of disjoint regions can be computed simply by adding their +// Centroid() results. Caveat: for caps that contain a single point +// (i.e., zero radius), this method always returns the origin (0, 0, 0). +// This is because shapes with no area don't affect the centroid of a +// union whose total area is positive. +func (c Cap) Centroid() Point { + // From symmetry, the centroid of the cap must be somewhere on the line + // from the origin to the center of the cap on the surface of the sphere. + // When a sphere is divided into slices of constant thickness by a set of + // parallel planes, all slices have the same surface area. This implies + // that the radial component of the centroid is simply the midpoint of the + // range of radial distances spanned by the cap. That is easily computed + // from the cap height. + if c.IsEmpty() { + return Point{} + } + r := 1 - 0.5*c.Height() + return Point{c.center.Mul(r * c.Area())} +} + +// Union returns the smallest cap which encloses this cap and other. +func (c Cap) Union(other Cap) Cap { + // If the other cap is larger, swap c and other for the rest of the computations. + if c.radius < other.radius { + c, other = other, c + } + + if c.IsFull() || other.IsEmpty() { + return c + } + + // TODO: This calculation would be more efficient using s1.ChordAngles. + cRadius := c.Radius() + otherRadius := other.Radius() + distance := c.center.Distance(other.center) + if cRadius >= distance+otherRadius { + return c + } + + resRadius := 0.5 * (distance + cRadius + otherRadius) + resCenter := InterpolateAtDistance(0.5*(distance-cRadius+otherRadius), c.center, other.center) + return CapFromCenterAngle(resCenter, resRadius) +} + +// Encode encodes the Cap. +func (c Cap) Encode(w io.Writer) error { + e := &encoder{w: w} + c.encode(e) + return e.err +} + +func (c Cap) encode(e *encoder) { + e.writeFloat64(c.center.X) + e.writeFloat64(c.center.Y) + e.writeFloat64(c.center.Z) + e.writeFloat64(float64(c.radius)) +} + +// Decode decodes the Cap. +func (c *Cap) Decode(r io.Reader) error { + d := &decoder{r: asByteReader(r)} + c.decode(d) + return d.err +} + +func (c *Cap) decode(d *decoder) { + c.center.X = d.readFloat64() + c.center.Y = d.readFloat64() + c.center.Z = d.readFloat64() + c.radius = s1.ChordAngle(d.readFloat64()) +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/cell.go b/backend/vendor/github.com/blevesearch/geo/s2/cell.go new file mode 100644 index 0000000000..0a01a4f1fd --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/cell.go @@ -0,0 +1,698 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "io" + "math" + + "github.com/golang/geo/r1" + "github.com/golang/geo/r2" + "github.com/golang/geo/r3" + "github.com/golang/geo/s1" +) + +// Cell is an S2 region object that represents a cell. Unlike CellIDs, +// it supports efficient containment and intersection tests. However, it is +// also a more expensive representation. +type Cell struct { + face int8 + level int8 + orientation int8 + id CellID + uv r2.Rect +} + +// CellFromCellID constructs a Cell corresponding to the given CellID. +func CellFromCellID(id CellID) Cell { + c := Cell{} + c.id = id + f, i, j, o := c.id.faceIJOrientation() + c.face = int8(f) + c.level = int8(c.id.Level()) + c.orientation = int8(o) + c.uv = ijLevelToBoundUV(i, j, int(c.level)) + return c +} + +// CellFromPoint constructs a cell for the given Point. +func CellFromPoint(p Point) Cell { + return CellFromCellID(cellIDFromPoint(p)) +} + +// CellFromLatLng constructs a cell for the given LatLng. +func CellFromLatLng(ll LatLng) Cell { + return CellFromCellID(CellIDFromLatLng(ll)) +} + +// Face returns the face this cell is on. +func (c Cell) Face() int { + return int(c.face) +} + +// oppositeFace returns the face opposite the given face. +func oppositeFace(face int) int { + return (face + 3) % 6 +} + +// Level returns the level of this cell. +func (c Cell) Level() int { + return int(c.level) +} + +// ID returns the CellID this cell represents. +func (c Cell) ID() CellID { + return c.id +} + +// IsLeaf returns whether this Cell is a leaf or not. +func (c Cell) IsLeaf() bool { + return c.level == maxLevel +} + +// SizeIJ returns the edge length of this cell in (i,j)-space. +func (c Cell) SizeIJ() int { + return sizeIJ(int(c.level)) +} + +// SizeST returns the edge length of this cell in (s,t)-space. +func (c Cell) SizeST() float64 { + return c.id.sizeST(int(c.level)) +} + +// Vertex returns the k-th vertex of the cell (k = 0,1,2,3) in CCW order +// (lower left, lower right, upper right, upper left in the UV plane). +func (c Cell) Vertex(k int) Point { + return Point{faceUVToXYZ(int(c.face), c.uv.Vertices()[k].X, c.uv.Vertices()[k].Y).Normalize()} +} + +// Edge returns the inward-facing normal of the great circle passing through +// the CCW ordered edge from vertex k to vertex k+1 (mod 4) (for k = 0,1,2,3). +func (c Cell) Edge(k int) Point { + switch k { + case 0: + return Point{vNorm(int(c.face), c.uv.Y.Lo).Normalize()} // Bottom + case 1: + return Point{uNorm(int(c.face), c.uv.X.Hi).Normalize()} // Right + case 2: + return Point{vNorm(int(c.face), c.uv.Y.Hi).Mul(-1.0).Normalize()} // Top + default: + return Point{uNorm(int(c.face), c.uv.X.Lo).Mul(-1.0).Normalize()} // Left + } +} + +// BoundUV returns the bounds of this cell in (u,v)-space. +func (c Cell) BoundUV() r2.Rect { + return c.uv +} + +// Center returns the direction vector corresponding to the center in +// (s,t)-space of the given cell. This is the point at which the cell is +// divided into four subcells; it is not necessarily the centroid of the +// cell in (u,v)-space or (x,y,z)-space +func (c Cell) Center() Point { + return Point{c.id.rawPoint().Normalize()} +} + +// Children returns the four direct children of this cell in traversal order +// and returns true. If this is a leaf cell, or the children could not be created, +// false is returned. +// The C++ method is called Subdivide. +func (c Cell) Children() ([4]Cell, bool) { + var children [4]Cell + + if c.id.IsLeaf() { + return children, false + } + + // Compute the cell midpoint in uv-space. + uvMid := c.id.centerUV() + + // Create four children with the appropriate bounds. + cid := c.id.ChildBegin() + for pos := 0; pos < 4; pos++ { + children[pos] = Cell{ + face: c.face, + level: c.level + 1, + orientation: c.orientation ^ int8(posToOrientation[pos]), + id: cid, + } + + // We want to split the cell in half in u and v. To decide which + // side to set equal to the midpoint value, we look at cell's (i,j) + // position within its parent. The index for i is in bit 1 of ij. + ij := posToIJ[c.orientation][pos] + i := ij >> 1 + j := ij & 1 + if i == 1 { + children[pos].uv.X.Hi = c.uv.X.Hi + children[pos].uv.X.Lo = uvMid.X + } else { + children[pos].uv.X.Lo = c.uv.X.Lo + children[pos].uv.X.Hi = uvMid.X + } + if j == 1 { + children[pos].uv.Y.Hi = c.uv.Y.Hi + children[pos].uv.Y.Lo = uvMid.Y + } else { + children[pos].uv.Y.Lo = c.uv.Y.Lo + children[pos].uv.Y.Hi = uvMid.Y + } + cid = cid.Next() + } + return children, true +} + +// ExactArea returns the area of this cell as accurately as possible. +func (c Cell) ExactArea() float64 { + v0, v1, v2, v3 := c.Vertex(0), c.Vertex(1), c.Vertex(2), c.Vertex(3) + return PointArea(v0, v1, v2) + PointArea(v0, v2, v3) +} + +// ApproxArea returns the approximate area of this cell. This method is accurate +// to within 3% percent for all cell sizes and accurate to within 0.1% for cells +// at level 5 or higher (i.e. squares 350km to a side or smaller on the Earth's +// surface). It is moderately cheap to compute. +func (c Cell) ApproxArea() float64 { + // All cells at the first two levels have the same area. + if c.level < 2 { + return c.AverageArea() + } + + // First, compute the approximate area of the cell when projected + // perpendicular to its normal. The cross product of its diagonals gives + // the normal, and the length of the normal is twice the projected area. + flatArea := 0.5 * (c.Vertex(2).Sub(c.Vertex(0).Vector). + Cross(c.Vertex(3).Sub(c.Vertex(1).Vector)).Norm()) + + // Now, compensate for the curvature of the cell surface by pretending + // that the cell is shaped like a spherical cap. The ratio of the + // area of a spherical cap to the area of its projected disc turns out + // to be 2 / (1 + sqrt(1 - r*r)) where r is the radius of the disc. + // For example, when r=0 the ratio is 1, and when r=1 the ratio is 2. + // Here we set Pi*r*r == flatArea to find the equivalent disc. + return flatArea * 2 / (1 + math.Sqrt(1-math.Min(1/math.Pi*flatArea, 1))) +} + +// AverageArea returns the average area of cells at the level of this cell. +// This is accurate to within a factor of 1.7. +func (c Cell) AverageArea() float64 { + return AvgAreaMetric.Value(int(c.level)) +} + +// IntersectsCell reports whether the intersection of this cell and the other cell is not nil. +func (c Cell) IntersectsCell(oc Cell) bool { + return c.id.Intersects(oc.id) +} + +// ContainsCell reports whether this cell contains the other cell. +func (c Cell) ContainsCell(oc Cell) bool { + return c.id.Contains(oc.id) +} + +// CellUnionBound computes a covering of the Cell. +func (c Cell) CellUnionBound() []CellID { + return c.CapBound().CellUnionBound() +} + +// latitude returns the latitude of the cell vertex in radians given by (i,j), +// where i and j indicate the Hi (1) or Lo (0) corner. +func (c Cell) latitude(i, j int) float64 { + var u, v float64 + switch { + case i == 0 && j == 0: + u = c.uv.X.Lo + v = c.uv.Y.Lo + case i == 0 && j == 1: + u = c.uv.X.Lo + v = c.uv.Y.Hi + case i == 1 && j == 0: + u = c.uv.X.Hi + v = c.uv.Y.Lo + case i == 1 && j == 1: + u = c.uv.X.Hi + v = c.uv.Y.Hi + default: + panic("i and/or j is out of bounds") + } + return latitude(Point{faceUVToXYZ(int(c.face), u, v)}).Radians() +} + +// longitude returns the longitude of the cell vertex in radians given by (i,j), +// where i and j indicate the Hi (1) or Lo (0) corner. +func (c Cell) longitude(i, j int) float64 { + var u, v float64 + switch { + case i == 0 && j == 0: + u = c.uv.X.Lo + v = c.uv.Y.Lo + case i == 0 && j == 1: + u = c.uv.X.Lo + v = c.uv.Y.Hi + case i == 1 && j == 0: + u = c.uv.X.Hi + v = c.uv.Y.Lo + case i == 1 && j == 1: + u = c.uv.X.Hi + v = c.uv.Y.Hi + default: + panic("i and/or j is out of bounds") + } + return longitude(Point{faceUVToXYZ(int(c.face), u, v)}).Radians() +} + +var ( + poleMinLat = math.Asin(math.Sqrt(1.0/3)) - 0.5*dblEpsilon +) + +// RectBound returns the bounding rectangle of this cell. +func (c Cell) RectBound() Rect { + if c.level > 0 { + // Except for cells at level 0, the latitude and longitude extremes are + // attained at the vertices. Furthermore, the latitude range is + // determined by one pair of diagonally opposite vertices and the + // longitude range is determined by the other pair. + // + // We first determine which corner (i,j) of the cell has the largest + // absolute latitude. To maximize latitude, we want to find the point in + // the cell that has the largest absolute z-coordinate and the smallest + // absolute x- and y-coordinates. To do this we look at each coordinate + // (u and v), and determine whether we want to minimize or maximize that + // coordinate based on the axis direction and the cell's (u,v) quadrant. + u := c.uv.X.Lo + c.uv.X.Hi + v := c.uv.Y.Lo + c.uv.Y.Hi + var i, j int + if uAxis(int(c.face)).Z == 0 { + if u < 0 { + i = 1 + } + } else if u > 0 { + i = 1 + } + if vAxis(int(c.face)).Z == 0 { + if v < 0 { + j = 1 + } + } else if v > 0 { + j = 1 + } + lat := r1.IntervalFromPoint(c.latitude(i, j)).AddPoint(c.latitude(1-i, 1-j)) + lng := s1.EmptyInterval().AddPoint(c.longitude(i, 1-j)).AddPoint(c.longitude(1-i, j)) + + // We grow the bounds slightly to make sure that the bounding rectangle + // contains LatLngFromPoint(P) for any point P inside the loop L defined by the + // four *normalized* vertices. Note that normalization of a vector can + // change its direction by up to 0.5 * dblEpsilon radians, and it is not + // enough just to add Normalize calls to the code above because the + // latitude/longitude ranges are not necessarily determined by diagonally + // opposite vertex pairs after normalization. + // + // We would like to bound the amount by which the latitude/longitude of a + // contained point P can exceed the bounds computed above. In the case of + // longitude, the normalization error can change the direction of rounding + // leading to a maximum difference in longitude of 2 * dblEpsilon. In + // the case of latitude, the normalization error can shift the latitude by + // up to 0.5 * dblEpsilon and the other sources of error can cause the + // two latitudes to differ by up to another 1.5 * dblEpsilon, which also + // leads to a maximum difference of 2 * dblEpsilon. + return Rect{lat, lng}.expanded(LatLng{s1.Angle(2 * dblEpsilon), s1.Angle(2 * dblEpsilon)}).PolarClosure() + } + + // The 4 cells around the equator extend to +/-45 degrees latitude at the + // midpoints of their top and bottom edges. The two cells covering the + // poles extend down to +/-35.26 degrees at their vertices. The maximum + // error in this calculation is 0.5 * dblEpsilon. + var bound Rect + switch c.face { + case 0: + bound = Rect{r1.Interval{-math.Pi / 4, math.Pi / 4}, s1.Interval{-math.Pi / 4, math.Pi / 4}} + case 1: + bound = Rect{r1.Interval{-math.Pi / 4, math.Pi / 4}, s1.Interval{math.Pi / 4, 3 * math.Pi / 4}} + case 2: + bound = Rect{r1.Interval{poleMinLat, math.Pi / 2}, s1.FullInterval()} + case 3: + bound = Rect{r1.Interval{-math.Pi / 4, math.Pi / 4}, s1.Interval{3 * math.Pi / 4, -3 * math.Pi / 4}} + case 4: + bound = Rect{r1.Interval{-math.Pi / 4, math.Pi / 4}, s1.Interval{-3 * math.Pi / 4, -math.Pi / 4}} + default: + bound = Rect{r1.Interval{-math.Pi / 2, -poleMinLat}, s1.FullInterval()} + } + + // Finally, we expand the bound to account for the error when a point P is + // converted to an LatLng to test for containment. (The bound should be + // large enough so that it contains the computed LatLng of any contained + // point, not just the infinite-precision version.) We don't need to expand + // longitude because longitude is calculated via a single call to math.Atan2, + // which is guaranteed to be semi-monotonic. + return bound.expanded(LatLng{s1.Angle(dblEpsilon), s1.Angle(0)}) +} + +// CapBound returns the bounding cap of this cell. +func (c Cell) CapBound() Cap { + // We use the cell center in (u,v)-space as the cap axis. This vector is very close + // to GetCenter() and faster to compute. Neither one of these vectors yields the + // bounding cap with minimal surface area, but they are both pretty close. + cap := CapFromPoint(Point{faceUVToXYZ(int(c.face), c.uv.Center().X, c.uv.Center().Y).Normalize()}) + for k := 0; k < 4; k++ { + cap = cap.AddPoint(c.Vertex(k)) + } + return cap +} + +// ContainsPoint reports whether this cell contains the given point. Note that +// unlike Loop/Polygon, a Cell is considered to be a closed set. This means +// that a point on a Cell's edge or vertex belong to the Cell and the relevant +// adjacent Cells too. +// +// If you want every point to be contained by exactly one Cell, +// you will need to convert the Cell to a Loop. +func (c Cell) ContainsPoint(p Point) bool { + var uv r2.Point + var ok bool + if uv.X, uv.Y, ok = faceXYZToUV(int(c.face), p); !ok { + return false + } + + // Expand the (u,v) bound to ensure that + // + // CellFromPoint(p).ContainsPoint(p) + // + // is always true. To do this, we need to account for the error when + // converting from (u,v) coordinates to (s,t) coordinates. In the + // normal case the total error is at most dblEpsilon. + return c.uv.ExpandedByMargin(dblEpsilon).ContainsPoint(uv) +} + +// Encode encodes the Cell. +func (c Cell) Encode(w io.Writer) error { + e := &encoder{w: w} + c.encode(e) + return e.err +} + +func (c Cell) encode(e *encoder) { + c.id.encode(e) +} + +// Decode decodes the Cell. +func (c *Cell) Decode(r io.Reader) error { + d := &decoder{r: asByteReader(r)} + c.decode(d) + return d.err +} + +func (c *Cell) decode(d *decoder) { + c.id.decode(d) + *c = CellFromCellID(c.id) +} + +// vertexChordDist2 returns the squared chord distance from point P to the +// given corner vertex specified by the Hi or Lo values of each. +func (c Cell) vertexChordDist2(p Point, xHi, yHi bool) s1.ChordAngle { + x := c.uv.X.Lo + y := c.uv.Y.Lo + if xHi { + x = c.uv.X.Hi + } + if yHi { + y = c.uv.Y.Hi + } + + return ChordAngleBetweenPoints(p, PointFromCoords(x, y, 1)) +} + +// uEdgeIsClosest reports whether a point P is closer to the interior of the specified +// Cell edge (either the lower or upper edge of the Cell) or to the endpoints. +func (c Cell) uEdgeIsClosest(p Point, vHi bool) bool { + u0 := c.uv.X.Lo + u1 := c.uv.X.Hi + v := c.uv.Y.Lo + if vHi { + v = c.uv.Y.Hi + } + // These are the normals to the planes that are perpendicular to the edge + // and pass through one of its two endpoints. + dir0 := r3.Vector{v*v + 1, -u0 * v, -u0} + dir1 := r3.Vector{v*v + 1, -u1 * v, -u1} + return p.Dot(dir0) > 0 && p.Dot(dir1) < 0 +} + +// vEdgeIsClosest reports whether a point P is closer to the interior of the specified +// Cell edge (either the right or left edge of the Cell) or to the endpoints. +func (c Cell) vEdgeIsClosest(p Point, uHi bool) bool { + v0 := c.uv.Y.Lo + v1 := c.uv.Y.Hi + u := c.uv.X.Lo + if uHi { + u = c.uv.X.Hi + } + dir0 := r3.Vector{-u * v0, u*u + 1, -v0} + dir1 := r3.Vector{-u * v1, u*u + 1, -v1} + return p.Dot(dir0) > 0 && p.Dot(dir1) < 0 +} + +// edgeDistance reports the distance from a Point P to a given Cell edge. The point +// P is given by its dot product, and the uv edge by its normal in the +// given coordinate value. +func edgeDistance(ij, uv float64) s1.ChordAngle { + // Let P by the target point and let R be the closest point on the given + // edge AB. The desired distance PR can be expressed as PR^2 = PQ^2 + QR^2 + // where Q is the point P projected onto the plane through the great circle + // through AB. We can compute the distance PQ^2 perpendicular to the plane + // from "dirIJ" (the dot product of the target point P with the edge + // normal) and the squared length the edge normal (1 + uv**2). + pq2 := (ij * ij) / (1 + uv*uv) + + // We can compute the distance QR as (1 - OQ) where O is the sphere origin, + // and we can compute OQ^2 = 1 - PQ^2 using the Pythagorean theorem. + // (This calculation loses accuracy as angle POQ approaches Pi/2.) + qr := 1 - math.Sqrt(1-pq2) + return s1.ChordAngleFromSquaredLength(pq2 + qr*qr) +} + +// distanceInternal reports the distance from the given point to the interior of +// the cell if toInterior is true or to the boundary of the cell otherwise. +func (c Cell) distanceInternal(targetXYZ Point, toInterior bool) s1.ChordAngle { + // All calculations are done in the (u,v,w) coordinates of this cell's face. + target := faceXYZtoUVW(int(c.face), targetXYZ) + + // Compute dot products with all four upward or rightward-facing edge + // normals. dirIJ is the dot product for the edge corresponding to axis + // I, endpoint J. For example, dir01 is the right edge of the Cell + // (corresponding to the upper endpoint of the u-axis). + dir00 := target.X - target.Z*c.uv.X.Lo + dir01 := target.X - target.Z*c.uv.X.Hi + dir10 := target.Y - target.Z*c.uv.Y.Lo + dir11 := target.Y - target.Z*c.uv.Y.Hi + inside := true + if dir00 < 0 { + inside = false // Target is to the left of the cell + if c.vEdgeIsClosest(target, false) { + return edgeDistance(-dir00, c.uv.X.Lo) + } + } + if dir01 > 0 { + inside = false // Target is to the right of the cell + if c.vEdgeIsClosest(target, true) { + return edgeDistance(dir01, c.uv.X.Hi) + } + } + if dir10 < 0 { + inside = false // Target is below the cell + if c.uEdgeIsClosest(target, false) { + return edgeDistance(-dir10, c.uv.Y.Lo) + } + } + if dir11 > 0 { + inside = false // Target is above the cell + if c.uEdgeIsClosest(target, true) { + return edgeDistance(dir11, c.uv.Y.Hi) + } + } + if inside { + if toInterior { + return s1.ChordAngle(0) + } + // Although you might think of Cells as rectangles, they are actually + // arbitrary quadrilaterals after they are projected onto the sphere. + // Therefore the simplest approach is just to find the minimum distance to + // any of the four edges. + return minChordAngle(edgeDistance(-dir00, c.uv.X.Lo), + edgeDistance(dir01, c.uv.X.Hi), + edgeDistance(-dir10, c.uv.Y.Lo), + edgeDistance(dir11, c.uv.Y.Hi)) + } + + // Otherwise, the closest point is one of the four cell vertices. Note that + // it is *not* trivial to narrow down the candidates based on the edge sign + // tests above, because (1) the edges don't meet at right angles and (2) + // there are points on the far side of the sphere that are both above *and* + // below the cell, etc. + return minChordAngle(c.vertexChordDist2(target, false, false), + c.vertexChordDist2(target, true, false), + c.vertexChordDist2(target, false, true), + c.vertexChordDist2(target, true, true)) +} + +// Distance reports the distance from the cell to the given point. Returns zero if +// the point is inside the cell. +func (c Cell) Distance(target Point) s1.ChordAngle { + return c.distanceInternal(target, true) +} + +// MaxDistance reports the maximum distance from the cell (including its interior) to the +// given point. +func (c Cell) MaxDistance(target Point) s1.ChordAngle { + // First check the 4 cell vertices. If all are within the hemisphere + // centered around target, the max distance will be to one of these vertices. + targetUVW := faceXYZtoUVW(int(c.face), target) + maxDist := maxChordAngle(c.vertexChordDist2(targetUVW, false, false), + c.vertexChordDist2(targetUVW, true, false), + c.vertexChordDist2(targetUVW, false, true), + c.vertexChordDist2(targetUVW, true, true)) + + if maxDist <= s1.RightChordAngle { + return maxDist + } + + // Otherwise, find the minimum distance dMin to the antipodal point and the + // maximum distance will be pi - dMin. + return s1.StraightChordAngle - c.BoundaryDistance(Point{target.Mul(-1)}) +} + +// BoundaryDistance reports the distance from the cell boundary to the given point. +func (c Cell) BoundaryDistance(target Point) s1.ChordAngle { + return c.distanceInternal(target, false) +} + +// DistanceToEdge returns the minimum distance from the cell to the given edge AB. Returns +// zero if the edge intersects the cell interior. +func (c Cell) DistanceToEdge(a, b Point) s1.ChordAngle { + // Possible optimizations: + // - Currently the (cell vertex, edge endpoint) distances are computed + // twice each, and the length of AB is computed 4 times. + // - To fix this, refactor GetDistance(target) so that it skips calculating + // the distance to each cell vertex. Instead, compute the cell vertices + // and distances in this function, and add a low-level UpdateMinDistance + // that allows the XA, XB, and AB distances to be passed in. + // - It might also be more efficient to do all calculations in UVW-space, + // since this would involve transforming 2 points rather than 4. + + // First, check the minimum distance to the edge endpoints A and B. + // (This also detects whether either endpoint is inside the cell.) + minDist := minChordAngle(c.Distance(a), c.Distance(b)) + if minDist == 0 { + return minDist + } + + // Otherwise, check whether the edge crosses the cell boundary. + crosser := NewChainEdgeCrosser(a, b, c.Vertex(3)) + for i := 0; i < 4; i++ { + if crosser.ChainCrossingSign(c.Vertex(i)) != DoNotCross { + return 0 + } + } + + // Finally, check whether the minimum distance occurs between a cell vertex + // and the interior of the edge AB. (Some of this work is redundant, since + // it also checks the distance to the endpoints A and B again.) + // + // Note that we don't need to check the distance from the interior of AB to + // the interior of a cell edge, because the only way that this distance can + // be minimal is if the two edges cross (already checked above). + for i := 0; i < 4; i++ { + minDist, _ = UpdateMinDistance(c.Vertex(i), a, b, minDist) + } + return minDist +} + +// MaxDistanceToEdge returns the maximum distance from the cell (including its interior) +// to the given edge AB. +func (c Cell) MaxDistanceToEdge(a, b Point) s1.ChordAngle { + // If the maximum distance from both endpoints to the cell is less than π/2 + // then the maximum distance from the edge to the cell is the maximum of the + // two endpoint distances. + maxDist := maxChordAngle(c.MaxDistance(a), c.MaxDistance(b)) + if maxDist <= s1.RightChordAngle { + return maxDist + } + + return s1.StraightChordAngle - c.DistanceToEdge(Point{a.Mul(-1)}, Point{b.Mul(-1)}) +} + +// DistanceToCell returns the minimum distance from this cell to the given cell. +// It returns zero if one cell contains the other. +func (c Cell) DistanceToCell(target Cell) s1.ChordAngle { + // If the cells intersect, the distance is zero. We use the (u,v) ranges + // rather than CellID intersects so that cells that share a partial edge or + // corner are considered to intersect. + if c.face == target.face && c.uv.Intersects(target.uv) { + return 0 + } + + // Otherwise, the minimum distance always occurs between a vertex of one + // cell and an edge of the other cell (including the edge endpoints). This + // represents a total of 32 possible (vertex, edge) pairs. + // + // TODO(roberts): This could be optimized to be at least 5x faster by pruning + // the set of possible closest vertex/edge pairs using the faces and (u,v) + // ranges of both cells. + var va, vb [4]Point + for i := 0; i < 4; i++ { + va[i] = c.Vertex(i) + vb[i] = target.Vertex(i) + } + minDist := s1.InfChordAngle() + for i := 0; i < 4; i++ { + for j := 0; j < 4; j++ { + minDist, _ = UpdateMinDistance(va[i], vb[j], vb[(j+1)&3], minDist) + minDist, _ = UpdateMinDistance(vb[i], va[j], va[(j+1)&3], minDist) + } + } + return minDist +} + +// MaxDistanceToCell returns the maximum distance from the cell (including its +// interior) to the given target cell. +func (c Cell) MaxDistanceToCell(target Cell) s1.ChordAngle { + // Need to check the antipodal target for intersection with the cell. If it + // intersects, the distance is the straight ChordAngle. + // antipodalUV is the transpose of the original UV, interpreted within the opposite face. + antipodalUV := r2.Rect{target.uv.Y, target.uv.X} + if int(c.face) == oppositeFace(int(target.face)) && c.uv.Intersects(antipodalUV) { + return s1.StraightChordAngle + } + + // Otherwise, the maximum distance always occurs between a vertex of one + // cell and an edge of the other cell (including the edge endpoints). This + // represents a total of 32 possible (vertex, edge) pairs. + // + // TODO(roberts): When the maximum distance is at most π/2, the maximum is + // always attained between a pair of vertices, and this could be made much + // faster by testing each vertex pair once rather than the current 4 times. + var va, vb [4]Point + for i := 0; i < 4; i++ { + va[i] = c.Vertex(i) + vb[i] = target.Vertex(i) + } + maxDist := s1.NegativeChordAngle + for i := 0; i < 4; i++ { + for j := 0; j < 4; j++ { + maxDist, _ = UpdateMaxDistance(va[i], vb[j], vb[(j+1)&3], maxDist) + maxDist, _ = UpdateMaxDistance(vb[i], va[j], va[(j+1)&3], maxDist) + } + } + return maxDist +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/cell_index.go b/backend/vendor/github.com/blevesearch/geo/s2/cell_index.go new file mode 100644 index 0000000000..879df48aad --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/cell_index.go @@ -0,0 +1,584 @@ +// Copyright 2020 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "sort" +) + +const ( + // A special label indicating that the ContentsIterator done is true. + cellIndexDoneContents = -1 +) + +// cellIndexNode represents a node in the CellIndex. Cells are organized in a +// tree such that the ancestors of a given node contain that node. +type cellIndexNode struct { + cellID CellID + label int32 + parent int32 +} + +// newCellIndexNode returns a node with the appropriate default values. +func newCellIndexNode() cellIndexNode { + return cellIndexNode{ + cellID: 0, + label: cellIndexDoneContents, + parent: -1, + } +} + +// A rangeNode represents a range of leaf CellIDs. The range starts at +// startID (a leaf cell) and ends at the startID field of the next +// rangeNode. contents points to the node of the CellIndex cellTree +// representing the cells that overlap this range. +type rangeNode struct { + startID CellID // First leaf cell contained by this range. + contents int32 // Contents of this node (an index within the cell tree). +} + +// CellIndexIterator is an iterator that visits the entire set of indexed +// (CellID, label) pairs in an unspecified order. +type CellIndexIterator struct { + // TODO(roberts): Implement + cellTree []cellIndexNode + pos int +} + +// NewCellIndexIterator creates an iterator for the given CellIndex. +func NewCellIndexIterator(index *CellIndex) *CellIndexIterator { + return &CellIndexIterator{ + cellTree: index.cellTree, + } +} + +// CellID returns the current CellID. +func (c *CellIndexIterator) CellID() CellID { + return c.cellTree[c.pos].cellID +} + +// Label returns the current Label. +func (c *CellIndexIterator) Label() int32 { + return c.cellTree[c.pos].label +} + +func (c *CellIndexIterator) Done() bool { + return c.pos == len(c.cellTree)-1 +} + +func (c *CellIndexIterator) Next() { + c.pos++ +} + +// CellIndexRangeIterator is an iterator that seeks and iterates over a set of +// non-overlapping leaf cell ranges that cover the entire sphere. The indexed +// (CellID, label) pairs that intersect the current leaf cell range can be +// visited using CellIndexContentsIterator (see below). +type CellIndexRangeIterator struct { + rangeNodes []rangeNode + pos int + nonEmpty bool +} + +// NewCellIndexRangeIterator creates an iterator for the given CellIndex. +// The iterator is initially *unpositioned*; you must call a positioning method +// such as Begin() or Seek() before accessing its contents. +func NewCellIndexRangeIterator(index *CellIndex) *CellIndexRangeIterator { + return &CellIndexRangeIterator{ + rangeNodes: index.rangeNodes, + } +} + +// NewCellIndexNonEmptyRangeIterator creates an iterator for the given CellIndex. +// The iterator is initially *unpositioned*; you must call a positioning method such as +// Begin() or Seek() before accessing its contents. +func NewCellIndexNonEmptyRangeIterator(index *CellIndex) *CellIndexRangeIterator { + return &CellIndexRangeIterator{ + rangeNodes: index.rangeNodes, + nonEmpty: true, + } +} + +// StartID reports the CellID of the start of the current range of leaf CellIDs. +// +// If done is true, this returns the last possible CellID. This property means +// that most loops do not need to test done explicitly. +func (c *CellIndexRangeIterator) StartID() CellID { + return c.rangeNodes[c.pos].startID +} + +// LimitID reports the non-inclusive end of the current range of leaf CellIDs. +// +// This assumes the iterator is not done. +func (c *CellIndexRangeIterator) LimitID() CellID { + return c.rangeNodes[c.pos+1].startID +} + +// IsEmpty reports if no (CellID, label) pairs intersect this range. +// Also returns true if done() is true. +func (c *CellIndexRangeIterator) IsEmpty() bool { + return c.rangeNodes[c.pos].contents == cellIndexDoneContents +} + +// Begin positions the iterator at the first range of leaf cells (if any). +func (c *CellIndexRangeIterator) Begin() { + c.pos = 0 + for c.nonEmpty && c.IsEmpty() && !c.Done() { + c.pos++ + } +} + +// Prev positions the iterator at the previous entry and reports whether it was not +// already positioned at the beginning. +func (c *CellIndexRangeIterator) Prev() bool { + if c.nonEmpty { + return c.nonEmptyPrev() + } + return c.prev() +} + +// prev is used to position the iterator at the previous entry without checking +// if nonEmpty is true to prevent unwanted recursion. +func (c *CellIndexRangeIterator) prev() bool { + if c.pos == 0 { + return false + } + + c.pos-- + return true +} + +// Prev positions the iterator at the previous entry, and reports whether it was +// already positioned at the beginning. +func (c *CellIndexRangeIterator) nonEmptyPrev() bool { + for c.prev() { + if !c.IsEmpty() { + return true + } + } + + // Return the iterator to its original position. + if c.IsEmpty() && !c.Done() { + c.Next() + } + return false +} + +// Next advances the iterator to the next range of leaf cells. +// +// This assumes the iterator is not done. +func (c *CellIndexRangeIterator) Next() { + c.pos++ + for c.nonEmpty && c.IsEmpty() && !c.Done() { + c.pos++ + } +} + +// Advance reports if advancing would leave it positioned on a valid range. If +// the value would not be valid, the positioning is not changed. +func (c *CellIndexRangeIterator) Advance(n int) bool { + // Note that the last element of rangeNodes is a sentinel value. + if n >= len(c.rangeNodes)-1-c.pos { + return false + } + c.pos += n + return true +} + +// Finish positions the iterator so that done is true. +func (c *CellIndexRangeIterator) Finish() { + // Note that the last element of rangeNodes is a sentinel value. + c.pos = len(c.rangeNodes) - 1 +} + +// Done reports if the iterator is positioned beyond the last valid range. +func (c *CellIndexRangeIterator) Done() bool { + return c.pos >= len(c.rangeNodes)-1 +} + +// Seek positions the iterator at the first range with startID >= target. +// Such an entry always exists as long as "target" is a valid leaf cell. +// +// Note that it is valid to access startID even when done is true. +func (c *CellIndexRangeIterator) Seek(target CellID) { + c.pos = sort.Search(len(c.rangeNodes), func(i int) bool { + return c.rangeNodes[i].startID > target + }) - 1 + + // Ensure we don't go beyond the beginning. + if c.pos < 0 { + c.pos = 0 + } + + // Nonempty needs to find the next non-empty entry. + for c.nonEmpty && c.IsEmpty() && !c.Done() { + // c.Next() + c.pos++ + } +} + +// CellIndexContentsIterator is an iterator that visits the (CellID, label) pairs +// that cover a set of leaf cell ranges (see CellIndexRangeIterator). Note that +// when multiple leaf cell ranges are visited, this iterator only guarantees that +// each result will be reported at least once, i.e. duplicate values may be +// suppressed. If you want duplicate values to be reported again, be sure to call +// Clear first. +// +// In particular, the implementation guarantees that when multiple leaf +// cell ranges are visited in monotonically increasing order, then each +// (CellID, label) pair is reported exactly once. +type CellIndexContentsIterator struct { + // The maximum index within the cellTree slice visited during the + // previous call to StartUnion. This is used to eliminate duplicate + // values when StartUnion is called multiple times. + nodeCutoff int32 + + // The maximum index within the cellTree visited during the + // current call to StartUnion. This is used to update nodeCutoff. + nextNodeCutoff int32 + + // The value of startID from the previous call to StartUnion. + // This is used to check whether these values are monotonically + // increasing. + prevStartID CellID + + // The cell tree from CellIndex + cellTree []cellIndexNode + + // A copy of the current node in the cell tree. + node cellIndexNode +} + +// NewCellIndexContentsIterator returns a new contents iterator. +// +// Note that the iterator needs to be positioned using StartUnion before +// it can be safely used. +func NewCellIndexContentsIterator(index *CellIndex) *CellIndexContentsIterator { + it := &CellIndexContentsIterator{ + cellTree: index.cellTree, + prevStartID: 0, + nodeCutoff: -1, + nextNodeCutoff: -1, + node: cellIndexNode{label: cellIndexDoneContents}, + } + return it +} + +// Clear clears all state with respect to which range(s) have been visited. +func (c *CellIndexContentsIterator) Clear() { + c.prevStartID = 0 + c.nodeCutoff = -1 + c.nextNodeCutoff = -1 + c.node.label = cellIndexDoneContents +} + +// CellID returns the current CellID. +func (c *CellIndexContentsIterator) CellID() CellID { + return c.node.cellID +} + +// Label returns the current Label. +func (c *CellIndexContentsIterator) Label() int32 { + return c.node.label +} + +// Next advances the iterator to the next (CellID, label) pair covered by the +// current leaf cell range. +// +// This requires the iterator to not be done. +func (c *CellIndexContentsIterator) Next() { + if c.node.parent <= c.nodeCutoff { + // We have already processed this node and its ancestors. + c.nodeCutoff = c.nextNodeCutoff + c.node.label = cellIndexDoneContents + } else { + c.node = c.cellTree[c.node.parent] + } +} + +// Done reports if all (CellID, label) pairs have been visited. +func (c *CellIndexContentsIterator) Done() bool { + return c.node.label == cellIndexDoneContents +} + +// StartUnion positions the ContentsIterator at the first (cell_id, label) pair +// that covers the given leaf cell range. Note that when multiple leaf cell +// ranges are visited using the same ContentsIterator, duplicate values +// may be suppressed. If you don't want this behavior, call Reset() first. +func (c *CellIndexContentsIterator) StartUnion(r *CellIndexRangeIterator) { + if r.StartID() < c.prevStartID { + c.nodeCutoff = -1 // Can't automatically eliminate duplicates. + } + c.prevStartID = r.StartID() + + contents := r.rangeNodes[r.pos].contents + if contents <= c.nodeCutoff { + c.node.label = cellIndexDoneContents + } else { + c.node = c.cellTree[contents] + } + + // When visiting ancestors, we can stop as soon as the node index is smaller + // than any previously visited node index. Because indexes are assigned + // using a preorder traversal, such nodes are guaranteed to have already + // been reported. + c.nextNodeCutoff = contents +} + +// CellIndex stores a collection of (CellID, label) pairs. +// +// The CellIDs may be overlapping or contain duplicate values. For example, a +// CellIndex could store a collection of CellUnions, where each CellUnion +// gets its own non-negative int32 label. +// +// Similar to ShapeIndex and PointIndex which map each stored element to an +// identifier, CellIndex stores a label that is typically used to map the +// results of queries back to client's specific data. +// +// The zero value for a CellIndex is sufficient when constructing a CellIndex. +// +// To build a CellIndex where each Cell has a distinct label, call Add for each +// (CellID, label) pair, and then Build the index. For example: +// +// // contents is a mapping of an identifier in my system (restaurantID, +// // vehicleID, etc) to a CellID +// var contents = map[int32]CellID{...} +// +// for key, val := range contents { +// index.Add(val, key) +// } +// +// index.Build() +// +// There is also a helper method that adds all elements of CellUnion with the +// same label: +// +// index.AddCellUnion(cellUnion, label) +// +// Note that the index is not dynamic; the contents of the index cannot be +// changed once it has been built. Adding more after calling Build results in +// undefined behavior of the index. +// +// There are several options for retrieving data from the index. The simplest +// is to use a built-in method such as IntersectingLabels (which returns +// the labels of all cells that intersect a given target CellUnion): +// +// labels := index.IntersectingLabels(targetUnion); +// +// Alternatively, you can use a ClosestCellQuery which computes the cell(s) +// that are closest to a given target geometry. +// +// For example, here is how to find all cells that are closer than +// distanceLimit to a given target point: +// +// query := NewClosestCellQuery(cellIndex, opts) +// target := NewMinDistanceToPointTarget(targetPoint); +// for result := range query.FindCells(target) { +// // result.Distance() is the distance to the target. +// // result.CellID() is the indexed CellID. +// // result.Label() is the label associated with the CellID. +// DoSomething(targetPoint, result); +// } +// +// Internally, the index consists of a set of non-overlapping leaf cell ranges +// that subdivide the sphere and such that each range intersects a particular +// set of (cellID, label) pairs. +// +// Most clients should use either the methods such as VisitIntersectingCells +// and IntersectingLabels, or a helper such as ClosestCellQuery. +type CellIndex struct { + // A tree of (cellID, label) pairs such that if X is an ancestor of Y, then + // X.cellID contains Y.cellID. The contents of a given range of leaf + // cells can be represented by pointing to a node of this tree. + cellTree []cellIndexNode + + // The last element of rangeNodes is a sentinel value, which is necessary + // in order to represent the range covered by the previous element. + rangeNodes []rangeNode +} + +// Add adds the given CellID and Label to the index. +func (c *CellIndex) Add(id CellID, label int32) { + if label < 0 { + panic("labels must be non-negative") + } + c.cellTree = append(c.cellTree, cellIndexNode{cellID: id, label: label, parent: -1}) +} + +// AddCellUnion adds all of the elements of the given CellUnion to the index with the same label. +func (c *CellIndex) AddCellUnion(cu CellUnion, label int32) { + if label < 0 { + panic("labels must be non-negative") + } + for _, cell := range cu { + c.Add(cell, label) + } +} + +// Build builds the index for use. This method should only be called once. +func (c *CellIndex) Build() { + // To build the cell tree and leaf cell ranges, we maintain a stack of + // (CellID, label) pairs that contain the current leaf cell. This struct + // represents an instruction to push or pop a (cellID, label) pair. + // + // If label >= 0, the (cellID, label) pair is pushed on the stack. + // If CellID == SentinelCellID, a pair is popped from the stack. + // Otherwise the stack is unchanged but a rangeNode is still emitted. + + // delta represents an entry in a stack of (CellID, label) pairs used in the + // construction of the CellIndex structure. + type delta struct { + startID CellID + cellID CellID + label int32 + } + + deltas := make([]delta, 0, 2*len(c.cellTree)+2) + + // Create two deltas for each (cellID, label) pair: one to add the pair to + // the stack (at the start of its leaf cell range), and one to remove it from + // the stack (at the end of its leaf cell range). + for _, node := range c.cellTree { + deltas = append(deltas, delta{ + startID: node.cellID.RangeMin(), + cellID: node.cellID, + label: node.label, + }) + deltas = append(deltas, delta{ + startID: node.cellID.RangeMax().Next(), + cellID: SentinelCellID, + label: -1, + }) + } + + // We also create two special deltas to ensure that a RangeNode is emitted at + // the beginning and end of the CellID range. + deltas = append(deltas, delta{ + startID: CellIDFromFace(0).ChildBeginAtLevel(maxLevel), + cellID: CellID(0), + label: -1, + }) + deltas = append(deltas, delta{ + startID: CellIDFromFace(5).ChildEndAtLevel(maxLevel), + cellID: CellID(0), + label: -1, + }) + + sort.Slice(deltas, func(i, j int) bool { + // deltas are sorted first by startID, then in reverse order by cellID, + // and then by label. This is necessary to ensure that (1) larger cells + // are pushed on the stack before smaller cells, and (2) cells are popped + // off the stack before any new cells are added. + + if si, sj := deltas[i].startID, deltas[j].startID; si != sj { + return si < sj + } + if si, sj := deltas[i].cellID, deltas[j].cellID; si != sj { + return si > sj + } + return deltas[i].label < deltas[j].label + }) + + // Now walk through the deltas to build the leaf cell ranges and cell tree + // (which is essentially a permanent form of the "stack" described above). + c.cellTree = nil + c.rangeNodes = nil + contents := int32(-1) + for i := 0; i < len(deltas); { + startID := deltas[i].startID + // Process all the deltas associated with the current startID. + for ; i < len(deltas) && deltas[i].startID == startID; i++ { + if deltas[i].label >= 0 { + c.cellTree = append(c.cellTree, cellIndexNode{ + cellID: deltas[i].cellID, + label: deltas[i].label, + parent: contents}) + contents = int32(len(c.cellTree) - 1) + } else if deltas[i].cellID == SentinelCellID { + contents = c.cellTree[contents].parent + } + } + c.rangeNodes = append(c.rangeNodes, rangeNode{startID, contents}) + } +} + +type CellVisitor func(CellID, int32) bool + +func (c *CellIndex) GetIntersectingLabels(target CellUnion) []int32 { + var rv []int32 + c.IntersectingLabels(target, &rv) + return rv +} + +func (c *CellIndex) IntersectingLabels(target CellUnion, labels *[]int32) { + c.VisitIntersectingCells(target, func(cellID CellID, label int32) bool { + *labels = append(*labels, label) + return true + }) + dedupe(labels) + sort.Slice(*labels, func(i, j int) bool { return (*labels)[i] < (*labels)[j] }) +} + +func dedupe(labels *[]int32) { + encountered := make(map[int32]struct{}) + + for v := range *labels { + encountered[(*labels)[v]] = struct{}{} + } + + (*labels) = (*labels)[:0] + for key, _ := range encountered { + *labels = append(*labels, key) + } +} + +func (c *CellIndex) VisitIntersectingCells(target CellUnion, + visitor CellVisitor) bool { + if len(target) == 0 { + return true + } + + var pos int + cItr := NewCellIndexContentsIterator(c) + rItr := NewCellIndexNonEmptyRangeIterator(c) + rItr.Begin() + for pos < len(target) { + if rItr.LimitID() <= target[pos].RangeMin() { + rItr.Seek(target[pos].RangeMin()) + } + + for rItr.StartID() <= target[pos].RangeMax() { + for cItr.StartUnion(rItr); cItr.Done(); cItr.Next() { + if !visitor(cItr.CellID(), cItr.Label()) { + return false + } + } + } + + pos++ + if pos < len(target) && target[pos].RangeMax() < rItr.StartID() { + pos = target.lowerBound(pos, len(target), rItr.StartID()) + if target[pos-1].RangeMax() >= rItr.StartID() { + pos-- + } + } + } + return true +} + +// TODO(roberts): Differences from C++ +// IntersectingLabels +// VisitIntersectingCells +// CellIndexIterator diff --git a/backend/vendor/github.com/blevesearch/geo/s2/cellid.go b/backend/vendor/github.com/blevesearch/geo/s2/cellid.go new file mode 100644 index 0000000000..c6cbaf2db7 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/cellid.go @@ -0,0 +1,944 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "bytes" + "fmt" + "io" + "math" + "sort" + "strconv" + "strings" + + "github.com/golang/geo/r1" + "github.com/golang/geo/r2" + "github.com/golang/geo/r3" + "github.com/golang/geo/s1" +) + +// CellID uniquely identifies a cell in the S2 cell decomposition. +// The most significant 3 bits encode the face number (0-5). The +// remaining 61 bits encode the position of the center of this cell +// along the Hilbert curve on that face. The zero value and the value +// (1<<64)-1 are invalid cell IDs. The first compares less than any +// valid cell ID, the second as greater than any valid cell ID. +// +// Sequentially increasing cell IDs follow a continuous space-filling curve +// over the entire sphere. They have the following properties: +// +// - The ID of a cell at level k consists of a 3-bit face number followed +// by k bit pairs that recursively select one of the four children of +// each cell. The next bit is always 1, and all other bits are 0. +// Therefore, the level of a cell is determined by the position of its +// lowest-numbered bit that is turned on (for a cell at level k, this +// position is 2 * (maxLevel - k)). +// +// - The ID of a parent cell is at the midpoint of the range of IDs spanned +// by its children (or by its descendants at any level). +// +// Leaf cells are often used to represent points on the unit sphere, and +// this type provides methods for converting directly between these two +// representations. For cells that represent 2D regions rather than +// discrete point, it is better to use Cells. +type CellID uint64 + +// SentinelCellID is an invalid cell ID guaranteed to be larger than any +// valid cell ID. It is used primarily by ShapeIndex. The value is also used +// by some S2 types when encoding data. +// Note that the sentinel's RangeMin == RangeMax == itself. +const SentinelCellID = CellID(^uint64(0)) + +// sortCellIDs sorts the slice of CellIDs in place. +func sortCellIDs(ci []CellID) { + sort.Sort(cellIDs(ci)) +} + +// cellIDs implements the Sort interface for slices of CellIDs. +type cellIDs []CellID + +func (c cellIDs) Len() int { return len(c) } +func (c cellIDs) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +func (c cellIDs) Less(i, j int) bool { return c[i] < c[j] } + +// TODO(dsymonds): Some of these constants should probably be exported. +const ( + faceBits = 3 + numFaces = 6 + + // This is the number of levels needed to specify a leaf cell. + maxLevel = 30 + + // The extra position bit (61 rather than 60) lets us encode each cell as its + // Hilbert curve position at the cell center (which is halfway along the + // portion of the Hilbert curve that fills that cell). + posBits = 2*maxLevel + 1 + + // The maximum index of a valid leaf cell plus one. The range of valid leaf + // cell indices is [0..maxSize-1]. + maxSize = 1 << maxLevel + + wrapOffset = uint64(numFaces) << posBits +) + +// CellIDFromFacePosLevel returns a cell given its face in the range +// [0,5], the 61-bit Hilbert curve position pos within that face, and +// the level in the range [0,maxLevel]. The position in the cell ID +// will be truncated to correspond to the Hilbert curve position at +// the center of the returned cell. +func CellIDFromFacePosLevel(face int, pos uint64, level int) CellID { + return CellID(uint64(face)< 16 { + return CellID(0) + } + n, err := strconv.ParseUint(s, 16, 64) + if err != nil { + return CellID(0) + } + // Equivalent to right-padding string with zeros to 16 characters. + if len(s) < 16 { + n = n << (4 * uint(16-len(s))) + } + return CellID(n) +} + +// ToToken returns a hex-encoded string of the uint64 cell id, with leading +// zeros included but trailing zeros stripped. +func (ci CellID) ToToken() string { + s := strings.TrimRight(fmt.Sprintf("%016x", uint64(ci)), "0") + if len(s) == 0 { + return "X" + } + return s +} + +// IsValid reports whether ci represents a valid cell. +func (ci CellID) IsValid() bool { + return ci.Face() < numFaces && (ci.lsb()&0x1555555555555555 != 0) +} + +// Face returns the cube face for this cell ID, in the range [0,5]. +func (ci CellID) Face() int { return int(uint64(ci) >> posBits) } + +// Pos returns the position along the Hilbert curve of this cell ID, in the range [0,2^posBits-1]. +func (ci CellID) Pos() uint64 { return uint64(ci) & (^uint64(0) >> faceBits) } + +// Level returns the subdivision level of this cell ID, in the range [0, maxLevel]. +func (ci CellID) Level() int { + return maxLevel - findLSBSetNonZero64(uint64(ci))>>1 +} + +// IsLeaf returns whether this cell ID is at the deepest level; +// that is, the level at which the cells are smallest. +func (ci CellID) IsLeaf() bool { return uint64(ci)&1 != 0 } + +// ChildPosition returns the child position (0..3) of this cell's +// ancestor at the given level, relative to its parent. The argument +// should be in the range 1..kMaxLevel. For example, +// ChildPosition(1) returns the position of this cell's level-1 +// ancestor within its top-level face cell. +func (ci CellID) ChildPosition(level int) int { + return int(uint64(ci)>>uint64(2*(maxLevel-level)+1)) & 3 +} + +// lsbForLevel returns the lowest-numbered bit that is on for cells at the given level. +func lsbForLevel(level int) uint64 { return 1 << uint64(2*(maxLevel-level)) } + +// Parent returns the cell at the given level, which must be no greater than the current level. +func (ci CellID) Parent(level int) CellID { + lsb := lsbForLevel(level) + return CellID((uint64(ci) & -lsb) | lsb) +} + +// immediateParent is cheaper than Parent, but assumes !ci.isFace(). +func (ci CellID) immediateParent() CellID { + nlsb := CellID(ci.lsb() << 2) + return (ci & -nlsb) | nlsb +} + +// isFace returns whether this is a top-level (face) cell. +func (ci CellID) isFace() bool { return uint64(ci)&(lsbForLevel(0)-1) == 0 } + +// lsb returns the least significant bit that is set. +func (ci CellID) lsb() uint64 { return uint64(ci) & -uint64(ci) } + +// Children returns the four immediate children of this cell. +// If ci is a leaf cell, it returns four identical cells that are not the children. +func (ci CellID) Children() [4]CellID { + var ch [4]CellID + lsb := CellID(ci.lsb()) + ch[0] = ci - lsb + lsb>>2 + lsb >>= 1 + ch[1] = ch[0] + lsb + ch[2] = ch[1] + lsb + ch[3] = ch[2] + lsb + return ch +} + +func sizeIJ(level int) int { + return 1 << uint(maxLevel-level) +} + +// EdgeNeighbors returns the four cells that are adjacent across the cell's four edges. +// Edges 0, 1, 2, 3 are in the down, right, up, left directions in the face space. +// All neighbors are guaranteed to be distinct. +func (ci CellID) EdgeNeighbors() [4]CellID { + level := ci.Level() + size := sizeIJ(level) + f, i, j, _ := ci.faceIJOrientation() + return [4]CellID{ + cellIDFromFaceIJWrap(f, i, j-size).Parent(level), + cellIDFromFaceIJWrap(f, i+size, j).Parent(level), + cellIDFromFaceIJWrap(f, i, j+size).Parent(level), + cellIDFromFaceIJWrap(f, i-size, j).Parent(level), + } +} + +// VertexNeighbors returns the neighboring cellIDs with vertex closest to this cell at the given level. +// (Normally there are four neighbors, but the closest vertex may only have three neighbors if it is one of +// the 8 cube vertices.) +func (ci CellID) VertexNeighbors(level int) []CellID { + halfSize := sizeIJ(level + 1) + size := halfSize << 1 + f, i, j, _ := ci.faceIJOrientation() + + var isame, jsame bool + var ioffset, joffset int + if i&halfSize != 0 { + ioffset = size + isame = (i + size) < maxSize + } else { + ioffset = -size + isame = (i - size) >= 0 + } + if j&halfSize != 0 { + joffset = size + jsame = (j + size) < maxSize + } else { + joffset = -size + jsame = (j - size) >= 0 + } + + results := []CellID{ + ci.Parent(level), + cellIDFromFaceIJSame(f, i+ioffset, j, isame).Parent(level), + cellIDFromFaceIJSame(f, i, j+joffset, jsame).Parent(level), + } + + if isame || jsame { + results = append(results, cellIDFromFaceIJSame(f, i+ioffset, j+joffset, isame && jsame).Parent(level)) + } + + return results +} + +// AllNeighbors returns all neighbors of this cell at the given level. Two +// cells X and Y are neighbors if their boundaries intersect but their +// interiors do not. In particular, two cells that intersect at a single +// point are neighbors. Note that for cells adjacent to a face vertex, the +// same neighbor may be returned more than once. There could be up to eight +// neighbors including the diagonal ones that share the vertex. +// +// This requires level >= ci.Level(). +func (ci CellID) AllNeighbors(level int) []CellID { + var neighbors []CellID + + face, i, j, _ := ci.faceIJOrientation() + + // Find the coordinates of the lower left-hand leaf cell. We need to + // normalize (i,j) to a known position within the cell because level + // may be larger than this cell's level. + size := sizeIJ(ci.Level()) + i &= -size + j &= -size + + nbrSize := sizeIJ(level) + + // We compute the top-bottom, left-right, and diagonal neighbors in one + // pass. The loop test is at the end of the loop to avoid 32-bit overflow. + for k := -nbrSize; ; k += nbrSize { + var sameFace bool + if k < 0 { + sameFace = (j+k >= 0) + } else if k >= size { + sameFace = (j+k < maxSize) + } else { + sameFace = true + // Top and bottom neighbors. + neighbors = append(neighbors, cellIDFromFaceIJSame(face, i+k, j-nbrSize, + j-size >= 0).Parent(level)) + neighbors = append(neighbors, cellIDFromFaceIJSame(face, i+k, j+size, + j+size < maxSize).Parent(level)) + } + + // Left, right, and diagonal neighbors. + neighbors = append(neighbors, cellIDFromFaceIJSame(face, i-nbrSize, j+k, + sameFace && i-size >= 0).Parent(level)) + neighbors = append(neighbors, cellIDFromFaceIJSame(face, i+size, j+k, + sameFace && i+size < maxSize).Parent(level)) + + if k >= size { + break + } + } + + return neighbors +} + +// RangeMin returns the minimum CellID that is contained within this cell. +func (ci CellID) RangeMin() CellID { return CellID(uint64(ci) - (ci.lsb() - 1)) } + +// RangeMax returns the maximum CellID that is contained within this cell. +func (ci CellID) RangeMax() CellID { return CellID(uint64(ci) + (ci.lsb() - 1)) } + +// Contains returns true iff the CellID contains oci. +func (ci CellID) Contains(oci CellID) bool { + return uint64(ci.RangeMin()) <= uint64(oci) && uint64(oci) <= uint64(ci.RangeMax()) +} + +// Intersects returns true iff the CellID intersects oci. +func (ci CellID) Intersects(oci CellID) bool { + return uint64(oci.RangeMin()) <= uint64(ci.RangeMax()) && uint64(oci.RangeMax()) >= uint64(ci.RangeMin()) +} + +// String returns the string representation of the cell ID in the form "1/3210". +func (ci CellID) String() string { + if !ci.IsValid() { + return "Invalid: " + strconv.FormatInt(int64(ci), 16) + } + var b bytes.Buffer + b.WriteByte("012345"[ci.Face()]) // values > 5 will have been picked off by !IsValid above + b.WriteByte('/') + for level := 1; level <= ci.Level(); level++ { + b.WriteByte("0123"[ci.ChildPosition(level)]) + } + return b.String() +} + +// cellIDFromString returns a CellID from a string in the form "1/3210". +func cellIDFromString(s string) CellID { + level := len(s) - 2 + if level < 0 || level > maxLevel { + return CellID(0) + } + face := int(s[0] - '0') + if face < 0 || face > 5 || s[1] != '/' { + return CellID(0) + } + id := CellIDFromFace(face) + for i := 2; i < len(s); i++ { + childPos := s[i] - '0' + if childPos < 0 || childPos > 3 { + return CellID(0) + } + id = id.Children()[childPos] + } + return id +} + +// Point returns the center of the s2 cell on the sphere as a Point. +// The maximum directional error in Point (compared to the exact +// mathematical result) is 1.5 * dblEpsilon radians, and the maximum length +// error is 2 * dblEpsilon (the same as Normalize). +func (ci CellID) Point() Point { return Point{ci.rawPoint().Normalize()} } + +// LatLng returns the center of the s2 cell on the sphere as a LatLng. +func (ci CellID) LatLng() LatLng { return LatLngFromPoint(Point{ci.rawPoint()}) } + +// ChildBegin returns the first child in a traversal of the children of this cell, in Hilbert curve order. +// +// for ci := c.ChildBegin(); ci != c.ChildEnd(); ci = ci.Next() { +// ... +// } +func (ci CellID) ChildBegin() CellID { + ol := ci.lsb() + return CellID(uint64(ci) - ol + ol>>2) +} + +// ChildBeginAtLevel returns the first cell in a traversal of children a given level deeper than this cell, in +// Hilbert curve order. The given level must be no smaller than the cell's level. +// See ChildBegin for example use. +func (ci CellID) ChildBeginAtLevel(level int) CellID { + return CellID(uint64(ci) - ci.lsb() + lsbForLevel(level)) +} + +// ChildEnd returns the first cell after a traversal of the children of this cell in Hilbert curve order. +// The returned cell may be invalid. +func (ci CellID) ChildEnd() CellID { + ol := ci.lsb() + return CellID(uint64(ci) + ol + ol>>2) +} + +// ChildEndAtLevel returns the first cell after the last child in a traversal of children a given level deeper +// than this cell, in Hilbert curve order. +// The given level must be no smaller than the cell's level. +// The returned cell may be invalid. +func (ci CellID) ChildEndAtLevel(level int) CellID { + return CellID(uint64(ci) + ci.lsb() + lsbForLevel(level)) +} + +// Next returns the next cell along the Hilbert curve. +// This is expected to be used with ChildBegin and ChildEnd, +// or ChildBeginAtLevel and ChildEndAtLevel. +func (ci CellID) Next() CellID { + return CellID(uint64(ci) + ci.lsb()<<1) +} + +// Prev returns the previous cell along the Hilbert curve. +func (ci CellID) Prev() CellID { + return CellID(uint64(ci) - ci.lsb()<<1) +} + +// NextWrap returns the next cell along the Hilbert curve, wrapping from last to +// first as necessary. This should not be used with ChildBegin and ChildEnd. +func (ci CellID) NextWrap() CellID { + n := ci.Next() + if uint64(n) < wrapOffset { + return n + } + return CellID(uint64(n) - wrapOffset) +} + +// PrevWrap returns the previous cell along the Hilbert curve, wrapping around from +// first to last as necessary. This should not be used with ChildBegin and ChildEnd. +func (ci CellID) PrevWrap() CellID { + p := ci.Prev() + if uint64(p) < wrapOffset { + return p + } + return CellID(uint64(p) + wrapOffset) +} + +// AdvanceWrap advances or retreats the indicated number of steps along the +// Hilbert curve at the current level and returns the new position. The +// position wraps between the first and last faces as necessary. +func (ci CellID) AdvanceWrap(steps int64) CellID { + if steps == 0 { + return ci + } + + // We clamp the number of steps if necessary to ensure that we do not + // advance past the End() or before the Begin() of this level. + shift := uint(2*(maxLevel-ci.Level()) + 1) + if steps < 0 { + if min := -int64(uint64(ci) >> shift); steps < min { + wrap := int64(wrapOffset >> shift) + steps %= wrap + if steps < min { + steps += wrap + } + } + } else { + // Unlike Advance(), we don't want to return End(level). + if max := int64((wrapOffset - uint64(ci)) >> shift); steps > max { + wrap := int64(wrapOffset >> shift) + steps %= wrap + if steps > max { + steps -= wrap + } + } + } + + // If steps is negative, then shifting it left has undefined behavior. + // Cast to uint64 for a 2's complement answer. + return CellID(uint64(ci) + (uint64(steps) << shift)) +} + +// Encode encodes the CellID. +func (ci CellID) Encode(w io.Writer) error { + e := &encoder{w: w} + ci.encode(e) + return e.err +} + +func (ci CellID) encode(e *encoder) { + e.writeUint64(uint64(ci)) +} + +// Decode decodes the CellID. +func (ci *CellID) Decode(r io.Reader) error { + d := &decoder{r: asByteReader(r)} + ci.decode(d) + return d.err +} + +func (ci *CellID) decode(d *decoder) { + *ci = CellID(d.readUint64()) +} + +// TODO: the methods below are not exported yet. Settle on the entire API design +// before doing this. Do we want to mirror the C++ one as closely as possible? + +// distanceFromBegin returns the number of steps along the Hilbert curve that +// this cell is from the first node in the S2 hierarchy at our level. (i.e., +// FromFace(0).ChildBeginAtLevel(ci.Level())). This is analogous to Pos(), but +// for this cell's level. +// The return value is always non-negative. +func (ci CellID) distanceFromBegin() int64 { + return int64(ci >> uint64(2*(maxLevel-ci.Level())+1)) +} + +// rawPoint returns an unnormalized r3 vector from the origin through the center +// of the s2 cell on the sphere. +func (ci CellID) rawPoint() r3.Vector { + face, si, ti := ci.faceSiTi() + return faceUVToXYZ(face, stToUV((0.5/maxSize)*float64(si)), stToUV((0.5/maxSize)*float64(ti))) +} + +// faceSiTi returns the Face/Si/Ti coordinates of the center of the cell. +func (ci CellID) faceSiTi() (face int, si, ti uint32) { + face, i, j, _ := ci.faceIJOrientation() + delta := 0 + if ci.IsLeaf() { + delta = 1 + } else { + if (i^(int(ci)>>2))&1 != 0 { + delta = 2 + } + } + return face, uint32(2*i + delta), uint32(2*j + delta) +} + +// faceIJOrientation uses the global lookupIJ table to unfiddle the bits of ci. +func (ci CellID) faceIJOrientation() (f, i, j, orientation int) { + f = ci.Face() + orientation = f & swapMask + nbits := maxLevel - 7*lookupBits // first iteration + + // Each iteration maps 8 bits of the Hilbert curve position into + // 4 bits of "i" and "j". The lookup table transforms a key of the + // form "ppppppppoo" to a value of the form "iiiijjjjoo", where the + // letters [ijpo] represents bits of "i", "j", the Hilbert curve + // position, and the Hilbert curve orientation respectively. + // + // On the first iteration we need to be careful to clear out the bits + // representing the cube face. + for k := 7; k >= 0; k-- { + orientation += (int(uint64(ci)>>uint64(k*2*lookupBits+1)) & ((1 << uint(2*nbits)) - 1)) << 2 + orientation = lookupIJ[orientation] + i += (orientation >> (lookupBits + 2)) << uint(k*lookupBits) + j += ((orientation >> 2) & ((1 << lookupBits) - 1)) << uint(k*lookupBits) + orientation &= (swapMask | invertMask) + nbits = lookupBits // following iterations + } + + // The position of a non-leaf cell at level "n" consists of a prefix of + // 2*n bits that identifies the cell, followed by a suffix of + // 2*(maxLevel-n)+1 bits of the form 10*. If n==maxLevel, the suffix is + // just "1" and has no effect. Otherwise, it consists of "10", followed + // by (maxLevel-n-1) repetitions of "00", followed by "0". The "10" has + // no effect, while each occurrence of "00" has the effect of reversing + // the swapMask bit. + if ci.lsb()&0x1111111111111110 != 0 { + orientation ^= swapMask + } + + return +} + +// cellIDFromFaceIJ returns a leaf cell given its cube face (range 0..5) and IJ coordinates. +func cellIDFromFaceIJ(f, i, j int) CellID { + // Note that this value gets shifted one bit to the left at the end + // of the function. + n := uint64(f) << (posBits - 1) + // Alternating faces have opposite Hilbert curve orientations; this + // is necessary in order for all faces to have a right-handed + // coordinate system. + bits := f & swapMask + // Each iteration maps 4 bits of "i" and "j" into 8 bits of the Hilbert + // curve position. The lookup table transforms a 10-bit key of the form + // "iiiijjjjoo" to a 10-bit value of the form "ppppppppoo", where the + // letters [ijpo] denote bits of "i", "j", Hilbert curve position, and + // Hilbert curve orientation respectively. + for k := 7; k >= 0; k-- { + mask := (1 << lookupBits) - 1 + bits += ((i >> uint(k*lookupBits)) & mask) << (lookupBits + 2) + bits += ((j >> uint(k*lookupBits)) & mask) << 2 + bits = lookupPos[bits] + n |= uint64(bits>>2) << (uint(k) * 2 * lookupBits) + bits &= (swapMask | invertMask) + } + return CellID(n*2 + 1) +} + +func cellIDFromFaceIJWrap(f, i, j int) CellID { + // Convert i and j to the coordinates of a leaf cell just beyond the + // boundary of this face. This prevents 32-bit overflow in the case + // of finding the neighbors of a face cell. + i = clampInt(i, -1, maxSize) + j = clampInt(j, -1, maxSize) + + // We want to wrap these coordinates onto the appropriate adjacent face. + // The easiest way to do this is to convert the (i,j) coordinates to (x,y,z) + // (which yields a point outside the normal face boundary), and then call + // xyzToFaceUV to project back onto the correct face. + // + // The code below converts (i,j) to (si,ti), and then (si,ti) to (u,v) using + // the linear projection (u=2*s-1 and v=2*t-1). (The code further below + // converts back using the inverse projection, s=0.5*(u+1) and t=0.5*(v+1). + // Any projection would work here, so we use the simplest.) We also clamp + // the (u,v) coordinates so that the point is barely outside the + // [-1,1]x[-1,1] face rectangle, since otherwise the reprojection step + // (which divides by the new z coordinate) might change the other + // coordinates enough so that we end up in the wrong leaf cell. + const scale = 1.0 / maxSize + limit := math.Nextafter(1, 2) + u := math.Max(-limit, math.Min(limit, scale*float64((i<<1)+1-maxSize))) + v := math.Max(-limit, math.Min(limit, scale*float64((j<<1)+1-maxSize))) + + // Find the leaf cell coordinates on the adjacent face, and convert + // them to a cell id at the appropriate level. + f, u, v = xyzToFaceUV(faceUVToXYZ(f, u, v)) + return cellIDFromFaceIJ(f, stToIJ(0.5*(u+1)), stToIJ(0.5*(v+1))) +} + +func cellIDFromFaceIJSame(f, i, j int, sameFace bool) CellID { + if sameFace { + return cellIDFromFaceIJ(f, i, j) + } + return cellIDFromFaceIJWrap(f, i, j) +} + +// ijToSTMin converts the i- or j-index of a leaf cell to the minimum corresponding +// s- or t-value contained by that cell. The argument must be in the range +// [0..2**30], i.e. up to one position beyond the normal range of valid leaf +// cell indices. +func ijToSTMin(i int) float64 { + return float64(i) / float64(maxSize) +} + +// stToIJ converts value in ST coordinates to a value in IJ coordinates. +func stToIJ(s float64) int { + return clampInt(int(math.Floor(maxSize*s)), 0, maxSize-1) +} + +// cellIDFromPoint returns a leaf cell containing point p. Usually there is +// exactly one such cell, but for points along the edge of a cell, any +// adjacent cell may be (deterministically) chosen. This is because +// s2.CellIDs are considered to be closed sets. The returned cell will +// always contain the given point, i.e. +// +// CellFromPoint(p).ContainsPoint(p) +// +// is always true. +func cellIDFromPoint(p Point) CellID { + f, u, v := xyzToFaceUV(r3.Vector{p.X, p.Y, p.Z}) + i := stToIJ(uvToST(u)) + j := stToIJ(uvToST(v)) + return cellIDFromFaceIJ(f, i, j) +} + +// ijLevelToBoundUV returns the bounds in (u,v)-space for the cell at the given +// level containing the leaf cell with the given (i,j)-coordinates. +func ijLevelToBoundUV(i, j, level int) r2.Rect { + cellSize := sizeIJ(level) + xLo := i & -cellSize + yLo := j & -cellSize + + return r2.Rect{ + X: r1.Interval{ + Lo: stToUV(ijToSTMin(xLo)), + Hi: stToUV(ijToSTMin(xLo + cellSize)), + }, + Y: r1.Interval{ + Lo: stToUV(ijToSTMin(yLo)), + Hi: stToUV(ijToSTMin(yLo + cellSize)), + }, + } +} + +// Constants related to the bit mangling in the Cell ID. +const ( + lookupBits = 4 + swapMask = 0x01 + invertMask = 0x02 +) + +// The following lookup tables are used to convert efficiently between an +// (i,j) cell index and the corresponding position along the Hilbert curve. +// +// lookupPos maps 4 bits of "i", 4 bits of "j", and 2 bits representing the +// orientation of the current cell into 8 bits representing the order in which +// that subcell is visited by the Hilbert curve, plus 2 bits indicating the +// new orientation of the Hilbert curve within that subcell. (Cell +// orientations are represented as combination of swapMask and invertMask.) +// +// lookupIJ is an inverted table used for mapping in the opposite +// direction. +// +// We also experimented with looking up 16 bits at a time (14 bits of position +// plus 2 of orientation) but found that smaller lookup tables gave better +// performance. (2KB fits easily in the primary cache.) +var ( + ijToPos = [4][4]int{ + {0, 1, 3, 2}, // canonical order + {0, 3, 1, 2}, // axes swapped + {2, 3, 1, 0}, // bits inverted + {2, 1, 3, 0}, // swapped & inverted + } + posToIJ = [4][4]int{ + {0, 1, 3, 2}, // canonical order: (0,0), (0,1), (1,1), (1,0) + {0, 2, 3, 1}, // axes swapped: (0,0), (1,0), (1,1), (0,1) + {3, 2, 0, 1}, // bits inverted: (1,1), (1,0), (0,0), (0,1) + {3, 1, 0, 2}, // swapped & inverted: (1,1), (0,1), (0,0), (1,0) + } + posToOrientation = [4]int{swapMask, 0, 0, invertMask | swapMask} + lookupIJ [1 << (2*lookupBits + 2)]int + lookupPos [1 << (2*lookupBits + 2)]int +) + +func init() { + initLookupCell(0, 0, 0, 0, 0, 0) + initLookupCell(0, 0, 0, swapMask, 0, swapMask) + initLookupCell(0, 0, 0, invertMask, 0, invertMask) + initLookupCell(0, 0, 0, swapMask|invertMask, 0, swapMask|invertMask) +} + +// initLookupCell initializes the lookupIJ table at init time. +func initLookupCell(level, i, j, origOrientation, pos, orientation int) { + if level == lookupBits { + ij := (i << lookupBits) + j + lookupPos[(ij<<2)+origOrientation] = (pos << 2) + orientation + lookupIJ[(pos<<2)+origOrientation] = (ij << 2) + orientation + return + } + + level++ + i <<= 1 + j <<= 1 + pos <<= 2 + r := posToIJ[orientation] + initLookupCell(level, i+(r[0]>>1), j+(r[0]&1), origOrientation, pos, orientation^posToOrientation[0]) + initLookupCell(level, i+(r[1]>>1), j+(r[1]&1), origOrientation, pos+1, orientation^posToOrientation[1]) + initLookupCell(level, i+(r[2]>>1), j+(r[2]&1), origOrientation, pos+2, orientation^posToOrientation[2]) + initLookupCell(level, i+(r[3]>>1), j+(r[3]&1), origOrientation, pos+3, orientation^posToOrientation[3]) +} + +// CommonAncestorLevel returns the level of the common ancestor of the two S2 CellIDs. +func (ci CellID) CommonAncestorLevel(other CellID) (level int, ok bool) { + bits := uint64(ci ^ other) + if bits < ci.lsb() { + bits = ci.lsb() + } + if bits < other.lsb() { + bits = other.lsb() + } + + msbPos := findMSBSetNonZero64(bits) + if msbPos > 60 { + return 0, false + } + return (60 - msbPos) >> 1, true +} + +// Advance advances or retreats the indicated number of steps along the +// Hilbert curve at the current level, and returns the new position. The +// position is never advanced past End() or before Begin(). +func (ci CellID) Advance(steps int64) CellID { + if steps == 0 { + return ci + } + + // We clamp the number of steps if necessary to ensure that we do not + // advance past the End() or before the Begin() of this level. Note that + // minSteps and maxSteps always fit in a signed 64-bit integer. + stepShift := uint(2*(maxLevel-ci.Level()) + 1) + if steps < 0 { + minSteps := -int64(uint64(ci) >> stepShift) + if steps < minSteps { + steps = minSteps + } + } else { + maxSteps := int64((wrapOffset + ci.lsb() - uint64(ci)) >> stepShift) + if steps > maxSteps { + steps = maxSteps + } + } + return ci + CellID(steps)<= limit.RangeMin() { + return limit + } + + if ci.RangeMax() >= limit { + // The cell is too large, shrink it. Note that when generating coverings + // of CellID ranges, this loop usually executes only once. Also because + // ci.RangeMin() < limit.RangeMin(), we will always exit the loop by the + // time we reach a leaf cell. + for { + ci = ci.Children()[0] + if ci.RangeMax() < limit { + break + } + } + return ci + } + + // The cell may be too small. Grow it if necessary. Note that generally + // this loop only iterates once. + for !ci.isFace() { + parent := ci.immediateParent() + if parent.RangeMin() != start || parent.RangeMax() >= limit { + break + } + ci = parent + } + return ci +} + +// centerFaceSiTi returns the (face, si, ti) coordinates of the center of the cell. +// Note that although (si,ti) coordinates span the range [0,2**31] in general, +// the cell center coordinates are always in the range [1,2**31-1] and +// therefore can be represented using a signed 32-bit integer. +func (ci CellID) centerFaceSiTi() (face, si, ti int) { + // First we compute the discrete (i,j) coordinates of a leaf cell contained + // within the given cell. Given that cells are represented by the Hilbert + // curve position corresponding at their center, it turns out that the cell + // returned by faceIJOrientation is always one of two leaf cells closest + // to the center of the cell (unless the given cell is a leaf cell itself, + // in which case there is only one possibility). + // + // Given a cell of size s >= 2 (i.e. not a leaf cell), and letting (imin, + // jmin) be the coordinates of its lower left-hand corner, the leaf cell + // returned by faceIJOrientation is either (imin + s/2, jmin + s/2) + // (imin + s/2 - 1, jmin + s/2 - 1). The first case is the one we want. + // We can distinguish these two cases by looking at the low bit of i or + // j. In the second case the low bit is one, unless s == 2 (i.e. the + // level just above leaf cells) in which case the low bit is zero. + // + // In the code below, the expression ((i ^ (int(id) >> 2)) & 1) is true + // if we are in the second case described above. + face, i, j, _ := ci.faceIJOrientation() + delta := 0 + if ci.IsLeaf() { + delta = 1 + } else if (int64(i)^(int64(ci)>>2))&1 == 1 { + delta = 2 + } + + // Note that (2 * {i,j} + delta) will never overflow a 32-bit integer. + return face, 2*i + delta, 2*j + delta +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/cellunion.go b/backend/vendor/github.com/blevesearch/geo/s2/cellunion.go new file mode 100644 index 0000000000..0654de9733 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/cellunion.go @@ -0,0 +1,590 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "fmt" + "io" + "sort" + + "github.com/golang/geo/s1" +) + +// A CellUnion is a collection of CellIDs. +// +// It is normalized if it is sorted, and does not contain redundancy. +// Specifically, it may not contain the same CellID twice, nor a CellID that +// is contained by another, nor the four sibling CellIDs that are children of +// a single higher level CellID. +// +// CellUnions are not required to be normalized, but certain operations will +// return different results if they are not (e.g. Contains). +type CellUnion []CellID + +// CellUnionFromRange creates a CellUnion that covers the half-open range +// of leaf cells [begin, end). If begin == end the resulting union is empty. +// This requires that begin and end are both leaves, and begin <= end. +// To create a closed-ended range, pass in end.Next(). +func CellUnionFromRange(begin, end CellID) CellUnion { + // We repeatedly add the largest cell we can. + var cu CellUnion + for id := begin.MaxTile(end); id != end; id = id.Next().MaxTile(end) { + cu = append(cu, id) + } + // The output is normalized because the cells are added in order by the iteration. + return cu +} + +// CellUnionFromUnion creates a CellUnion from the union of the given CellUnions. +func CellUnionFromUnion(cellUnions ...CellUnion) CellUnion { + var cu CellUnion + for _, cellUnion := range cellUnions { + cu = append(cu, cellUnion...) + } + cu.Normalize() + return cu +} + +// CellUnionFromIntersection creates a CellUnion from the intersection of the given CellUnions. +func CellUnionFromIntersection(x, y CellUnion) CellUnion { + var cu CellUnion + + // This is a fairly efficient calculation that uses binary search to skip + // over sections of both input vectors. It takes constant time if all the + // cells of x come before or after all the cells of y in CellID order. + var i, j int + for i < len(x) && j < len(y) { + iMin := x[i].RangeMin() + jMin := y[j].RangeMin() + if iMin > jMin { + // Either j.Contains(i) or the two cells are disjoint. + if x[i] <= y[j].RangeMax() { + cu = append(cu, x[i]) + i++ + } else { + // Advance j to the first cell possibly contained by x[i]. + j = y.lowerBound(j+1, len(y), iMin) + // The previous cell y[j-1] may now contain x[i]. + if x[i] <= y[j-1].RangeMax() { + j-- + } + } + } else if jMin > iMin { + // Identical to the code above with i and j reversed. + if y[j] <= x[i].RangeMax() { + cu = append(cu, y[j]) + j++ + } else { + i = x.lowerBound(i+1, len(x), jMin) + if y[j] <= x[i-1].RangeMax() { + i-- + } + } + } else { + // i and j have the same RangeMin(), so one contains the other. + if x[i] < y[j] { + cu = append(cu, x[i]) + i++ + } else { + cu = append(cu, y[j]) + j++ + } + } + } + + // The output is generated in sorted order. + cu.Normalize() + return cu +} + +// CellUnionFromIntersectionWithCellID creates a CellUnion from the intersection +// of a CellUnion with the given CellID. This can be useful for splitting a +// CellUnion into chunks. +func CellUnionFromIntersectionWithCellID(x CellUnion, id CellID) CellUnion { + var cu CellUnion + if x.ContainsCellID(id) { + cu = append(cu, id) + cu.Normalize() + return cu + } + + idmax := id.RangeMax() + for i := x.lowerBound(0, len(x), id.RangeMin()); i < len(x) && x[i] <= idmax; i++ { + cu = append(cu, x[i]) + } + + cu.Normalize() + return cu +} + +// CellUnionFromDifference creates a CellUnion from the difference (x - y) +// of the given CellUnions. +func CellUnionFromDifference(x, y CellUnion) CellUnion { + // TODO(roberts): This is approximately O(N*log(N)), but could probably + // use similar techniques as CellUnionFromIntersectionWithCellID to be more efficient. + + var cu CellUnion + for _, xid := range x { + cu.cellUnionDifferenceInternal(xid, &y) + } + + // The output is generated in sorted order, and there should not be any + // cells that can be merged (provided that both inputs were normalized). + return cu +} + +// The C++ constructor methods FromNormalized and FromVerbatim are not necessary +// since they don't call Normalize, and just set the CellIDs directly on the object, +// so straight casting is sufficient in Go to replicate this behavior. + +// IsValid reports whether the cell union is valid, meaning that the CellIDs are +// valid, non-overlapping, and sorted in increasing order. +func (cu *CellUnion) IsValid() bool { + for i, cid := range *cu { + if !cid.IsValid() { + return false + } + if i == 0 { + continue + } + if (*cu)[i-1].RangeMax() >= cid.RangeMin() { + return false + } + } + return true +} + +// IsNormalized reports whether the cell union is normalized, meaning that it is +// satisfies IsValid and that no four cells have a common parent. +// Certain operations such as Contains will return a different +// result if the cell union is not normalized. +func (cu *CellUnion) IsNormalized() bool { + for i, cid := range *cu { + if !cid.IsValid() { + return false + } + if i == 0 { + continue + } + if (*cu)[i-1].RangeMax() >= cid.RangeMin() { + return false + } + if i < 3 { + continue + } + if areSiblings((*cu)[i-3], (*cu)[i-2], (*cu)[i-1], cid) { + return false + } + } + return true +} + +// Normalize normalizes the CellUnion. +func (cu *CellUnion) Normalize() { + sortCellIDs(*cu) + + output := make([]CellID, 0, len(*cu)) // the list of accepted cells + // Loop invariant: output is a sorted list of cells with no redundancy. + for _, ci := range *cu { + // The first two passes here either ignore this new candidate, + // or remove previously accepted cells that are covered by this candidate. + + // Ignore this cell if it is contained by the previous one. + // We only need to check the last accepted cell. The ordering of the + // cells implies containment (but not the converse), and output has no redundancy, + // so if this candidate is not contained by the last accepted cell + // then it cannot be contained by any previously accepted cell. + if len(output) > 0 && output[len(output)-1].Contains(ci) { + continue + } + + // Discard any previously accepted cells contained by this one. + // This could be any contiguous trailing subsequence, but it can't be + // a discontiguous subsequence because of the containment property of + // sorted S2 cells mentioned above. + j := len(output) - 1 // last index to keep + for j >= 0 { + if !ci.Contains(output[j]) { + break + } + j-- + } + output = output[:j+1] + + // See if the last three cells plus this one can be collapsed. + // We loop because collapsing three accepted cells and adding a higher level cell + // could cascade into previously accepted cells. + for len(output) >= 3 && areSiblings(output[len(output)-3], output[len(output)-2], output[len(output)-1], ci) { + // Replace four children by their parent cell. + output = output[:len(output)-3] + ci = ci.immediateParent() // checked !ci.isFace above + } + output = append(output, ci) + } + *cu = output +} + +// IntersectsCellID reports whether this CellUnion intersects the given cell ID. +func (cu *CellUnion) IntersectsCellID(id CellID) bool { + // Find index of array item that occurs directly after our probe cell: + i := sort.Search(len(*cu), func(i int) bool { return id < (*cu)[i] }) + + if i != len(*cu) && (*cu)[i].RangeMin() <= id.RangeMax() { + return true + } + return i != 0 && (*cu)[i-1].RangeMax() >= id.RangeMin() +} + +// ContainsCellID reports whether the CellUnion contains the given cell ID. +// Containment is defined with respect to regions, e.g. a cell contains its 4 children. +// +// CAVEAT: If you have constructed a non-normalized CellUnion, note that groups +// of 4 child cells are *not* considered to contain their parent cell. To get +// this behavior you must use one of the call Normalize() explicitly. +func (cu *CellUnion) ContainsCellID(id CellID) bool { + // Find index of array item that occurs directly after our probe cell: + i := sort.Search(len(*cu), func(i int) bool { return id < (*cu)[i] }) + + if i != len(*cu) && (*cu)[i].RangeMin() <= id { + return true + } + return i != 0 && (*cu)[i-1].RangeMax() >= id +} + +// Denormalize replaces this CellUnion with an expanded version of the +// CellUnion where any cell whose level is less than minLevel or where +// (level - minLevel) is not a multiple of levelMod is replaced by its +// children, until either both of these conditions are satisfied or the +// maximum level is reached. +func (cu *CellUnion) Denormalize(minLevel, levelMod int) { + var denorm CellUnion + for _, id := range *cu { + level := id.Level() + newLevel := level + if newLevel < minLevel { + newLevel = minLevel + } + if levelMod > 1 { + newLevel += (maxLevel - (newLevel - minLevel)) % levelMod + if newLevel > maxLevel { + newLevel = maxLevel + } + } + if newLevel == level { + denorm = append(denorm, id) + } else { + end := id.ChildEndAtLevel(newLevel) + for ci := id.ChildBeginAtLevel(newLevel); ci != end; ci = ci.Next() { + denorm = append(denorm, ci) + } + } + } + *cu = denorm +} + +// RectBound returns a Rect that bounds this entity. +func (cu *CellUnion) RectBound() Rect { + bound := EmptyRect() + for _, c := range *cu { + bound = bound.Union(CellFromCellID(c).RectBound()) + } + return bound +} + +// CapBound returns a Cap that bounds this entity. +func (cu *CellUnion) CapBound() Cap { + if len(*cu) == 0 { + return EmptyCap() + } + + // Compute the approximate centroid of the region. This won't produce the + // bounding cap of minimal area, but it should be close enough. + var centroid Point + + for _, ci := range *cu { + area := AvgAreaMetric.Value(ci.Level()) + centroid = Point{centroid.Add(ci.Point().Mul(area))} + } + + if zero := (Point{}); centroid == zero { + centroid = PointFromCoords(1, 0, 0) + } else { + centroid = Point{centroid.Normalize()} + } + + // Use the centroid as the cap axis, and expand the cap angle so that it + // contains the bounding caps of all the individual cells. Note that it is + // *not* sufficient to just bound all the cell vertices because the bounding + // cap may be concave (i.e. cover more than one hemisphere). + c := CapFromPoint(centroid) + for _, ci := range *cu { + c = c.AddCap(CellFromCellID(ci).CapBound()) + } + + return c +} + +// ContainsCell reports whether this cell union contains the given cell. +func (cu *CellUnion) ContainsCell(c Cell) bool { + return cu.ContainsCellID(c.id) +} + +// IntersectsCell reports whether this cell union intersects the given cell. +func (cu *CellUnion) IntersectsCell(c Cell) bool { + return cu.IntersectsCellID(c.id) +} + +// ContainsPoint reports whether this cell union contains the given point. +func (cu *CellUnion) ContainsPoint(p Point) bool { + return cu.ContainsCell(CellFromPoint(p)) +} + +// CellUnionBound computes a covering of the CellUnion. +func (cu *CellUnion) CellUnionBound() []CellID { + return cu.CapBound().CellUnionBound() +} + +// LeafCellsCovered reports the number of leaf cells covered by this cell union. +// This will be no more than 6*2^60 for the whole sphere. +func (cu *CellUnion) LeafCellsCovered() int64 { + var numLeaves int64 + for _, c := range *cu { + numLeaves += 1 << uint64((maxLevel-int64(c.Level()))<<1) + } + return numLeaves +} + +// Returns true if the given four cells have a common parent. +// This requires that the four CellIDs are distinct. +func areSiblings(a, b, c, d CellID) bool { + // A necessary (but not sufficient) condition is that the XOR of the + // four cell IDs must be zero. This is also very fast to test. + if (a ^ b ^ c) != d { + return false + } + + // Now we do a slightly more expensive but exact test. First, compute a + // mask that blocks out the two bits that encode the child position of + // "id" with respect to its parent, then check that the other three + // children all agree with "mask". + mask := d.lsb() << 1 + mask = ^(mask + (mask << 1)) + idMasked := (uint64(d) & mask) + return ((uint64(a)&mask) == idMasked && + (uint64(b)&mask) == idMasked && + (uint64(c)&mask) == idMasked && + !d.isFace()) +} + +// Contains reports whether this CellUnion contains all of the CellIDs of the given CellUnion. +func (cu *CellUnion) Contains(o CellUnion) bool { + // TODO(roberts): Investigate alternatives such as divide-and-conquer + // or alternating-skip-search that may be significantly faster in both + // the average and worst case. This applies to Intersects as well. + for _, id := range o { + if !cu.ContainsCellID(id) { + return false + } + } + + return true +} + +// Intersects reports whether this CellUnion intersects any of the CellIDs of the given CellUnion. +func (cu *CellUnion) Intersects(o CellUnion) bool { + for _, c := range *cu { + if o.IntersectsCellID(c) { + return true + } + } + + return false +} + +// lowerBound returns the index in this CellUnion to the first element whose value +// is not considered to go before the given cell id. (i.e., either it is equivalent +// or comes after the given id.) If there is no match, then end is returned. +func (cu *CellUnion) lowerBound(begin, end int, id CellID) int { + for i := begin; i < end; i++ { + if (*cu)[i] >= id { + return i + } + } + + return end +} + +// cellUnionDifferenceInternal adds the difference between the CellID and the union to +// the result CellUnion. If they intersect but the difference is non-empty, it divides +// and conquers. +func (cu *CellUnion) cellUnionDifferenceInternal(id CellID, other *CellUnion) { + if !other.IntersectsCellID(id) { + (*cu) = append((*cu), id) + return + } + + if !other.ContainsCellID(id) { + for _, child := range id.Children() { + cu.cellUnionDifferenceInternal(child, other) + } + } +} + +// ExpandAtLevel expands this CellUnion by adding a rim of cells at expandLevel +// around the unions boundary. +// +// For each cell c in the union, we add all cells at level +// expandLevel that abut c. There are typically eight of those +// (four edge-abutting and four sharing a vertex). However, if c is +// finer than expandLevel, we add all cells abutting +// c.Parent(expandLevel) as well as c.Parent(expandLevel) itself, +// as an expandLevel cell rarely abuts a smaller cell. +// +// Note that the size of the output is exponential in +// expandLevel. For example, if expandLevel == 20 and the input +// has a cell at level 10, there will be on the order of 4000 +// adjacent cells in the output. For most applications the +// ExpandByRadius method below is easier to use. +func (cu *CellUnion) ExpandAtLevel(level int) { + var output CellUnion + levelLsb := lsbForLevel(level) + for i := len(*cu) - 1; i >= 0; i-- { + id := (*cu)[i] + if id.lsb() < levelLsb { + id = id.Parent(level) + // Optimization: skip over any cells contained by this one. This is + // especially important when very small regions are being expanded. + for i > 0 && id.Contains((*cu)[i-1]) { + i-- + } + } + output = append(output, id) + output = append(output, id.AllNeighbors(level)...) + } + sortCellIDs(output) + + *cu = output + cu.Normalize() +} + +// ExpandByRadius expands this CellUnion such that it contains all points whose +// distance to the CellUnion is at most minRadius, but do not use cells that +// are more than maxLevelDiff levels higher than the largest cell in the input. +// The second parameter controls the tradeoff between accuracy and output size +// when a large region is being expanded by a small amount (e.g. expanding Canada +// by 1km). For example, if maxLevelDiff == 4 the region will always be expanded +// by approximately 1/16 the width of its largest cell. Note that in the worst case, +// the number of cells in the output can be up to 4 * (1 + 2 ** maxLevelDiff) times +// larger than the number of cells in the input. +func (cu *CellUnion) ExpandByRadius(minRadius s1.Angle, maxLevelDiff int) { + minLevel := maxLevel + for _, cid := range *cu { + minLevel = minInt(minLevel, cid.Level()) + } + + // Find the maximum level such that all cells are at least "minRadius" wide. + radiusLevel := MinWidthMetric.MaxLevel(minRadius.Radians()) + if radiusLevel == 0 && minRadius.Radians() > MinWidthMetric.Value(0) { + // The requested expansion is greater than the width of a face cell. + // The easiest way to handle this is to expand twice. + cu.ExpandAtLevel(0) + } + cu.ExpandAtLevel(minInt(minLevel+maxLevelDiff, radiusLevel)) +} + +// Equal reports whether the two CellUnions are equal. +func (cu CellUnion) Equal(o CellUnion) bool { + if len(cu) != len(o) { + return false + } + for i := 0; i < len(cu); i++ { + if cu[i] != o[i] { + return false + } + } + return true +} + +// AverageArea returns the average area of this CellUnion. +// This is accurate to within a factor of 1.7. +func (cu *CellUnion) AverageArea() float64 { + return AvgAreaMetric.Value(maxLevel) * float64(cu.LeafCellsCovered()) +} + +// ApproxArea returns the approximate area of this CellUnion. This method is accurate +// to within 3% percent for all cell sizes and accurate to within 0.1% for cells +// at level 5 or higher within the union. +func (cu *CellUnion) ApproxArea() float64 { + var area float64 + for _, id := range *cu { + area += CellFromCellID(id).ApproxArea() + } + return area +} + +// ExactArea returns the area of this CellUnion as accurately as possible. +func (cu *CellUnion) ExactArea() float64 { + var area float64 + for _, id := range *cu { + area += CellFromCellID(id).ExactArea() + } + return area +} + +// Encode encodes the CellUnion. +func (cu *CellUnion) Encode(w io.Writer) error { + e := &encoder{w: w} + cu.encode(e) + return e.err +} + +func (cu *CellUnion) encode(e *encoder) { + e.writeInt8(encodingVersion) + e.writeInt64(int64(len(*cu))) + for _, ci := range *cu { + ci.encode(e) + } +} + +// Decode decodes the CellUnion. +func (cu *CellUnion) Decode(r io.Reader) error { + d := &decoder{r: asByteReader(r)} + cu.decode(d) + return d.err +} + +func (cu *CellUnion) decode(d *decoder) { + version := d.readInt8() + if d.err != nil { + return + } + if version != encodingVersion { + d.err = fmt.Errorf("only version %d is supported", encodingVersion) + return + } + n := d.readInt64() + if d.err != nil { + return + } + const maxCells = 1000000 + if n > maxCells { + d.err = fmt.Errorf("too many cells (%d; max is %d)", n, maxCells) + return + } + *cu = make([]CellID, n) + for i := range *cu { + (*cu)[i].decode(d) + } +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/centroids.go b/backend/vendor/github.com/blevesearch/geo/s2/centroids.go new file mode 100644 index 0000000000..e8a91c4422 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/centroids.go @@ -0,0 +1,133 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "math" + + "github.com/golang/geo/r3" +) + +// There are several notions of the "centroid" of a triangle. First, there +// is the planar centroid, which is simply the centroid of the ordinary +// (non-spherical) triangle defined by the three vertices. Second, there is +// the surface centroid, which is defined as the intersection of the three +// medians of the spherical triangle. It is possible to show that this +// point is simply the planar centroid projected to the surface of the +// sphere. Finally, there is the true centroid (mass centroid), which is +// defined as the surface integral over the spherical triangle of (x,y,z) +// divided by the triangle area. This is the point that the triangle would +// rotate around if it was spinning in empty space. +// +// The best centroid for most purposes is the true centroid. Unlike the +// planar and surface centroids, the true centroid behaves linearly as +// regions are added or subtracted. That is, if you split a triangle into +// pieces and compute the average of their centroids (weighted by triangle +// area), the result equals the centroid of the original triangle. This is +// not true of the other centroids. +// +// Also note that the surface centroid may be nowhere near the intuitive +// "center" of a spherical triangle. For example, consider the triangle +// with vertices A=(1,eps,0), B=(0,0,1), C=(-1,eps,0) (a quarter-sphere). +// The surface centroid of this triangle is at S=(0, 2*eps, 1), which is +// within a distance of 2*eps of the vertex B. Note that the median from A +// (the segment connecting A to the midpoint of BC) passes through S, since +// this is the shortest path connecting the two endpoints. On the other +// hand, the true centroid is at M=(0, 0.5, 0.5), which when projected onto +// the surface is a much more reasonable interpretation of the "center" of +// this triangle. +// + +// TrueCentroid returns the true centroid of the spherical triangle ABC +// multiplied by the signed area of spherical triangle ABC. The reasons for +// multiplying by the signed area are (1) this is the quantity that needs to be +// summed to compute the centroid of a union or difference of triangles, and +// (2) it's actually easier to calculate this way. All points must have unit length. +// +// Note that the result of this function is defined to be Point(0, 0, 0) if +// the triangle is degenerate. +func TrueCentroid(a, b, c Point) Point { + // Use Distance to get accurate results for small triangles. + ra := float64(1) + if sa := float64(b.Distance(c)); sa != 0 { + ra = sa / math.Sin(sa) + } + rb := float64(1) + if sb := float64(c.Distance(a)); sb != 0 { + rb = sb / math.Sin(sb) + } + rc := float64(1) + if sc := float64(a.Distance(b)); sc != 0 { + rc = sc / math.Sin(sc) + } + + // Now compute a point M such that: + // + // [Ax Ay Az] [Mx] [ra] + // [Bx By Bz] [My] = 0.5 * det(A,B,C) * [rb] + // [Cx Cy Cz] [Mz] [rc] + // + // To improve the numerical stability we subtract the first row (A) from the + // other two rows; this reduces the cancellation error when A, B, and C are + // very close together. Then we solve it using Cramer's rule. + // + // The result is the true centroid of the triangle multiplied by the + // triangle's area. + // + // This code still isn't as numerically stable as it could be. + // The biggest potential improvement is to compute B-A and C-A more + // accurately so that (B-A)x(C-A) is always inside triangle ABC. + x := r3.Vector{a.X, b.X - a.X, c.X - a.X} + y := r3.Vector{a.Y, b.Y - a.Y, c.Y - a.Y} + z := r3.Vector{a.Z, b.Z - a.Z, c.Z - a.Z} + r := r3.Vector{ra, rb - ra, rc - ra} + + return Point{r3.Vector{y.Cross(z).Dot(r), z.Cross(x).Dot(r), x.Cross(y).Dot(r)}.Mul(0.5)} +} + +// EdgeTrueCentroid returns the true centroid of the spherical geodesic edge AB +// multiplied by the length of the edge AB. As with triangles, the true centroid +// of a collection of line segments may be computed simply by summing the result +// of this method for each segment. +// +// Note that the planar centroid of a line segment is simply 0.5 * (a + b), +// while the surface centroid is (a + b).Normalize(). However neither of +// these values is appropriate for computing the centroid of a collection of +// edges (such as a polyline). +// +// Also note that the result of this function is defined to be Point(0, 0, 0) +// if the edge is degenerate. +func EdgeTrueCentroid(a, b Point) Point { + // The centroid (multiplied by length) is a vector toward the midpoint + // of the edge, whose length is twice the sine of half the angle between + // the two vertices. Defining theta to be this angle, we have: + vDiff := a.Sub(b.Vector) // Length == 2*sin(theta) + vSum := a.Add(b.Vector) // Length == 2*cos(theta) + sin2 := vDiff.Norm2() + cos2 := vSum.Norm2() + if cos2 == 0 { + return Point{} // Ignore antipodal edges. + } + return Point{vSum.Mul(math.Sqrt(sin2 / cos2))} // Length == 2*sin(theta) +} + +// PlanarCentroid returns the centroid of the planar triangle ABC. This can be +// normalized to unit length to obtain the "surface centroid" of the corresponding +// spherical triangle, i.e. the intersection of the three medians. However, note +// that for large spherical triangles the surface centroid may be nowhere near +// the intuitive "center". +func PlanarCentroid(a, b, c Point) Point { + return Point{a.Add(b.Vector).Add(c.Vector).Mul(1. / 3)} +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/contains_point_query.go b/backend/vendor/github.com/blevesearch/geo/s2/contains_point_query.go new file mode 100644 index 0000000000..3026f3601e --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/contains_point_query.go @@ -0,0 +1,190 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +// VertexModel defines whether shapes are considered to contain their vertices. +// Note that these definitions differ from the ones used by BooleanOperation. +// +// Note that points other than vertices are never contained by polylines. +// If you want need this behavior, use ClosestEdgeQuery's IsDistanceLess +// with a suitable distance threshold instead. +type VertexModel int + +const ( + // VertexModelOpen means no shapes contain their vertices (not even + // points). Therefore Contains(Point) returns true if and only if the + // point is in the interior of some polygon. + VertexModelOpen VertexModel = iota + + // VertexModelSemiOpen means that polygon point containment is defined + // such that if several polygons tile the region around a vertex, then + // exactly one of those polygons contains that vertex. Points and + // polylines still do not contain any vertices. + VertexModelSemiOpen + + // VertexModelClosed means all shapes contain their vertices (including + // points and polylines). + VertexModelClosed +) + +// ContainsPointQuery determines whether one or more shapes in a ShapeIndex +// contain a given Point. The ShapeIndex may contain any number of points, +// polylines, and/or polygons (possibly overlapping). Shape boundaries may be +// modeled as Open, SemiOpen, or Closed (this affects whether or not shapes are +// considered to contain their vertices). +// +// This type is not safe for concurrent use. +// +// However, note that if you need to do a large number of point containment +// tests, it is more efficient to re-use the query rather than creating a new +// one each time. +type ContainsPointQuery struct { + model VertexModel + index *ShapeIndex + iter *ShapeIndexIterator +} + +// NewContainsPointQuery creates a new instance of the ContainsPointQuery for the index +// and given vertex model choice. +func NewContainsPointQuery(index *ShapeIndex, model VertexModel) *ContainsPointQuery { + return &ContainsPointQuery{ + index: index, + model: model, + iter: index.Iterator(), + } +} + +// Contains reports whether any shape in the queries index contains the point p +// under the queries vertex model (Open, SemiOpen, or Closed). +func (q *ContainsPointQuery) Contains(p Point) bool { + if !q.iter.LocatePoint(p) { + return false + } + + cell := q.iter.IndexCell() + for _, clipped := range cell.shapes { + if q.shapeContains(clipped, q.iter.Center(), p) { + return true + } + } + return false +} + +// shapeContains reports whether the clippedShape from the iterator's center position contains +// the given point. +func (q *ContainsPointQuery) shapeContains(clipped *clippedShape, center, p Point) bool { + inside := clipped.containsCenter + numEdges := clipped.numEdges() + if numEdges <= 0 { + return inside + } + + shape := q.index.Shape(clipped.shapeID) + if shape.Dimension() != 2 { + // Points and polylines can be ignored unless the vertex model is Closed. + if q.model != VertexModelClosed { + return false + } + + // Otherwise, the point is contained if and only if it matches a vertex. + for _, edgeID := range clipped.edges { + edge := shape.Edge(edgeID) + if edge.V0 == p || edge.V1 == p { + return true + } + } + return false + } + + // Test containment by drawing a line segment from the cell center to the + // given point and counting edge crossings. + crosser := NewEdgeCrosser(center, p) + for _, edgeID := range clipped.edges { + edge := shape.Edge(edgeID) + sign := crosser.CrossingSign(edge.V0, edge.V1) + if sign == DoNotCross { + continue + } + if sign == MaybeCross { + // For the Open and Closed models, check whether p is a vertex. + if q.model != VertexModelSemiOpen && (edge.V0 == p || edge.V1 == p) { + return (q.model == VertexModelClosed) + } + // C++ plays fast and loose with the int <-> bool conversions here. + if VertexCrossing(crosser.a, crosser.b, edge.V0, edge.V1) { + sign = Cross + } else { + sign = DoNotCross + } + } + inside = inside != (sign == Cross) + } + + return inside +} + +// ShapeContains reports whether the given shape contains the point under this +// queries vertex model (Open, SemiOpen, or Closed). +// +// This requires the shape belongs to this queries index. +func (q *ContainsPointQuery) ShapeContains(shape Shape, p Point) bool { + if !q.iter.LocatePoint(p) { + return false + } + + clipped := q.iter.IndexCell().findByShapeID(q.index.idForShape(shape)) + if clipped == nil { + return false + } + return q.shapeContains(clipped, q.iter.Center(), p) +} + +// shapeVisitorFunc is a type of function that can be called against shaped in an index. +type shapeVisitorFunc func(shape Shape) bool + +// visitContainingShapes visits all shapes in the given index that contain the +// given point p, terminating early if the given visitor function returns false, +// in which case visitContainingShapes returns false. Each shape is +// visited at most once. +func (q *ContainsPointQuery) visitContainingShapes(p Point, f shapeVisitorFunc) bool { + // This function returns false only if the algorithm terminates early + // because the visitor function returned false. + if !q.iter.LocatePoint(p) { + return true + } + + cell := q.iter.IndexCell() + for _, clipped := range cell.shapes { + if q.shapeContains(clipped, q.iter.Center(), p) && + !f(q.index.Shape(clipped.shapeID)) { + return false + } + } + return true +} + +// ContainingShapes returns a slice of all shapes that contain the given point. +func (q *ContainsPointQuery) ContainingShapes(p Point) []Shape { + var shapes []Shape + q.visitContainingShapes(p, func(shape Shape) bool { + shapes = append(shapes, shape) + return true + }) + return shapes +} + +// TODO(roberts): Remaining methods from C++ +// type edgeVisitorFunc func(shape ShapeEdge) bool +// func (q *ContainsPointQuery) visitIncidentEdges(p Point, v edgeVisitorFunc) bool diff --git a/backend/vendor/github.com/blevesearch/geo/s2/contains_vertex_query.go b/backend/vendor/github.com/blevesearch/geo/s2/contains_vertex_query.go new file mode 100644 index 0000000000..8e74f9e5b6 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/contains_vertex_query.go @@ -0,0 +1,63 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +// ContainsVertexQuery is used to track the edges entering and leaving the +// given vertex of a Polygon in order to be able to determine if the point is +// contained by the Polygon. +// +// Point containment is defined according to the semi-open boundary model +// which means that if several polygons tile the region around a vertex, +// then exactly one of those polygons contains that vertex. +type ContainsVertexQuery struct { + target Point + edgeMap map[Point]int +} + +// NewContainsVertexQuery returns a new query for the given vertex whose +// containment will be determined. +func NewContainsVertexQuery(target Point) *ContainsVertexQuery { + return &ContainsVertexQuery{ + target: target, + edgeMap: make(map[Point]int), + } +} + +// AddEdge adds the edge between target and v with the given direction. +// (+1 = outgoing, -1 = incoming, 0 = degenerate). +func (q *ContainsVertexQuery) AddEdge(v Point, direction int) { + q.edgeMap[v] += direction +} + +// ContainsVertex reports a +1 if the target vertex is contained, -1 if it is +// not contained, and 0 if the incident edges consisted of matched sibling pairs. +func (q *ContainsVertexQuery) ContainsVertex() int { + // Find the unmatched edge that is immediately clockwise from Ortho(P). + referenceDir := Point{q.target.Ortho()} + + bestPoint := referenceDir + bestDir := 0 + + for k, v := range q.edgeMap { + if v == 0 { + continue // This is a "matched" edge. + } + if OrderedCCW(referenceDir, bestPoint, k, q.target) { + bestPoint = k + bestDir = v + } + } + return bestDir +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/convex_hull_query.go b/backend/vendor/github.com/blevesearch/geo/s2/convex_hull_query.go new file mode 100644 index 0000000000..68539abb12 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/convex_hull_query.go @@ -0,0 +1,258 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "sort" + + "github.com/golang/geo/r3" +) + +// ConvexHullQuery builds the convex hull of any collection of points, +// polylines, loops, and polygons. It returns a single convex loop. +// +// The convex hull is defined as the smallest convex region on the sphere that +// contains all of your input geometry. Recall that a region is "convex" if +// for every pair of points inside the region, the straight edge between them +// is also inside the region. In our case, a "straight" edge is a geodesic, +// i.e. the shortest path on the sphere between two points. +// +// Containment of input geometry is defined as follows: +// +// - Each input loop and polygon is contained by the convex hull exactly +// (i.e., according to Polygon's Contains(Polygon)). +// +// - Each input point is either contained by the convex hull or is a vertex +// of the convex hull. (Recall that S2Loops do not necessarily contain their +// vertices.) +// +// - For each input polyline, the convex hull contains all of its vertices +// according to the rule for points above. (The definition of convexity +// then ensures that the convex hull also contains the polyline edges.) +// +// To use this type, call the various Add... methods to add your input geometry, and +// then call ConvexHull. Note that ConvexHull does *not* reset the +// state; you can continue adding geometry if desired and compute the convex +// hull again. If you want to start from scratch, simply create a new +// ConvexHullQuery value. +// +// This implement Andrew's monotone chain algorithm, which is a variant of the +// Graham scan (see https://en.wikipedia.org/wiki/Graham_scan). The time +// complexity is O(n log n), and the space required is O(n). In fact only the +// call to "sort" takes O(n log n) time; the rest of the algorithm is linear. +// +// Demonstration of the algorithm and code: +// en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain +// +// This type is not safe for concurrent use. +type ConvexHullQuery struct { + bound Rect + points []Point +} + +// NewConvexHullQuery creates a new ConvexHullQuery. +func NewConvexHullQuery() *ConvexHullQuery { + return &ConvexHullQuery{ + bound: EmptyRect(), + } +} + +// AddPoint adds the given point to the input geometry. +func (q *ConvexHullQuery) AddPoint(p Point) { + q.bound = q.bound.AddPoint(LatLngFromPoint(p)) + q.points = append(q.points, p) +} + +// AddPolyline adds the given polyline to the input geometry. +func (q *ConvexHullQuery) AddPolyline(p *Polyline) { + q.bound = q.bound.Union(p.RectBound()) + q.points = append(q.points, (*p)...) +} + +// AddLoop adds the given loop to the input geometry. +func (q *ConvexHullQuery) AddLoop(l *Loop) { + q.bound = q.bound.Union(l.RectBound()) + if l.isEmptyOrFull() { + return + } + q.points = append(q.points, l.vertices...) +} + +// AddPolygon adds the given polygon to the input geometry. +func (q *ConvexHullQuery) AddPolygon(p *Polygon) { + q.bound = q.bound.Union(p.RectBound()) + for _, l := range p.loops { + // Only loops at depth 0 can contribute to the convex hull. + if l.depth == 0 { + q.AddLoop(l) + } + } +} + +// CapBound returns a bounding cap for the input geometry provided. +// +// Note that this method does not clear the geometry; you can continue +// adding to it and call this method again if desired. +func (q *ConvexHullQuery) CapBound() Cap { + // We keep track of a rectangular bound rather than a spherical cap because + // it is easy to compute a tight bound for a union of rectangles, whereas it + // is quite difficult to compute a tight bound around a union of caps. + // Also, polygons and polylines implement CapBound() in terms of + // RectBound() for this same reason, so it is much better to keep track + // of a rectangular bound as we go along and convert it at the end. + // + // TODO(roberts): We could compute an optimal bound by implementing Welzl's + // algorithm. However we would still need to have special handling of loops + // and polygons, since if a loop spans more than 180 degrees in any + // direction (i.e., if it contains two antipodal points), then it is not + // enough just to bound its vertices. In this case the only convex bounding + // cap is FullCap(), and the only convex bounding loop is the full loop. + return q.bound.CapBound() +} + +// ConvexHull returns a Loop representing the convex hull of the input geometry provided. +// +// If there is no geometry, this method returns an empty loop containing no +// points. +// +// If the geometry spans more than half of the sphere, this method returns a +// full loop containing the entire sphere. +// +// If the geometry contains 1 or 2 points, or a single edge, this method +// returns a very small loop consisting of three vertices (which are a +// superset of the input vertices). +// +// Note that this method does not clear the geometry; you can continue +// adding to the query and call this method again. +func (q *ConvexHullQuery) ConvexHull() *Loop { + c := q.CapBound() + if c.Height() >= 1 { + // The bounding cap is not convex. The current bounding cap + // implementation is not optimal, but nevertheless it is likely that the + // input geometry itself is not contained by any convex polygon. In any + // case, we need a convex bounding cap to proceed with the algorithm below + // (in order to construct a point "origin" that is definitely outside the + // convex hull). + return FullLoop() + } + + // Remove duplicates. We need to do this before checking whether there are + // fewer than 3 points. + x := make(map[Point]bool) + r, w := 0, 0 // read/write indexes + for ; r < len(q.points); r++ { + if x[q.points[r]] { + continue + } + q.points[w] = q.points[r] + x[q.points[r]] = true + w++ + } + q.points = q.points[:w] + + // This code implements Andrew's monotone chain algorithm, which is a simple + // variant of the Graham scan. Rather than sorting by x-coordinate, instead + // we sort the points in CCW order around an origin O such that all points + // are guaranteed to be on one side of some geodesic through O. This + // ensures that as we scan through the points, each new point can only + // belong at the end of the chain (i.e., the chain is monotone in terms of + // the angle around O from the starting point). + origin := Point{c.Center().Ortho()} + sort.Slice(q.points, func(i, j int) bool { + return RobustSign(origin, q.points[i], q.points[j]) == CounterClockwise + }) + + // Special cases for fewer than 3 points. + switch len(q.points) { + case 0: + return EmptyLoop() + case 1: + return singlePointLoop(q.points[0]) + case 2: + return singleEdgeLoop(q.points[0], q.points[1]) + } + + // Generate the lower and upper halves of the convex hull. Each half + // consists of the maximal subset of vertices such that the edge chain + // makes only left (CCW) turns. + lower := q.monotoneChain() + + // reverse the points + for left, right := 0, len(q.points)-1; left < right; left, right = left+1, right-1 { + q.points[left], q.points[right] = q.points[right], q.points[left] + } + upper := q.monotoneChain() + + // Remove the duplicate vertices and combine the chains. + lower = lower[:len(lower)-1] + upper = upper[:len(upper)-1] + lower = append(lower, upper...) + + return LoopFromPoints(lower) +} + +// monotoneChain iterates through the points, selecting the maximal subset of points +// such that the edge chain makes only left (CCW) turns. +func (q *ConvexHullQuery) monotoneChain() []Point { + var output []Point + for _, p := range q.points { + // Remove any points that would cause the chain to make a clockwise turn. + for len(output) >= 2 && RobustSign(output[len(output)-2], output[len(output)-1], p) != CounterClockwise { + output = output[:len(output)-1] + } + output = append(output, p) + } + return output +} + +// singlePointLoop constructs a 3-vertex polygon consisting of "p" and two nearby +// vertices. Note that ContainsPoint(p) may be false for the resulting loop. +func singlePointLoop(p Point) *Loop { + const offset = 1e-15 + d0 := p.Ortho() + d1 := p.Cross(d0) + vertices := []Point{ + p, + {p.Add(d0.Mul(offset)).Normalize()}, + {p.Add(d1.Mul(offset)).Normalize()}, + } + return LoopFromPoints(vertices) +} + +// singleEdgeLoop constructs a loop consisting of the two vertices and their midpoint. +func singleEdgeLoop(a, b Point) *Loop { + // If the points are exactly antipodal we return the full loop. + // + // Note that we could use the code below even in this case (which would + // return a zero-area loop that follows the edge AB), except that (1) the + // direction of AB is defined using symbolic perturbations and therefore is + // not predictable by ordinary users, and (2) Loop disallows anitpodal + // adjacent vertices and so we would need to use 4 vertices to define the + // degenerate loop. (Note that the Loop antipodal vertex restriction is + // historical and now could easily be removed, however it would still have + // the problem that the edge direction is not easily predictable.) + if a.Add(b.Vector) == (r3.Vector{}) { + return FullLoop() + } + + // Construct a loop consisting of the two vertices and their midpoint. We + // use Interpolate() to ensure that the midpoint is very close to + // the edge even when its endpoints nearly antipodal. + vertices := []Point{a, b, Interpolate(0.5, a, b)} + loop := LoopFromPoints(vertices) + // The resulting loop may be clockwise, so invert it if necessary. + loop.Normalize() + return loop +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/crossing_edge_query.go b/backend/vendor/github.com/blevesearch/geo/s2/crossing_edge_query.go new file mode 100644 index 0000000000..51852dab47 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/crossing_edge_query.go @@ -0,0 +1,409 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "sort" + + "github.com/golang/geo/r2" +) + +// CrossingEdgeQuery is used to find the Edge IDs of Shapes that are crossed by +// a given edge(s). +// +// Note that if you need to query many edges, it is more efficient to declare +// a single CrossingEdgeQuery instance and reuse it. +// +// If you want to find *all* the pairs of crossing edges, it is more efficient to +// use the not yet implemented VisitCrossings in shapeutil. +type CrossingEdgeQuery struct { + index *ShapeIndex + + // temporary values used while processing a query. + a, b r2.Point + iter *ShapeIndexIterator + + // candidate cells generated when finding crossings. + cells []*ShapeIndexCell +} + +// NewCrossingEdgeQuery creates a CrossingEdgeQuery for the given index. +func NewCrossingEdgeQuery(index *ShapeIndex) *CrossingEdgeQuery { + c := &CrossingEdgeQuery{ + index: index, + iter: index.Iterator(), + } + return c +} + +// Crossings returns the set of edge of the shape S that intersect the given edge AB. +// If the CrossingType is Interior, then only intersections at a point interior to both +// edges are reported, while if it is CrossingTypeAll then edges that share a vertex +// are also reported. +func (c *CrossingEdgeQuery) Crossings(a, b Point, shape Shape, crossType CrossingType) []int { + edges := c.candidates(a, b, shape) + if len(edges) == 0 { + return nil + } + + crosser := NewEdgeCrosser(a, b) + out := 0 + n := len(edges) + + for in := 0; in < n; in++ { + b := shape.Edge(edges[in]) + sign := crosser.CrossingSign(b.V0, b.V1) + if crossType == CrossingTypeAll && (sign == MaybeCross || sign == Cross) || crossType != CrossingTypeAll && sign == Cross { + edges[out] = edges[in] + out++ + } + } + + if out < n { + edges = edges[0:out] + } + return edges +} + +// EdgeMap stores a sorted set of edge ids for each shape. +type EdgeMap map[Shape][]int + +// CrossingsEdgeMap returns the set of all edges in the index that intersect the given +// edge AB. If crossType is CrossingTypeInterior, then only intersections at a +// point interior to both edges are reported, while if it is CrossingTypeAll +// then edges that share a vertex are also reported. +// +// The edges are returned as a mapping from shape to the edges of that shape +// that intersect AB. Every returned shape has at least one crossing edge. +func (c *CrossingEdgeQuery) CrossingsEdgeMap(a, b Point, crossType CrossingType) EdgeMap { + edgeMap := c.candidatesEdgeMap(a, b) + if len(edgeMap) == 0 { + return nil + } + + crosser := NewEdgeCrosser(a, b) + for shape, edges := range edgeMap { + out := 0 + n := len(edges) + for in := 0; in < n; in++ { + edge := shape.Edge(edges[in]) + sign := crosser.CrossingSign(edge.V0, edge.V1) + if (crossType == CrossingTypeAll && (sign == MaybeCross || sign == Cross)) || (crossType != CrossingTypeAll && sign == Cross) { + edgeMap[shape][out] = edges[in] + out++ + } + } + + if out == 0 { + delete(edgeMap, shape) + } else { + if out < n { + edgeMap[shape] = edgeMap[shape][0:out] + } + } + } + return edgeMap +} + +// candidates returns a superset of the edges of the given shape that intersect +// the edge AB. +func (c *CrossingEdgeQuery) candidates(a, b Point, shape Shape) []int { + var edges []int + + // For small loops it is faster to use brute force. The threshold below was + // determined using benchmarks. + const maxBruteForceEdges = 27 + maxEdges := shape.NumEdges() + if maxEdges <= maxBruteForceEdges { + edges = make([]int, maxEdges) + for i := 0; i < maxEdges; i++ { + edges[i] = i + } + return edges + } + + // Compute the set of index cells intersected by the query edge. + c.getCellsForEdge(a, b) + if len(c.cells) == 0 { + return nil + } + + // Gather all the edges that intersect those cells and sort them. + // TODO(roberts): Shapes don't track their ID, so we need to range over + // the index to find the ID manually. + var shapeID int32 + for k, v := range c.index.shapes { + if v == shape { + shapeID = k + } + } + + for _, cell := range c.cells { + if cell == nil { + continue + } + clipped := cell.findByShapeID(shapeID) + if clipped == nil { + continue + } + edges = append(edges, clipped.edges...) + } + + if len(c.cells) > 1 { + edges = uniqueInts(edges) + } + + return edges +} + +// uniqueInts returns the sorted uniqued values from the given input. +func uniqueInts(in []int) []int { + var edges []int + m := make(map[int]bool) + for _, i := range in { + if m[i] { + continue + } + m[i] = true + edges = append(edges, i) + } + sort.Ints(edges) + return edges +} + +// candidatesEdgeMap returns a map from shapes to the superse of edges for that +// shape that intersect the edge AB. +// +// CAVEAT: This method may return shapes that have an empty set of candidate edges. +// However the return value is non-empty only if at least one shape has a candidate edge. +func (c *CrossingEdgeQuery) candidatesEdgeMap(a, b Point) EdgeMap { + edgeMap := make(EdgeMap) + + // If there are only a few edges then it's faster to use brute force. We + // only bother with this optimization when there is a single shape. + if len(c.index.shapes) == 1 { + // Typically this method is called many times, so it is worth checking + // whether the edge map is empty or already consists of a single entry for + // this shape, and skip clearing edge map in that case. + shape := c.index.Shape(0) + + // Note that we leave the edge map non-empty even if there are no candidates + // (i.e., there is a single entry with an empty set of edges). + edgeMap[shape] = c.candidates(a, b, shape) + return edgeMap + } + + // Compute the set of index cells intersected by the query edge. + c.getCellsForEdge(a, b) + if len(c.cells) == 0 { + return edgeMap + } + + // Gather all the edges that intersect those cells and sort them. + for _, cell := range c.cells { + for _, clipped := range cell.shapes { + s := c.index.Shape(clipped.shapeID) + for j := 0; j < clipped.numEdges(); j++ { + edgeMap[s] = append(edgeMap[s], clipped.edges[j]) + } + } + } + + if len(c.cells) > 1 { + for s, edges := range edgeMap { + edgeMap[s] = uniqueInts(edges) + } + } + + return edgeMap +} + +// getCells returns the set of ShapeIndexCells that might contain edges intersecting +// the edge AB in the given cell root. This method is used primarily by loop and shapeutil. +func (c *CrossingEdgeQuery) getCells(a, b Point, root *PaddedCell) []*ShapeIndexCell { + aUV, bUV, ok := ClipToFace(a, b, root.id.Face()) + if ok { + c.a = aUV + c.b = bUV + edgeBound := r2.RectFromPoints(c.a, c.b) + if root.Bound().Intersects(edgeBound) { + c.computeCellsIntersected(root, edgeBound) + } + } + + if len(c.cells) == 0 { + return nil + } + + return c.cells +} + +// getCellsForEdge populates the cells field to the set of index cells intersected by an edge AB. +func (c *CrossingEdgeQuery) getCellsForEdge(a, b Point) { + c.cells = nil + + segments := FaceSegments(a, b) + for _, segment := range segments { + c.a = segment.a + c.b = segment.b + + // Optimization: rather than always starting the recursive subdivision at + // the top level face cell, instead we start at the smallest S2CellId that + // contains the edge (the edge root cell). This typically lets us skip + // quite a few levels of recursion since most edges are short. + edgeBound := r2.RectFromPoints(c.a, c.b) + pcell := PaddedCellFromCellID(CellIDFromFace(segment.face), 0) + edgeRoot := pcell.ShrinkToFit(edgeBound) + + // Now we need to determine how the edge root cell is related to the cells + // in the spatial index (cellMap). There are three cases: + // + // 1. edgeRoot is an index cell or is contained within an index cell. + // In this case we only need to look at the contents of that cell. + // 2. edgeRoot is subdivided into one or more index cells. In this case + // we recursively subdivide to find the cells intersected by AB. + // 3. edgeRoot does not intersect any index cells. In this case there + // is nothing to do. + relation := c.iter.LocateCellID(edgeRoot) + if relation == Indexed { + // edgeRoot is an index cell or is contained by an index cell (case 1). + c.cells = append(c.cells, c.iter.IndexCell()) + } else if relation == Subdivided { + // edgeRoot is subdivided into one or more index cells (case 2). We + // find the cells intersected by AB using recursive subdivision. + if !edgeRoot.isFace() { + pcell = PaddedCellFromCellID(edgeRoot, 0) + } + c.computeCellsIntersected(pcell, edgeBound) + } + } +} + +// computeCellsIntersected computes the index cells intersected by the current +// edge that are descendants of pcell and adds them to this queries set of cells. +func (c *CrossingEdgeQuery) computeCellsIntersected(pcell *PaddedCell, edgeBound r2.Rect) { + + c.iter.seek(pcell.id.RangeMin()) + if c.iter.Done() || c.iter.CellID() > pcell.id.RangeMax() { + // The index does not contain pcell or any of its descendants. + return + } + if c.iter.CellID() == pcell.id { + // The index contains this cell exactly. + c.cells = append(c.cells, c.iter.IndexCell()) + return + } + + // Otherwise, split the edge among the four children of pcell. + center := pcell.Middle().Lo() + + if edgeBound.X.Hi < center.X { + // Edge is entirely contained in the two left children. + c.clipVAxis(edgeBound, center.Y, 0, pcell) + return + } else if edgeBound.X.Lo >= center.X { + // Edge is entirely contained in the two right children. + c.clipVAxis(edgeBound, center.Y, 1, pcell) + return + } + + childBounds := c.splitUBound(edgeBound, center.X) + if edgeBound.Y.Hi < center.Y { + // Edge is entirely contained in the two lower children. + c.computeCellsIntersected(PaddedCellFromParentIJ(pcell, 0, 0), childBounds[0]) + c.computeCellsIntersected(PaddedCellFromParentIJ(pcell, 1, 0), childBounds[1]) + } else if edgeBound.Y.Lo >= center.Y { + // Edge is entirely contained in the two upper children. + c.computeCellsIntersected(PaddedCellFromParentIJ(pcell, 0, 1), childBounds[0]) + c.computeCellsIntersected(PaddedCellFromParentIJ(pcell, 1, 1), childBounds[1]) + } else { + // The edge bound spans all four children. The edge itself intersects + // at most three children (since no padding is being used). + c.clipVAxis(childBounds[0], center.Y, 0, pcell) + c.clipVAxis(childBounds[1], center.Y, 1, pcell) + } +} + +// clipVAxis computes the intersected cells recursively for a given padded cell. +// Given either the left (i=0) or right (i=1) side of a padded cell pcell, +// determine whether the current edge intersects the lower child, upper child, +// or both children, and call c.computeCellsIntersected recursively on those children. +// The center is the v-coordinate at the center of pcell. +func (c *CrossingEdgeQuery) clipVAxis(edgeBound r2.Rect, center float64, i int, pcell *PaddedCell) { + if edgeBound.Y.Hi < center { + // Edge is entirely contained in the lower child. + c.computeCellsIntersected(PaddedCellFromParentIJ(pcell, i, 0), edgeBound) + } else if edgeBound.Y.Lo >= center { + // Edge is entirely contained in the upper child. + c.computeCellsIntersected(PaddedCellFromParentIJ(pcell, i, 1), edgeBound) + } else { + // The edge intersects both children. + childBounds := c.splitVBound(edgeBound, center) + c.computeCellsIntersected(PaddedCellFromParentIJ(pcell, i, 0), childBounds[0]) + c.computeCellsIntersected(PaddedCellFromParentIJ(pcell, i, 1), childBounds[1]) + } +} + +// splitUBound returns the bound for two children as a result of spliting the +// current edge at the given value U. +func (c *CrossingEdgeQuery) splitUBound(edgeBound r2.Rect, u float64) [2]r2.Rect { + v := edgeBound.Y.ClampPoint(interpolateFloat64(u, c.a.X, c.b.X, c.a.Y, c.b.Y)) + // diag indicates which diagonal of the bounding box is spanned by AB: + // it is 0 if AB has positive slope, and 1 if AB has negative slope. + var diag int + if (c.a.X > c.b.X) != (c.a.Y > c.b.Y) { + diag = 1 + } + return splitBound(edgeBound, 0, diag, u, v) +} + +// splitVBound returns the bound for two children as a result of spliting the +// current edge into two child edges at the given value V. +func (c *CrossingEdgeQuery) splitVBound(edgeBound r2.Rect, v float64) [2]r2.Rect { + u := edgeBound.X.ClampPoint(interpolateFloat64(v, c.a.Y, c.b.Y, c.a.X, c.b.X)) + var diag int + if (c.a.X > c.b.X) != (c.a.Y > c.b.Y) { + diag = 1 + } + return splitBound(edgeBound, diag, 0, u, v) +} + +// splitBound returns the bounds for the two childrenn as a result of spliting +// the current edge into two child edges at the given point (u,v). uEnd and vEnd +// indicate which bound endpoints of the first child will be updated. +func splitBound(edgeBound r2.Rect, uEnd, vEnd int, u, v float64) [2]r2.Rect { + var childBounds = [2]r2.Rect{ + edgeBound, + edgeBound, + } + + if uEnd == 1 { + childBounds[0].X.Lo = u + childBounds[1].X.Hi = u + } else { + childBounds[0].X.Hi = u + childBounds[1].X.Lo = u + } + + if vEnd == 1 { + childBounds[0].Y.Lo = v + childBounds[1].Y.Hi = v + } else { + childBounds[0].Y.Hi = v + childBounds[1].Y.Lo = v + } + + return childBounds +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/distance_target.go b/backend/vendor/github.com/blevesearch/geo/s2/distance_target.go new file mode 100644 index 0000000000..066bbacfaf --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/distance_target.go @@ -0,0 +1,149 @@ +// Copyright 2019 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "github.com/golang/geo/s1" +) + +// The distance interface represents a set of common methods used by algorithms +// that compute distances between various S2 types. +type distance interface { + // chordAngle returns this type as a ChordAngle. + chordAngle() s1.ChordAngle + + // fromChordAngle is used to type convert a ChordAngle to this type. + // This is to work around needing to be clever in parts of the code + // where a distanceTarget interface method expects distances, but the + // user only supplies a ChordAngle, and we need to dynamically cast it + // to an appropriate distance interface types. + fromChordAngle(o s1.ChordAngle) distance + + // zero returns a zero distance. + zero() distance + // negative returns a value smaller than any valid value. + negative() distance + // infinity returns a value larger than any valid value. + infinity() distance + + // less is similar to the Less method in Sort. To get minimum values, + // this would be a less than type operation. For maximum, this would + // be a greater than type operation. + less(other distance) bool + + // sub subtracts the other value from this one and returns the new value. + // This is done as a method and not simple mathematical operation to + // allow closest and furthest to implement this in opposite ways. + sub(other distance) distance + + // chordAngleBound reports the upper bound on a ChordAngle corresponding + // to this distance. For example, if distance measures WGS84 ellipsoid + // distance then the corresponding angle needs to be 0.56% larger. + chordAngleBound() s1.ChordAngle + + // updateDistance may update the value this distance represents + // based on the given input. The updated value and a boolean reporting + // if the value was changed are returned. + updateDistance(other distance) (distance, bool) +} + +// distanceTarget is an interface that represents a geometric type to which distances +// are measured. +// +// For example, there are implementations that measure distances to a Point, +// an Edge, a Cell, a CellUnion, and even to an arbitrary collection of geometry +// stored in ShapeIndex. +// +// The distanceTarget types are provided for the benefit of types that measure +// distances and/or find nearby geometry, such as ClosestEdgeQuery, FurthestEdgeQuery, +// ClosestPointQuery, and ClosestCellQuery, etc. +type distanceTarget interface { + // capBound returns a Cap that bounds the set of points whose distance to the + // target is distance.zero(). + capBound() Cap + + // updateDistanceToPoint updates the distance if the distance to + // the point P is within than the given dist. + // The boolean reports if the value was updated. + updateDistanceToPoint(p Point, dist distance) (distance, bool) + + // updateDistanceToEdge updates the distance if the distance to + // the edge E is within than the given dist. + // The boolean reports if the value was updated. + updateDistanceToEdge(e Edge, dist distance) (distance, bool) + + // updateDistanceToCell updates the distance if the distance to the cell C + // (including its interior) is within than the given dist. + // The boolean reports if the value was updated. + updateDistanceToCell(c Cell, dist distance) (distance, bool) + + // setMaxError potentially updates the value of MaxError, and reports if + // the specific type supports altering it. Whenever one of the + // updateDistanceTo... methods above returns true, the returned distance + // is allowed to be up to maxError larger than the true minimum distance. + // In other words, it gives this target object permission to terminate its + // distance calculation as soon as it has determined that (1) the minimum + // distance is less than minDist and (2) the best possible further + // improvement is less than maxError. + // + // If the target takes advantage of maxError to optimize its distance + // calculation, this method must return true. (Most target types will + // default to return false.) + setMaxError(maxErr s1.ChordAngle) bool + + // maxBruteForceIndexSize reports the maximum number of indexed objects for + // which it is faster to compute the distance by brute force (e.g., by testing + // every edge) rather than by using an index. + // + // The following method is provided as a convenience for types that compute + // distances to a collection of indexed geometry, such as ClosestEdgeQuery + // and ClosestPointQuery. + // + // Types that do not support this should return a -1. + maxBruteForceIndexSize() int + + // distance returns an instance of the underlying distance type this + // target uses. This is to work around the use of Templates in the C++. + distance() distance + + // visitContainingShapes finds all polygons in the given index that + // completely contain a connected component of the target geometry. (For + // example, if the target consists of 10 points, this method finds + // polygons that contain any of those 10 points.) For each such polygon, + // the visit function is called with the Shape of the polygon along with + // a point of the target geometry that is contained by that polygon. + // + // Optionally, any polygon that intersects the target geometry may also be + // returned. In other words, this method returns all polygons that + // contain any connected component of the target, along with an arbitrary + // subset of the polygons that intersect the target. + // + // For example, suppose that the index contains two abutting polygons + // A and B. If the target consists of two points "a" contained by A and + // "b" contained by B, then both A and B are returned. But if the target + // consists of the edge "ab", then any subset of {A, B} could be returned + // (because both polygons intersect the target but neither one contains + // the edge "ab"). + // + // If the visit function returns false, this method terminates early and + // returns false as well. Otherwise returns true. + // + // NOTE(roberts): This method exists only for the purpose of implementing + // edgeQuery IncludeInteriors efficiently. + visitContainingShapes(index *ShapeIndex, v shapePointVisitorFunc) bool +} + +// shapePointVisitorFunc defines a type of function the visitContainingShapes can call. +type shapePointVisitorFunc func(containingShape Shape, targetPoint Point) bool diff --git a/backend/vendor/github.com/blevesearch/geo/s2/doc.go b/backend/vendor/github.com/blevesearch/geo/s2/doc.go new file mode 100644 index 0000000000..43e7a6344c --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/doc.go @@ -0,0 +1,29 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* +Package s2 is a library for working with geometry in S² (spherical geometry). + +Its related packages, parallel to this one, are s1 (operates on S¹), r1 (operates on ℝ¹), +r2 (operates on ℝ²) and r3 (operates on ℝ³). + +This package provides types and functions for the S2 cell hierarchy and coordinate systems. +The S2 cell hierarchy is a hierarchical decomposition of the surface of a unit sphere (S²) +into ``cells''; it is highly efficient, scales from continental size to under 1 cm² +and preserves spatial locality (nearby cells have close IDs). + +More information including an in-depth introduction to S2 can be found on the +S2 website https://s2geometry.io/ +*/ +package s2 diff --git a/backend/vendor/github.com/blevesearch/geo/s2/edge_clipping.go b/backend/vendor/github.com/blevesearch/geo/s2/edge_clipping.go new file mode 100644 index 0000000000..57a53bf0fb --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/edge_clipping.go @@ -0,0 +1,672 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +// This file contains a collection of methods for: +// +// (1) Robustly clipping geodesic edges to the faces of the S2 biunit cube +// (see s2stuv), and +// +// (2) Robustly clipping 2D edges against 2D rectangles. +// +// These functions can be used to efficiently find the set of CellIDs that +// are intersected by a geodesic edge (e.g., see CrossingEdgeQuery). + +import ( + "math" + + "github.com/golang/geo/r1" + "github.com/golang/geo/r2" + "github.com/golang/geo/r3" +) + +const ( + // edgeClipErrorUVCoord is the maximum error in a u- or v-coordinate + // compared to the exact result, assuming that the points A and B are in + // the rectangle [-1,1]x[1,1] or slightly outside it (by 1e-10 or less). + edgeClipErrorUVCoord = 2.25 * dblEpsilon + + // edgeClipErrorUVDist is the maximum distance from a clipped point to + // the corresponding exact result. It is equal to the error in a single + // coordinate because at most one coordinate is subject to error. + edgeClipErrorUVDist = 2.25 * dblEpsilon + + // faceClipErrorRadians is the maximum angle between a returned vertex + // and the nearest point on the exact edge AB. It is equal to the + // maximum directional error in PointCross, plus the error when + // projecting points onto a cube face. + faceClipErrorRadians = 3 * dblEpsilon + + // faceClipErrorDist is the same angle expressed as a maximum distance + // in (u,v)-space. In other words, a returned vertex is at most this far + // from the exact edge AB projected into (u,v)-space. + faceClipErrorUVDist = 9 * dblEpsilon + + // faceClipErrorUVCoord is the maximum angle between a returned vertex + // and the nearest point on the exact edge AB expressed as the maximum error + // in an individual u- or v-coordinate. In other words, for each + // returned vertex there is a point on the exact edge AB whose u- and + // v-coordinates differ from the vertex by at most this amount. + faceClipErrorUVCoord = 9.0 * (1.0 / math.Sqrt2) * dblEpsilon + + // intersectsRectErrorUVDist is the maximum error when computing if a point + // intersects with a given Rect. If some point of AB is inside the + // rectangle by at least this distance, the result is guaranteed to be true; + // if all points of AB are outside the rectangle by at least this distance, + // the result is guaranteed to be false. This bound assumes that rect is + // a subset of the rectangle [-1,1]x[-1,1] or extends slightly outside it + // (e.g., by 1e-10 or less). + intersectsRectErrorUVDist = 3 * math.Sqrt2 * dblEpsilon +) + +// ClipToFace returns the (u,v) coordinates for the portion of the edge AB that +// intersects the given face, or false if the edge AB does not intersect. +// This method guarantees that the clipped vertices lie within the [-1,1]x[-1,1] +// cube face rectangle and are within faceClipErrorUVDist of the line AB, but +// the results may differ from those produced by FaceSegments. +func ClipToFace(a, b Point, face int) (aUV, bUV r2.Point, intersects bool) { + return ClipToPaddedFace(a, b, face, 0.0) +} + +// ClipToPaddedFace returns the (u,v) coordinates for the portion of the edge AB that +// intersects the given face, but rather than clipping to the square [-1,1]x[-1,1] +// in (u,v) space, this method clips to [-R,R]x[-R,R] where R=(1+padding). +// Padding must be non-negative. +func ClipToPaddedFace(a, b Point, f int, padding float64) (aUV, bUV r2.Point, intersects bool) { + // Fast path: both endpoints are on the given face. + if face(a.Vector) == f && face(b.Vector) == f { + au, av := validFaceXYZToUV(f, a.Vector) + bu, bv := validFaceXYZToUV(f, b.Vector) + return r2.Point{au, av}, r2.Point{bu, bv}, true + } + + // Convert everything into the (u,v,w) coordinates of the given face. Note + // that the cross product *must* be computed in the original (x,y,z) + // coordinate system because PointCross (unlike the mathematical cross + // product) can produce different results in different coordinate systems + // when one argument is a linear multiple of the other, due to the use of + // symbolic perturbations. + normUVW := pointUVW(faceXYZtoUVW(f, a.PointCross(b))) + aUVW := pointUVW(faceXYZtoUVW(f, a)) + bUVW := pointUVW(faceXYZtoUVW(f, b)) + + // Padding is handled by scaling the u- and v-components of the normal. + // Letting R=1+padding, this means that when we compute the dot product of + // the normal with a cube face vertex (such as (-1,-1,1)), we will actually + // compute the dot product with the scaled vertex (-R,-R,1). This allows + // methods such as intersectsFace, exitAxis, etc, to handle padding + // with no further modifications. + scaleUV := 1 + padding + scaledN := pointUVW{r3.Vector{X: scaleUV * normUVW.X, Y: scaleUV * normUVW.Y, Z: normUVW.Z}} + if !scaledN.intersectsFace() { + return aUV, bUV, false + } + + // TODO(roberts): This is a workaround for extremely small vectors where some + // loss of precision can occur in Normalize causing underflow. When PointCross + // is updated to work around this, this can be removed. + if math.Max(math.Abs(normUVW.X), math.Max(math.Abs(normUVW.Y), math.Abs(normUVW.Z))) < math.Ldexp(1, -511) { + normUVW = pointUVW{normUVW.Mul(math.Ldexp(1, 563))} + } + + normUVW = pointUVW{normUVW.Normalize()} + + aTan := pointUVW{normUVW.Cross(aUVW.Vector)} + bTan := pointUVW{bUVW.Cross(normUVW.Vector)} + + // As described in clipDestination, if the sum of the scores from clipping the two + // endpoints is 3 or more, then the segment does not intersect this face. + aUV, aScore := clipDestination(bUVW, aUVW, pointUVW{scaledN.Mul(-1)}, bTan, aTan, scaleUV) + bUV, bScore := clipDestination(aUVW, bUVW, scaledN, aTan, bTan, scaleUV) + + return aUV, bUV, aScore+bScore < 3 +} + +// ClipEdge returns the portion of the edge defined by AB that is contained by the +// given rectangle. If there is no intersection, false is returned and aClip and bClip +// are undefined. +func ClipEdge(a, b r2.Point, clip r2.Rect) (aClip, bClip r2.Point, intersects bool) { + // Compute the bounding rectangle of AB, clip it, and then extract the new + // endpoints from the clipped bound. + bound := r2.RectFromPoints(a, b) + if bound, intersects = clipEdgeBound(a, b, clip, bound); !intersects { + return aClip, bClip, false + } + ai := 0 + if a.X > b.X { + ai = 1 + } + aj := 0 + if a.Y > b.Y { + aj = 1 + } + + return bound.VertexIJ(ai, aj), bound.VertexIJ(1-ai, 1-aj), true +} + +// The three functions below (sumEqual, intersectsFace, intersectsOppositeEdges) +// all compare a sum (u + v) to a third value w. They are implemented in such a +// way that they produce an exact result even though all calculations are done +// with ordinary floating-point operations. Here are the principles on which these +// functions are based: +// +// A. If u + v < w in floating-point, then u + v < w in exact arithmetic. +// +// B. If u + v < w in exact arithmetic, then at least one of the following +// expressions is true in floating-point: +// u + v < w +// u < w - v +// v < w - u +// +// Proof: By rearranging terms and substituting ">" for "<", we can assume +// that all values are non-negative. Now clearly "w" is not the smallest +// value, so assume WLOG that "u" is the smallest. We want to show that +// u < w - v in floating-point. If v >= w/2, the calculation of w - v is +// exact since the result is smaller in magnitude than either input value, +// so the result holds. Otherwise we have u <= v < w/2 and w - v >= w/2 +// (even in floating point), so the result also holds. + +// sumEqual reports whether u + v == w exactly. +func sumEqual(u, v, w float64) bool { + return (u+v == w) && (u == w-v) && (v == w-u) +} + +// pointUVW represents a Point in (u,v,w) coordinate space of a cube face. +type pointUVW Point + +// intersectsFace reports whether a given directed line L intersects the cube face F. +// The line L is defined by its normal N in the (u,v,w) coordinates of F. +func (p pointUVW) intersectsFace() bool { + // L intersects the [-1,1]x[-1,1] square in (u,v) if and only if the dot + // products of N with the four corner vertices (-1,-1,1), (1,-1,1), (1,1,1), + // and (-1,1,1) do not all have the same sign. This is true exactly when + // |Nu| + |Nv| >= |Nw|. The code below evaluates this expression exactly. + u := math.Abs(p.X) + v := math.Abs(p.Y) + w := math.Abs(p.Z) + + // We only need to consider the cases where u or v is the smallest value, + // since if w is the smallest then both expressions below will have a + // positive LHS and a negative RHS. + return (v >= w-u) && (u >= w-v) +} + +// intersectsOppositeEdges reports whether a directed line L intersects two +// opposite edges of a cube face F. This includs the case where L passes +// exactly through a corner vertex of F. The directed line L is defined +// by its normal N in the (u,v,w) coordinates of F. +func (p pointUVW) intersectsOppositeEdges() bool { + // The line L intersects opposite edges of the [-1,1]x[-1,1] (u,v) square if + // and only exactly two of the corner vertices lie on each side of L. This + // is true exactly when ||Nu| - |Nv|| >= |Nw|. The code below evaluates this + // expression exactly. + u := math.Abs(p.X) + v := math.Abs(p.Y) + w := math.Abs(p.Z) + + // If w is the smallest, the following line returns an exact result. + if math.Abs(u-v) != w { + return math.Abs(u-v) >= w + } + + // Otherwise u - v = w exactly, or w is not the smallest value. In either + // case the following returns the correct result. + if u >= v { + return u-w >= v + } + return v-w >= u +} + +// axis represents the possible results of exitAxis. +type axis int + +const ( + axisU axis = iota + axisV +) + +// exitAxis reports which axis the directed line L exits the cube face F on. +// The directed line L is represented by its CCW normal N in the (u,v,w) coordinates +// of F. It returns axisU if L exits through the u=-1 or u=+1 edge, and axisV if L exits +// through the v=-1 or v=+1 edge. Either result is acceptable if L exits exactly +// through a corner vertex of the cube face. +func (p pointUVW) exitAxis() axis { + if p.intersectsOppositeEdges() { + // The line passes through through opposite edges of the face. + // It exits through the v=+1 or v=-1 edge if the u-component of N has a + // larger absolute magnitude than the v-component. + if math.Abs(p.X) >= math.Abs(p.Y) { + return axisV + } + return axisU + } + + // The line passes through through two adjacent edges of the face. + // It exits the v=+1 or v=-1 edge if an even number of the components of N + // are negative. We test this using signbit() rather than multiplication + // to avoid the possibility of underflow. + var x, y, z int + if math.Signbit(p.X) { + x = 1 + } + if math.Signbit(p.Y) { + y = 1 + } + if math.Signbit(p.Z) { + z = 1 + } + + if x^y^z == 0 { + return axisV + } + return axisU +} + +// exitPoint returns the UV coordinates of the point where a directed line L (represented +// by the CCW normal of this point), exits the cube face this point is derived from along +// the given axis. +func (p pointUVW) exitPoint(a axis) r2.Point { + if a == axisU { + u := -1.0 + if p.Y > 0 { + u = 1.0 + } + return r2.Point{u, (-u*p.X - p.Z) / p.Y} + } + + v := -1.0 + if p.X < 0 { + v = 1.0 + } + return r2.Point{(-v*p.Y - p.Z) / p.X, v} +} + +// clipDestination returns a score which is used to indicate if the clipped edge AB +// on the given face intersects the face at all. This function returns the score for +// the given endpoint, which is an integer ranging from 0 to 3. If the sum of the scores +// from both of the endpoints is 3 or more, then edge AB does not intersect this face. +// +// First, it clips the line segment AB to find the clipped destination B' on a given +// face. (The face is specified implicitly by expressing *all arguments* in the (u,v,w) +// coordinates of that face.) Second, it partially computes whether the segment AB +// intersects this face at all. The actual condition is fairly complicated, but it +// turns out that it can be expressed as a "score" that can be computed independently +// when clipping the two endpoints A and B. +func clipDestination(a, b, scaledN, aTan, bTan pointUVW, scaleUV float64) (r2.Point, int) { + var uv r2.Point + + // Optimization: if B is within the safe region of the face, use it. + maxSafeUVCoord := 1 - faceClipErrorUVCoord + if b.Z > 0 { + uv = r2.Point{b.X / b.Z, b.Y / b.Z} + if math.Max(math.Abs(uv.X), math.Abs(uv.Y)) <= maxSafeUVCoord { + return uv, 0 + } + } + + // Otherwise find the point B' where the line AB exits the face. + uv = scaledN.exitPoint(scaledN.exitAxis()).Mul(scaleUV) + + p := pointUVW(Point{r3.Vector{uv.X, uv.Y, 1.0}}) + + // Determine if the exit point B' is contained within the segment. We do this + // by computing the dot products with two inward-facing tangent vectors at A + // and B. If either dot product is negative, we say that B' is on the "wrong + // side" of that point. As the point B' moves around the great circle AB past + // the segment endpoint B, it is initially on the wrong side of B only; as it + // moves further it is on the wrong side of both endpoints; and then it is on + // the wrong side of A only. If the exit point B' is on the wrong side of + // either endpoint, we can't use it; instead the segment is clipped at the + // original endpoint B. + // + // We reject the segment if the sum of the scores of the two endpoints is 3 + // or more. Here is what that rule encodes: + // - If B' is on the wrong side of A, then the other clipped endpoint A' + // must be in the interior of AB (otherwise AB' would go the wrong way + // around the circle). There is a similar rule for A'. + // - If B' is on the wrong side of either endpoint (and therefore we must + // use the original endpoint B instead), then it must be possible to + // project B onto this face (i.e., its w-coordinate must be positive). + // This rule is only necessary to handle certain zero-length edges (A=B). + score := 0 + if p.Sub(a.Vector).Dot(aTan.Vector) < 0 { + score = 2 // B' is on wrong side of A. + } else if p.Sub(b.Vector).Dot(bTan.Vector) < 0 { + score = 1 // B' is on wrong side of B. + } + + if score > 0 { // B' is not in the interior of AB. + if b.Z <= 0 { + score = 3 // B cannot be projected onto this face. + } else { + uv = r2.Point{b.X / b.Z, b.Y / b.Z} + } + } + + return uv, score +} + +// updateEndpoint returns the interval with the specified endpoint updated to +// the given value. If the value lies beyond the opposite endpoint, nothing is +// changed and false is returned. +func updateEndpoint(bound r1.Interval, highEndpoint bool, value float64) (r1.Interval, bool) { + if !highEndpoint { + if bound.Hi < value { + return bound, false + } + if bound.Lo < value { + bound.Lo = value + } + return bound, true + } + + if bound.Lo > value { + return bound, false + } + if bound.Hi > value { + bound.Hi = value + } + return bound, true +} + +// clipBoundAxis returns the clipped versions of the bounding intervals for the given +// axes for the line segment from (a0,a1) to (b0,b1) so that neither extends beyond the +// given clip interval. negSlope is a precomputed helper variable that indicates which +// diagonal of the bounding box is spanned by AB; it is false if AB has positive slope, +// and true if AB has negative slope. If the clipping interval doesn't overlap the bounds, +// false is returned. +func clipBoundAxis(a0, b0 float64, bound0 r1.Interval, a1, b1 float64, bound1 r1.Interval, + negSlope bool, clip r1.Interval) (bound0c, bound1c r1.Interval, updated bool) { + + if bound0.Lo < clip.Lo { + // If the upper bound is below the clips lower bound, there is nothing to do. + if bound0.Hi < clip.Lo { + return bound0, bound1, false + } + // narrow the intervals lower bound to the clip bound. + bound0.Lo = clip.Lo + if bound1, updated = updateEndpoint(bound1, negSlope, interpolateFloat64(clip.Lo, a0, b0, a1, b1)); !updated { + return bound0, bound1, false + } + } + + if bound0.Hi > clip.Hi { + // If the lower bound is above the clips upper bound, there is nothing to do. + if bound0.Lo > clip.Hi { + return bound0, bound1, false + } + // narrow the intervals upper bound to the clip bound. + bound0.Hi = clip.Hi + if bound1, updated = updateEndpoint(bound1, !negSlope, interpolateFloat64(clip.Hi, a0, b0, a1, b1)); !updated { + return bound0, bound1, false + } + } + return bound0, bound1, true +} + +// edgeIntersectsRect reports whether the edge defined by AB intersects the +// given closed rectangle to within the error bound. +func edgeIntersectsRect(a, b r2.Point, r r2.Rect) bool { + // First check whether the bounds of a Rect around AB intersects the given rect. + if !r.Intersects(r2.RectFromPoints(a, b)) { + return false + } + + // Otherwise AB intersects the rect if and only if all four vertices of rect + // do not lie on the same side of the extended line AB. We test this by finding + // the two vertices of rect with minimum and maximum projections onto the normal + // of AB, and computing their dot products with the edge normal. + n := b.Sub(a).Ortho() + + i := 0 + if n.X >= 0 { + i = 1 + } + j := 0 + if n.Y >= 0 { + j = 1 + } + + max := n.Dot(r.VertexIJ(i, j).Sub(a)) + min := n.Dot(r.VertexIJ(1-i, 1-j).Sub(a)) + + return (max >= 0) && (min <= 0) +} + +// clippedEdgeBound returns the bounding rectangle of the portion of the edge defined +// by AB intersected by clip. The resulting bound may be empty. This is a convenience +// function built on top of clipEdgeBound. +func clippedEdgeBound(a, b r2.Point, clip r2.Rect) r2.Rect { + bound := r2.RectFromPoints(a, b) + if b1, intersects := clipEdgeBound(a, b, clip, bound); intersects { + return b1 + } + return r2.EmptyRect() +} + +// clipEdgeBound clips an edge AB to sequence of rectangles efficiently. +// It represents the clipped edges by their bounding boxes rather than as a pair of +// endpoints. Specifically, let A'B' be some portion of an edge AB, and let bound be +// a tight bound of A'B'. This function returns the bound that is a tight bound +// of A'B' intersected with a given rectangle. If A'B' does not intersect clip, +// it returns false and the original bound. +func clipEdgeBound(a, b r2.Point, clip, bound r2.Rect) (r2.Rect, bool) { + // negSlope indicates which diagonal of the bounding box is spanned by AB: it + // is false if AB has positive slope, and true if AB has negative slope. This is + // used to determine which interval endpoints need to be updated each time + // the edge is clipped. + negSlope := (a.X > b.X) != (a.Y > b.Y) + + b0x, b0y, up1 := clipBoundAxis(a.X, b.X, bound.X, a.Y, b.Y, bound.Y, negSlope, clip.X) + if !up1 { + return bound, false + } + b1y, b1x, up2 := clipBoundAxis(a.Y, b.Y, b0y, a.X, b.X, b0x, negSlope, clip.Y) + if !up2 { + return r2.Rect{b0x, b0y}, false + } + return r2.Rect{X: b1x, Y: b1y}, true +} + +// interpolateFloat64 returns a value with the same combination of a1 and b1 as the +// given value x is of a and b. This function makes the following guarantees: +// - If x == a, then x1 = a1 (exactly). +// - If x == b, then x1 = b1 (exactly). +// - If a <= x <= b, then a1 <= x1 <= b1 (even if a1 == b1). +// This requires a != b. +func interpolateFloat64(x, a, b, a1, b1 float64) float64 { + // To get results that are accurate near both A and B, we interpolate + // starting from the closer of the two points. + if math.Abs(a-x) <= math.Abs(b-x) { + return a1 + (b1-a1)*(x-a)/(b-a) + } + return b1 + (a1-b1)*(x-b)/(a-b) +} + +// FaceSegment represents an edge AB clipped to an S2 cube face. It is +// represented by a face index and a pair of (u,v) coordinates. +type FaceSegment struct { + face int + a, b r2.Point +} + +// FaceSegments subdivides the given edge AB at every point where it crosses the +// boundary between two S2 cube faces and returns the corresponding FaceSegments. +// The segments are returned in order from A toward B. The input points must be +// unit length. +// +// This function guarantees that the returned segments form a continuous path +// from A to B, and that all vertices are within faceClipErrorUVDist of the +// line AB. All vertices lie within the [-1,1]x[-1,1] cube face rectangles. +// The results are consistent with Sign, i.e. the edge is well-defined even its +// endpoints are antipodal. +// TODO(roberts): Extend the implementation of PointCross so that this is true. +func FaceSegments(a, b Point) []FaceSegment { + var segment FaceSegment + + // Fast path: both endpoints are on the same face. + var aFace, bFace int + aFace, segment.a.X, segment.a.Y = xyzToFaceUV(a.Vector) + bFace, segment.b.X, segment.b.Y = xyzToFaceUV(b.Vector) + if aFace == bFace { + segment.face = aFace + return []FaceSegment{segment} + } + + // Starting at A, we follow AB from face to face until we reach the face + // containing B. The following code is designed to ensure that we always + // reach B, even in the presence of numerical errors. + // + // First we compute the normal to the plane containing A and B. This normal + // becomes the ultimate definition of the line AB; it is used to resolve all + // questions regarding where exactly the line goes. Unfortunately due to + // numerical errors, the line may not quite intersect the faces containing + // the original endpoints. We handle this by moving A and/or B slightly if + // necessary so that they are on faces intersected by the line AB. + ab := a.PointCross(b) + + aFace, segment.a = moveOriginToValidFace(aFace, a, ab, segment.a) + bFace, segment.b = moveOriginToValidFace(bFace, b, Point{ab.Mul(-1)}, segment.b) + + // Now we simply follow AB from face to face until we reach B. + var segments []FaceSegment + segment.face = aFace + bSaved := segment.b + + for face := aFace; face != bFace; { + // Complete the current segment by finding the point where AB + // exits the current face. + z := faceXYZtoUVW(face, ab) + n := pointUVW{z.Vector} + + exitAxis := n.exitAxis() + segment.b = n.exitPoint(exitAxis) + segments = append(segments, segment) + + // Compute the next face intersected by AB, and translate the exit + // point of the current segment into the (u,v) coordinates of the + // next face. This becomes the first point of the next segment. + exitXyz := faceUVToXYZ(face, segment.b.X, segment.b.Y) + face = nextFace(face, segment.b, exitAxis, n, bFace) + exitUvw := faceXYZtoUVW(face, Point{exitXyz}) + segment.face = face + segment.a = r2.Point{exitUvw.X, exitUvw.Y} + } + // Finish the last segment. + segment.b = bSaved + return append(segments, segment) +} + +// moveOriginToValidFace updates the origin point to a valid face if necessary. +// Given a line segment AB whose origin A has been projected onto a given cube +// face, determine whether it is necessary to project A onto a different face +// instead. This can happen because the normal of the line AB is not computed +// exactly, so that the line AB (defined as the set of points perpendicular to +// the normal) may not intersect the cube face containing A. Even if it does +// intersect the face, the exit point of the line from that face may be on +// the wrong side of A (i.e., in the direction away from B). If this happens, +// we reproject A onto the adjacent face where the line AB approaches A most +// closely. This moves the origin by a small amount, but never more than the +// error tolerances. +func moveOriginToValidFace(face int, a, ab Point, aUV r2.Point) (int, r2.Point) { + // Fast path: if the origin is sufficiently far inside the face, it is + // always safe to use it. + const maxSafeUVCoord = 1 - faceClipErrorUVCoord + if math.Max(math.Abs((aUV).X), math.Abs((aUV).Y)) <= maxSafeUVCoord { + return face, aUV + } + + // Otherwise check whether the normal AB even intersects this face. + z := faceXYZtoUVW(face, ab) + n := pointUVW{z.Vector} + if n.intersectsFace() { + // Check whether the point where the line AB exits this face is on the + // wrong side of A (by more than the acceptable error tolerance). + uv := n.exitPoint(n.exitAxis()) + exit := faceUVToXYZ(face, uv.X, uv.Y) + aTangent := ab.Normalize().Cross(a.Vector) + + // We can use the given face. + if exit.Sub(a.Vector).Dot(aTangent) >= -faceClipErrorRadians { + return face, aUV + } + } + + // Otherwise we reproject A to the nearest adjacent face. (If line AB does + // not pass through a given face, it must pass through all adjacent faces.) + var dir int + if math.Abs((aUV).X) >= math.Abs((aUV).Y) { + // U-axis + if aUV.X > 0 { + dir = 1 + } + face = uvwFace(face, 0, dir) + } else { + // V-axis + if aUV.Y > 0 { + dir = 1 + } + face = uvwFace(face, 1, dir) + } + + aUV.X, aUV.Y = validFaceXYZToUV(face, a.Vector) + aUV.X = math.Max(-1.0, math.Min(1.0, aUV.X)) + aUV.Y = math.Max(-1.0, math.Min(1.0, aUV.Y)) + + return face, aUV +} + +// nextFace returns the next face that should be visited by FaceSegments, given that +// we have just visited face and we are following the line AB (represented +// by its normal N in the (u,v,w) coordinates of that face). The other +// arguments include the point where AB exits face, the corresponding +// exit axis, and the target face containing the destination point B. +func nextFace(face int, exit r2.Point, axis axis, n pointUVW, targetFace int) int { + // this bit is to work around C++ cleverly casting bools to ints for you. + exitA := exit.X + exit1MinusA := exit.Y + + if axis == axisV { + exitA = exit.Y + exit1MinusA = exit.X + } + exitAPos := 0 + if exitA > 0 { + exitAPos = 1 + } + exit1MinusAPos := 0 + if exit1MinusA > 0 { + exit1MinusAPos = 1 + } + + // We return the face that is adjacent to the exit point along the given + // axis. If line AB exits *exactly* through a corner of the face, there are + // two possible next faces. If one is the target face containing B, then + // we guarantee that we advance to that face directly. + // + // The three conditions below check that (1) AB exits approximately through + // a corner, (2) the adjacent face along the non-exit axis is the target + // face, and (3) AB exits *exactly* through the corner. (The sumEqual + // code checks whether the dot product of (u,v,1) and n is exactly zero.) + if math.Abs(exit1MinusA) == 1 && + uvwFace(face, int(1-axis), exit1MinusAPos) == targetFace && + sumEqual(exit.X*n.X, exit.Y*n.Y, -n.Z) { + return targetFace + } + + // Otherwise return the face that is adjacent to the exit point in the + // direction of the exit axis. + return uvwFace(face, int(axis), exitAPos) +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/edge_crosser.go b/backend/vendor/github.com/blevesearch/geo/s2/edge_crosser.go new file mode 100644 index 0000000000..69c6da6b9f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/edge_crosser.go @@ -0,0 +1,227 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "math" +) + +// EdgeCrosser allows edges to be efficiently tested for intersection with a +// given fixed edge AB. It is especially efficient when testing for +// intersection with an edge chain connecting vertices v0, v1, v2, ... +// +// Example usage: +// +// func CountIntersections(a, b Point, edges []Edge) int { +// count := 0 +// crosser := NewEdgeCrosser(a, b) +// for _, edge := range edges { +// if crosser.CrossingSign(&edge.First, &edge.Second) != DoNotCross { +// count++ +// } +// } +// return count +// } +// +type EdgeCrosser struct { + a Point + b Point + aXb Point + + // To reduce the number of calls to expensiveSign, we compute an + // outward-facing tangent at A and B if necessary. If the plane + // perpendicular to one of these tangents separates AB from CD (i.e., one + // edge on each side) then there is no intersection. + aTangent Point // Outward-facing tangent at A. + bTangent Point // Outward-facing tangent at B. + + // The fields below are updated for each vertex in the chain. + c Point // Previous vertex in the vertex chain. + acb Direction // The orientation of triangle ACB. +} + +// NewEdgeCrosser returns an EdgeCrosser with the fixed edge AB. +func NewEdgeCrosser(a, b Point) *EdgeCrosser { + norm := a.PointCross(b) + return &EdgeCrosser{ + a: a, + b: b, + aXb: Point{a.Cross(b.Vector)}, + aTangent: Point{a.Cross(norm.Vector)}, + bTangent: Point{norm.Cross(b.Vector)}, + } +} + +// CrossingSign reports whether the edge AB intersects the edge CD. If any two +// vertices from different edges are the same, returns MaybeCross. If either edge +// is degenerate (A == B or C == D), returns either DoNotCross or MaybeCross. +// +// Properties of CrossingSign: +// +// (1) CrossingSign(b,a,c,d) == CrossingSign(a,b,c,d) +// (2) CrossingSign(c,d,a,b) == CrossingSign(a,b,c,d) +// (3) CrossingSign(a,b,c,d) == MaybeCross if a==c, a==d, b==c, b==d +// (3) CrossingSign(a,b,c,d) == DoNotCross or MaybeCross if a==b or c==d +// +// Note that if you want to check an edge against a chain of other edges, +// it is slightly more efficient to use the single-argument version +// ChainCrossingSign below. +func (e *EdgeCrosser) CrossingSign(c, d Point) Crossing { + if c != e.c { + e.RestartAt(c) + } + return e.ChainCrossingSign(d) +} + +// EdgeOrVertexCrossing reports whether if CrossingSign(c, d) > 0, or AB and +// CD share a vertex and VertexCrossing(a, b, c, d) is true. +// +// This method extends the concept of a "crossing" to the case where AB +// and CD have a vertex in common. The two edges may or may not cross, +// according to the rules defined in VertexCrossing above. The rules +// are designed so that point containment tests can be implemented simply +// by counting edge crossings. Similarly, determining whether one edge +// chain crosses another edge chain can be implemented by counting. +func (e *EdgeCrosser) EdgeOrVertexCrossing(c, d Point) bool { + if c != e.c { + e.RestartAt(c) + } + return e.EdgeOrVertexChainCrossing(d) +} + +// NewChainEdgeCrosser is a convenience constructor that uses AB as the fixed edge, +// and C as the first vertex of the vertex chain (equivalent to calling RestartAt(c)). +// +// You don't need to use this or any of the chain functions unless you're trying to +// squeeze out every last drop of performance. Essentially all you are saving is a test +// whether the first vertex of the current edge is the same as the second vertex of the +// previous edge. +func NewChainEdgeCrosser(a, b, c Point) *EdgeCrosser { + e := NewEdgeCrosser(a, b) + e.RestartAt(c) + return e +} + +// RestartAt sets the current point of the edge crosser to be c. +// Call this method when your chain 'jumps' to a new place. +// The argument must point to a value that persists until the next call. +func (e *EdgeCrosser) RestartAt(c Point) { + e.c = c + e.acb = -triageSign(e.a, e.b, e.c) +} + +// ChainCrossingSign is like CrossingSign, but uses the last vertex passed to one of +// the crossing methods (or RestartAt) as the first vertex of the current edge. +func (e *EdgeCrosser) ChainCrossingSign(d Point) Crossing { + // For there to be an edge crossing, the triangles ACB, CBD, BDA, DAC must + // all be oriented the same way (CW or CCW). We keep the orientation of ACB + // as part of our state. When each new point D arrives, we compute the + // orientation of BDA and check whether it matches ACB. This checks whether + // the points C and D are on opposite sides of the great circle through AB. + + // Recall that triageSign is invariant with respect to rotating its + // arguments, i.e. ABD has the same orientation as BDA. + bda := triageSign(e.a, e.b, d) + if e.acb == -bda && bda != Indeterminate { + // The most common case -- triangles have opposite orientations. Save the + // current vertex D as the next vertex C, and also save the orientation of + // the new triangle ACB (which is opposite to the current triangle BDA). + e.c = d + e.acb = -bda + return DoNotCross + } + return e.crossingSign(d, bda) +} + +// EdgeOrVertexChainCrossing is like EdgeOrVertexCrossing, but uses the last vertex +// passed to one of the crossing methods (or RestartAt) as the first vertex of the current edge. +func (e *EdgeCrosser) EdgeOrVertexChainCrossing(d Point) bool { + // We need to copy e.c since it is clobbered by ChainCrossingSign. + c := e.c + switch e.ChainCrossingSign(d) { + case DoNotCross: + return false + case Cross: + return true + } + return VertexCrossing(e.a, e.b, c, d) +} + +// crossingSign handle the slow path of CrossingSign. +func (e *EdgeCrosser) crossingSign(d Point, bda Direction) Crossing { + // Compute the actual result, and then save the current vertex D as the next + // vertex C, and save the orientation of the next triangle ACB (which is + // opposite to the current triangle BDA). + defer func() { + e.c = d + e.acb = -bda + }() + + // At this point, a very common situation is that A,B,C,D are four points on + // a line such that AB does not overlap CD. (For example, this happens when + // a line or curve is sampled finely, or when geometry is constructed by + // computing the union of S2CellIds.) Most of the time, we can determine + // that AB and CD do not intersect using the two outward-facing + // tangents at A and B (parallel to AB) and testing whether AB and CD are on + // opposite sides of the plane perpendicular to one of these tangents. This + // is moderately expensive but still much cheaper than expensiveSign. + + // The error in RobustCrossProd is insignificant. The maximum error in + // the call to CrossProd (i.e., the maximum norm of the error vector) is + // (0.5 + 1/sqrt(3)) * dblEpsilon. The maximum error in each call to + // DotProd below is dblEpsilon. (There is also a small relative error + // term that is insignificant because we are comparing the result against a + // constant that is very close to zero.) + maxError := (1.5 + 1/math.Sqrt(3)) * dblEpsilon + if (e.c.Dot(e.aTangent.Vector) > maxError && d.Dot(e.aTangent.Vector) > maxError) || (e.c.Dot(e.bTangent.Vector) > maxError && d.Dot(e.bTangent.Vector) > maxError) { + return DoNotCross + } + + // Otherwise, eliminate the cases where two vertices from different edges are + // equal. (These cases could be handled in the code below, but we would rather + // avoid calling ExpensiveSign if possible.) + if e.a == e.c || e.a == d || e.b == e.c || e.b == d { + return MaybeCross + } + + // Eliminate the cases where an input edge is degenerate. (Note that in + // most cases, if CD is degenerate then this method is not even called + // because acb and bda have different signs.) + if e.a == e.b || e.c == d { + return DoNotCross + } + + // Otherwise it's time to break out the big guns. + if e.acb == Indeterminate { + e.acb = -expensiveSign(e.a, e.b, e.c) + } + if bda == Indeterminate { + bda = expensiveSign(e.a, e.b, d) + } + + if bda != e.acb { + return DoNotCross + } + + cbd := -RobustSign(e.c, d, e.b) + if cbd != e.acb { + return DoNotCross + } + dac := RobustSign(e.c, d, e.a) + if dac != e.acb { + return DoNotCross + } + return Cross +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/edge_crossings.go b/backend/vendor/github.com/blevesearch/geo/s2/edge_crossings.go new file mode 100644 index 0000000000..a98ec76ff8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/edge_crossings.go @@ -0,0 +1,396 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "fmt" + "math" + + "github.com/golang/geo/r3" + "github.com/golang/geo/s1" +) + +const ( + // intersectionError can be set somewhat arbitrarily, because the algorithm + // uses more precision if necessary in order to achieve the specified error. + // The only strict requirement is that intersectionError >= dblEpsilon + // radians. However, using a larger error tolerance makes the algorithm more + // efficient because it reduces the number of cases where exact arithmetic is + // needed. + intersectionError = s1.Angle(8 * dblError) + + // intersectionMergeRadius is used to ensure that intersection points that + // are supposed to be coincident are merged back together into a single + // vertex. This is required in order for various polygon operations (union, + // intersection, etc) to work correctly. It is twice the intersection error + // because two coincident intersection points might have errors in + // opposite directions. + intersectionMergeRadius = 2 * intersectionError +) + +// A Crossing indicates how edges cross. +type Crossing int + +const ( + // Cross means the edges cross. + Cross Crossing = iota + // MaybeCross means two vertices from different edges are the same. + MaybeCross + // DoNotCross means the edges do not cross. + DoNotCross +) + +func (c Crossing) String() string { + switch c { + case Cross: + return "Cross" + case MaybeCross: + return "MaybeCross" + case DoNotCross: + return "DoNotCross" + default: + return fmt.Sprintf("(BAD CROSSING %d)", c) + } +} + +// CrossingSign reports whether the edge AB intersects the edge CD. +// If AB crosses CD at a point that is interior to both edges, Cross is returned. +// If any two vertices from different edges are the same it returns MaybeCross. +// Otherwise it returns DoNotCross. +// If either edge is degenerate (A == B or C == D), the return value is MaybeCross +// if two vertices from different edges are the same and DoNotCross otherwise. +// +// Properties of CrossingSign: +// +// (1) CrossingSign(b,a,c,d) == CrossingSign(a,b,c,d) +// (2) CrossingSign(c,d,a,b) == CrossingSign(a,b,c,d) +// (3) CrossingSign(a,b,c,d) == MaybeCross if a==c, a==d, b==c, b==d +// (3) CrossingSign(a,b,c,d) == DoNotCross or MaybeCross if a==b or c==d +// +// This method implements an exact, consistent perturbation model such +// that no three points are ever considered to be collinear. This means +// that even if you have 4 points A, B, C, D that lie exactly in a line +// (say, around the equator), C and D will be treated as being slightly to +// one side or the other of AB. This is done in a way such that the +// results are always consistent (see RobustSign). +func CrossingSign(a, b, c, d Point) Crossing { + crosser := NewChainEdgeCrosser(a, b, c) + return crosser.ChainCrossingSign(d) +} + +// VertexCrossing reports whether two edges "cross" in such a way that point-in-polygon +// containment tests can be implemented by counting the number of edge crossings. +// +// Given two edges AB and CD where at least two vertices are identical +// (i.e. CrossingSign(a,b,c,d) == 0), the basic rule is that a "crossing" +// occurs if AB is encountered after CD during a CCW sweep around the shared +// vertex starting from a fixed reference point. +// +// Note that according to this rule, if AB crosses CD then in general CD +// does not cross AB. However, this leads to the correct result when +// counting polygon edge crossings. For example, suppose that A,B,C are +// three consecutive vertices of a CCW polygon. If we now consider the edge +// crossings of a segment BP as P sweeps around B, the crossing number +// changes parity exactly when BP crosses BA or BC. +// +// Useful properties of VertexCrossing (VC): +// +// (1) VC(a,a,c,d) == VC(a,b,c,c) == false +// (2) VC(a,b,a,b) == VC(a,b,b,a) == true +// (3) VC(a,b,c,d) == VC(a,b,d,c) == VC(b,a,c,d) == VC(b,a,d,c) +// (3) If exactly one of a,b equals one of c,d, then exactly one of +// VC(a,b,c,d) and VC(c,d,a,b) is true +// +// It is an error to call this method with 4 distinct vertices. +func VertexCrossing(a, b, c, d Point) bool { + // If A == B or C == D there is no intersection. We need to check this + // case first in case 3 or more input points are identical. + if a == b || c == d { + return false + } + + // If any other pair of vertices is equal, there is a crossing if and only + // if OrderedCCW indicates that the edge AB is further CCW around the + // shared vertex O (either A or B) than the edge CD, starting from an + // arbitrary fixed reference point. + + // Optimization: if AB=CD or AB=DC, we can avoid most of the calculations. + switch { + case a == c: + return (b == d) || OrderedCCW(Point{a.Ortho()}, d, b, a) + case b == d: + return OrderedCCW(Point{b.Ortho()}, c, a, b) + case a == d: + return (b == c) || OrderedCCW(Point{a.Ortho()}, c, b, a) + case b == c: + return OrderedCCW(Point{b.Ortho()}, d, a, b) + } + + return false +} + +// EdgeOrVertexCrossing is a convenience function that calls CrossingSign to +// handle cases where all four vertices are distinct, and VertexCrossing to +// handle cases where two or more vertices are the same. This defines a crossing +// function such that point-in-polygon containment tests can be implemented +// by simply counting edge crossings. +func EdgeOrVertexCrossing(a, b, c, d Point) bool { + switch CrossingSign(a, b, c, d) { + case DoNotCross: + return false + case Cross: + return true + default: + return VertexCrossing(a, b, c, d) + } +} + +// Intersection returns the intersection point of two edges AB and CD that cross +// (CrossingSign(a,b,c,d) == Crossing). +// +// Useful properties of Intersection: +// +// (1) Intersection(b,a,c,d) == Intersection(a,b,d,c) == Intersection(a,b,c,d) +// (2) Intersection(c,d,a,b) == Intersection(a,b,c,d) +// +// The returned intersection point X is guaranteed to be very close to the +// true intersection point of AB and CD, even if the edges intersect at a +// very small angle. +func Intersection(a0, a1, b0, b1 Point) Point { + // It is difficult to compute the intersection point of two edges accurately + // when the angle between the edges is very small. Previously we handled + // this by only guaranteeing that the returned intersection point is within + // intersectionError of each edge. However, this means that when the edges + // cross at a very small angle, the computed result may be very far from the + // true intersection point. + // + // Instead this function now guarantees that the result is always within + // intersectionError of the true intersection. This requires using more + // sophisticated techniques and in some cases extended precision. + // + // - intersectionStable computes the intersection point using + // projection and interpolation, taking care to minimize cancellation + // error. + // + // - intersectionExact computes the intersection point using precision + // arithmetic and converts the final result back to an Point. + pt, ok := intersectionStable(a0, a1, b0, b1) + if !ok { + pt = intersectionExact(a0, a1, b0, b1) + } + + // Make sure the intersection point is on the correct side of the sphere. + // Since all vertices are unit length, and edges are less than 180 degrees, + // (a0 + a1) and (b0 + b1) both have positive dot product with the + // intersection point. We use the sum of all vertices to make sure that the + // result is unchanged when the edges are swapped or reversed. + if pt.Dot((a0.Add(a1.Vector)).Add(b0.Add(b1.Vector))) < 0 { + pt = Point{pt.Mul(-1)} + } + + return pt +} + +// Computes the cross product of two vectors, normalized to be unit length. +// Also returns the length of the cross +// product before normalization, which is useful for estimating the amount of +// error in the result. For numerical stability, the vectors should both be +// approximately unit length. +func robustNormalWithLength(x, y r3.Vector) (r3.Vector, float64) { + var pt r3.Vector + // This computes 2 * (x.Cross(y)), but has much better numerical + // stability when x and y are unit length. + tmp := x.Sub(y).Cross(x.Add(y)) + length := tmp.Norm() + if length != 0 { + pt = tmp.Mul(1 / length) + } + return pt, 0.5 * length // Since tmp == 2 * (x.Cross(y)) +} + +/* +// intersectionSimple is not used by the C++ so it is skipped here. +*/ + +// projection returns the projection of aNorm onto X (x.Dot(aNorm)), and a bound +// on the error in the result. aNorm is not necessarily unit length. +// +// The remaining parameters (the length of aNorm (aNormLen) and the edge endpoints +// a0 and a1) allow this dot product to be computed more accurately and efficiently. +func projection(x, aNorm r3.Vector, aNormLen float64, a0, a1 Point) (proj, bound float64) { + // The error in the dot product is proportional to the lengths of the input + // vectors, so rather than using x itself (a unit-length vector) we use + // the vectors from x to the closer of the two edge endpoints. This + // typically reduces the error by a huge factor. + x0 := x.Sub(a0.Vector) + x1 := x.Sub(a1.Vector) + x0Dist2 := x0.Norm2() + x1Dist2 := x1.Norm2() + + // If both distances are the same, we need to be careful to choose one + // endpoint deterministically so that the result does not change if the + // order of the endpoints is reversed. + var dist float64 + if x0Dist2 < x1Dist2 || (x0Dist2 == x1Dist2 && x0.Cmp(x1) == -1) { + dist = math.Sqrt(x0Dist2) + proj = x0.Dot(aNorm) + } else { + dist = math.Sqrt(x1Dist2) + proj = x1.Dot(aNorm) + } + + // This calculation bounds the error from all sources: the computation of + // the normal, the subtraction of one endpoint, and the dot product itself. + // dblError appears because the input points are assumed to be + // normalized in double precision. + // + // For reference, the bounds that went into this calculation are: + // ||N'-N|| <= ((1 + 2 * sqrt(3))||N|| + 32 * sqrt(3) * dblError) * epsilon + // |(A.B)'-(A.B)| <= (1.5 * (A.B) + 1.5 * ||A|| * ||B||) * epsilon + // ||(X-Y)'-(X-Y)|| <= ||X-Y|| * epsilon + bound = (((3.5+2*math.Sqrt(3))*aNormLen+32*math.Sqrt(3)*dblError)*dist + 1.5*math.Abs(proj)) * epsilon + return proj, bound +} + +// compareEdges reports whether (a0,a1) is less than (b0,b1) with respect to a total +// ordering on edges that is invariant under edge reversals. +func compareEdges(a0, a1, b0, b1 Point) bool { + if a0.Cmp(a1.Vector) != -1 { + a0, a1 = a1, a0 + } + if b0.Cmp(b1.Vector) != -1 { + b0, b1 = b1, b0 + } + return a0.Cmp(b0.Vector) == -1 || (a0 == b0 && b0.Cmp(b1.Vector) == -1) +} + +// intersectionStable returns the intersection point of the edges (a0,a1) and +// (b0,b1) if it can be computed to within an error of at most intersectionError +// by this function. +// +// The intersection point is not guaranteed to have the correct sign because we +// choose to use the longest of the two edges first. The sign is corrected by +// Intersection. +func intersectionStable(a0, a1, b0, b1 Point) (Point, bool) { + // Sort the two edges so that (a0,a1) is longer, breaking ties in a + // deterministic way that does not depend on the ordering of the endpoints. + // This is desirable for two reasons: + // - So that the result doesn't change when edges are swapped or reversed. + // - It reduces error, since the first edge is used to compute the edge + // normal (where a longer edge means less error), and the second edge + // is used for interpolation (where a shorter edge means less error). + aLen2 := a1.Sub(a0.Vector).Norm2() + bLen2 := b1.Sub(b0.Vector).Norm2() + if aLen2 < bLen2 || (aLen2 == bLen2 && compareEdges(a0, a1, b0, b1)) { + return intersectionStableSorted(b0, b1, a0, a1) + } + return intersectionStableSorted(a0, a1, b0, b1) +} + +// intersectionStableSorted is a helper function for intersectionStable. +// It expects that the edges (a0,a1) and (b0,b1) have been sorted so that +// the first edge passed in is longer. +func intersectionStableSorted(a0, a1, b0, b1 Point) (Point, bool) { + var pt Point + + // Compute the normal of the plane through (a0, a1) in a stable way. + aNorm := a0.Sub(a1.Vector).Cross(a0.Add(a1.Vector)) + aNormLen := aNorm.Norm() + bLen := b1.Sub(b0.Vector).Norm() + + // Compute the projection (i.e., signed distance) of b0 and b1 onto the + // plane through (a0, a1). Distances are scaled by the length of aNorm. + b0Dist, b0Error := projection(b0.Vector, aNorm, aNormLen, a0, a1) + b1Dist, b1Error := projection(b1.Vector, aNorm, aNormLen, a0, a1) + + // The total distance from b0 to b1 measured perpendicularly to (a0,a1) is + // |b0Dist - b1Dist|. Note that b0Dist and b1Dist generally have + // opposite signs because b0 and b1 are on opposite sides of (a0, a1). The + // code below finds the intersection point by interpolating along the edge + // (b0, b1) to a fractional distance of b0Dist / (b0Dist - b1Dist). + // + // It can be shown that the maximum error in the interpolation fraction is + // + // (b0Dist * b1Error - b1Dist * b0Error) / (distSum * (distSum - errorSum)) + // + // We save ourselves some work by scaling the result and the error bound by + // "distSum", since the result is normalized to be unit length anyway. + distSum := math.Abs(b0Dist - b1Dist) + errorSum := b0Error + b1Error + if distSum <= errorSum { + return pt, false // Error is unbounded in this case. + } + + x := b1.Mul(b0Dist).Sub(b0.Mul(b1Dist)) + err := bLen*math.Abs(b0Dist*b1Error-b1Dist*b0Error)/ + (distSum-errorSum) + 2*distSum*epsilon + + // Finally we normalize the result, compute the corresponding error, and + // check whether the total error is acceptable. + xLen := x.Norm() + maxError := intersectionError + if err > (float64(maxError)-epsilon)*xLen { + return pt, false + } + + return Point{x.Mul(1 / xLen)}, true +} + +// intersectionExact returns the intersection point of (a0, a1) and (b0, b1) +// using precise arithmetic. Note that the result is not exact because it is +// rounded down to double precision at the end. Also, the intersection point +// is not guaranteed to have the correct sign (i.e., the return value may need +// to be negated). +func intersectionExact(a0, a1, b0, b1 Point) Point { + // Since we are using presice arithmetic, we don't need to worry about + // numerical stability. + a0P := r3.PreciseVectorFromVector(a0.Vector) + a1P := r3.PreciseVectorFromVector(a1.Vector) + b0P := r3.PreciseVectorFromVector(b0.Vector) + b1P := r3.PreciseVectorFromVector(b1.Vector) + aNormP := a0P.Cross(a1P) + bNormP := b0P.Cross(b1P) + xP := aNormP.Cross(bNormP) + + // The final Normalize() call is done in double precision, which creates a + // directional error of up to 2*dblError. (Precise conversion and Normalize() + // each contribute up to dblError of directional error.) + x := xP.Vector() + + if x == (r3.Vector{}) { + // The two edges are exactly collinear, but we still consider them to be + // "crossing" because of simulation of simplicity. Out of the four + // endpoints, exactly two lie in the interior of the other edge. Of + // those two we return the one that is lexicographically smallest. + x = r3.Vector{10, 10, 10} // Greater than any valid S2Point + + aNorm := Point{aNormP.Vector()} + bNorm := Point{bNormP.Vector()} + if OrderedCCW(b0, a0, b1, bNorm) && a0.Cmp(x) == -1 { + return a0 + } + if OrderedCCW(b0, a1, b1, bNorm) && a1.Cmp(x) == -1 { + return a1 + } + if OrderedCCW(a0, b0, a1, aNorm) && b0.Cmp(x) == -1 { + return b0 + } + if OrderedCCW(a0, b1, a1, aNorm) && b1.Cmp(x) == -1 { + return b1 + } + } + + return Point{x} +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/edge_distances.go b/backend/vendor/github.com/blevesearch/geo/s2/edge_distances.go new file mode 100644 index 0000000000..ca197af1da --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/edge_distances.go @@ -0,0 +1,408 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +// This file defines a collection of methods for computing the distance to an edge, +// interpolating along an edge, projecting points onto edges, etc. + +import ( + "math" + + "github.com/golang/geo/s1" +) + +// DistanceFromSegment returns the distance of point X from line segment AB. +// The points are expected to be normalized. The result is very accurate for small +// distances but may have some numerical error if the distance is large +// (approximately pi/2 or greater). The case A == B is handled correctly. +func DistanceFromSegment(x, a, b Point) s1.Angle { + var minDist s1.ChordAngle + minDist, _ = updateMinDistance(x, a, b, minDist, true) + return minDist.Angle() +} + +// IsDistanceLess reports whether the distance from X to the edge AB is less +// than limit. (For less than or equal to, specify limit.Successor()). +// This method is faster than DistanceFromSegment(). If you want to +// compare against a fixed s1.Angle, you should convert it to an s1.ChordAngle +// once and save the value, since this conversion is relatively expensive. +func IsDistanceLess(x, a, b Point, limit s1.ChordAngle) bool { + _, less := UpdateMinDistance(x, a, b, limit) + return less +} + +// UpdateMinDistance checks if the distance from X to the edge AB is less +// than minDist, and if so, returns the updated value and true. +// The case A == B is handled correctly. +// +// Use this method when you want to compute many distances and keep track of +// the minimum. It is significantly faster than using DistanceFromSegment +// because (1) using s1.ChordAngle is much faster than s1.Angle, and (2) it +// can save a lot of work by not actually computing the distance when it is +// obviously larger than the current minimum. +func UpdateMinDistance(x, a, b Point, minDist s1.ChordAngle) (s1.ChordAngle, bool) { + return updateMinDistance(x, a, b, minDist, false) +} + +// UpdateMaxDistance checks if the distance from X to the edge AB is greater +// than maxDist, and if so, returns the updated value and true. +// Otherwise it returns false. The case A == B is handled correctly. +func UpdateMaxDistance(x, a, b Point, maxDist s1.ChordAngle) (s1.ChordAngle, bool) { + dist := maxChordAngle(ChordAngleBetweenPoints(x, a), ChordAngleBetweenPoints(x, b)) + if dist > s1.RightChordAngle { + dist, _ = updateMinDistance(Point{x.Mul(-1)}, a, b, dist, true) + dist = s1.StraightChordAngle - dist + } + if maxDist < dist { + return dist, true + } + + return maxDist, false +} + +// IsInteriorDistanceLess reports whether the minimum distance from X to the edge +// AB is attained at an interior point of AB (i.e., not an endpoint), and that +// distance is less than limit. (Specify limit.Successor() for less than or equal to). +func IsInteriorDistanceLess(x, a, b Point, limit s1.ChordAngle) bool { + _, less := UpdateMinInteriorDistance(x, a, b, limit) + return less +} + +// UpdateMinInteriorDistance reports whether the minimum distance from X to AB +// is attained at an interior point of AB (i.e., not an endpoint), and that distance +// is less than minDist. If so, the value of minDist is updated and true is returned. +// Otherwise it is unchanged and returns false. +func UpdateMinInteriorDistance(x, a, b Point, minDist s1.ChordAngle) (s1.ChordAngle, bool) { + return interiorDist(x, a, b, minDist, false) +} + +// Project returns the point along the edge AB that is closest to the point X. +// The fractional distance of this point along the edge AB can be obtained +// using DistanceFraction. +// +// This requires that all points are unit length. +func Project(x, a, b Point) Point { + aXb := a.PointCross(b) + // Find the closest point to X along the great circle through AB. + p := x.Sub(aXb.Mul(x.Dot(aXb.Vector) / aXb.Vector.Norm2())) + + // If this point is on the edge AB, then it's the closest point. + if Sign(aXb, a, Point{p}) && Sign(Point{p}, b, aXb) { + return Point{p.Normalize()} + } + + // Otherwise, the closest point is either A or B. + if x.Sub(a.Vector).Norm2() <= x.Sub(b.Vector).Norm2() { + return a + } + return b +} + +// DistanceFraction returns the distance ratio of the point X along an edge AB. +// If X is on the line segment AB, this is the fraction T such +// that X == Interpolate(T, A, B). +// +// This requires that A and B are distinct. +func DistanceFraction(x, a, b Point) float64 { + d0 := x.Angle(a.Vector) + d1 := x.Angle(b.Vector) + return float64(d0 / (d0 + d1)) +} + +// Interpolate returns the point X along the line segment AB whose distance from A +// is the given fraction "t" of the distance AB. Does NOT require that "t" be +// between 0 and 1. Note that all distances are measured on the surface of +// the sphere, so this is more complicated than just computing (1-t)*a + t*b +// and normalizing the result. +func Interpolate(t float64, a, b Point) Point { + if t == 0 { + return a + } + if t == 1 { + return b + } + ab := a.Angle(b.Vector) + return InterpolateAtDistance(s1.Angle(t)*ab, a, b) +} + +// InterpolateAtDistance returns the point X along the line segment AB whose +// distance from A is the angle ax. +func InterpolateAtDistance(ax s1.Angle, a, b Point) Point { + aRad := ax.Radians() + + // Use PointCross to compute the tangent vector at A towards B. The + // result is always perpendicular to A, even if A=B or A=-B, but it is not + // necessarily unit length. (We effectively normalize it below.) + normal := a.PointCross(b) + tangent := normal.Vector.Cross(a.Vector) + + // Now compute the appropriate linear combination of A and "tangent". With + // infinite precision the result would always be unit length, but we + // normalize it anyway to ensure that the error is within acceptable bounds. + // (Otherwise errors can build up when the result of one interpolation is + // fed into another interpolation.) + return Point{(a.Mul(math.Cos(aRad)).Add(tangent.Mul(math.Sin(aRad) / tangent.Norm()))).Normalize()} +} + +// minUpdateDistanceMaxError returns the maximum error in the result of +// UpdateMinDistance (and the associated functions such as +// UpdateMinInteriorDistance, IsDistanceLess, etc), assuming that all +// input points are normalized to within the bounds guaranteed by r3.Vector's +// Normalize. The error can be added or subtracted from an s1.ChordAngle +// using its Expanded method. +func minUpdateDistanceMaxError(dist s1.ChordAngle) float64 { + // There are two cases for the maximum error in UpdateMinDistance(), + // depending on whether the closest point is interior to the edge. + return math.Max(minUpdateInteriorDistanceMaxError(dist), dist.MaxPointError()) +} + +// minUpdateInteriorDistanceMaxError returns the maximum error in the result of +// UpdateMinInteriorDistance, assuming that all input points are normalized +// to within the bounds guaranteed by Point's Normalize. The error can be added +// or subtracted from an s1.ChordAngle using its Expanded method. +// +// Note that accuracy goes down as the distance approaches 0 degrees or 180 +// degrees (for different reasons). Near 0 degrees the error is acceptable +// for all practical purposes (about 1.2e-15 radians ~= 8 nanometers). For +// exactly antipodal points the maximum error is quite high (0.5 meters), +// but this error drops rapidly as the points move away from antipodality +// (approximately 1 millimeter for points that are 50 meters from antipodal, +// and 1 micrometer for points that are 50km from antipodal). +// +// TODO(roberts): Currently the error bound does not hold for edges whose endpoints +// are antipodal to within about 1e-15 radians (less than 1 micron). This could +// be fixed by extending PointCross to use higher precision when necessary. +func minUpdateInteriorDistanceMaxError(dist s1.ChordAngle) float64 { + // If a point is more than 90 degrees from an edge, then the minimum + // distance is always to one of the endpoints, not to the edge interior. + if dist >= s1.RightChordAngle { + return 0.0 + } + + // This bound includes all source of error, assuming that the input points + // are normalized. a and b are components of chord length that are + // perpendicular and parallel to a plane containing the edge respectively. + b := math.Min(1.0, 0.5*float64(dist)) + a := math.Sqrt(b * (2 - b)) + return ((2.5+2*math.Sqrt(3)+8.5*a)*a + + (2+2*math.Sqrt(3)/3+6.5*(1-b))*b + + (23+16/math.Sqrt(3))*dblEpsilon) * dblEpsilon +} + +// updateMinDistance computes the distance from a point X to a line segment AB, +// and if either the distance was less than the given minDist, or alwaysUpdate is +// true, the value and whether it was updated are returned. +func updateMinDistance(x, a, b Point, minDist s1.ChordAngle, alwaysUpdate bool) (s1.ChordAngle, bool) { + if d, ok := interiorDist(x, a, b, minDist, alwaysUpdate); ok { + // Minimum distance is attained along the edge interior. + return d, true + } + + // Otherwise the minimum distance is to one of the endpoints. + xa2, xb2 := (x.Sub(a.Vector)).Norm2(), x.Sub(b.Vector).Norm2() + dist := s1.ChordAngle(math.Min(xa2, xb2)) + if !alwaysUpdate && dist >= minDist { + return minDist, false + } + return dist, true +} + +// interiorDist returns the shortest distance from point x to edge ab, assuming +// that the closest point to X is interior to AB. If the closest point is not +// interior to AB, interiorDist returns (minDist, false). If alwaysUpdate is set to +// false, the distance is only updated when the value exceeds certain the given minDist. +func interiorDist(x, a, b Point, minDist s1.ChordAngle, alwaysUpdate bool) (s1.ChordAngle, bool) { + // Chord distance of x to both end points a and b. + xa2, xb2 := (x.Sub(a.Vector)).Norm2(), x.Sub(b.Vector).Norm2() + + // The closest point on AB could either be one of the two vertices (the + // vertex case) or in the interior (the interior case). Let C = A x B. + // If X is in the spherical wedge extending from A to B around the axis + // through C, then we are in the interior case. Otherwise we are in the + // vertex case. + // + // Check whether we might be in the interior case. For this to be true, XAB + // and XBA must both be acute angles. Checking this condition exactly is + // expensive, so instead we consider the planar triangle ABX (which passes + // through the sphere's interior). The planar angles XAB and XBA are always + // less than the corresponding spherical angles, so if we are in the + // interior case then both of these angles must be acute. + // + // We check this by computing the squared edge lengths of the planar + // triangle ABX, and testing whether angles XAB and XBA are both acute using + // the law of cosines: + // + // | XA^2 - XB^2 | < AB^2 (*) + // + // This test must be done conservatively (taking numerical errors into + // account) since otherwise we might miss a situation where the true minimum + // distance is achieved by a point on the edge interior. + // + // There are two sources of error in the expression above (*). The first is + // that points are not normalized exactly; they are only guaranteed to be + // within 2 * dblEpsilon of unit length. Under the assumption that the two + // sides of (*) are nearly equal, the total error due to normalization errors + // can be shown to be at most + // + // 2 * dblEpsilon * (XA^2 + XB^2 + AB^2) + 8 * dblEpsilon ^ 2 . + // + // The other source of error is rounding of results in the calculation of (*). + // Each of XA^2, XB^2, AB^2 has a maximum relative error of 2.5 * dblEpsilon, + // plus an additional relative error of 0.5 * dblEpsilon in the final + // subtraction which we further bound as 0.25 * dblEpsilon * (XA^2 + XB^2 + + // AB^2) for convenience. This yields a final error bound of + // + // 4.75 * dblEpsilon * (XA^2 + XB^2 + AB^2) + 8 * dblEpsilon ^ 2 . + ab2 := a.Sub(b.Vector).Norm2() + maxError := (4.75*dblEpsilon*(xa2+xb2+ab2) + 8*dblEpsilon*dblEpsilon) + if math.Abs(xa2-xb2) >= ab2+maxError { + return minDist, false + } + + // The minimum distance might be to a point on the edge interior. Let R + // be closest point to X that lies on the great circle through AB. Rather + // than computing the geodesic distance along the surface of the sphere, + // instead we compute the "chord length" through the sphere's interior. + // + // The squared chord length XR^2 can be expressed as XQ^2 + QR^2, where Q + // is the point X projected onto the plane through the great circle AB. + // The distance XQ^2 can be written as (X.C)^2 / |C|^2 where C = A x B. + // We ignore the QR^2 term and instead use XQ^2 as a lower bound, since it + // is faster and the corresponding distance on the Earth's surface is + // accurate to within 1% for distances up to about 1800km. + c := a.PointCross(b) + c2 := c.Norm2() + xDotC := x.Dot(c.Vector) + xDotC2 := xDotC * xDotC + if !alwaysUpdate && xDotC2 > c2*float64(minDist) { + // The closest point on the great circle AB is too far away. We need to + // test this using ">" rather than ">=" because the actual minimum bound + // on the distance is (xDotC2 / c2), which can be rounded differently + // than the (more efficient) multiplicative test above. + return minDist, false + } + + // Otherwise we do the exact, more expensive test for the interior case. + // This test is very likely to succeed because of the conservative planar + // test we did initially. + // + // TODO(roberts): Ensure that the errors in test are accurately reflected in the + // minUpdateInteriorDistanceMaxError. + cx := c.Cross(x.Vector) + if a.Sub(x.Vector).Dot(cx) >= 0 || b.Sub(x.Vector).Dot(cx) <= 0 { + return minDist, false + } + + // Compute the squared chord length XR^2 = XQ^2 + QR^2 (see above). + // This calculation has good accuracy for all chord lengths since it + // is based on both the dot product and cross product (rather than + // deriving one from the other). However, note that the chord length + // representation itself loses accuracy as the angle approaches π. + qr := 1 - math.Sqrt(cx.Norm2()/c2) + dist := s1.ChordAngle((xDotC2 / c2) + (qr * qr)) + + if !alwaysUpdate && dist >= minDist { + return minDist, false + } + + return dist, true +} + +// updateEdgePairMinDistance computes the minimum distance between the given +// pair of edges. If the two edges cross, the distance is zero. The cases +// a0 == a1 and b0 == b1 are handled correctly. +func updateEdgePairMinDistance(a0, a1, b0, b1 Point, minDist s1.ChordAngle) (s1.ChordAngle, bool) { + if minDist == 0 { + return 0, false + } + if CrossingSign(a0, a1, b0, b1) == Cross { + minDist = 0 + return 0, true + } + + // Otherwise, the minimum distance is achieved at an endpoint of at least + // one of the two edges. We ensure that all four possibilities are always checked. + // + // The calculation below computes each of the six vertex-vertex distances + // twice (this could be optimized). + var ok1, ok2, ok3, ok4 bool + minDist, ok1 = UpdateMinDistance(a0, b0, b1, minDist) + minDist, ok2 = UpdateMinDistance(a1, b0, b1, minDist) + minDist, ok3 = UpdateMinDistance(b0, a0, a1, minDist) + minDist, ok4 = UpdateMinDistance(b1, a0, a1, minDist) + return minDist, ok1 || ok2 || ok3 || ok4 +} + +// updateEdgePairMaxDistance reports the minimum distance between the given pair of edges. +// If one edge crosses the antipodal reflection of the other, the distance is pi. +func updateEdgePairMaxDistance(a0, a1, b0, b1 Point, maxDist s1.ChordAngle) (s1.ChordAngle, bool) { + if maxDist == s1.StraightChordAngle { + return s1.StraightChordAngle, false + } + if CrossingSign(a0, a1, Point{b0.Mul(-1)}, Point{b1.Mul(-1)}) == Cross { + return s1.StraightChordAngle, true + } + + // Otherwise, the maximum distance is achieved at an endpoint of at least + // one of the two edges. We ensure that all four possibilities are always checked. + // + // The calculation below computes each of the six vertex-vertex distances + // twice (this could be optimized). + var ok1, ok2, ok3, ok4 bool + maxDist, ok1 = UpdateMaxDistance(a0, b0, b1, maxDist) + maxDist, ok2 = UpdateMaxDistance(a1, b0, b1, maxDist) + maxDist, ok3 = UpdateMaxDistance(b0, a0, a1, maxDist) + maxDist, ok4 = UpdateMaxDistance(b1, a0, a1, maxDist) + return maxDist, ok1 || ok2 || ok3 || ok4 +} + +// EdgePairClosestPoints returns the pair of points (a, b) that achieves the +// minimum distance between edges a0a1 and b0b1, where a is a point on a0a1 and +// b is a point on b0b1. If the two edges intersect, a and b are both equal to +// the intersection point. Handles a0 == a1 and b0 == b1 correctly. +func EdgePairClosestPoints(a0, a1, b0, b1 Point) (Point, Point) { + if CrossingSign(a0, a1, b0, b1) == Cross { + x := Intersection(a0, a1, b0, b1) + return x, x + } + // We save some work by first determining which vertex/edge pair achieves + // the minimum distance, and then computing the closest point on that edge. + var minDist s1.ChordAngle + var ok bool + + minDist, ok = updateMinDistance(a0, b0, b1, minDist, true) + closestVertex := 0 + if minDist, ok = UpdateMinDistance(a1, b0, b1, minDist); ok { + closestVertex = 1 + } + if minDist, ok = UpdateMinDistance(b0, a0, a1, minDist); ok { + closestVertex = 2 + } + if minDist, ok = UpdateMinDistance(b1, a0, a1, minDist); ok { + closestVertex = 3 + } + switch closestVertex { + case 0: + return a0, Project(a0, b0, b1) + case 1: + return a1, Project(a1, b0, b1) + case 2: + return Project(b0, a0, a1), b0 + case 3: + return Project(b1, a0, a1), b1 + default: + panic("illegal case reached") + } +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/edge_query.go b/backend/vendor/github.com/blevesearch/geo/s2/edge_query.go new file mode 100644 index 0000000000..6c86962b77 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/edge_query.go @@ -0,0 +1,816 @@ +// Copyright 2019 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "sort" + + "github.com/golang/geo/s1" +) + +// EdgeQueryOptions holds the options for controlling how EdgeQuery operates. +// +// Options can be chained together builder-style: +// +// opts = NewClosestEdgeQueryOptions(). +// MaxResults(1). +// DistanceLimit(s1.ChordAngleFromAngle(3 * s1.Degree)). +// MaxError(s1.ChordAngleFromAngle(0.001 * s1.Degree)) +// query = NewClosestEdgeQuery(index, opts) +// +// or set individually: +// +// opts = NewClosestEdgeQueryOptions() +// opts.IncludeInteriors(true) +// +// or just inline: +// +// query = NewClosestEdgeQuery(index, NewClosestEdgeQueryOptions().MaxResults(3)) +// +// If you pass a nil as the options you get the default values for the options. +type EdgeQueryOptions struct { + common *queryOptions +} + +// DistanceLimit specifies that only edges whose distance to the target is +// within, this distance should be returned. Edges whose distance is equal +// are not returned. To include values that are equal, specify the limit with +// the next largest representable distance. i.e. limit.Successor(). +func (e *EdgeQueryOptions) DistanceLimit(limit s1.ChordAngle) *EdgeQueryOptions { + e.common = e.common.DistanceLimit(limit) + return e +} + +// IncludeInteriors specifies whether polygon interiors should be +// included when measuring distances. +func (e *EdgeQueryOptions) IncludeInteriors(x bool) *EdgeQueryOptions { + e.common = e.common.IncludeInteriors(x) + return e +} + +// UseBruteForce sets or disables the use of brute force in a query. +func (e *EdgeQueryOptions) UseBruteForce(x bool) *EdgeQueryOptions { + e.common = e.common.UseBruteForce(x) + return e +} + +// MaxError specifies that edges up to dist away than the true +// matching edges may be substituted in the result set, as long as such +// edges satisfy all the remaining search criteria (such as DistanceLimit). +// This option only has an effect if MaxResults is also specified; +// otherwise all edges closer than MaxDistance will always be returned. +func (e *EdgeQueryOptions) MaxError(dist s1.ChordAngle) *EdgeQueryOptions { + e.common = e.common.MaxError(dist) + return e +} + +// MaxResults specifies that at most MaxResults edges should be returned. +// This must be at least 1. +func (e *EdgeQueryOptions) MaxResults(n int) *EdgeQueryOptions { + e.common = e.common.MaxResults(n) + return e +} + +// NewClosestEdgeQueryOptions returns a set of edge query options suitable +// for performing closest edge queries. +func NewClosestEdgeQueryOptions() *EdgeQueryOptions { + return &EdgeQueryOptions{ + common: newQueryOptions(minDistance(0)), + } +} + +// NewFurthestEdgeQueryOptions returns a set of edge query options suitable +// for performing furthest edge queries. +func NewFurthestEdgeQueryOptions() *EdgeQueryOptions { + return &EdgeQueryOptions{ + common: newQueryOptions(maxDistance(0)), + } +} + +// EdgeQueryResult represents an edge that meets the target criteria for the +// query. Note the following special cases: +// +// - ShapeID >= 0 && EdgeID < 0 represents the interior of a shape. +// Such results may be returned when the option IncludeInteriors is true. +// +// - ShapeID < 0 && EdgeID < 0 is returned to indicate that no edge +// satisfies the requested query options. +type EdgeQueryResult struct { + distance distance + shapeID int32 + edgeID int32 +} + +// Distance reports the distance between the edge in this shape that satisfied +// the query's parameters. +func (e EdgeQueryResult) Distance() s1.ChordAngle { return e.distance.chordAngle() } + +// ShapeID reports the ID of the Shape this result is for. +func (e EdgeQueryResult) ShapeID() int32 { return e.shapeID } + +// EdgeID reports the ID of the edge in the results Shape. +func (e EdgeQueryResult) EdgeID() int32 { return e.edgeID } + +// newEdgeQueryResult returns a result instance with default values. +func newEdgeQueryResult(target distanceTarget) EdgeQueryResult { + return EdgeQueryResult{ + distance: target.distance().infinity(), + shapeID: -1, + edgeID: -1, + } +} + +// IsInterior reports if this result represents the interior of a Shape. +func (e EdgeQueryResult) IsInterior() bool { + return e.shapeID >= 0 && e.edgeID < 0 +} + +// IsEmpty reports if this has no edge that satisfies the given edge query options. +// This result is only returned in one special case, namely when FindEdge() does +// not find any suitable edges. +func (e EdgeQueryResult) IsEmpty() bool { + return e.shapeID < 0 +} + +// Less reports if this results is less that the other first by distance, +// then by (shapeID, edgeID). This is used for sorting. +func (e EdgeQueryResult) Less(other EdgeQueryResult) bool { + if e.distance.chordAngle() != other.distance.chordAngle() { + return e.distance.less(other.distance) + } + if e.shapeID != other.shapeID { + return e.shapeID < other.shapeID + } + return e.edgeID < other.edgeID +} + +// EdgeQuery is used to find the edge(s) between two geometries that match a +// given set of options. It is flexible enough so that it can be adapted to +// compute maximum distances and even potentially Hausdorff distances. +// +// By using the appropriate options, this type can answer questions such as: +// +// - Find the minimum distance between two geometries A and B. +// - Find all edges of geometry A that are within a distance D of geometry B. +// - Find the k edges of geometry A that are closest to a given point P. +// +// You can also specify whether polygons should include their interiors (i.e., +// if a point is contained by a polygon, should the distance be zero or should +// it be measured to the polygon boundary?) +// +// The input geometries may consist of any number of points, polylines, and +// polygons (collectively referred to as "shapes"). Shapes do not need to be +// disjoint; they may overlap or intersect arbitrarily. The implementation is +// designed to be fast for both simple and complex geometries. +type EdgeQuery struct { + index *ShapeIndex + opts *queryOptions + target distanceTarget + + // True if opts.maxError must be subtracted from ShapeIndex cell distances + // in order to ensure that such distances are measured conservatively. This + // is true only if the target takes advantage of maxError in order to + // return faster results, and 0 < maxError < distanceLimit. + useConservativeCellDistance bool + + // The decision about whether to use the brute force algorithm is based on + // counting the total number of edges in the index. However if the index + // contains a large number of shapes, this in itself might take too long. + // So instead we only count edges up to (maxBruteForceIndexSize() + 1) + // for the current target type (stored as indexNumEdgesLimit). + indexNumEdges int + indexNumEdgesLimit int + + // The distance beyond which we can safely ignore further candidate edges. + // (Candidates that are exactly at the limit are ignored; this is more + // efficient for UpdateMinDistance and should not affect clients since + // distance measurements have a small amount of error anyway.) + // + // Initially this is the same as the maximum distance specified by the user, + // but it can also be updated by the algorithm (see maybeAddResult). + distanceLimit distance + + // The current set of results of the query. + results []EdgeQueryResult + + // This field is true when duplicates must be avoided explicitly. This + // is achieved by maintaining a separate set keyed by (shapeID, edgeID) + // only, and checking whether each edge is in that set before computing the + // distance to it. + avoidDuplicates bool + + // testedEdges tracks the set of shape and edges that have already been tested. + testedEdges map[ShapeEdgeID]uint32 + + // For the optimized algorihm we precompute the top-level CellIDs that + // will be added to the priority queue. There can be at most 6 of these + // cells. Essentially this is just a covering of the indexed edges, except + // that we also store pointers to the corresponding ShapeIndexCells to + // reduce the number of index seeks required. + indexCovering []CellID + indexCells []*ShapeIndexCell + + // The algorithm maintains a priority queue of unprocessed CellIDs, sorted + // in increasing order of distance from the target. + queue *queryQueue + + iter *ShapeIndexIterator + maxDistanceCovering []CellID + initialCells []CellID +} + +// NewClosestEdgeQuery returns an EdgeQuery that is used for finding the +// closest edge(s) to a given Point, Edge, Cell, or geometry collection. +// +// You can find either the k closest edges, or all edges within a given +// radius, or both (i.e., the k closest edges up to a given maximum radius). +// E.g. to find all the edges within 5 kilometers, set the DistanceLimit in +// the options. +// +// By default *all* edges are returned, so you should always specify either +// MaxResults or DistanceLimit options or both. +// +// Note that by default, distances are measured to the boundary and interior +// of polygons. For example, if a point is inside a polygon then its distance +// is zero. To change this behavior, set the IncludeInteriors option to false. +// +// If you only need to test whether the distance is above or below a given +// threshold (e.g., 10 km), you can use the IsDistanceLess() method. This is +// much faster than actually calculating the distance with FindEdge, +// since the implementation can stop as soon as it can prove that the minimum +// distance is either above or below the threshold. +func NewClosestEdgeQuery(index *ShapeIndex, opts *EdgeQueryOptions) *EdgeQuery { + if opts == nil { + opts = NewClosestEdgeQueryOptions() + } + e := &EdgeQuery{ + testedEdges: make(map[ShapeEdgeID]uint32), + index: index, + opts: opts.common, + queue: newQueryQueue(), + } + + return e +} + +// NewFurthestEdgeQuery returns an EdgeQuery that is used for finding the +// furthest edge(s) to a given Point, Edge, Cell, or geometry collection. +// +// The furthest edge is defined as the one which maximizes the +// distance from any point on that edge to any point on the target geometry. +// +// Similar to the example in NewClosestEdgeQuery, to find the 5 furthest edges +// from a given Point: +func NewFurthestEdgeQuery(index *ShapeIndex, opts *EdgeQueryOptions) *EdgeQuery { + if opts == nil { + opts = NewFurthestEdgeQueryOptions() + } + e := &EdgeQuery{ + testedEdges: make(map[ShapeEdgeID]uint32), + index: index, + opts: opts.common, + queue: newQueryQueue(), + } + + return e +} + +// Reset resets the state of this EdgeQuery. +func (e *EdgeQuery) Reset() { + e.indexNumEdges = 0 + e.indexNumEdgesLimit = 0 + e.indexCovering = nil + e.indexCells = nil +} + +// FindEdges returns the edges for the given target that satisfy the current options. +// +// Note that if opts.IncludeInteriors is true, the results may include some +// entries with edge_id == -1. This indicates that the target intersects +// the indexed polygon with the given ShapeID. +func (e *EdgeQuery) FindEdges(target distanceTarget) []EdgeQueryResult { + return e.findEdges(target, e.opts) +} + +// Distance reports the distance to the target. If the index or target is empty, +// returns the EdgeQuery's maximal sentinel. +// +// Use IsDistanceLess()/IsDistanceGreater() if you only want to compare the +// distance against a threshold value, since it is often much faster. +func (e *EdgeQuery) Distance(target distanceTarget) s1.ChordAngle { + return e.findEdge(target, e.opts).Distance() +} + +// IsDistanceLess reports if the distance to target is less than the given limit. +// +// This method is usually much faster than Distance(), since it is much +// less work to determine whether the minimum distance is above or below a +// threshold than it is to calculate the actual minimum distance. +// +// If you wish to check if the distance is less than or equal to the limit, use: +// +// query.IsDistanceLess(target, limit.Successor()) +// +func (e *EdgeQuery) IsDistanceLess(target distanceTarget, limit s1.ChordAngle) bool { + opts := e.opts + opts = opts.MaxResults(1). + DistanceLimit(limit). + MaxError(s1.StraightChordAngle) + return !e.findEdge(target, opts).IsEmpty() +} + +// IsDistanceGreater reports if the distance to target is greater than limit. +// +// This method is usually much faster than Distance, since it is much +// less work to determine whether the maximum distance is above or below a +// threshold than it is to calculate the actual maximum distance. +// If you wish to check if the distance is less than or equal to the limit, use: +// +// query.IsDistanceGreater(target, limit.Predecessor()) +// +func (e *EdgeQuery) IsDistanceGreater(target distanceTarget, limit s1.ChordAngle) bool { + return e.IsDistanceLess(target, limit) +} + +// IsConservativeDistanceLessOrEqual reports if the distance to target is less +// or equal to the limit, where the limit has been expanded by the maximum error +// for the distance calculation. +// +// For example, suppose that we want to test whether two geometries might +// intersect each other after they are snapped together using Builder +// (using the IdentitySnapFunction with a given "snap radius"). Since +// Builder uses exact distance predicates (s2predicates), we need to +// measure the distance between the two geometries conservatively. If the +// distance is definitely greater than "snap radius", then the geometries +// are guaranteed to not intersect after snapping. +func (e *EdgeQuery) IsConservativeDistanceLessOrEqual(target distanceTarget, limit s1.ChordAngle) bool { + return e.IsDistanceLess(target, limit.Expanded(minUpdateDistanceMaxError(limit))) +} + +// IsConservativeDistanceGreaterOrEqual reports if the distance to the target is greater +// than or equal to the given limit with some small tolerance. +func (e *EdgeQuery) IsConservativeDistanceGreaterOrEqual(target distanceTarget, limit s1.ChordAngle) bool { + return e.IsDistanceGreater(target, limit.Expanded(-minUpdateDistanceMaxError(limit))) +} + +// findEdges returns the closest edges to the given target that satisfy the given options. +// +// Note that if opts.includeInteriors is true, the results may include some +// entries with edgeID == -1. This indicates that the target intersects the +// indexed polygon with the given shapeID. +func (e *EdgeQuery) findEdges(target distanceTarget, opts *queryOptions) []EdgeQueryResult { + e.findEdgesInternal(target, opts) + // TODO(roberts): Revisit this if there is a heap or other sorted and + // uniquing datastructure we can use instead of just a slice. + e.results = sortAndUniqueResults(e.results) + if len(e.results) > e.opts.maxResults { + e.results = e.results[:e.opts.maxResults] + } + return e.results +} + +func sortAndUniqueResults(results []EdgeQueryResult) []EdgeQueryResult { + if len(results) <= 1 { + return results + } + sort.Slice(results, func(i, j int) bool { return results[i].Less(results[j]) }) + j := 0 + for i := 1; i < len(results); i++ { + if results[j] == results[i] { + continue + } + j++ + results[j] = results[i] + } + return results[:j+1] +} + +// findEdge is a convenience method that returns exactly one edge, and if no +// edges satisfy the given search criteria, then a default Result is returned. +// +// This is primarily to ease the usage of a number of the methods in the DistanceTargets +// and in EdgeQuery. +func (e *EdgeQuery) findEdge(target distanceTarget, opts *queryOptions) EdgeQueryResult { + opts.MaxResults(1) + e.findEdges(target, opts) + if len(e.results) > 0 { + return e.results[0] + } + + return newEdgeQueryResult(target) +} + +// findEdgesInternal does the actual work for find edges that match the given options. +func (e *EdgeQuery) findEdgesInternal(target distanceTarget, opts *queryOptions) { + e.target = target + e.opts = opts + + e.testedEdges = make(map[ShapeEdgeID]uint32) + e.distanceLimit = target.distance().fromChordAngle(opts.distanceLimit) + e.results = make([]EdgeQueryResult, 0) + + if e.distanceLimit == target.distance().zero() { + return + } + + if opts.includeInteriors { + shapeIDs := map[int32]struct{}{} + e.target.visitContainingShapes(e.index, func(containingShape Shape, targetPoint Point) bool { + shapeIDs[e.index.idForShape(containingShape)] = struct{}{} + return len(shapeIDs) < opts.maxResults + }) + for shapeID := range shapeIDs { + e.addResult(EdgeQueryResult{target.distance().zero(), shapeID, -1}) + } + + if e.distanceLimit == target.distance().zero() { + return + } + } + + // If maxError > 0 and the target takes advantage of this, then we may + // need to adjust the distance estimates to ShapeIndex cells to ensure + // that they are always a lower bound on the true distance. For example, + // suppose max_distance == 100, maxError == 30, and we compute the distance + // to the target from some cell C0 as d(C0) == 80. Then because the target + // takes advantage of maxError, the true distance could be as low as 50. + // In order not to miss edges contained by such cells, we need to subtract + // maxError from the distance estimates. This behavior is controlled by + // the useConservativeCellDistance flag. + // + // However there is one important case where this adjustment is not + // necessary, namely when distanceLimit < maxError, This is because + // maxError only affects the algorithm once at least maxEdges edges + // have been found that satisfy the given distance limit. At that point, + // maxError is subtracted from distanceLimit in order to ensure that + // any further matches are closer by at least that amount. But when + // distanceLimit < maxError, this reduces the distance limit to 0, + // i.e. all remaining candidate cells and edges can safely be discarded. + // (This is how IsDistanceLess() and friends are implemented.) + targetUsesMaxError := opts.maxError != target.distance().zero().chordAngle() && + e.target.setMaxError(opts.maxError) + + // Note that we can't compare maxError and distanceLimit directly + // because one is a Delta and one is a Distance. Instead we subtract them. + e.useConservativeCellDistance = targetUsesMaxError && + (e.distanceLimit == target.distance().infinity() || + target.distance().zero().less(e.distanceLimit.sub(target.distance().fromChordAngle(opts.maxError)))) + + // Use the brute force algorithm if the index is small enough. To avoid + // spending too much time counting edges when there are many shapes, we stop + // counting once there are too many edges. We may need to recount the edges + // if we later see a target with a larger brute force edge threshold. + minOptimizedEdges := e.target.maxBruteForceIndexSize() + 1 + if minOptimizedEdges > e.indexNumEdgesLimit && e.indexNumEdges >= e.indexNumEdgesLimit { + e.indexNumEdges = e.index.NumEdgesUpTo(minOptimizedEdges) + e.indexNumEdgesLimit = minOptimizedEdges + } + + if opts.useBruteForce || e.indexNumEdges < minOptimizedEdges { + // The brute force algorithm already considers each edge exactly once. + e.avoidDuplicates = false + e.findEdgesBruteForce() + } else { + // If the target takes advantage of maxError then we need to avoid + // duplicate edges explicitly. (Otherwise it happens automatically.) + e.avoidDuplicates = targetUsesMaxError && opts.maxResults > 1 + e.findEdgesOptimized() + } +} + +func (e *EdgeQuery) addResult(r EdgeQueryResult) { + e.results = append(e.results, r) + if e.opts.maxResults == 1 { + // Optimization for the common case where only the closest edge is wanted. + e.distanceLimit = r.distance.sub(e.target.distance().fromChordAngle(e.opts.maxError)) + } + // TODO(roberts): Add the other if/else cases when a different data structure + // is used for the results. +} + +func (e *EdgeQuery) maybeAddResult(shape Shape, edgeID int32) { + if _, ok := e.testedEdges[ShapeEdgeID{e.index.idForShape(shape), edgeID}]; e.avoidDuplicates && !ok { + return + } + edge := shape.Edge(int(edgeID)) + dist := e.distanceLimit + + if dist, ok := e.target.updateDistanceToEdge(edge, dist); ok { + e.addResult(EdgeQueryResult{dist, e.index.idForShape(shape), edgeID}) + } +} + +func (e *EdgeQuery) findEdgesBruteForce() { + // Range over all shapes in the index. Does order matter here? if so + // switch to for i = 0 .. n? + for _, shape := range e.index.shapes { + // TODO(roberts): can this happen if we are only ranging over current entries? + if shape == nil { + continue + } + for edgeID := int32(0); edgeID < int32(shape.NumEdges()); edgeID++ { + e.maybeAddResult(shape, edgeID) + } + } +} + +func (e *EdgeQuery) findEdgesOptimized() { + e.initQueue() + // Repeatedly find the closest Cell to "target" and either split it into + // its four children or process all of its edges. + for e.queue.size() > 0 { + // We need to copy the top entry before removing it, and we need to + // remove it before adding any new entries to the queue. + entry := e.queue.pop() + + if !entry.distance.less(e.distanceLimit) { + e.queue.reset() // Clear any remaining entries. + break + } + // If this is already known to be an index cell, just process it. + if entry.indexCell != nil { + e.processEdges(entry) + continue + } + // Otherwise split the cell into its four children. Before adding a + // child back to the queue, we first check whether it is empty. We do + // this in two seek operations rather than four by seeking to the key + // between children 0 and 1 and to the key between children 2 and 3. + id := entry.id + ch := id.Children() + e.iter.seek(ch[1].RangeMin()) + + if !e.iter.Done() && e.iter.CellID() <= ch[1].RangeMax() { + e.processOrEnqueueCell(ch[1]) + } + if e.iter.Prev() && e.iter.CellID() >= id.RangeMin() { + e.processOrEnqueueCell(ch[0]) + } + + e.iter.seek(ch[3].RangeMin()) + if !e.iter.Done() && e.iter.CellID() <= id.RangeMax() { + e.processOrEnqueueCell(ch[3]) + } + if e.iter.Prev() && e.iter.CellID() >= ch[2].RangeMin() { + e.processOrEnqueueCell(ch[2]) + } + } +} + +func (e *EdgeQuery) processOrEnqueueCell(id CellID) { + if e.iter.CellID() == id { + e.processOrEnqueue(id, e.iter.IndexCell()) + } else { + e.processOrEnqueue(id, nil) + } +} + +func (e *EdgeQuery) initQueue() { + if len(e.indexCovering) == 0 { + // We delay iterator initialization until now to make queries on very + // small indexes a bit faster (i.e., where brute force is used). + e.iter = NewShapeIndexIterator(e.index) + } + + // Optimization: if the user is searching for just the closest edge, and the + // center of the target's bounding cap happens to intersect an index cell, + // then we try to limit the search region to a small disc by first + // processing the edges in that cell. This sets distance_limit_ based on + // the closest edge in that cell, which we can then use to limit the search + // area. This means that the cell containing "target" will be processed + // twice, but in general this is still faster. + // + // TODO(roberts): Even if the cap center is not contained, we could still + // process one or both of the adjacent index cells in CellID order, + // provided that those cells are closer than distanceLimit. + cb := e.target.capBound() + if cb.IsEmpty() { + return // Empty target. + } + + if e.opts.maxResults == 1 && e.iter.LocatePoint(cb.Center()) { + e.processEdges(&queryQueueEntry{ + distance: e.target.distance().zero(), + id: e.iter.CellID(), + indexCell: e.iter.IndexCell(), + }) + // Skip the rest of the algorithm if we found an intersecting edge. + if e.distanceLimit == e.target.distance().zero() { + return + } + } + if len(e.indexCovering) == 0 { + e.initCovering() + } + if e.distanceLimit == e.target.distance().infinity() { + // Start with the precomputed index covering. + for i := range e.indexCovering { + e.processOrEnqueue(e.indexCovering[i], e.indexCells[i]) + } + } else { + // Compute a covering of the search disc and intersect it with the + // precomputed index covering. + coverer := &RegionCoverer{MaxCells: 4, LevelMod: 1, MaxLevel: maxLevel} + + radius := cb.Radius() + e.distanceLimit.chordAngleBound().Angle() + searchCB := CapFromCenterAngle(cb.Center(), radius) + maxDistCover := coverer.FastCovering(searchCB) + e.initialCells = CellUnionFromIntersection(e.indexCovering, maxDistCover) + + // Now we need to clean up the initial cells to ensure that they all + // contain at least one cell of the ShapeIndex. (Some may not intersect + // the index at all, while other may be descendants of an index cell.) + i, j := 0, 0 + for i < len(e.initialCells) { + idI := e.initialCells[i] + // Find the top-level cell that contains this initial cell. + for e.indexCovering[j].RangeMax() < idI { + j++ + } + + idJ := e.indexCovering[j] + if idI == idJ { + // This initial cell is one of the top-level cells. Use the + // precomputed ShapeIndexCell pointer to avoid an index seek. + e.processOrEnqueue(idJ, e.indexCells[j]) + i++ + j++ + } else { + // This initial cell is a proper descendant of a top-level cell. + // Check how it is related to the cells of the ShapeIndex. + r := e.iter.LocateCellID(idI) + if r == Indexed { + // This cell is a descendant of an index cell. + // Enqueue it and skip any other initial cells + // that are also descendants of this cell. + e.processOrEnqueue(e.iter.CellID(), e.iter.IndexCell()) + lastID := e.iter.CellID().RangeMax() + for i < len(e.initialCells) && e.initialCells[i] <= lastID { + i++ + } + } else { + // Enqueue the cell only if it contains at least one index cell. + if r == Subdivided { + e.processOrEnqueue(idI, nil) + } + i++ + } + } + } + } +} + +func (e *EdgeQuery) initCovering() { + // Find the range of Cells spanned by the index and choose a level such + // that the entire index can be covered with just a few cells. These are + // the "top-level" cells. There are two cases: + // + // - If the index spans more than one face, then there is one top-level cell + // per spanned face, just big enough to cover the index cells on that face. + // + // - If the index spans only one face, then we find the smallest cell "C" + // that covers the index cells on that face (just like the case above). + // Then for each of the 4 children of "C", if the child contains any index + // cells then we create a top-level cell that is big enough to just fit + // those index cells (i.e., shrinking the child as much as possible to fit + // its contents). This essentially replicates what would happen if we + // started with "C" as the top-level cell, since "C" would immediately be + // split, except that we take the time to prune the children further since + // this will save work on every subsequent query. + e.indexCovering = make([]CellID, 0, 6) + + // TODO(roberts): Use a single iterator below and save position + // information using pair {CellID, ShapeIndexCell}. + next := NewShapeIndexIterator(e.index, IteratorBegin) + last := NewShapeIndexIterator(e.index, IteratorEnd) + last.Prev() + if next.CellID() != last.CellID() { + // The index has at least two cells. Choose a level such that the entire + // index can be spanned with at most 6 cells (if the index spans multiple + // faces) or 4 cells (it the index spans a single face). + level, ok := next.CellID().CommonAncestorLevel(last.CellID()) + if !ok { + level = 0 + } else { + level++ + } + + // Visit each potential top-level cell except the last (handled below). + lastID := last.CellID().Parent(level) + for id := next.CellID().Parent(level); id != lastID; id = id.Next() { + // Skip any top-level cells that don't contain any index cells. + if id.RangeMax() < next.CellID() { + continue + } + + // Find the range of index cells contained by this top-level cell and + // then shrink the cell if necessary so that it just covers them. + cellFirst := next.clone() + next.seek(id.RangeMax().Next()) + cellLast := next.clone() + cellLast.Prev() + e.addInitialRange(cellFirst, cellLast) + break + } + + } + e.addInitialRange(next, last) +} + +// addInitialRange adds an entry to the indexCovering and indexCells that covers the given +// inclusive range of cells. +// +// This requires that first and last cells have a common ancestor. +func (e *EdgeQuery) addInitialRange(first, last *ShapeIndexIterator) { + if first.CellID() == last.CellID() { + // The range consists of a single index cell. + e.indexCovering = append(e.indexCovering, first.CellID()) + e.indexCells = append(e.indexCells, first.IndexCell()) + } else { + // Add the lowest common ancestor of the given range. + level, _ := first.CellID().CommonAncestorLevel(last.CellID()) + e.indexCovering = append(e.indexCovering, first.CellID().Parent(level)) + e.indexCells = append(e.indexCells, nil) + } +} + +// processEdges processes all the edges of the given index cell. +func (e *EdgeQuery) processEdges(entry *queryQueueEntry) { + for _, clipped := range entry.indexCell.shapes { + shape := e.index.Shape(clipped.shapeID) + for j := 0; j < clipped.numEdges(); j++ { + e.maybeAddResult(shape, int32(clipped.edges[j])) + } + } +} + +// processOrEnqueue the given cell id and indexCell. +func (e *EdgeQuery) processOrEnqueue(id CellID, indexCell *ShapeIndexCell) { + if indexCell != nil { + // If this index cell has only a few edges, then it is faster to check + // them directly rather than computing the minimum distance to the Cell + // and inserting it into the queue. + const minEdgesToEnqueue = 10 + numEdges := indexCell.numEdges() + if numEdges == 0 { + return + } + if numEdges < minEdgesToEnqueue { + // Set "distance" to zero to avoid the expense of computing it. + e.processEdges(&queryQueueEntry{ + distance: e.target.distance().zero(), + id: id, + indexCell: indexCell, + }) + return + } + } + + // Otherwise compute the minimum distance to any point in the cell and add + // it to the priority queue. + cell := CellFromCellID(id) + dist := e.distanceLimit + var ok bool + if dist, ok = e.target.updateDistanceToCell(cell, dist); !ok { + return + } + if e.useConservativeCellDistance { + // Ensure that "distance" is a lower bound on the true distance to the cell. + dist = dist.sub(e.target.distance().fromChordAngle(e.opts.maxError)) + } + + e.queue.push(&queryQueueEntry{ + distance: dist, + id: id, + indexCell: indexCell, + }) +} + +func (e *EdgeQuery) GetEdge(result EdgeQueryResult) Edge { + return e.index.Shape(result.shapeID).Edge(int(result.edgeID)) +} + +func (e *EdgeQuery) Project(point Point, result EdgeQueryResult) Point { + if result.edgeID < 0 { + return point + } + + edge := e.GetEdge(result) + return Project(point, edge.V0, edge.V1) +} + +// TODO(roberts): Remaining pieces +// GetEdge +// Project diff --git a/backend/vendor/github.com/blevesearch/geo/s2/edge_tessellator.go b/backend/vendor/github.com/blevesearch/geo/s2/edge_tessellator.go new file mode 100644 index 0000000000..1d5805c26e --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/edge_tessellator.go @@ -0,0 +1,291 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "github.com/golang/geo/r2" + "github.com/golang/geo/s1" +) + +// Tessellation is implemented by subdividing the edge until the estimated +// maximum error is below the given tolerance. Estimating error is a hard +// problem, especially when the only methods available are point evaluation of +// the projection and its inverse. (These are the only methods that +// Projection provides, which makes it easier and less error-prone to +// implement new projections.) +// +// One technique that significantly increases robustness is to treat the +// geodesic and projected edges as parametric curves rather than geometric ones. +// Given a spherical edge AB and a projection p:S2->R2, let f(t) be the +// normalized arc length parametrization of AB and let g(t) be the normalized +// arc length parameterization of the projected edge p(A)p(B). (In other words, +// f(0)=A, f(1)=B, g(0)=p(A), g(1)=p(B).) We now define the geometric error as +// the maximum distance from the point p^-1(g(t)) to the geodesic edge AB for +// any t in [0,1], where p^-1 denotes the inverse projection. In other words, +// the geometric error is the maximum distance from any point on the projected +// edge (mapped back onto the sphere) to the geodesic edge AB. On the other +// hand we define the parametric error as the maximum distance between the +// points f(t) and p^-1(g(t)) for any t in [0,1], i.e. the maximum distance +// (measured on the sphere) between the geodesic and projected points at the +// same interpolation fraction t. +// +// The easiest way to estimate the parametric error is to simply evaluate both +// edges at their midpoints and measure the distance between them (the "midpoint +// method"). This is very fast and works quite well for most edges, however it +// has one major drawback: it doesn't handle points of inflection (i.e., points +// where the curvature changes sign). For example, edges in the Mercator and +// Plate Carree projections always curve towards the equator relative to the +// corresponding geodesic edge, so in these projections there is a point of +// inflection whenever the projected edge crosses the equator. The worst case +// occurs when the edge endpoints have different longitudes but the same +// absolute latitude, since in that case the error is non-zero but the edges +// have exactly the same midpoint (on the equator). +// +// One solution to this problem is to split the input edges at all inflection +// points (i.e., along the equator in the case of the Mercator and Plate Carree +// projections). However for general projections these inflection points can +// occur anywhere on the sphere (e.g., consider the Transverse Mercator +// projection). This could be addressed by adding methods to the S2Projection +// interface to split edges at inflection points but this would make it harder +// and more error-prone to implement new projections. +// +// Another problem with this approach is that the midpoint method sometimes +// underestimates the true error even when edges do not cross the equator. +// For the Plate Carree and Mercator projections, the midpoint method can +// underestimate the error by up to 3%. +// +// Both of these problems can be solved as follows. We assume that the error +// can be modeled as a convex combination of two worst-case functions, one +// where the error is maximized at the edge midpoint and another where the +// error is *minimized* (i.e., zero) at the edge midpoint. For example, we +// could choose these functions as: +// +// E1(x) = 1 - x^2 +// E2(x) = x * (1 - x^2) +// +// where for convenience we use an interpolation parameter "x" in the range +// [-1, 1] rather than the original "t" in the range [0, 1]. Note that both +// error functions must have roots at x = {-1, 1} since the error must be zero +// at the edge endpoints. E1 is simply a parabola whose maximum value is 1 +// attained at x = 0, while E2 is a cubic with an additional root at x = 0, +// and whose maximum value is 2 * sqrt(3) / 9 attained at x = 1 / sqrt(3). +// +// Next, it is convenient to scale these functions so that the both have a +// maximum value of 1. E1 already satisfies this requirement, and we simply +// redefine E2 as +// +// E2(x) = x * (1 - x^2) / (2 * sqrt(3) / 9) +// +// Now define x0 to be the point where these two functions intersect, i.e. the +// point in the range (-1, 1) where E1(x0) = E2(x0). This value has the very +// convenient property that if we evaluate the actual error E(x0), then the +// maximum error on the entire interval [-1, 1] is bounded by +// +// E(x) <= E(x0) / E1(x0) +// +// since whether the error is modeled using E1 or E2, the resulting function +// has the same maximum value (namely E(x0) / E1(x0)). If it is modeled as +// some other convex combination of E1 and E2, the maximum value can only +// decrease. +// +// Finally, since E2 is not symmetric about the y-axis, we must also allow for +// the possibility that the error is a convex combination of E1 and -E2. This +// can be handled by evaluating the error at E(-x0) as well, and then +// computing the final error bound as +// +// E(x) <= max(E(x0), E(-x0)) / E1(x0) . +// +// Effectively, this method is simply evaluating the error at two points about +// 1/3 and 2/3 of the way along the edges, and then scaling the maximum of +// these two errors by a constant factor. Intuitively, the reason this works +// is that if the two edges cross somewhere in the interior, then at least one +// of these points will be far from the crossing. +// +// The actual algorithm implemented below has some additional refinements. +// First, edges longer than 90 degrees are always subdivided; this avoids +// various unusual situations that can happen with very long edges, and there +// is really no reason to avoid adding vertices to edges that are so long. +// +// Second, the error function E1 above needs to be modified to take into +// account spherical distortions. (It turns out that spherical distortions are +// beneficial in the case of E2, i.e. they only make its error estimates +// slightly more conservative.) To do this, we model E1 as the maximum error +// in a Plate Carree edge of length 90 degrees or less. This turns out to be +// an edge from 45:-90 to 45:90 (in lat:lng format). The corresponding error +// as a function of "x" in the range [-1, 1] can be computed as the distance +// between the Plate Caree edge point (45, 90 * x) and the geodesic +// edge point (90 - 45 * abs(x), 90 * sgn(x)). Using the Haversine formula, +// the corresponding function E1 (normalized to have a maximum value of 1) is: +// +// E1(x) = +// asin(sqrt(sin(Pi / 8 * (1 - x)) ^ 2 + +// sin(Pi / 4 * (1 - x)) ^ 2 * cos(Pi / 4) * sin(Pi / 4 * x))) / +// asin(sqrt((1 - 1 / sqrt(2)) / 2)) +// +// Note that this function does not need to be evaluated at runtime, it +// simply affects the calculation of the value x0 where E1(x0) = E2(x0) +// and the corresponding scaling factor C = 1 / E1(x0). +// +// ------------------------------------------------------------------ +// +// In the case of the Mercator and Plate Carree projections this strategy +// produces a conservative upper bound (verified using 10 million random +// edges). Furthermore the bound is nearly tight; the scaling constant is +// C = 1.19289, whereas the maximum observed value was 1.19254. +// +// Compared to the simpler midpoint evaluation method, this strategy requires +// more function evaluations (currently twice as many, but with a smarter +// tessellation algorithm it will only be 50% more). It also results in a +// small amount of additional tessellation (about 1.5%) compared to the +// midpoint method, but this is due almost entirely to the fact that the +// midpoint method does not yield conservative error estimates. +// +// For random edges with a tolerance of 1 meter, the expected amount of +// overtessellation is as follows: +// +// Midpoint Method Cubic Method +// Plate Carree 1.8% 3.0% +// Mercator 15.8% 17.4% + +const ( + // tessellationInterpolationFraction is the fraction at which the two edges + // are evaluated in order to measure the error between them. (Edges are + // evaluated at two points measured this fraction from either end.) + tessellationInterpolationFraction = 0.31215691082248312 + tessellationScaleFactor = 0.83829992569888509 + + // minTessellationTolerance is the minimum supported tolerance (which + // corresponds to a distance less than 1 micrometer on the Earth's + // surface, but is still much larger than the expected projection and + // interpolation errors). + minTessellationTolerance s1.Angle = 1e-13 +) + +// EdgeTessellator converts an edge in a given projection (e.g., Mercator) into +// a chain of spherical geodesic edges such that the maximum distance between +// the original edge and the geodesic edge chain is at most the requested +// tolerance. Similarly, it can convert a spherical geodesic edge into a chain +// of edges in a given 2D projection such that the maximum distance between the +// geodesic edge and the chain of projected edges is at most the requested tolerance. +// +// Method | Input | Output +// ------------|------------------------|----------------------- +// Projected | S2 geodesics | Planar projected edges +// Unprojected | Planar projected edges | S2 geodesics +type EdgeTessellator struct { + projection Projection + + // The given tolerance scaled by a constant fraction so that it can be + // compared against the result returned by estimateMaxError. + scaledTolerance s1.ChordAngle +} + +// NewEdgeTessellator creates a new edge tessellator for the given projection and tolerance. +func NewEdgeTessellator(p Projection, tolerance s1.Angle) *EdgeTessellator { + return &EdgeTessellator{ + projection: p, + scaledTolerance: s1.ChordAngleFromAngle(maxAngle(tolerance, minTessellationTolerance)), + } +} + +// AppendProjected converts the spherical geodesic edge AB to a chain of planar edges +// in the given projection and returns the corresponding vertices. +// +// If the given projection has one or more coordinate axes that wrap, then +// every vertex's coordinates will be as close as possible to the previous +// vertex's coordinates. Note that this may yield vertices whose +// coordinates are outside the usual range. For example, tessellating the +// edge (0:170, 0:-170) (in lat:lng notation) yields (0:170, 0:190). +func (e *EdgeTessellator) AppendProjected(a, b Point, vertices []r2.Point) []r2.Point { + pa := e.projection.Project(a) + if len(vertices) == 0 { + vertices = []r2.Point{pa} + } else { + pa = e.projection.WrapDestination(vertices[len(vertices)-1], pa) + } + + pb := e.projection.Project(b) + return e.appendProjected(pa, a, pb, b, vertices) +} + +// appendProjected splits a geodesic edge AB as necessary and returns the +// projected vertices appended to the given vertices. +// +// The maximum recursion depth is (math.Pi / minTessellationTolerance) < 45 +func (e *EdgeTessellator) appendProjected(pa r2.Point, a Point, pbIn r2.Point, b Point, vertices []r2.Point) []r2.Point { + pb := e.projection.WrapDestination(pa, pbIn) + if e.estimateMaxError(pa, a, pb, b) <= e.scaledTolerance { + return append(vertices, pb) + } + + mid := Point{a.Add(b.Vector).Normalize()} + pmid := e.projection.WrapDestination(pa, e.projection.Project(mid)) + vertices = e.appendProjected(pa, a, pmid, mid, vertices) + return e.appendProjected(pmid, mid, pb, b, vertices) +} + +// AppendUnprojected converts the planar edge AB in the given projection to a chain of +// spherical geodesic edges and returns the vertices. +// +// Note that to construct a Loop, you must eliminate the duplicate first and last +// vertex. Note also that if the given projection involves coordinate wrapping +// (e.g. across the 180 degree meridian) then the first and last vertices may not +// be exactly the same. +func (e *EdgeTessellator) AppendUnprojected(pa, pb r2.Point, vertices []Point) []Point { + a := e.projection.Unproject(pa) + b := e.projection.Unproject(pb) + + if len(vertices) == 0 { + vertices = []Point{a} + } + + // Note that coordinate wrapping can create a small amount of error. For + // example in the edge chain "0:-175, 0:179, 0:-177", the first edge is + // transformed into "0:-175, 0:-181" while the second is transformed into + // "0:179, 0:183". The two coordinate pairs for the middle vertex + // ("0:-181" and "0:179") may not yield exactly the same S2Point. + return e.appendUnprojected(pa, a, pb, b, vertices) +} + +// appendUnprojected interpolates a projected edge and appends the corresponding +// points on the sphere. +func (e *EdgeTessellator) appendUnprojected(pa r2.Point, a Point, pbIn r2.Point, b Point, vertices []Point) []Point { + pb := e.projection.WrapDestination(pa, pbIn) + if e.estimateMaxError(pa, a, pb, b) <= e.scaledTolerance { + return append(vertices, b) + } + + pmid := e.projection.Interpolate(0.5, pa, pb) + mid := e.projection.Unproject(pmid) + + vertices = e.appendUnprojected(pa, a, pmid, mid, vertices) + return e.appendUnprojected(pmid, mid, pb, b, vertices) +} + +func (e *EdgeTessellator) estimateMaxError(pa r2.Point, a Point, pb r2.Point, b Point) s1.ChordAngle { + // See the algorithm description at the top of this file. + // We always tessellate edges longer than 90 degrees on the sphere, since the + // approximation below is not robust enough to handle such edges. + if a.Dot(b.Vector) < -1e-14 { + return s1.InfChordAngle() + } + t1 := tessellationInterpolationFraction + t2 := 1 - tessellationInterpolationFraction + mid1 := Interpolate(t1, a, b) + mid2 := Interpolate(t2, a, b) + pmid1 := e.projection.Unproject(e.projection.Interpolate(t1, pa, pb)) + pmid2 := e.projection.Unproject(e.projection.Interpolate(t2, pa, pb)) + return maxChordAngle(ChordAngleBetweenPoints(mid1, pmid1), ChordAngleBetweenPoints(mid2, pmid2)) +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/encode.go b/backend/vendor/github.com/blevesearch/geo/s2/encode.go new file mode 100644 index 0000000000..00d0adc719 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/encode.go @@ -0,0 +1,224 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "encoding/binary" + "io" + "math" +) + +const ( + // encodingVersion is the current version of the encoding + // format that is compatible with C++ and other S2 libraries. + encodingVersion = int8(1) + + // encodingCompressedVersion is the current version of the + // compressed format. + encodingCompressedVersion = int8(4) +) + +// encoder handles the specifics of encoding for S2 types. +type encoder struct { + w io.Writer // the real writer passed to Encode + err error +} + +func (e *encoder) writeUvarint(x uint64) { + if e.err != nil { + return + } + var buf [binary.MaxVarintLen64]byte + n := binary.PutUvarint(buf[:], x) + _, e.err = e.w.Write(buf[:n]) +} + +func (e *encoder) writeBool(x bool) { + if e.err != nil { + return + } + var val int8 + if x { + val = 1 + } + e.err = binary.Write(e.w, binary.LittleEndian, val) +} + +func (e *encoder) writeInt8(x int8) { + if e.err != nil { + return + } + e.err = binary.Write(e.w, binary.LittleEndian, x) +} + +func (e *encoder) writeInt16(x int16) { + if e.err != nil { + return + } + e.err = binary.Write(e.w, binary.LittleEndian, x) +} + +func (e *encoder) writeInt32(x int32) { + if e.err != nil { + return + } + e.err = binary.Write(e.w, binary.LittleEndian, x) +} + +func (e *encoder) writeInt64(x int64) { + if e.err != nil { + return + } + e.err = binary.Write(e.w, binary.LittleEndian, x) +} + +func (e *encoder) writeUint8(x uint8) { + if e.err != nil { + return + } + _, e.err = e.w.Write([]byte{x}) +} + +func (e *encoder) writeUint32(x uint32) { + if e.err != nil { + return + } + e.err = binary.Write(e.w, binary.LittleEndian, x) +} + +func (e *encoder) writeUint64(x uint64) { + if e.err != nil { + return + } + e.err = binary.Write(e.w, binary.LittleEndian, x) +} + +func (e *encoder) writeFloat32(x float32) { + if e.err != nil { + return + } + e.err = binary.Write(e.w, binary.LittleEndian, x) +} + +func (e *encoder) writeFloat64(x float64) { + if e.err != nil { + return + } + e.err = binary.Write(e.w, binary.LittleEndian, x) +} + +type byteReader interface { + io.Reader + io.ByteReader +} + +// byteReaderAdapter embellishes an io.Reader with a ReadByte method, +// so that it implements the io.ByteReader interface. +type byteReaderAdapter struct { + io.Reader +} + +func (b byteReaderAdapter) ReadByte() (byte, error) { + buf := []byte{0} + _, err := io.ReadFull(b, buf) + return buf[0], err +} + +func asByteReader(r io.Reader) byteReader { + if br, ok := r.(byteReader); ok { + return br + } + return byteReaderAdapter{r} +} + +type decoder struct { + r byteReader // the real reader passed to Decode + err error + buf []byte +} + +// Get a buffer of size 8, to avoid allocating over and over. +func (d *decoder) buffer() []byte { + if d.buf == nil { + d.buf = make([]byte, 8) + } + return d.buf +} + +func (d *decoder) readBool() (x bool) { + if d.err != nil { + return + } + var val int8 + d.err = binary.Read(d.r, binary.LittleEndian, &val) + return val == 1 +} + +func (d *decoder) readInt8() (x int8) { + if d.err != nil { + return + } + d.err = binary.Read(d.r, binary.LittleEndian, &x) + return +} + +func (d *decoder) readInt64() (x int64) { + if d.err != nil { + return + } + d.err = binary.Read(d.r, binary.LittleEndian, &x) + return +} + +func (d *decoder) readUint8() (x uint8) { + if d.err != nil { + return + } + x, d.err = d.r.ReadByte() + return +} + +func (d *decoder) readUint32() (x uint32) { + if d.err != nil { + return + } + d.err = binary.Read(d.r, binary.LittleEndian, &x) + return +} + +func (d *decoder) readUint64() (x uint64) { + if d.err != nil { + return + } + d.err = binary.Read(d.r, binary.LittleEndian, &x) + return +} + +func (d *decoder) readFloat64() float64 { + if d.err != nil { + return 0 + } + buf := d.buffer() + _, d.err = io.ReadFull(d.r, buf) + return math.Float64frombits(binary.LittleEndian.Uint64(buf)) +} + +func (d *decoder) readUvarint() (x uint64) { + if d.err != nil { + return + } + x, d.err = binary.ReadUvarint(d.r) + return +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/interleave.go b/backend/vendor/github.com/blevesearch/geo/s2/interleave.go new file mode 100644 index 0000000000..6ac6ef58da --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/interleave.go @@ -0,0 +1,143 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +/* +The lookup table below can convert a sequence of interleaved 8 bits into +non-interleaved 4 bits. The table can convert both odd and even bits at the +same time, and lut[x & 0x55] converts the even bits (bits 0, 2, 4 and 6), +while lut[x & 0xaa] converts the odd bits (bits 1, 3, 5 and 7). + +The lookup table below was generated using the following python code: + + def deinterleave(bits): + if bits == 0: return 0 + if bits < 4: return 1 + return deinterleave(bits / 4) * 2 + deinterleave(bits & 3) + + for i in range(256): print "0x%x," % deinterleave(i), +*/ +var deinterleaveLookup = [256]uint32{ + 0x0, 0x1, 0x1, 0x1, 0x2, 0x3, 0x3, 0x3, + 0x2, 0x3, 0x3, 0x3, 0x2, 0x3, 0x3, 0x3, + 0x4, 0x5, 0x5, 0x5, 0x6, 0x7, 0x7, 0x7, + 0x6, 0x7, 0x7, 0x7, 0x6, 0x7, 0x7, 0x7, + 0x4, 0x5, 0x5, 0x5, 0x6, 0x7, 0x7, 0x7, + 0x6, 0x7, 0x7, 0x7, 0x6, 0x7, 0x7, 0x7, + 0x4, 0x5, 0x5, 0x5, 0x6, 0x7, 0x7, 0x7, + 0x6, 0x7, 0x7, 0x7, 0x6, 0x7, 0x7, 0x7, + + 0x8, 0x9, 0x9, 0x9, 0xa, 0xb, 0xb, 0xb, + 0xa, 0xb, 0xb, 0xb, 0xa, 0xb, 0xb, 0xb, + 0xc, 0xd, 0xd, 0xd, 0xe, 0xf, 0xf, 0xf, + 0xe, 0xf, 0xf, 0xf, 0xe, 0xf, 0xf, 0xf, + 0xc, 0xd, 0xd, 0xd, 0xe, 0xf, 0xf, 0xf, + 0xe, 0xf, 0xf, 0xf, 0xe, 0xf, 0xf, 0xf, + 0xc, 0xd, 0xd, 0xd, 0xe, 0xf, 0xf, 0xf, + 0xe, 0xf, 0xf, 0xf, 0xe, 0xf, 0xf, 0xf, + + 0x8, 0x9, 0x9, 0x9, 0xa, 0xb, 0xb, 0xb, + 0xa, 0xb, 0xb, 0xb, 0xa, 0xb, 0xb, 0xb, + 0xc, 0xd, 0xd, 0xd, 0xe, 0xf, 0xf, 0xf, + 0xe, 0xf, 0xf, 0xf, 0xe, 0xf, 0xf, 0xf, + 0xc, 0xd, 0xd, 0xd, 0xe, 0xf, 0xf, 0xf, + 0xe, 0xf, 0xf, 0xf, 0xe, 0xf, 0xf, 0xf, + 0xc, 0xd, 0xd, 0xd, 0xe, 0xf, 0xf, 0xf, + 0xe, 0xf, 0xf, 0xf, 0xe, 0xf, 0xf, 0xf, + + 0x8, 0x9, 0x9, 0x9, 0xa, 0xb, 0xb, 0xb, + 0xa, 0xb, 0xb, 0xb, 0xa, 0xb, 0xb, 0xb, + 0xc, 0xd, 0xd, 0xd, 0xe, 0xf, 0xf, 0xf, + 0xe, 0xf, 0xf, 0xf, 0xe, 0xf, 0xf, 0xf, + 0xc, 0xd, 0xd, 0xd, 0xe, 0xf, 0xf, 0xf, + 0xe, 0xf, 0xf, 0xf, 0xe, 0xf, 0xf, 0xf, + 0xc, 0xd, 0xd, 0xd, 0xe, 0xf, 0xf, 0xf, + 0xe, 0xf, 0xf, 0xf, 0xe, 0xf, 0xf, 0xf, +} + +// deinterleaveUint32 decodes the interleaved values. +func deinterleaveUint32(code uint64) (uint32, uint32) { + x := (deinterleaveLookup[code&0x55]) | + (deinterleaveLookup[(code>>8)&0x55] << 4) | + (deinterleaveLookup[(code>>16)&0x55] << 8) | + (deinterleaveLookup[(code>>24)&0x55] << 12) | + (deinterleaveLookup[(code>>32)&0x55] << 16) | + (deinterleaveLookup[(code>>40)&0x55] << 20) | + (deinterleaveLookup[(code>>48)&0x55] << 24) | + (deinterleaveLookup[(code>>56)&0x55] << 28) + y := (deinterleaveLookup[code&0xaa]) | + (deinterleaveLookup[(code>>8)&0xaa] << 4) | + (deinterleaveLookup[(code>>16)&0xaa] << 8) | + (deinterleaveLookup[(code>>24)&0xaa] << 12) | + (deinterleaveLookup[(code>>32)&0xaa] << 16) | + (deinterleaveLookup[(code>>40)&0xaa] << 20) | + (deinterleaveLookup[(code>>48)&0xaa] << 24) | + (deinterleaveLookup[(code>>56)&0xaa] << 28) + return x, y +} + +var interleaveLookup = [256]uint64{ + 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, + 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, + 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, + 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, + 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, + 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, + 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, + 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, + + 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, + 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, + 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, + 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, + 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, + 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, + 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, + 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, + + 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, + 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, + 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, + 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, + 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, + 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, + 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, + 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, + + 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, + 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, + 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, + 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, + 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, + 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, + 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, + 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555, +} + +// interleaveUint32 interleaves the given arguments into the return value. +// +// The 0-bit in val0 will be the 0-bit in the return value. +// The 0-bit in val1 will be the 1-bit in the return value. +// The 1-bit of val0 will be the 2-bit in the return value, and so on. +func interleaveUint32(x, y uint32) uint64 { + return (interleaveLookup[x&0xff]) | + (interleaveLookup[(x>>8)&0xff] << 16) | + (interleaveLookup[(x>>16)&0xff] << 32) | + (interleaveLookup[x>>24] << 48) | + (interleaveLookup[y&0xff] << 1) | + (interleaveLookup[(y>>8)&0xff] << 17) | + (interleaveLookup[(y>>16)&0xff] << 33) | + (interleaveLookup[y>>24] << 49) +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/latlng.go b/backend/vendor/github.com/blevesearch/geo/s2/latlng.go new file mode 100644 index 0000000000..a750304ab4 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/latlng.go @@ -0,0 +1,101 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "fmt" + "math" + + "github.com/golang/geo/r3" + "github.com/golang/geo/s1" +) + +const ( + northPoleLat = s1.Angle(math.Pi/2) * s1.Radian + southPoleLat = -northPoleLat +) + +// LatLng represents a point on the unit sphere as a pair of angles. +type LatLng struct { + Lat, Lng s1.Angle +} + +// LatLngFromDegrees returns a LatLng for the coordinates given in degrees. +func LatLngFromDegrees(lat, lng float64) LatLng { + return LatLng{s1.Angle(lat) * s1.Degree, s1.Angle(lng) * s1.Degree} +} + +// IsValid returns true iff the LatLng is normalized, with Lat ∈ [-π/2,π/2] and Lng ∈ [-π,π]. +func (ll LatLng) IsValid() bool { + return math.Abs(ll.Lat.Radians()) <= math.Pi/2 && math.Abs(ll.Lng.Radians()) <= math.Pi +} + +// Normalized returns the normalized version of the LatLng, +// with Lat clamped to [-π/2,π/2] and Lng wrapped in [-π,π]. +func (ll LatLng) Normalized() LatLng { + lat := ll.Lat + if lat > northPoleLat { + lat = northPoleLat + } else if lat < southPoleLat { + lat = southPoleLat + } + lng := s1.Angle(math.Remainder(ll.Lng.Radians(), 2*math.Pi)) * s1.Radian + return LatLng{lat, lng} +} + +func (ll LatLng) String() string { return fmt.Sprintf("[%v, %v]", ll.Lat, ll.Lng) } + +// Distance returns the angle between two LatLngs. +func (ll LatLng) Distance(ll2 LatLng) s1.Angle { + // Haversine formula, as used in C++ S2LatLng::GetDistance. + lat1, lat2 := ll.Lat.Radians(), ll2.Lat.Radians() + lng1, lng2 := ll.Lng.Radians(), ll2.Lng.Radians() + dlat := math.Sin(0.5 * (lat2 - lat1)) + dlng := math.Sin(0.5 * (lng2 - lng1)) + x := dlat*dlat + dlng*dlng*math.Cos(lat1)*math.Cos(lat2) + return s1.Angle(2*math.Atan2(math.Sqrt(x), math.Sqrt(math.Max(0, 1-x)))) * s1.Radian +} + +// NOTE(mikeperrow): The C++ implementation publicly exposes latitude/longitude +// functions. Let's see if that's really necessary before exposing the same functionality. + +func latitude(p Point) s1.Angle { + return s1.Angle(math.Atan2(p.Z, math.Sqrt(p.X*p.X+p.Y*p.Y))) * s1.Radian +} + +func longitude(p Point) s1.Angle { + return s1.Angle(math.Atan2(p.Y, p.X)) * s1.Radian +} + +// PointFromLatLng returns an Point for the given LatLng. +// The maximum error in the result is 1.5 * dblEpsilon. (This does not +// include the error of converting degrees, E5, E6, or E7 into radians.) +func PointFromLatLng(ll LatLng) Point { + phi := ll.Lat.Radians() + theta := ll.Lng.Radians() + cosphi := math.Cos(phi) + return Point{r3.Vector{math.Cos(theta) * cosphi, math.Sin(theta) * cosphi, math.Sin(phi)}} +} + +// LatLngFromPoint returns an LatLng for a given Point. +func LatLngFromPoint(p Point) LatLng { + return LatLng{latitude(p), longitude(p)} +} + +// ApproxEqual reports whether the latitude and longitude of the two LatLngs +// are the same up to a small tolerance. +func (ll LatLng) ApproxEqual(other LatLng) bool { + return ll.Lat.ApproxEqual(other.Lat) && ll.Lng.ApproxEqual(other.Lng) +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/lexicon.go b/backend/vendor/github.com/blevesearch/geo/s2/lexicon.go new file mode 100644 index 0000000000..41cbffdc24 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/lexicon.go @@ -0,0 +1,175 @@ +// Copyright 2020 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "encoding/binary" + "hash/adler32" + "math" + "sort" +) + +// TODO(roberts): If any of these are worth making public, change the +// method signatures and type names. + +// emptySetID represents the last ID that will ever be generated. +// (Non-negative IDs are reserved for singleton sets.) +var emptySetID = int32(math.MinInt32) + +// idSetLexicon compactly represents a set of non-negative +// integers such as array indices ("ID sets"). It is especially suitable when +// either (1) there are many duplicate sets, or (2) there are many singleton +// or empty sets. See also sequenceLexicon. +// +// Each distinct ID set is mapped to a 32-bit integer. Empty and singleton +// sets take up no additional space; the set itself is represented +// by the unique ID assigned to the set. Duplicate sets are automatically +// eliminated. Note also that ID sets are referred to using 32-bit integers +// rather than pointers. +type idSetLexicon struct { + idSets *sequenceLexicon +} + +func newIDSetLexicon() *idSetLexicon { + return &idSetLexicon{ + idSets: newSequenceLexicon(), + } +} + +// add adds the given set of integers to the lexicon if it is not already +// present, and return the unique ID for this set. The values are automatically +// sorted and duplicates are removed. +// +// The primary difference between this and sequenceLexicon are: +// 1. Empty and singleton sets are represented implicitly; they use no space. +// 2. Sets are represented rather than sequences; the ordering of values is +// not important and duplicates are removed. +// 3. The values must be 32-bit non-negative integers only. +func (l *idSetLexicon) add(ids ...int32) int32 { + // Empty sets have a special ID chosen not to conflict with other IDs. + if len(ids) == 0 { + return emptySetID + } + + // Singleton sets are represented by their element. + if len(ids) == 1 { + return ids[0] + } + + // Canonicalize the set by sorting and removing duplicates. + // + // Creates a new slice in order to not alter the supplied values. + set := uniqueInt32s(ids) + + // Non-singleton sets are represented by the bitwise complement of the ID + // returned by the sequenceLexicon + return ^l.idSets.add(set) +} + +// idSet returns the set of integers corresponding to an ID returned by add. +func (l *idSetLexicon) idSet(setID int32) []int32 { + if setID >= 0 { + return []int32{setID} + } + if setID == emptySetID { + return []int32{} + } + + return l.idSets.sequence(^setID) +} + +func (l *idSetLexicon) clear() { + l.idSets.clear() +} + +// sequenceLexicon compactly represents a sequence of values (e.g., tuples). +// It automatically eliminates duplicates slices, and maps the remaining +// sequences to sequentially increasing integer IDs. See also idSetLexicon. +// +// Each distinct sequence is mapped to a 32-bit integer. +type sequenceLexicon struct { + values []int32 + begins []uint32 + + // idSet is a mapping of a sequence hash to sequence index in the lexicon. + idSet map[uint32]int32 +} + +func newSequenceLexicon() *sequenceLexicon { + return &sequenceLexicon{ + begins: []uint32{0}, + idSet: make(map[uint32]int32), + } +} + +// clears all data from the lexicon. +func (l *sequenceLexicon) clear() { + l.values = nil + l.begins = []uint32{0} + l.idSet = make(map[uint32]int32) +} + +// add adds the given value to the lexicon if it is not already present, and +// returns its ID. IDs are assigned sequentially starting from zero. +func (l *sequenceLexicon) add(ids []int32) int32 { + if id, ok := l.idSet[hashSet(ids)]; ok { + return id + } + for _, v := range ids { + l.values = append(l.values, v) + } + l.begins = append(l.begins, uint32(len(l.values))) + + id := int32(len(l.begins)) - 2 + l.idSet[hashSet(ids)] = id + + return id +} + +// sequence returns the original sequence of values for the given ID. +func (l *sequenceLexicon) sequence(id int32) []int32 { + return l.values[l.begins[id]:l.begins[id+1]] +} + +// size reports the number of value sequences in the lexicon. +func (l *sequenceLexicon) size() int { + // Subtract one because the list of begins starts out with the first element set to 0. + return len(l.begins) - 1 +} + +// hash returns a hash of this sequence of int32s. +func hashSet(s []int32) uint32 { + // TODO(roberts): We just need a way to nicely hash all the values down to + // a 32-bit value. To ensure no unnecessary dependencies we use the core + // library types available to do this. Is there a better option? + a := adler32.New() + binary.Write(a, binary.LittleEndian, s) + return a.Sum32() +} + +// uniqueInt32s returns the sorted and uniqued set of int32s from the input. +func uniqueInt32s(in []int32) []int32 { + var vals []int32 + m := make(map[int32]bool) + for _, i := range in { + if m[i] { + continue + } + m[i] = true + vals = append(vals, i) + } + sort.Slice(vals, func(i, j int) bool { return vals[i] < vals[j] }) + return vals +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/loop.go b/backend/vendor/github.com/blevesearch/geo/s2/loop.go new file mode 100644 index 0000000000..d0035dfa93 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/loop.go @@ -0,0 +1,1833 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "fmt" + "io" + "math" + + "github.com/golang/geo/r1" + "github.com/golang/geo/r3" + "github.com/golang/geo/s1" +) + +// Loop represents a simple spherical polygon. It consists of a sequence +// of vertices where the first vertex is implicitly connected to the +// last. All loops are defined to have a CCW orientation, i.e. the interior of +// the loop is on the left side of the edges. This implies that a clockwise +// loop enclosing a small area is interpreted to be a CCW loop enclosing a +// very large area. +// +// Loops are not allowed to have any duplicate vertices (whether adjacent or +// not). Non-adjacent edges are not allowed to intersect, and furthermore edges +// of length 180 degrees are not allowed (i.e., adjacent vertices cannot be +// antipodal). Loops must have at least 3 vertices (except for the "empty" and +// "full" loops discussed below). +// +// There are two special loops: the "empty" loop contains no points and the +// "full" loop contains all points. These loops do not have any edges, but to +// preserve the invariant that every loop can be represented as a vertex +// chain, they are defined as having exactly one vertex each (see EmptyLoop +// and FullLoop). +type Loop struct { + vertices []Point + + // originInside keeps a precomputed value whether this loop contains the origin + // versus computing from the set of vertices every time. + originInside bool + + // depth is the nesting depth of this Loop if it is contained by a Polygon + // or other shape and is used to determine if this loop represents a hole + // or a filled in portion. + depth int + + // bound is a conservative bound on all points contained by this loop. + // If l.ContainsPoint(P), then l.bound.ContainsPoint(P). + bound Rect + + // Since bound is not exact, it is possible that a loop A contains + // another loop B whose bounds are slightly larger. subregionBound + // has been expanded sufficiently to account for this error, i.e. + // if A.Contains(B), then A.subregionBound.Contains(B.bound). + subregionBound Rect + + // index is the spatial index for this Loop. + index *ShapeIndex +} + +// LoopFromPoints constructs a loop from the given points. +func LoopFromPoints(pts []Point) *Loop { + l := &Loop{ + vertices: pts, + index: NewShapeIndex(), + } + + l.initOriginAndBound() + return l +} + +// LoopFromCell constructs a loop corresponding to the given cell. +// +// Note that the loop and cell *do not* contain exactly the same set of +// points, because Loop and Cell have slightly different definitions of +// point containment. For example, a Cell vertex is contained by all +// four neighboring Cells, but it is contained by exactly one of four +// Loops constructed from those cells. As another example, the cell +// coverings of cell and LoopFromCell(cell) will be different, because the +// loop contains points on its boundary that actually belong to other cells +// (i.e., the covering will include a layer of neighboring cells). +func LoopFromCell(c Cell) *Loop { + l := &Loop{ + vertices: []Point{ + c.Vertex(0), + c.Vertex(1), + c.Vertex(2), + c.Vertex(3), + }, + index: NewShapeIndex(), + } + + l.initOriginAndBound() + return l +} + +// These two points are used for the special Empty and Full loops. +var ( + emptyLoopPoint = Point{r3.Vector{X: 0, Y: 0, Z: 1}} + fullLoopPoint = Point{r3.Vector{X: 0, Y: 0, Z: -1}} +) + +// EmptyLoop returns a special "empty" loop. +func EmptyLoop() *Loop { + return LoopFromPoints([]Point{emptyLoopPoint}) +} + +// FullLoop returns a special "full" loop. +func FullLoop() *Loop { + return LoopFromPoints([]Point{fullLoopPoint}) +} + +// initOriginAndBound sets the origin containment for the given point and then calls +// the initialization for the bounds objects and the internal index. +func (l *Loop) initOriginAndBound() { + if len(l.vertices) < 3 { + // Check for the special "empty" and "full" loops (which have one vertex). + if !l.isEmptyOrFull() { + l.originInside = false + return + } + + // This is the special empty or full loop, so the origin depends on if + // the vertex is in the southern hemisphere or not. + l.originInside = l.vertices[0].Z < 0 + } else { + // Point containment testing is done by counting edge crossings starting + // at a fixed point on the sphere (OriginPoint). We need to know whether + // the reference point (OriginPoint) is inside or outside the loop before + // we can construct the ShapeIndex. We do this by first guessing that + // it is outside, and then seeing whether we get the correct containment + // result for vertex 1. If the result is incorrect, the origin must be + // inside the loop. + // + // A loop with consecutive vertices A,B,C contains vertex B if and only if + // the fixed vector R = B.Ortho is contained by the wedge ABC. The + // wedge is closed at A and open at C, i.e. the point B is inside the loop + // if A = R but not if C = R. This convention is required for compatibility + // with VertexCrossing. (Note that we can't use OriginPoint + // as the fixed vector because of the possibility that B == OriginPoint.) + l.originInside = false + v1Inside := OrderedCCW(Point{l.vertices[1].Ortho()}, l.vertices[0], l.vertices[2], l.vertices[1]) + if v1Inside != l.ContainsPoint(l.vertices[1]) { + l.originInside = true + } + } + + // We *must* call initBound before initializing the index, because + // initBound calls ContainsPoint which does a bounds check before using + // the index. + l.initBound() + + // Create a new index and add us to it. + l.index = NewShapeIndex() + l.index.Add(l) +} + +// initBound sets up the approximate bounding Rects for this loop. +func (l *Loop) initBound() { + if len(l.vertices) == 0 { + *l = *EmptyLoop() + return + } + // Check for the special "empty" and "full" loops. + if l.isEmptyOrFull() { + if l.IsEmpty() { + l.bound = EmptyRect() + } else { + l.bound = FullRect() + } + l.subregionBound = l.bound + return + } + + // The bounding rectangle of a loop is not necessarily the same as the + // bounding rectangle of its vertices. First, the maximal latitude may be + // attained along the interior of an edge. Second, the loop may wrap + // entirely around the sphere (e.g. a loop that defines two revolutions of a + // candy-cane stripe). Third, the loop may include one or both poles. + // Note that a small clockwise loop near the equator contains both poles. + bounder := NewRectBounder() + for i := 0; i <= len(l.vertices); i++ { // add vertex 0 twice + bounder.AddPoint(l.Vertex(i)) + } + b := bounder.RectBound() + + if l.ContainsPoint(Point{r3.Vector{0, 0, 1}}) { + b = Rect{r1.Interval{b.Lat.Lo, math.Pi / 2}, s1.FullInterval()} + } + // If a loop contains the south pole, then either it wraps entirely + // around the sphere (full longitude range), or it also contains the + // north pole in which case b.Lng.IsFull() due to the test above. + // Either way, we only need to do the south pole containment test if + // b.Lng.IsFull(). + if b.Lng.IsFull() && l.ContainsPoint(Point{r3.Vector{0, 0, -1}}) { + b.Lat.Lo = -math.Pi / 2 + } + l.bound = b + l.subregionBound = ExpandForSubregions(l.bound) +} + +// Validate checks whether this is a valid loop. +func (l *Loop) Validate() error { + if err := l.findValidationErrorNoIndex(); err != nil { + return err + } + + // Check for intersections between non-adjacent edges (including at vertices) + // TODO(roberts): Once shapeutil gets findAnyCrossing uncomment this. + // return findAnyCrossing(l.index) + + return nil +} + +// findValidationErrorNoIndex reports whether this is not a valid loop, but +// skips checks that would require a ShapeIndex to be built for the loop. This +// is primarily used by Polygon to do validation so it doesn't trigger the +// creation of unneeded ShapeIndices. +func (l *Loop) findValidationErrorNoIndex() error { + // All vertices must be unit length. + for i, v := range l.vertices { + if !v.IsUnit() { + return fmt.Errorf("vertex %d is not unit length", i) + } + } + + // Loops must have at least 3 vertices (except for empty and full). + if len(l.vertices) < 3 { + if l.isEmptyOrFull() { + return nil // Skip remaining tests. + } + return fmt.Errorf("non-empty, non-full loops must have at least 3 vertices") + } + + // Loops are not allowed to have any duplicate vertices or edge crossings. + // We split this check into two parts. First we check that no edge is + // degenerate (identical endpoints). Then we check that there are no + // intersections between non-adjacent edges (including at vertices). The + // second check needs the ShapeIndex, so it does not fall within the scope + // of this method. + for i, v := range l.vertices { + if v == l.Vertex(i+1) { + return fmt.Errorf("edge %d is degenerate (duplicate vertex)", i) + } + + // Antipodal vertices are not allowed. + if other := (Point{l.Vertex(i + 1).Mul(-1)}); v == other { + return fmt.Errorf("vertices %d and %d are antipodal", i, + (i+1)%len(l.vertices)) + } + } + + return nil +} + +// Contains reports whether the region contained by this loop is a superset of the +// region contained by the given other loop. +func (l *Loop) Contains(o *Loop) bool { + // For a loop A to contain the loop B, all of the following must + // be true: + // + // (1) There are no edge crossings between A and B except at vertices. + // + // (2) At every vertex that is shared between A and B, the local edge + // ordering implies that A contains B. + // + // (3) If there are no shared vertices, then A must contain a vertex of B + // and B must not contain a vertex of A. (An arbitrary vertex may be + // chosen in each case.) + // + // The second part of (3) is necessary to detect the case of two loops whose + // union is the entire sphere, i.e. two loops that contains each other's + // boundaries but not each other's interiors. + if !l.subregionBound.Contains(o.bound) { + return false + } + + // Special cases to handle either loop being empty or full. + if l.isEmptyOrFull() || o.isEmptyOrFull() { + return l.IsFull() || o.IsEmpty() + } + + // Check whether there are any edge crossings, and also check the loop + // relationship at any shared vertices. + relation := &containsRelation{} + if hasCrossingRelation(l, o, relation) { + return false + } + + // There are no crossings, and if there are any shared vertices then A + // contains B locally at each shared vertex. + if relation.foundSharedVertex { + return true + } + + // Since there are no edge intersections or shared vertices, we just need to + // test condition (3) above. We can skip this test if we discovered that A + // contains at least one point of B while checking for edge crossings. + if !l.ContainsPoint(o.Vertex(0)) { + return false + } + + // We still need to check whether (A union B) is the entire sphere. + // Normally this check is very cheap due to the bounding box precondition. + if (o.subregionBound.Contains(l.bound) || o.bound.Union(l.bound).IsFull()) && + o.ContainsPoint(l.Vertex(0)) { + return false + } + return true +} + +// Intersects reports whether the region contained by this loop intersects the region +// contained by the other loop. +func (l *Loop) Intersects(o *Loop) bool { + // Given two loops, A and B, A.Intersects(B) if and only if !A.Complement().Contains(B). + // + // This code is similar to Contains, but is optimized for the case + // where both loops enclose less than half of the sphere. + if !l.bound.Intersects(o.bound) { + return false + } + + // Check whether there are any edge crossings, and also check the loop + // relationship at any shared vertices. + relation := &intersectsRelation{} + if hasCrossingRelation(l, o, relation) { + return true + } + if relation.foundSharedVertex { + return false + } + + // Since there are no edge intersections or shared vertices, the loops + // intersect only if A contains B, B contains A, or the two loops contain + // each other's boundaries. These checks are usually cheap because of the + // bounding box preconditions. Note that neither loop is empty (because of + // the bounding box check above), so it is safe to access vertex(0). + + // Check whether A contains B, or A and B contain each other's boundaries. + // (Note that A contains all the vertices of B in either case.) + if l.subregionBound.Contains(o.bound) || l.bound.Union(o.bound).IsFull() { + if l.ContainsPoint(o.Vertex(0)) { + return true + } + } + // Check whether B contains A. + if o.subregionBound.Contains(l.bound) { + if o.ContainsPoint(l.Vertex(0)) { + return true + } + } + return false +} + +// Equal reports whether two loops have the same vertices in the same linear order +// (i.e., cyclic rotations are not allowed). +func (l *Loop) Equal(other *Loop) bool { + if len(l.vertices) != len(other.vertices) { + return false + } + + for i, v := range l.vertices { + if v != other.Vertex(i) { + return false + } + } + return true +} + +// BoundaryEqual reports whether the two loops have the same boundary. This is +// true if and only if the loops have the same vertices in the same cyclic order +// (i.e., the vertices may be cyclically rotated). The empty and full loops are +// considered to have different boundaries. +func (l *Loop) BoundaryEqual(o *Loop) bool { + if len(l.vertices) != len(o.vertices) { + return false + } + + // Special case to handle empty or full loops. Since they have the same + // number of vertices, if one loop is empty/full then so is the other. + if l.isEmptyOrFull() { + return l.IsEmpty() == o.IsEmpty() + } + + // Loop through the vertices to find the first of ours that matches the + // starting vertex of the other loop. Use that offset to then 'align' the + // vertices for comparison. + for offset, vertex := range l.vertices { + if vertex == o.Vertex(0) { + // There is at most one starting offset since loop vertices are unique. + for i := 0; i < len(l.vertices); i++ { + if l.Vertex(i+offset) != o.Vertex(i) { + return false + } + } + return true + } + } + return false +} + +// compareBoundary returns +1 if this loop contains the boundary of the other loop, +// -1 if it excludes the boundary of the other, and 0 if the boundaries of the two +// loops cross. Shared edges are handled as follows: +// +// If XY is a shared edge, define Reversed(XY) to be true if XY +// appears in opposite directions in both loops. +// Then this loop contains XY if and only if Reversed(XY) == the other loop is a hole. +// (Intuitively, this checks whether this loop contains a vanishingly small region +// extending from the boundary of the other toward the interior of the polygon to +// which the other belongs.) +// +// This function is used for testing containment and intersection of +// multi-loop polygons. Note that this method is not symmetric, since the +// result depends on the direction of this loop but not on the direction of +// the other loop (in the absence of shared edges). +// +// This requires that neither loop is empty, and if other loop IsFull, then it must not +// be a hole. +func (l *Loop) compareBoundary(o *Loop) int { + // The bounds must intersect for containment or crossing. + if !l.bound.Intersects(o.bound) { + return -1 + } + + // Full loops are handled as though the loop surrounded the entire sphere. + if l.IsFull() { + return 1 + } + if o.IsFull() { + return -1 + } + + // Check whether there are any edge crossings, and also check the loop + // relationship at any shared vertices. + relation := newCompareBoundaryRelation(o.IsHole()) + if hasCrossingRelation(l, o, relation) { + return 0 + } + if relation.foundSharedVertex { + if relation.containsEdge { + return 1 + } + return -1 + } + + // There are no edge intersections or shared vertices, so we can check + // whether A contains an arbitrary vertex of B. + if l.ContainsPoint(o.Vertex(0)) { + return 1 + } + return -1 +} + +// ContainsOrigin reports true if this loop contains s2.OriginPoint(). +func (l *Loop) ContainsOrigin() bool { + return l.originInside +} + +// ReferencePoint returns the reference point for this loop. +func (l *Loop) ReferencePoint() ReferencePoint { + return OriginReferencePoint(l.originInside) +} + +// NumEdges returns the number of edges in this shape. +func (l *Loop) NumEdges() int { + if l.isEmptyOrFull() { + return 0 + } + return len(l.vertices) +} + +// Edge returns the endpoints for the given edge index. +func (l *Loop) Edge(i int) Edge { + return Edge{l.Vertex(i), l.Vertex(i + 1)} +} + +// NumChains reports the number of contiguous edge chains in the Loop. +func (l *Loop) NumChains() int { + if l.IsEmpty() { + return 0 + } + return 1 +} + +// Chain returns the i-th edge chain in the Shape. +func (l *Loop) Chain(chainID int) Chain { + return Chain{0, l.NumEdges()} +} + +// ChainEdge returns the j-th edge of the i-th edge chain. +func (l *Loop) ChainEdge(chainID, offset int) Edge { + return Edge{l.Vertex(offset), l.Vertex(offset + 1)} +} + +// ChainPosition returns a ChainPosition pair (i, j) such that edgeID is the +// j-th edge of the Loop. +func (l *Loop) ChainPosition(edgeID int) ChainPosition { + return ChainPosition{0, edgeID} +} + +// Dimension returns the dimension of the geometry represented by this Loop. +func (l *Loop) Dimension() int { return 2 } + +func (l *Loop) typeTag() typeTag { return typeTagNone } + +func (l *Loop) privateInterface() {} + +// IsEmpty reports true if this is the special empty loop that contains no points. +func (l *Loop) IsEmpty() bool { + return l.isEmptyOrFull() && !l.ContainsOrigin() +} + +// IsFull reports true if this is the special full loop that contains all points. +func (l *Loop) IsFull() bool { + return l.isEmptyOrFull() && l.ContainsOrigin() +} + +// isEmptyOrFull reports true if this loop is either the "empty" or "full" special loops. +func (l *Loop) isEmptyOrFull() bool { + return len(l.vertices) == 1 +} + +// Vertices returns the vertices in the loop. +func (l *Loop) Vertices() []Point { + return l.vertices +} + +// RectBound returns a tight bounding rectangle. If the loop contains the point, +// the bound also contains it. +func (l *Loop) RectBound() Rect { + return l.bound +} + +// CapBound returns a bounding cap that may have more padding than the corresponding +// RectBound. The bound is conservative such that if the loop contains a point P, +// the bound also contains it. +func (l *Loop) CapBound() Cap { + return l.bound.CapBound() +} + +// Vertex returns the vertex for the given index. For convenience, the vertex indices +// wrap automatically for methods that do index math such as Edge. +// i.e., Vertex(NumEdges() + n) is the same as Vertex(n). +func (l *Loop) Vertex(i int) Point { + return l.vertices[i%len(l.vertices)] +} + +// OrientedVertex returns the vertex in reverse order if the loop represents a polygon +// hole. For example, arguments 0, 1, 2 are mapped to vertices n-1, n-2, n-3, where +// n == len(vertices). This ensures that the interior of the polygon is always to +// the left of the vertex chain. +// +// This requires: 0 <= i < 2 * len(vertices) +func (l *Loop) OrientedVertex(i int) Point { + j := i - len(l.vertices) + if j < 0 { + j = i + } + if l.IsHole() { + j = len(l.vertices) - 1 - j + } + return l.Vertex(j) +} + +// NumVertices returns the number of vertices in this loop. +func (l *Loop) NumVertices() int { + return len(l.vertices) +} + +// bruteForceContainsPoint reports if the given point is contained by this loop. +// This method does not use the ShapeIndex, so it is only preferable below a certain +// size of loop. +func (l *Loop) bruteForceContainsPoint(p Point) bool { + origin := OriginPoint() + inside := l.originInside + crosser := NewChainEdgeCrosser(origin, p, l.Vertex(0)) + for i := 1; i <= len(l.vertices); i++ { // add vertex 0 twice + inside = inside != crosser.EdgeOrVertexChainCrossing(l.Vertex(i)) + } + return inside +} + +// ContainsPoint returns true if the loop contains the point. +func (l *Loop) ContainsPoint(p Point) bool { + if !l.index.IsFresh() && !l.bound.ContainsPoint(p) { + return false + } + + // For small loops it is faster to just check all the crossings. We also + // use this method during loop initialization because InitOriginAndBound() + // calls Contains() before InitIndex(). Otherwise, we keep track of the + // number of calls to Contains() and only build the index when enough calls + // have been made so that we think it is worth the effort. Note that the + // code below is structured so that if many calls are made in parallel only + // one thread builds the index, while the rest continue using brute force + // until the index is actually available. + + const maxBruteForceVertices = 32 + // TODO(roberts): add unindexed contains calls tracking + + if len(l.index.shapes) == 0 || // Index has not been initialized yet. + len(l.vertices) <= maxBruteForceVertices { + return l.bruteForceContainsPoint(p) + } + + // Otherwise, look up the point in the index. + it := l.index.Iterator() + if !it.LocatePoint(p) { + return false + } + return l.iteratorContainsPoint(it, p) +} + +// ContainsCell reports whether the given Cell is contained by this Loop. +func (l *Loop) ContainsCell(target Cell) bool { + it := l.index.Iterator() + relation := it.LocateCellID(target.ID()) + + // If "target" is disjoint from all index cells, it is not contained. + // Similarly, if "target" is subdivided into one or more index cells then it + // is not contained, since index cells are subdivided only if they (nearly) + // intersect a sufficient number of edges. (But note that if "target" itself + // is an index cell then it may be contained, since it could be a cell with + // no edges in the loop interior.) + if relation != Indexed { + return false + } + + // Otherwise check if any edges intersect "target". + if l.boundaryApproxIntersects(it, target) { + return false + } + + // Otherwise check if the loop contains the center of "target". + return l.iteratorContainsPoint(it, target.Center()) +} + +// IntersectsCell reports whether this Loop intersects the given cell. +func (l *Loop) IntersectsCell(target Cell) bool { + it := l.index.Iterator() + relation := it.LocateCellID(target.ID()) + + // If target does not overlap any index cell, there is no intersection. + if relation == Disjoint { + return false + } + // If target is subdivided into one or more index cells, there is an + // intersection to within the ShapeIndex error bound (see Contains). + if relation == Subdivided { + return true + } + // If target is an index cell, there is an intersection because index cells + // are created only if they have at least one edge or they are entirely + // contained by the loop. + if it.CellID() == target.id { + return true + } + // Otherwise check if any edges intersect target. + if l.boundaryApproxIntersects(it, target) { + return true + } + // Otherwise check if the loop contains the center of target. + return l.iteratorContainsPoint(it, target.Center()) +} + +// CellUnionBound computes a covering of the Loop. +func (l *Loop) CellUnionBound() []CellID { + return l.CapBound().CellUnionBound() +} + +// boundaryApproxIntersects reports if the loop's boundary intersects target. +// It may also return true when the loop boundary does not intersect target but +// some edge comes within the worst-case error tolerance. +// +// This requires that it.Locate(target) returned Indexed. +func (l *Loop) boundaryApproxIntersects(it *ShapeIndexIterator, target Cell) bool { + aClipped := it.IndexCell().findByShapeID(0) + + // If there are no edges, there is no intersection. + if len(aClipped.edges) == 0 { + return false + } + + // We can save some work if target is the index cell itself. + if it.CellID() == target.ID() { + return true + } + + // Otherwise check whether any of the edges intersect target. + maxError := (faceClipErrorUVCoord + intersectsRectErrorUVDist) + bound := target.BoundUV().ExpandedByMargin(maxError) + for _, ai := range aClipped.edges { + v0, v1, ok := ClipToPaddedFace(l.Vertex(ai), l.Vertex(ai+1), target.Face(), maxError) + if ok && edgeIntersectsRect(v0, v1, bound) { + return true + } + } + return false +} + +// iteratorContainsPoint reports if the iterator that is positioned at the ShapeIndexCell +// that may contain p, contains the point p. +func (l *Loop) iteratorContainsPoint(it *ShapeIndexIterator, p Point) bool { + // Test containment by drawing a line segment from the cell center to the + // given point and counting edge crossings. + aClipped := it.IndexCell().findByShapeID(0) + inside := aClipped.containsCenter + if len(aClipped.edges) > 0 { + center := it.Center() + crosser := NewEdgeCrosser(center, p) + aiPrev := -2 + for _, ai := range aClipped.edges { + if ai != aiPrev+1 { + crosser.RestartAt(l.Vertex(ai)) + } + aiPrev = ai + inside = inside != crosser.EdgeOrVertexChainCrossing(l.Vertex(ai+1)) + } + } + return inside +} + +// RegularLoop creates a loop with the given number of vertices, all +// located on a circle of the specified radius around the given center. +func RegularLoop(center Point, radius s1.Angle, numVertices int) *Loop { + return RegularLoopForFrame(getFrame(center), radius, numVertices) +} + +// RegularLoopForFrame creates a loop centered around the z-axis of the given +// coordinate frame, with the first vertex in the direction of the positive x-axis. +func RegularLoopForFrame(frame matrix3x3, radius s1.Angle, numVertices int) *Loop { + return LoopFromPoints(regularPointsForFrame(frame, radius, numVertices)) +} + +// CanonicalFirstVertex returns a first index and a direction (either +1 or -1) +// such that the vertex sequence (first, first+dir, ..., first+(n-1)*dir) does +// not change when the loop vertex order is rotated or inverted. This allows the +// loop vertices to be traversed in a canonical order. The return values are +// chosen such that (first, ..., first+n*dir) are in the range [0, 2*n-1] as +// expected by the Vertex method. +func (l *Loop) CanonicalFirstVertex() (firstIdx, direction int) { + firstIdx = 0 + n := len(l.vertices) + for i := 1; i < n; i++ { + if l.Vertex(i).Cmp(l.Vertex(firstIdx).Vector) == -1 { + firstIdx = i + } + } + + // 0 <= firstIdx <= n-1, so (firstIdx+n*dir) <= 2*n-1. + if l.Vertex(firstIdx+1).Cmp(l.Vertex(firstIdx+n-1).Vector) == -1 { + return firstIdx, 1 + } + + // n <= firstIdx <= 2*n-1, so (firstIdx+n*dir) >= 0. + firstIdx += n + return firstIdx, -1 +} + +// TurningAngle returns the sum of the turning angles at each vertex. The return +// value is positive if the loop is counter-clockwise, negative if the loop is +// clockwise, and zero if the loop is a great circle. Degenerate and +// nearly-degenerate loops are handled consistently with Sign. So for example, +// if a loop has zero area (i.e., it is a very small CCW loop) then the turning +// angle will always be negative. +// +// This quantity is also called the "geodesic curvature" of the loop. +func (l *Loop) TurningAngle() float64 { + // For empty and full loops, we return the limit value as the loop area + // approaches 0 or 4*Pi respectively. + if l.isEmptyOrFull() { + if l.ContainsOrigin() { + return -2 * math.Pi + } + return 2 * math.Pi + } + + // Don't crash even if the loop is not well-defined. + if len(l.vertices) < 3 { + return 0 + } + + // To ensure that we get the same result when the vertex order is rotated, + // and that the result is negated when the vertex order is reversed, we need + // to add up the individual turn angles in a consistent order. (In general, + // adding up a set of numbers in a different order can change the sum due to + // rounding errors.) + // + // Furthermore, if we just accumulate an ordinary sum then the worst-case + // error is quadratic in the number of vertices. (This can happen with + // spiral shapes, where the partial sum of the turning angles can be linear + // in the number of vertices.) To avoid this we use the Kahan summation + // algorithm (http://en.wikipedia.org/wiki/Kahan_summation_algorithm). + n := len(l.vertices) + i, dir := l.CanonicalFirstVertex() + sum := TurnAngle(l.Vertex((i+n-dir)%n), l.Vertex(i), l.Vertex((i+dir)%n)) + + compensation := s1.Angle(0) + for n-1 > 0 { + i += dir + angle := TurnAngle(l.Vertex(i-dir), l.Vertex(i), l.Vertex(i+dir)) + oldSum := sum + angle += compensation + sum += angle + compensation = (oldSum - sum) + angle + n-- + } + + const maxCurvature = 2*math.Pi - 4*dblEpsilon + + return math.Max(-maxCurvature, math.Min(maxCurvature, float64(dir)*float64(sum+compensation))) +} + +// turningAngleMaxError return the maximum error in TurningAngle. The value is not +// constant; it depends on the loop. +func (l *Loop) turningAngleMaxError() float64 { + // The maximum error can be bounded as follows: + // 3.00 * dblEpsilon for RobustCrossProd(b, a) + // 3.00 * dblEpsilon for RobustCrossProd(c, b) + // 3.25 * dblEpsilon for Angle() + // 2.00 * dblEpsilon for each addition in the Kahan summation + // ------------------ + // 11.25 * dblEpsilon + maxErrorPerVertex := 11.25 * dblEpsilon + return maxErrorPerVertex * float64(len(l.vertices)) +} + +// IsHole reports whether this loop represents a hole in its containing polygon. +func (l *Loop) IsHole() bool { return l.depth&1 != 0 } + +// Sign returns -1 if this Loop represents a hole in its containing polygon, and +1 otherwise. +func (l *Loop) Sign() int { + if l.IsHole() { + return -1 + } + return 1 +} + +// IsNormalized reports whether the loop area is at most 2*pi. Degenerate loops are +// handled consistently with Sign, i.e., if a loop can be +// expressed as the union of degenerate or nearly-degenerate CCW triangles, +// then it will always be considered normalized. +func (l *Loop) IsNormalized() bool { + // Optimization: if the longitude span is less than 180 degrees, then the + // loop covers less than half the sphere and is therefore normalized. + if l.bound.Lng.Length() < math.Pi { + return true + } + + // We allow some error so that hemispheres are always considered normalized. + // TODO(roberts): This is no longer required by the Polygon implementation, + // so alternatively we could create the invariant that a loop is normalized + // if and only if its complement is not normalized. + return l.TurningAngle() >= -l.turningAngleMaxError() +} + +// Normalize inverts the loop if necessary so that the area enclosed by the loop +// is at most 2*pi. +func (l *Loop) Normalize() { + if !l.IsNormalized() { + l.Invert() + } +} + +// Invert reverses the order of the loop vertices, effectively complementing the +// region represented by the loop. For example, the loop ABCD (with edges +// AB, BC, CD, DA) becomes the loop DCBA (with edges DC, CB, BA, AD). +// Notice that the last edge is the same in both cases except that its +// direction has been reversed. +func (l *Loop) Invert() { + l.index.Reset() + if l.isEmptyOrFull() { + if l.IsFull() { + l.vertices[0] = emptyLoopPoint + } else { + l.vertices[0] = fullLoopPoint + } + } else { + // For non-special loops, reverse the slice of vertices. + for i := len(l.vertices)/2 - 1; i >= 0; i-- { + opp := len(l.vertices) - 1 - i + l.vertices[i], l.vertices[opp] = l.vertices[opp], l.vertices[i] + } + } + + // originInside must be set correctly before building the ShapeIndex. + l.originInside = !l.originInside + if l.bound.Lat.Lo > -math.Pi/2 && l.bound.Lat.Hi < math.Pi/2 { + // The complement of this loop contains both poles. + l.bound = FullRect() + l.subregionBound = l.bound + } else { + l.initBound() + } + l.index.Add(l) +} + +// findVertex returns the index of the vertex at the given Point in the range +// 1..numVertices, and a boolean indicating if a vertex was found. +func (l *Loop) findVertex(p Point) (index int, ok bool) { + const notFound = 0 + if len(l.vertices) < 10 { + // Exhaustive search for loops below a small threshold. + for i := 1; i <= len(l.vertices); i++ { + if l.Vertex(i) == p { + return i, true + } + } + return notFound, false + } + + it := l.index.Iterator() + if !it.LocatePoint(p) { + return notFound, false + } + + aClipped := it.IndexCell().findByShapeID(0) + for i := aClipped.numEdges() - 1; i >= 0; i-- { + ai := aClipped.edges[i] + if l.Vertex(ai) == p { + if ai == 0 { + return len(l.vertices), true + } + return ai, true + } + + if l.Vertex(ai+1) == p { + return ai + 1, true + } + } + return notFound, false +} + +// ContainsNested reports whether the given loops is contained within this loop. +// This function does not test for edge intersections. The two loops must meet +// all of the Polygon requirements; for example this implies that their +// boundaries may not cross or have any shared edges (although they may have +// shared vertices). +func (l *Loop) ContainsNested(other *Loop) bool { + if !l.subregionBound.Contains(other.bound) { + return false + } + + // Special cases to handle either loop being empty or full. Also bail out + // when B has no vertices to avoid heap overflow on the vertex(1) call + // below. (This method is called during polygon initialization before the + // client has an opportunity to call IsValid().) + if l.isEmptyOrFull() || other.NumVertices() < 2 { + return l.IsFull() || other.IsEmpty() + } + + // We are given that A and B do not share any edges, and that either one + // loop contains the other or they do not intersect. + m, ok := l.findVertex(other.Vertex(1)) + if !ok { + // Since other.vertex(1) is not shared, we can check whether A contains it. + return l.ContainsPoint(other.Vertex(1)) + } + + // Check whether the edge order around other.Vertex(1) is compatible with + // A containing B. + return WedgeContains(l.Vertex(m-1), l.Vertex(m), l.Vertex(m+1), other.Vertex(0), other.Vertex(2)) +} + +// surfaceIntegralFloat64 computes the oriented surface integral of some quantity f(x) +// over the loop interior, given a function f(A,B,C) that returns the +// corresponding integral over the spherical triangle ABC. Here "oriented +// surface integral" means: +// +// (1) f(A,B,C) must be the integral of f if ABC is counterclockwise, +// and the integral of -f if ABC is clockwise. +// +// (2) The result of this function is *either* the integral of f over the +// loop interior, or the integral of (-f) over the loop exterior. +// +// Note that there are at least two common situations where it easy to work +// around property (2) above: +// +// - If the integral of f over the entire sphere is zero, then it doesn't +// matter which case is returned because they are always equal. +// +// - If f is non-negative, then it is easy to detect when the integral over +// the loop exterior has been returned, and the integral over the loop +// interior can be obtained by adding the integral of f over the entire +// unit sphere (a constant) to the result. +// +// Any changes to this method may need corresponding changes to surfaceIntegralPoint as well. +func (l *Loop) surfaceIntegralFloat64(f func(a, b, c Point) float64) float64 { + // We sum f over a collection T of oriented triangles, possibly + // overlapping. Let the sign of a triangle be +1 if it is CCW and -1 + // otherwise, and let the sign of a point x be the sum of the signs of the + // triangles containing x. Then the collection of triangles T is chosen + // such that either: + // + // (1) Each point in the loop interior has sign +1, and sign 0 otherwise; or + // (2) Each point in the loop exterior has sign -1, and sign 0 otherwise. + // + // The triangles basically consist of a fan from vertex 0 to every loop + // edge that does not include vertex 0. These triangles will always satisfy + // either (1) or (2). However, what makes this a bit tricky is that + // spherical edges become numerically unstable as their length approaches + // 180 degrees. Of course there is not much we can do if the loop itself + // contains such edges, but we would like to make sure that all the triangle + // edges under our control (i.e., the non-loop edges) are stable. For + // example, consider a loop around the equator consisting of four equally + // spaced points. This is a well-defined loop, but we cannot just split it + // into two triangles by connecting vertex 0 to vertex 2. + // + // We handle this type of situation by moving the origin of the triangle fan + // whenever we are about to create an unstable edge. We choose a new + // location for the origin such that all relevant edges are stable. We also + // create extra triangles with the appropriate orientation so that the sum + // of the triangle signs is still correct at every point. + + // The maximum length of an edge for it to be considered numerically stable. + // The exact value is fairly arbitrary since it depends on the stability of + // the function f. The value below is quite conservative but could be + // reduced further if desired. + const maxLength = math.Pi - 1e-5 + + var sum float64 + origin := l.Vertex(0) + for i := 1; i+1 < len(l.vertices); i++ { + // Let V_i be vertex(i), let O be the current origin, and let length(A,B) + // be the length of edge (A,B). At the start of each loop iteration, the + // "leading edge" of the triangle fan is (O,V_i), and we want to extend + // the triangle fan so that the leading edge is (O,V_i+1). + // + // Invariants: + // 1. length(O,V_i) < maxLength for all (i > 1). + // 2. Either O == V_0, or O is approximately perpendicular to V_0. + // 3. "sum" is the oriented integral of f over the area defined by + // (O, V_0, V_1, ..., V_i). + if l.Vertex(i+1).Angle(origin.Vector) > maxLength { + // We are about to create an unstable edge, so choose a new origin O' + // for the triangle fan. + oldOrigin := origin + if origin == l.Vertex(0) { + // The following point is well-separated from V_i and V_0 (and + // therefore V_i+1 as well). + origin = Point{l.Vertex(0).PointCross(l.Vertex(i)).Normalize()} + } else if l.Vertex(i).Angle(l.Vertex(0).Vector) < maxLength { + // All edges of the triangle (O, V_0, V_i) are stable, so we can + // revert to using V_0 as the origin. + origin = l.Vertex(0) + } else { + // (O, V_i+1) and (V_0, V_i) are antipodal pairs, and O and V_0 are + // perpendicular. Therefore V_0.CrossProd(O) is approximately + // perpendicular to all of {O, V_0, V_i, V_i+1}, and we can choose + // this point O' as the new origin. + origin = Point{l.Vertex(0).Cross(oldOrigin.Vector)} + + // Advance the edge (V_0,O) to (V_0,O'). + sum += f(l.Vertex(0), oldOrigin, origin) + } + // Advance the edge (O,V_i) to (O',V_i). + sum += f(oldOrigin, l.Vertex(i), origin) + } + // Advance the edge (O,V_i) to (O,V_i+1). + sum += f(origin, l.Vertex(i), l.Vertex(i+1)) + } + // If the origin is not V_0, we need to sum one more triangle. + if origin != l.Vertex(0) { + // Advance the edge (O,V_n-1) to (O,V_0). + sum += f(origin, l.Vertex(len(l.vertices)-1), l.Vertex(0)) + } + return sum +} + +// surfaceIntegralPoint mirrors the surfaceIntegralFloat64 method but over Points; +// see that method for commentary. The C++ version uses a templated method. +// Any changes to this method may need corresponding changes to surfaceIntegralFloat64 as well. +func (l *Loop) surfaceIntegralPoint(f func(a, b, c Point) Point) Point { + const maxLength = math.Pi - 1e-5 + var sum r3.Vector + + origin := l.Vertex(0) + for i := 1; i+1 < len(l.vertices); i++ { + if l.Vertex(i+1).Angle(origin.Vector) > maxLength { + oldOrigin := origin + if origin == l.Vertex(0) { + origin = Point{l.Vertex(0).PointCross(l.Vertex(i)).Normalize()} + } else if l.Vertex(i).Angle(l.Vertex(0).Vector) < maxLength { + origin = l.Vertex(0) + } else { + origin = Point{l.Vertex(0).Cross(oldOrigin.Vector)} + sum = sum.Add(f(l.Vertex(0), oldOrigin, origin).Vector) + } + sum = sum.Add(f(oldOrigin, l.Vertex(i), origin).Vector) + } + sum = sum.Add(f(origin, l.Vertex(i), l.Vertex(i+1)).Vector) + } + if origin != l.Vertex(0) { + sum = sum.Add(f(origin, l.Vertex(len(l.vertices)-1), l.Vertex(0)).Vector) + } + return Point{sum} +} + +// Area returns the area of the loop interior, i.e. the region on the left side of +// the loop. The return value is between 0 and 4*pi. (Note that the return +// value is not affected by whether this loop is a "hole" or a "shell".) +func (l *Loop) Area() float64 { + // It is surprisingly difficult to compute the area of a loop robustly. The + // main issues are (1) whether degenerate loops are considered to be CCW or + // not (i.e., whether their area is close to 0 or 4*pi), and (2) computing + // the areas of small loops with good relative accuracy. + // + // With respect to degeneracies, we would like Area to be consistent + // with ContainsPoint in that loops that contain many points + // should have large areas, and loops that contain few points should have + // small areas. For example, if a degenerate triangle is considered CCW + // according to s2predicates Sign, then it will contain very few points and + // its area should be approximately zero. On the other hand if it is + // considered clockwise, then it will contain virtually all points and so + // its area should be approximately 4*pi. + // + // More precisely, let U be the set of Points for which IsUnitLength + // is true, let P(U) be the projection of those points onto the mathematical + // unit sphere, and let V(P(U)) be the Voronoi diagram of the projected + // points. Then for every loop x, we would like Area to approximately + // equal the sum of the areas of the Voronoi regions of the points p for + // which x.ContainsPoint(p) is true. + // + // The second issue is that we want to compute the area of small loops + // accurately. This requires having good relative precision rather than + // good absolute precision. For example, if the area of a loop is 1e-12 and + // the error is 1e-15, then the area only has 3 digits of accuracy. (For + // reference, 1e-12 is about 40 square meters on the surface of the earth.) + // We would like to have good relative accuracy even for small loops. + // + // To achieve these goals, we combine two different methods of computing the + // area. This first method is based on the Gauss-Bonnet theorem, which says + // that the area enclosed by the loop equals 2*pi minus the total geodesic + // curvature of the loop (i.e., the sum of the "turning angles" at all the + // loop vertices). The big advantage of this method is that as long as we + // use Sign to compute the turning angle at each vertex, then + // degeneracies are always handled correctly. In other words, if a + // degenerate loop is CCW according to the symbolic perturbations used by + // Sign, then its turning angle will be approximately 2*pi. + // + // The disadvantage of the Gauss-Bonnet method is that its absolute error is + // about 2e-15 times the number of vertices (see turningAngleMaxError). + // So, it cannot compute the area of small loops accurately. + // + // The second method is based on splitting the loop into triangles and + // summing the area of each triangle. To avoid the difficulty and expense + // of decomposing the loop into a union of non-overlapping triangles, + // instead we compute a signed sum over triangles that may overlap (see the + // comments for surfaceIntegral). The advantage of this method + // is that the area of each triangle can be computed with much better + // relative accuracy (using l'Huilier's theorem). The disadvantage is that + // the result is a signed area: CCW loops may yield a small positive value, + // while CW loops may yield a small negative value (which is converted to a + // positive area by adding 4*pi). This means that small errors in computing + // the signed area may translate into a very large error in the result (if + // the sign of the sum is incorrect). + // + // So, our strategy is to combine these two methods as follows. First we + // compute the area using the "signed sum over triangles" approach (since it + // is generally more accurate). We also estimate the maximum error in this + // result. If the signed area is too close to zero (i.e., zero is within + // the error bounds), then we double-check the sign of the result using the + // Gauss-Bonnet method. (In fact we just call IsNormalized, which is + // based on this method.) If the two methods disagree, we return either 0 + // or 4*pi based on the result of IsNormalized. Otherwise we return the + // area that we computed originally. + if l.isEmptyOrFull() { + if l.ContainsOrigin() { + return 4 * math.Pi + } + return 0 + } + area := l.surfaceIntegralFloat64(SignedArea) + + // TODO(roberts): This error estimate is very approximate. There are two + // issues: (1) SignedArea needs some improvements to ensure that its error + // is actually never higher than GirardArea, and (2) although the number of + // triangles in the sum is typically N-2, in theory it could be as high as + // 2*N for pathological inputs. But in other respects this error bound is + // very conservative since it assumes that the maximum error is achieved on + // every triangle. + maxError := l.turningAngleMaxError() + + // The signed area should be between approximately -4*pi and 4*pi. + if area < 0 { + // We have computed the negative of the area of the loop exterior. + area += 4 * math.Pi + } + + if area > 4*math.Pi { + area = 4 * math.Pi + } + if area < 0 { + area = 0 + } + + // If the area is close enough to zero or 4*pi so that the loop orientation + // is ambiguous, then we compute the loop orientation explicitly. + if area < maxError && !l.IsNormalized() { + return 4 * math.Pi + } else if area > (4*math.Pi-maxError) && l.IsNormalized() { + return 0 + } + + return area +} + +// Centroid returns the true centroid of the loop multiplied by the area of the +// loop. The result is not unit length, so you may want to normalize it. Also +// note that in general, the centroid may not be contained by the loop. +// +// We prescale by the loop area for two reasons: (1) it is cheaper to +// compute this way, and (2) it makes it easier to compute the centroid of +// more complicated shapes (by splitting them into disjoint regions and +// adding their centroids). +// +// Note that the return value is not affected by whether this loop is a +// "hole" or a "shell". +func (l *Loop) Centroid() Point { + // surfaceIntegralPoint() returns either the integral of position over loop + // interior, or the negative of the integral of position over the loop + // exterior. But these two values are the same (!), because the integral of + // position over the entire sphere is (0, 0, 0). + return l.surfaceIntegralPoint(TrueCentroid) +} + +// Encode encodes the Loop. +func (l Loop) Encode(w io.Writer) error { + e := &encoder{w: w} + l.encode(e) + return e.err +} + +func (l Loop) encode(e *encoder) { + e.writeInt8(encodingVersion) + e.writeUint32(uint32(len(l.vertices))) + for _, v := range l.vertices { + e.writeFloat64(v.X) + e.writeFloat64(v.Y) + e.writeFloat64(v.Z) + } + + e.writeBool(l.originInside) + e.writeInt32(int32(l.depth)) + + // Encode the bound. + l.bound.encode(e) +} + +// Decode decodes a loop. +func (l *Loop) Decode(r io.Reader) error { + *l = Loop{} + d := &decoder{r: asByteReader(r)} + l.decode(d) + return d.err +} + +func (l *Loop) decode(d *decoder) { + version := int8(d.readUint8()) + if d.err != nil { + return + } + if version != encodingVersion { + d.err = fmt.Errorf("cannot decode version %d", version) + return + } + + // Empty loops are explicitly allowed here: a newly created loop has zero vertices + // and such loops encode and decode properly. + nvertices := d.readUint32() + if nvertices > maxEncodedVertices { + if d.err == nil { + d.err = fmt.Errorf("too many vertices (%d; max is %d)", nvertices, maxEncodedVertices) + + } + return + } + l.vertices = make([]Point, nvertices) + for i := range l.vertices { + l.vertices[i].X = d.readFloat64() + l.vertices[i].Y = d.readFloat64() + l.vertices[i].Z = d.readFloat64() + } + l.index = NewShapeIndex() + l.originInside = d.readBool() + l.depth = int(d.readUint32()) + l.bound.decode(d) + l.subregionBound = ExpandForSubregions(l.bound) + + l.index.Add(l) +} + +// Bitmasks to read from properties. +const ( + originInside = 1 << iota + boundEncoded +) + +func (l *Loop) xyzFaceSiTiVertices() []xyzFaceSiTi { + ret := make([]xyzFaceSiTi, len(l.vertices)) + for i, v := range l.vertices { + ret[i].xyz = v + ret[i].face, ret[i].si, ret[i].ti, ret[i].level = xyzToFaceSiTi(v) + } + return ret +} + +func (l *Loop) encodeCompressed(e *encoder, snapLevel int, vertices []xyzFaceSiTi) { + if len(l.vertices) != len(vertices) { + panic("encodeCompressed: vertices must be the same length as l.vertices") + } + if len(vertices) > maxEncodedVertices { + if e.err == nil { + e.err = fmt.Errorf("too many vertices (%d; max is %d)", len(vertices), maxEncodedVertices) + } + return + } + e.writeUvarint(uint64(len(vertices))) + encodePointsCompressed(e, vertices, snapLevel) + + props := l.compressedEncodingProperties() + e.writeUvarint(props) + e.writeUvarint(uint64(l.depth)) + if props&boundEncoded != 0 { + l.bound.encode(e) + } +} + +func (l *Loop) compressedEncodingProperties() uint64 { + var properties uint64 + if l.originInside { + properties |= originInside + } + + // Write whether there is a bound so we can change the threshold later. + // Recomputing the bound multiplies the decode time taken per vertex + // by a factor of about 3.5. Without recomputing the bound, decode + // takes approximately 125 ns / vertex. A loop with 63 vertices + // encoded without the bound will take ~30us to decode, which is + // acceptable. At ~3.5 bytes / vertex without the bound, adding + // the bound will increase the size by <15%, which is also acceptable. + const minVerticesForBound = 64 + if len(l.vertices) >= minVerticesForBound { + properties |= boundEncoded + } + + return properties +} + +func (l *Loop) decodeCompressed(d *decoder, snapLevel int) { + nvertices := d.readUvarint() + if d.err != nil { + return + } + if nvertices > maxEncodedVertices { + d.err = fmt.Errorf("too many vertices (%d; max is %d)", nvertices, maxEncodedVertices) + return + } + l.vertices = make([]Point, nvertices) + decodePointsCompressed(d, snapLevel, l.vertices) + properties := d.readUvarint() + + // Make sure values are valid before using. + if d.err != nil { + return + } + + l.index = NewShapeIndex() + l.originInside = (properties & originInside) != 0 + + l.depth = int(d.readUvarint()) + + if (properties & boundEncoded) != 0 { + l.bound.decode(d) + if d.err != nil { + return + } + l.subregionBound = ExpandForSubregions(l.bound) + } else { + l.initBound() + } + + l.index.Add(l) +} + +// crossingTarget is an enum representing the possible crossing target cases for relations. +type crossingTarget int + +const ( + crossingTargetDontCare crossingTarget = iota + crossingTargetDontCross + crossingTargetCross +) + +// loopRelation defines the interface for checking a type of relationship between two loops. +// Some examples of relations are Contains, Intersects, or CompareBoundary. +type loopRelation interface { + // Optionally, aCrossingTarget and bCrossingTarget can specify an early-exit + // condition for the loop relation. If any point P is found such that + // + // A.ContainsPoint(P) == aCrossingTarget() && + // B.ContainsPoint(P) == bCrossingTarget() + // + // then the loop relation is assumed to be the same as if a pair of crossing + // edges were found. For example, the ContainsPoint relation has + // + // aCrossingTarget() == crossingTargetDontCross + // bCrossingTarget() == crossingTargetCross + // + // because if A.ContainsPoint(P) == false and B.ContainsPoint(P) == true + // for any point P, then it is equivalent to finding an edge crossing (i.e., + // since Contains returns false in both cases). + // + // Loop relations that do not have an early-exit condition of this form + // should return crossingTargetDontCare for both crossing targets. + + // aCrossingTarget reports whether loop A crosses the target point with + // the given relation type. + aCrossingTarget() crossingTarget + // bCrossingTarget reports whether loop B crosses the target point with + // the given relation type. + bCrossingTarget() crossingTarget + + // wedgesCross reports if a shared vertex ab1 and the two associated wedges + // (a0, ab1, b2) and (b0, ab1, b2) are equivalent to an edge crossing. + // The loop relation is also allowed to maintain its own internal state, and + // can return true if it observes any sequence of wedges that are equivalent + // to an edge crossing. + wedgesCross(a0, ab1, a2, b0, b2 Point) bool +} + +// loopCrosser is a helper type for determining whether two loops cross. +// It is instantiated twice for each pair of loops to be tested, once for the +// pair (A,B) and once for the pair (B,A), in order to be able to process +// edges in either loop nesting order. +type loopCrosser struct { + a, b *Loop + relation loopRelation + swapped bool + aCrossingTarget crossingTarget + bCrossingTarget crossingTarget + + // state maintained by startEdge and edgeCrossesCell. + crosser *EdgeCrosser + aj, bjPrev int + + // temporary data declared here to avoid repeated memory allocations. + bQuery *CrossingEdgeQuery + bCells []*ShapeIndexCell +} + +// newLoopCrosser creates a loopCrosser from the given values. If swapped is true, +// the loops A and B have been swapped. This affects how arguments are passed to +// the given loop relation, since for example A.Contains(B) is not the same as +// B.Contains(A). +func newLoopCrosser(a, b *Loop, relation loopRelation, swapped bool) *loopCrosser { + l := &loopCrosser{ + a: a, + b: b, + relation: relation, + swapped: swapped, + aCrossingTarget: relation.aCrossingTarget(), + bCrossingTarget: relation.bCrossingTarget(), + bQuery: NewCrossingEdgeQuery(b.index), + } + if swapped { + l.aCrossingTarget, l.bCrossingTarget = l.bCrossingTarget, l.aCrossingTarget + } + + return l +} + +// startEdge sets the crossers state for checking the given edge of loop A. +func (l *loopCrosser) startEdge(aj int) { + l.crosser = NewEdgeCrosser(l.a.Vertex(aj), l.a.Vertex(aj+1)) + l.aj = aj + l.bjPrev = -2 +} + +// edgeCrossesCell reports whether the current edge of loop A has any crossings with +// edges of the index cell of loop B. +func (l *loopCrosser) edgeCrossesCell(bClipped *clippedShape) bool { + // Test the current edge of A against all edges of bClipped + bNumEdges := bClipped.numEdges() + for j := 0; j < bNumEdges; j++ { + bj := bClipped.edges[j] + if bj != l.bjPrev+1 { + l.crosser.RestartAt(l.b.Vertex(bj)) + } + l.bjPrev = bj + if crossing := l.crosser.ChainCrossingSign(l.b.Vertex(bj + 1)); crossing == DoNotCross { + continue + } else if crossing == Cross { + return true + } + + // We only need to check each shared vertex once, so we only + // consider the case where l.aVertex(l.aj+1) == l.b.Vertex(bj+1). + if l.a.Vertex(l.aj+1) == l.b.Vertex(bj+1) { + if l.swapped { + if l.relation.wedgesCross(l.b.Vertex(bj), l.b.Vertex(bj+1), l.b.Vertex(bj+2), l.a.Vertex(l.aj), l.a.Vertex(l.aj+2)) { + return true + } + } else { + if l.relation.wedgesCross(l.a.Vertex(l.aj), l.a.Vertex(l.aj+1), l.a.Vertex(l.aj+2), l.b.Vertex(bj), l.b.Vertex(bj+2)) { + return true + } + } + } + } + + return false +} + +// cellCrossesCell reports whether there are any edge crossings or wedge crossings +// within the two given cells. +func (l *loopCrosser) cellCrossesCell(aClipped, bClipped *clippedShape) bool { + // Test all edges of aClipped against all edges of bClipped. + for _, edge := range aClipped.edges { + l.startEdge(edge) + if l.edgeCrossesCell(bClipped) { + return true + } + } + + return false +} + +// cellCrossesAnySubcell reports whether given an index cell of A, if there are any +// edge or wedge crossings with any index cell of B contained within bID. +func (l *loopCrosser) cellCrossesAnySubcell(aClipped *clippedShape, bID CellID) bool { + // Test all edges of aClipped against all edges of B. The relevant B + // edges are guaranteed to be children of bID, which lets us find the + // correct index cells more efficiently. + bRoot := PaddedCellFromCellID(bID, 0) + for _, aj := range aClipped.edges { + // Use an CrossingEdgeQuery starting at bRoot to find the index cells + // of B that might contain crossing edges. + l.bCells = l.bQuery.getCells(l.a.Vertex(aj), l.a.Vertex(aj+1), bRoot) + if len(l.bCells) == 0 { + continue + } + l.startEdge(aj) + for c := 0; c < len(l.bCells); c++ { + if l.edgeCrossesCell(l.bCells[c].shapes[0]) { + return true + } + } + } + + return false +} + +// hasCrossing reports whether given two iterators positioned such that +// ai.cellID().ContainsCellID(bi.cellID()), there is an edge or wedge crossing +// anywhere within ai.cellID(). This function advances bi only past ai.cellID(). +func (l *loopCrosser) hasCrossing(ai, bi *rangeIterator) bool { + // If ai.CellID() intersects many edges of B, then it is faster to use + // CrossingEdgeQuery to narrow down the candidates. But if it intersects + // only a few edges, it is faster to check all the crossings directly. + // We handle this by advancing bi and keeping track of how many edges we + // would need to test. + const edgeQueryMinEdges = 20 // Tuned from benchmarks. + var totalEdges int + l.bCells = nil + + for { + if n := bi.it.IndexCell().shapes[0].numEdges(); n > 0 { + totalEdges += n + if totalEdges >= edgeQueryMinEdges { + // There are too many edges to test them directly, so use CrossingEdgeQuery. + if l.cellCrossesAnySubcell(ai.it.IndexCell().shapes[0], ai.cellID()) { + return true + } + bi.seekBeyond(ai) + return false + } + l.bCells = append(l.bCells, bi.indexCell()) + } + bi.next() + if bi.cellID() > ai.rangeMax { + break + } + } + + // Test all the edge crossings directly. + for _, c := range l.bCells { + if l.cellCrossesCell(ai.it.IndexCell().shapes[0], c.shapes[0]) { + return true + } + } + + return false +} + +// containsCenterMatches reports if the clippedShapes containsCenter boolean corresponds +// to the crossing target type given. (This is to work around C++ allowing false == 0, +// true == 1 type implicit conversions and comparisons) +func containsCenterMatches(a *clippedShape, target crossingTarget) bool { + return (!a.containsCenter && target == crossingTargetDontCross) || + (a.containsCenter && target == crossingTargetCross) +} + +// hasCrossingRelation reports whether given two iterators positioned such that +// ai.cellID().ContainsCellID(bi.cellID()), there is a crossing relationship +// anywhere within ai.cellID(). Specifically, this method returns true if there +// is an edge crossing, a wedge crossing, or a point P that matches both relations +// crossing targets. This function advances both iterators past ai.cellID. +func (l *loopCrosser) hasCrossingRelation(ai, bi *rangeIterator) bool { + aClipped := ai.it.IndexCell().shapes[0] + if aClipped.numEdges() != 0 { + // The current cell of A has at least one edge, so check for crossings. + if l.hasCrossing(ai, bi) { + return true + } + ai.next() + return false + } + + if !containsCenterMatches(aClipped, l.aCrossingTarget) { + // The crossing target for A is not satisfied, so we skip over these cells of B. + bi.seekBeyond(ai) + ai.next() + return false + } + + // All points within ai.cellID() satisfy the crossing target for A, so it's + // worth iterating through the cells of B to see whether any cell + // centers also satisfy the crossing target for B. + for bi.cellID() <= ai.rangeMax { + bClipped := bi.it.IndexCell().shapes[0] + if containsCenterMatches(bClipped, l.bCrossingTarget) { + return true + } + bi.next() + } + ai.next() + return false +} + +// hasCrossingRelation checks all edges of loop A for intersection against all edges +// of loop B and reports if there are any that satisfy the given relation. If there +// is any shared vertex, the wedges centered at this vertex are sent to the given +// relation to be tested. +// +// If the two loop boundaries cross, this method is guaranteed to return +// true. It also returns true in certain cases if the loop relationship is +// equivalent to crossing. For example, if the relation is Contains and a +// point P is found such that B contains P but A does not contain P, this +// method will return true to indicate that the result is the same as though +// a pair of crossing edges were found (since Contains returns false in +// both cases). +// +// See Contains, Intersects and CompareBoundary for the three uses of this function. +func hasCrossingRelation(a, b *Loop, relation loopRelation) bool { + // We look for CellID ranges where the indexes of A and B overlap, and + // then test those edges for crossings. + ai := newRangeIterator(a.index) + bi := newRangeIterator(b.index) + + ab := newLoopCrosser(a, b, relation, false) // Tests edges of A against B + ba := newLoopCrosser(b, a, relation, true) // Tests edges of B against A + + for !ai.done() || !bi.done() { + if ai.rangeMax < bi.rangeMin { + // The A and B cells don't overlap, and A precedes B. + ai.seekTo(bi) + } else if bi.rangeMax < ai.rangeMin { + // The A and B cells don't overlap, and B precedes A. + bi.seekTo(ai) + } else { + // One cell contains the other. Determine which cell is larger. + abRelation := int64(ai.it.CellID().lsb() - bi.it.CellID().lsb()) + if abRelation > 0 { + // A's index cell is larger. + if ab.hasCrossingRelation(ai, bi) { + return true + } + } else if abRelation < 0 { + // B's index cell is larger. + if ba.hasCrossingRelation(bi, ai) { + return true + } + } else { + // The A and B cells are the same. Since the two cells + // have the same center point P, check whether P satisfies + // the crossing targets. + aClipped := ai.it.IndexCell().shapes[0] + bClipped := bi.it.IndexCell().shapes[0] + if containsCenterMatches(aClipped, ab.aCrossingTarget) && + containsCenterMatches(bClipped, ab.bCrossingTarget) { + return true + } + // Otherwise test all the edge crossings directly. + if aClipped.numEdges() > 0 && bClipped.numEdges() > 0 && ab.cellCrossesCell(aClipped, bClipped) { + return true + } + ai.next() + bi.next() + } + } + } + return false +} + +// containsRelation implements loopRelation for a contains operation. If +// A.ContainsPoint(P) == false && B.ContainsPoint(P) == true, it is equivalent +// to having an edge crossing (i.e., Contains returns false). +type containsRelation struct { + foundSharedVertex bool +} + +func (c *containsRelation) aCrossingTarget() crossingTarget { return crossingTargetDontCross } +func (c *containsRelation) bCrossingTarget() crossingTarget { return crossingTargetCross } +func (c *containsRelation) wedgesCross(a0, ab1, a2, b0, b2 Point) bool { + c.foundSharedVertex = true + return !WedgeContains(a0, ab1, a2, b0, b2) +} + +// intersectsRelation implements loopRelation for an intersects operation. Given +// two loops, A and B, if A.ContainsPoint(P) == true && B.ContainsPoint(P) == true, +// it is equivalent to having an edge crossing (i.e., Intersects returns true). +type intersectsRelation struct { + foundSharedVertex bool +} + +func (i *intersectsRelation) aCrossingTarget() crossingTarget { return crossingTargetCross } +func (i *intersectsRelation) bCrossingTarget() crossingTarget { return crossingTargetCross } +func (i *intersectsRelation) wedgesCross(a0, ab1, a2, b0, b2 Point) bool { + i.foundSharedVertex = true + return WedgeIntersects(a0, ab1, a2, b0, b2) +} + +// compareBoundaryRelation implements loopRelation for comparing boundaries. +// +// The compare boundary relation does not have a useful early-exit condition, +// so we return crossingTargetDontCare for both crossing targets. +// +// Aside: A possible early exit condition could be based on the following. +// If A contains a point of both B and ~B, then A intersects Boundary(B). +// If ~A contains a point of both B and ~B, then ~A intersects Boundary(B). +// So if the intersections of {A, ~A} with {B, ~B} are all non-empty, +// the return value is 0, i.e., Boundary(A) intersects Boundary(B). +// Unfortunately it isn't worth detecting this situation because by the +// time we have seen a point in all four intersection regions, we are also +// guaranteed to have seen at least one pair of crossing edges. +type compareBoundaryRelation struct { + reverse bool // True if the other loop should be reversed. + foundSharedVertex bool // True if any wedge was processed. + containsEdge bool // True if any edge of the other loop is contained by this loop. + excludesEdge bool // True if any edge of the other loop is excluded by this loop. +} + +func newCompareBoundaryRelation(reverse bool) *compareBoundaryRelation { + return &compareBoundaryRelation{reverse: reverse} +} + +func (c *compareBoundaryRelation) aCrossingTarget() crossingTarget { return crossingTargetDontCare } +func (c *compareBoundaryRelation) bCrossingTarget() crossingTarget { return crossingTargetDontCare } +func (c *compareBoundaryRelation) wedgesCross(a0, ab1, a2, b0, b2 Point) bool { + // Because we don't care about the interior of the other, only its boundary, + // it is sufficient to check whether this one contains the semiwedge (ab1, b2). + c.foundSharedVertex = true + if wedgeContainsSemiwedge(a0, ab1, a2, b2, c.reverse) { + c.containsEdge = true + } else { + c.excludesEdge = true + } + return c.containsEdge && c.excludesEdge +} + +// wedgeContainsSemiwedge reports whether the wedge (a0, ab1, a2) contains the +// "semiwedge" defined as any non-empty open set of rays immediately CCW from +// the edge (ab1, b2). If reverse is true, then substitute clockwise for CCW; +// this simulates what would happen if the direction of the other loop was reversed. +func wedgeContainsSemiwedge(a0, ab1, a2, b2 Point, reverse bool) bool { + if b2 == a0 || b2 == a2 { + // We have a shared or reversed edge. + return (b2 == a0) == reverse + } + return OrderedCCW(a0, a2, b2, ab1) +} + +// containsNonCrossingBoundary reports whether given two loops whose boundaries +// do not cross (see compareBoundary), if this loop contains the boundary of the +// other loop. If reverse is true, the boundary of the other loop is reversed +// first (which only affects the result when there are shared edges). This method +// is cheaper than compareBoundary because it does not test for edge intersections. +// +// This function requires that neither loop is empty, and that if the other is full, +// then reverse == false. +func (l *Loop) containsNonCrossingBoundary(other *Loop, reverseOther bool) bool { + // The bounds must intersect for containment. + if !l.bound.Intersects(other.bound) { + return false + } + + // Full loops are handled as though the loop surrounded the entire sphere. + if l.IsFull() { + return true + } + if other.IsFull() { + return false + } + + m, ok := l.findVertex(other.Vertex(0)) + if !ok { + // Since the other loops vertex 0 is not shared, we can check if this contains it. + return l.ContainsPoint(other.Vertex(0)) + } + // Otherwise check whether the edge (b0, b1) is contained by this loop. + return wedgeContainsSemiwedge(l.Vertex(m-1), l.Vertex(m), l.Vertex(m+1), + other.Vertex(1), reverseOther) +} + +// TODO(roberts): Differences from the C++ version: +// DistanceToPoint +// DistanceToBoundary +// Project +// ProjectToBoundary +// BoundaryApproxEqual +// BoundaryNear diff --git a/backend/vendor/github.com/blevesearch/geo/s2/matrix3x3.go b/backend/vendor/github.com/blevesearch/geo/s2/matrix3x3.go new file mode 100644 index 0000000000..01696fe836 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/matrix3x3.go @@ -0,0 +1,127 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "fmt" + + "github.com/golang/geo/r3" +) + +// matrix3x3 represents a traditional 3x3 matrix of floating point values. +// This is not a full fledged matrix. It only contains the pieces needed +// to satisfy the computations done within the s2 package. +type matrix3x3 [3][3]float64 + +// col returns the given column as a Point. +func (m *matrix3x3) col(col int) Point { + return Point{r3.Vector{m[0][col], m[1][col], m[2][col]}} +} + +// row returns the given row as a Point. +func (m *matrix3x3) row(row int) Point { + return Point{r3.Vector{m[row][0], m[row][1], m[row][2]}} +} + +// setCol sets the specified column to the value in the given Point. +func (m *matrix3x3) setCol(col int, p Point) *matrix3x3 { + m[0][col] = p.X + m[1][col] = p.Y + m[2][col] = p.Z + + return m +} + +// setRow sets the specified row to the value in the given Point. +func (m *matrix3x3) setRow(row int, p Point) *matrix3x3 { + m[row][0] = p.X + m[row][1] = p.Y + m[row][2] = p.Z + + return m +} + +// scale multiplies the matrix by the given value. +func (m *matrix3x3) scale(f float64) *matrix3x3 { + return &matrix3x3{ + [3]float64{f * m[0][0], f * m[0][1], f * m[0][2]}, + [3]float64{f * m[1][0], f * m[1][1], f * m[1][2]}, + [3]float64{f * m[2][0], f * m[2][1], f * m[2][2]}, + } +} + +// mul returns the multiplication of m by the Point p and converts the +// resulting 1x3 matrix into a Point. +func (m *matrix3x3) mul(p Point) Point { + return Point{r3.Vector{ + m[0][0]*p.X + m[0][1]*p.Y + m[0][2]*p.Z, + m[1][0]*p.X + m[1][1]*p.Y + m[1][2]*p.Z, + m[2][0]*p.X + m[2][1]*p.Y + m[2][2]*p.Z, + }} +} + +// det returns the determinant of this matrix. +func (m *matrix3x3) det() float64 { + // | a b c | + // det | d e f | = aei + bfg + cdh - ceg - bdi - afh + // | g h i | + return m[0][0]*m[1][1]*m[2][2] + m[0][1]*m[1][2]*m[2][0] + m[0][2]*m[1][0]*m[2][1] - + m[0][2]*m[1][1]*m[2][0] - m[0][1]*m[1][0]*m[2][2] - m[0][0]*m[1][2]*m[2][1] +} + +// transpose reflects the matrix along its diagonal and returns the result. +func (m *matrix3x3) transpose() *matrix3x3 { + m[0][1], m[1][0] = m[1][0], m[0][1] + m[0][2], m[2][0] = m[2][0], m[0][2] + m[1][2], m[2][1] = m[2][1], m[1][2] + + return m +} + +// String formats the matrix into an easier to read layout. +func (m *matrix3x3) String() string { + return fmt.Sprintf("[ %0.4f %0.4f %0.4f ] [ %0.4f %0.4f %0.4f ] [ %0.4f %0.4f %0.4f ]", + m[0][0], m[0][1], m[0][2], + m[1][0], m[1][1], m[1][2], + m[2][0], m[2][1], m[2][2], + ) +} + +// getFrame returns the orthonormal frame for the given point on the unit sphere. +func getFrame(p Point) matrix3x3 { + // Given the point p on the unit sphere, extend this into a right-handed + // coordinate frame of unit-length column vectors m = (x,y,z). Note that + // the vectors (x,y) are an orthonormal frame for the tangent space at point p, + // while p itself is an orthonormal frame for the normal space at p. + m := matrix3x3{} + m.setCol(2, p) + m.setCol(1, Point{p.Ortho()}) + m.setCol(0, Point{m.col(1).Cross(p.Vector)}) + return m +} + +// toFrame returns the coordinates of the given point with respect to its orthonormal basis m. +// The resulting point q satisfies the identity (m * q == p). +func toFrame(m matrix3x3, p Point) Point { + // The inverse of an orthonormal matrix is its transpose. + return m.transpose().mul(p) +} + +// fromFrame returns the coordinates of the given point in standard axis-aligned basis +// from its orthonormal basis m. +// The resulting point p satisfies the identity (p == m * q). +func fromFrame(m matrix3x3, q Point) Point { + return m.mul(q) +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/max_distance_targets.go b/backend/vendor/github.com/blevesearch/geo/s2/max_distance_targets.go new file mode 100644 index 0000000000..92e916d98a --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/max_distance_targets.go @@ -0,0 +1,306 @@ +// Copyright 2019 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "math" + + "github.com/golang/geo/s1" +) + +// maxDistance implements distance as the supplementary distance (Pi - x) to find +// results that are the furthest using the distance related algorithms. +type maxDistance s1.ChordAngle + +func (m maxDistance) chordAngle() s1.ChordAngle { return s1.ChordAngle(m) } +func (m maxDistance) zero() distance { return maxDistance(s1.StraightChordAngle) } +func (m maxDistance) negative() distance { return maxDistance(s1.InfChordAngle()) } +func (m maxDistance) infinity() distance { return maxDistance(s1.NegativeChordAngle) } +func (m maxDistance) less(other distance) bool { return m.chordAngle() > other.chordAngle() } +func (m maxDistance) sub(other distance) distance { + return maxDistance(m.chordAngle() + other.chordAngle()) +} +func (m maxDistance) chordAngleBound() s1.ChordAngle { + return s1.StraightChordAngle - m.chordAngle() +} +func (m maxDistance) updateDistance(dist distance) (distance, bool) { + if dist.less(m) { + m = maxDistance(dist.chordAngle()) + return m, true + } + return m, false +} + +func (m maxDistance) fromChordAngle(o s1.ChordAngle) distance { + return maxDistance(o) +} + +// MaxDistanceToPointTarget is used for computing the maximum distance to a Point. +type MaxDistanceToPointTarget struct { + point Point + dist distance +} + +// NewMaxDistanceToPointTarget returns a new target for the given Point. +func NewMaxDistanceToPointTarget(point Point) *MaxDistanceToPointTarget { + m := maxDistance(0) + return &MaxDistanceToPointTarget{point: point, dist: &m} +} + +func (m *MaxDistanceToPointTarget) capBound() Cap { + return CapFromCenterChordAngle(Point{m.point.Mul(-1)}, (s1.ChordAngle(0))) +} + +func (m *MaxDistanceToPointTarget) updateDistanceToPoint(p Point, dist distance) (distance, bool) { + return dist.updateDistance(maxDistance(ChordAngleBetweenPoints(p, m.point))) +} + +func (m *MaxDistanceToPointTarget) updateDistanceToEdge(edge Edge, dist distance) (distance, bool) { + if d, ok := UpdateMaxDistance(m.point, edge.V0, edge.V1, dist.chordAngle()); ok { + dist, _ = dist.updateDistance(maxDistance(d)) + return dist, true + } + return dist, false +} + +func (m *MaxDistanceToPointTarget) updateDistanceToCell(cell Cell, dist distance) (distance, bool) { + return dist.updateDistance(maxDistance(cell.MaxDistance(m.point))) +} + +func (m *MaxDistanceToPointTarget) visitContainingShapes(index *ShapeIndex, v shapePointVisitorFunc) bool { + // For furthest points, we visit the polygons whose interior contains + // the antipode of the target point. These are the polygons whose + // distance to the target is maxDistance.zero() + q := NewContainsPointQuery(index, VertexModelSemiOpen) + return q.visitContainingShapes(Point{m.point.Mul(-1)}, func(shape Shape) bool { + return v(shape, m.point) + }) +} + +func (m *MaxDistanceToPointTarget) setMaxError(maxErr s1.ChordAngle) bool { return false } +func (m *MaxDistanceToPointTarget) maxBruteForceIndexSize() int { return 30 } +func (m *MaxDistanceToPointTarget) distance() distance { return m.dist } + +// MaxDistanceToEdgeTarget is used for computing the maximum distance to an Edge. +type MaxDistanceToEdgeTarget struct { + e Edge + dist distance +} + +// NewMaxDistanceToEdgeTarget returns a new target for the given Edge. +func NewMaxDistanceToEdgeTarget(e Edge) *MaxDistanceToEdgeTarget { + m := maxDistance(0) + return &MaxDistanceToEdgeTarget{e: e, dist: m} +} + +// capBound returns a Cap that bounds the antipode of the target. (This +// is the set of points whose maxDistance to the target is maxDistance.zero) +func (m *MaxDistanceToEdgeTarget) capBound() Cap { + // The following computes a radius equal to half the edge length in an + // efficient and numerically stable way. + d2 := float64(ChordAngleBetweenPoints(m.e.V0, m.e.V1)) + r2 := (0.5 * d2) / (1 + math.Sqrt(1-0.25*d2)) + return CapFromCenterChordAngle(Point{m.e.V0.Add(m.e.V1.Vector).Mul(-1).Normalize()}, s1.ChordAngleFromSquaredLength(r2)) +} + +func (m *MaxDistanceToEdgeTarget) updateDistanceToPoint(p Point, dist distance) (distance, bool) { + if d, ok := UpdateMaxDistance(p, m.e.V0, m.e.V1, dist.chordAngle()); ok { + dist, _ = dist.updateDistance(maxDistance(d)) + return dist, true + } + return dist, false +} + +func (m *MaxDistanceToEdgeTarget) updateDistanceToEdge(edge Edge, dist distance) (distance, bool) { + if d, ok := updateEdgePairMaxDistance(m.e.V0, m.e.V1, edge.V0, edge.V1, dist.chordAngle()); ok { + dist, _ = dist.updateDistance(maxDistance(d)) + return dist, true + } + return dist, false +} + +func (m *MaxDistanceToEdgeTarget) updateDistanceToCell(cell Cell, dist distance) (distance, bool) { + return dist.updateDistance(maxDistance(cell.MaxDistanceToEdge(m.e.V0, m.e.V1))) +} + +func (m *MaxDistanceToEdgeTarget) visitContainingShapes(index *ShapeIndex, v shapePointVisitorFunc) bool { + // We only need to test one edge point. That is because the method *must* + // visit a polygon if it fully contains the target, and *is allowed* to + // visit a polygon if it intersects the target. If the tested vertex is not + // contained, we know the full edge is not contained; if the tested vertex is + // contained, then the edge either is fully contained (must be visited) or it + // intersects (is allowed to be visited). We visit the center of the edge so + // that edge AB gives identical results to BA. + target := NewMaxDistanceToPointTarget(Point{m.e.V0.Add(m.e.V1.Vector).Normalize()}) + return target.visitContainingShapes(index, v) +} + +func (m *MaxDistanceToEdgeTarget) setMaxError(maxErr s1.ChordAngle) bool { return false } +func (m *MaxDistanceToEdgeTarget) maxBruteForceIndexSize() int { return 30 } +func (m *MaxDistanceToEdgeTarget) distance() distance { return m.dist } + +// MaxDistanceToCellTarget is used for computing the maximum distance to a Cell. +type MaxDistanceToCellTarget struct { + cell Cell + dist distance +} + +// NewMaxDistanceToCellTarget returns a new target for the given Cell. +func NewMaxDistanceToCellTarget(cell Cell) *MaxDistanceToCellTarget { + m := maxDistance(0) + return &MaxDistanceToCellTarget{cell: cell, dist: m} +} + +func (m *MaxDistanceToCellTarget) capBound() Cap { + c := m.cell.CapBound() + return CapFromCenterAngle(Point{c.Center().Mul(-1)}, c.Radius()) +} + +func (m *MaxDistanceToCellTarget) updateDistanceToPoint(p Point, dist distance) (distance, bool) { + return dist.updateDistance(maxDistance(m.cell.MaxDistance(p))) +} + +func (m *MaxDistanceToCellTarget) updateDistanceToEdge(edge Edge, dist distance) (distance, bool) { + return dist.updateDistance(maxDistance(m.cell.MaxDistanceToEdge(edge.V0, edge.V1))) +} + +func (m *MaxDistanceToCellTarget) updateDistanceToCell(cell Cell, dist distance) (distance, bool) { + return dist.updateDistance(maxDistance(m.cell.MaxDistanceToCell(cell))) +} + +func (m *MaxDistanceToCellTarget) visitContainingShapes(index *ShapeIndex, v shapePointVisitorFunc) bool { + // We only need to check one point here - cell center is simplest. + // See comment at MaxDistanceToEdgeTarget's visitContainingShapes. + target := NewMaxDistanceToPointTarget(m.cell.Center()) + return target.visitContainingShapes(index, v) +} + +func (m *MaxDistanceToCellTarget) setMaxError(maxErr s1.ChordAngle) bool { return false } +func (m *MaxDistanceToCellTarget) maxBruteForceIndexSize() int { return 30 } +func (m *MaxDistanceToCellTarget) distance() distance { return m.dist } + +// MaxDistanceToShapeIndexTarget is used for computing the maximum distance to a ShapeIndex. +type MaxDistanceToShapeIndexTarget struct { + index *ShapeIndex + query *EdgeQuery + dist distance +} + +// NewMaxDistanceToShapeIndexTarget returns a new target for the given ShapeIndex. +func NewMaxDistanceToShapeIndexTarget(index *ShapeIndex) *MaxDistanceToShapeIndexTarget { + m := maxDistance(0) + return &MaxDistanceToShapeIndexTarget{ + index: index, + dist: m, + query: NewFurthestEdgeQuery(index, NewFurthestEdgeQueryOptions()), + } +} + +// capBound returns a Cap that bounds the antipode of the target. This +// is the set of points whose maxDistance to the target is maxDistance.zero() +func (m *MaxDistanceToShapeIndexTarget) capBound() Cap { + // TODO(roberts): Depends on ShapeIndexRegion + // c := makeShapeIndexRegion(m.index).CapBound() + // return CapFromCenterRadius(Point{c.Center.Mul(-1)}, c.Radius()) + panic("not implemented yet") +} + +func (m *MaxDistanceToShapeIndexTarget) updateDistanceToPoint(p Point, dist distance) (distance, bool) { + m.query.opts.distanceLimit = dist.chordAngle() + target := NewMaxDistanceToPointTarget(p) + r := m.query.findEdge(target, m.query.opts) + if r.shapeID < 0 { + return dist, false + } + return r.distance, true +} + +func (m *MaxDistanceToShapeIndexTarget) updateDistanceToEdge(edge Edge, dist distance) (distance, bool) { + m.query.opts.distanceLimit = dist.chordAngle() + target := NewMaxDistanceToEdgeTarget(edge) + r := m.query.findEdge(target, m.query.opts) + if r.shapeID < 0 { + return dist, false + } + return r.distance, true +} + +func (m *MaxDistanceToShapeIndexTarget) updateDistanceToCell(cell Cell, dist distance) (distance, bool) { + m.query.opts.distanceLimit = dist.chordAngle() + target := NewMaxDistanceToCellTarget(cell) + r := m.query.findEdge(target, m.query.opts) + if r.shapeID < 0 { + return dist, false + } + return r.distance, true +} + +// visitContainingShapes returns the polygons containing the antipodal +// reflection of *any* connected component for target types consisting of +// multiple connected components. It is sufficient to test containment of +// one vertex per connected component, since this allows us to also return +// any polygon whose boundary has distance.zero() to the target. +func (m *MaxDistanceToShapeIndexTarget) visitContainingShapes(index *ShapeIndex, v shapePointVisitorFunc) bool { + // It is sufficient to find the set of chain starts in the target index + // (i.e., one vertex per connected component of edges) that are contained by + // the query index, except for one special case to handle full polygons. + // + // TODO(roberts): Do this by merge-joining the two ShapeIndexes and share + // the code with BooleanOperation. + for _, shape := range m.index.shapes { + numChains := shape.NumChains() + // Shapes that don't have any edges require a special case (below). + testedPoint := false + for c := 0; c < numChains; c++ { + chain := shape.Chain(c) + if chain.Length == 0 { + continue + } + testedPoint = true + target := NewMaxDistanceToPointTarget(shape.ChainEdge(c, 0).V0) + if !target.visitContainingShapes(index, v) { + return false + } + } + if !testedPoint { + // Special case to handle full polygons. + ref := shape.ReferencePoint() + if !ref.Contained { + continue + } + target := NewMaxDistanceToPointTarget(ref.Point) + if !target.visitContainingShapes(index, v) { + return false + } + } + } + return true +} + +func (m *MaxDistanceToShapeIndexTarget) setMaxError(maxErr s1.ChordAngle) bool { + m.query.opts.maxError = maxErr + return true +} +func (m *MaxDistanceToShapeIndexTarget) maxBruteForceIndexSize() int { return 30 } +func (m *MaxDistanceToShapeIndexTarget) distance() distance { return m.dist } +func (m *MaxDistanceToShapeIndexTarget) setIncludeInteriors(b bool) { + m.query.opts.includeInteriors = b +} +func (m *MaxDistanceToShapeIndexTarget) setUseBruteForce(b bool) { m.query.opts.useBruteForce = b } + +// TODO(roberts): Remaining methods +// +// func (m *MaxDistanceToShapeIndexTarget) capBound() Cap { +// CellUnionTarget diff --git a/backend/vendor/github.com/blevesearch/geo/s2/metric.go b/backend/vendor/github.com/blevesearch/geo/s2/metric.go new file mode 100644 index 0000000000..53db3d3173 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/metric.go @@ -0,0 +1,164 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +// This file implements functions for various S2 measurements. + +import "math" + +// A Metric is a measure for cells. It is used to describe the shape and size +// of cells. They are useful for deciding which cell level to use in order to +// satisfy a given condition (e.g. that cell vertices must be no further than +// "x" apart). You can use the Value(level) method to compute the corresponding +// length or area on the unit sphere for cells at a given level. The minimum +// and maximum bounds are valid for cells at all levels, but they may be +// somewhat conservative for very large cells (e.g. face cells). +type Metric struct { + // Dim is either 1 or 2, for a 1D or 2D metric respectively. + Dim int + // Deriv is the scaling factor for the metric. + Deriv float64 +} + +// Defined metrics. +// Of the projection methods defined in C++, Go only supports the quadratic projection. + +// Each cell is bounded by four planes passing through its four edges and +// the center of the sphere. These metrics relate to the angle between each +// pair of opposite bounding planes, or equivalently, between the planes +// corresponding to two different s-values or two different t-values. +var ( + MinAngleSpanMetric = Metric{1, 4.0 / 3} + AvgAngleSpanMetric = Metric{1, math.Pi / 2} + MaxAngleSpanMetric = Metric{1, 1.704897179199218452} +) + +// The width of geometric figure is defined as the distance between two +// parallel bounding lines in a given direction. For cells, the minimum +// width is always attained between two opposite edges, and the maximum +// width is attained between two opposite vertices. However, for our +// purposes we redefine the width of a cell as the perpendicular distance +// between a pair of opposite edges. A cell therefore has two widths, one +// in each direction. The minimum width according to this definition agrees +// with the classic geometric one, but the maximum width is different. (The +// maximum geometric width corresponds to MaxDiag defined below.) +// +// The average width in both directions for all cells at level k is approximately +// AvgWidthMetric.Value(k). +// +// The width is useful for bounding the minimum or maximum distance from a +// point on one edge of a cell to the closest point on the opposite edge. +// For example, this is useful when growing regions by a fixed distance. +var ( + MinWidthMetric = Metric{1, 2 * math.Sqrt2 / 3} + AvgWidthMetric = Metric{1, 1.434523672886099389} + MaxWidthMetric = Metric{1, MaxAngleSpanMetric.Deriv} +) + +// The edge length metrics can be used to bound the minimum, maximum, +// or average distance from the center of one cell to the center of one of +// its edge neighbors. In particular, it can be used to bound the distance +// between adjacent cell centers along the space-filling Hilbert curve for +// cells at any given level. +var ( + MinEdgeMetric = Metric{1, 2 * math.Sqrt2 / 3} + AvgEdgeMetric = Metric{1, 1.459213746386106062} + MaxEdgeMetric = Metric{1, MaxAngleSpanMetric.Deriv} + + // MaxEdgeAspect is the maximum edge aspect ratio over all cells at any level, + // where the edge aspect ratio of a cell is defined as the ratio of its longest + // edge length to its shortest edge length. + MaxEdgeAspect = 1.442615274452682920 + + MinAreaMetric = Metric{2, 8 * math.Sqrt2 / 9} + AvgAreaMetric = Metric{2, 4 * math.Pi / 6} + MaxAreaMetric = Metric{2, 2.635799256963161491} +) + +// The maximum diagonal is also the maximum diameter of any cell, +// and also the maximum geometric width (see the comment for widths). For +// example, the distance from an arbitrary point to the closest cell center +// at a given level is at most half the maximum diagonal length. +var ( + MinDiagMetric = Metric{1, 8 * math.Sqrt2 / 9} + AvgDiagMetric = Metric{1, 2.060422738998471683} + MaxDiagMetric = Metric{1, 2.438654594434021032} + + // MaxDiagAspect is the maximum diagonal aspect ratio over all cells at any + // level, where the diagonal aspect ratio of a cell is defined as the ratio + // of its longest diagonal length to its shortest diagonal length. + MaxDiagAspect = math.Sqrt(3) +) + +// Value returns the value of the metric at the given level. +func (m Metric) Value(level int) float64 { + return math.Ldexp(m.Deriv, -m.Dim*level) +} + +// MinLevel returns the minimum level such that the metric is at most +// the given value, or maxLevel (30) if there is no such level. +// +// For example, MinLevel(0.1) returns the minimum level such that all cell diagonal +// lengths are 0.1 or smaller. The returned value is always a valid level. +// +// In C++, this is called GetLevelForMaxValue. +func (m Metric) MinLevel(val float64) int { + if val < 0 { + return maxLevel + } + + level := -(math.Ilogb(val/m.Deriv) >> uint(m.Dim-1)) + if level > maxLevel { + level = maxLevel + } + if level < 0 { + level = 0 + } + return level +} + +// MaxLevel returns the maximum level such that the metric is at least +// the given value, or zero if there is no such level. +// +// For example, MaxLevel(0.1) returns the maximum level such that all cells have a +// minimum width of 0.1 or larger. The returned value is always a valid level. +// +// In C++, this is called GetLevelForMinValue. +func (m Metric) MaxLevel(val float64) int { + if val <= 0 { + return maxLevel + } + + level := math.Ilogb(m.Deriv/val) >> uint(m.Dim-1) + if level > maxLevel { + level = maxLevel + } + if level < 0 { + level = 0 + } + return level +} + +// ClosestLevel returns the level at which the metric has approximately the given +// value. The return value is always a valid level. For example, +// AvgEdgeMetric.ClosestLevel(0.1) returns the level at which the average cell edge +// length is approximately 0.1. +func (m Metric) ClosestLevel(val float64) int { + x := math.Sqrt2 + if m.Dim == 2 { + x = 2 + } + return m.MinLevel(x * val) +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/min_distance_targets.go b/backend/vendor/github.com/blevesearch/geo/s2/min_distance_targets.go new file mode 100644 index 0000000000..b4cbd43eff --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/min_distance_targets.go @@ -0,0 +1,362 @@ +// Copyright 2019 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "math" + + "github.com/golang/geo/s1" +) + +// minDistance implements distance interface to find closest distance types. +type minDistance s1.ChordAngle + +func (m minDistance) chordAngle() s1.ChordAngle { return s1.ChordAngle(m) } +func (m minDistance) zero() distance { return minDistance(0) } +func (m minDistance) negative() distance { return minDistance(s1.NegativeChordAngle) } +func (m minDistance) infinity() distance { return minDistance(s1.InfChordAngle()) } +func (m minDistance) less(other distance) bool { return m.chordAngle() < other.chordAngle() } +func (m minDistance) sub(other distance) distance { + return minDistance(m.chordAngle() - other.chordAngle()) +} +func (m minDistance) chordAngleBound() s1.ChordAngle { + return m.chordAngle().Expanded(m.chordAngle().MaxAngleError()) +} + +// updateDistance updates its own value if the other value is less() than it is, +// and reports if it updated. +func (m minDistance) updateDistance(dist distance) (distance, bool) { + if dist.less(m) { + m = minDistance(dist.chordAngle()) + return m, true + } + return m, false +} + +func (m minDistance) fromChordAngle(o s1.ChordAngle) distance { + return minDistance(o) +} + +// MinDistanceToPointTarget is a type for computing the minimum distance to a Point. +type MinDistanceToPointTarget struct { + point Point + dist distance +} + +// NewMinDistanceToPointTarget returns a new target for the given Point. +func NewMinDistanceToPointTarget(point Point) *MinDistanceToPointTarget { + m := minDistance(0) + return &MinDistanceToPointTarget{point: point, dist: &m} +} + +func (m *MinDistanceToPointTarget) capBound() Cap { + return CapFromCenterChordAngle(m.point, s1.ChordAngle(0)) +} + +func (m *MinDistanceToPointTarget) updateDistanceToPoint(p Point, dist distance) (distance, bool) { + var ok bool + dist, ok = dist.updateDistance(minDistance(ChordAngleBetweenPoints(p, m.point))) + return dist, ok +} + +func (m *MinDistanceToPointTarget) updateDistanceToEdge(edge Edge, dist distance) (distance, bool) { + if d, ok := UpdateMinDistance(m.point, edge.V0, edge.V1, dist.chordAngle()); ok { + dist, _ = dist.updateDistance(minDistance(d)) + return dist, true + } + return dist, false +} + +func (m *MinDistanceToPointTarget) updateDistanceToCell(cell Cell, dist distance) (distance, bool) { + var ok bool + dist, ok = dist.updateDistance(minDistance(cell.Distance(m.point))) + return dist, ok +} + +func (m *MinDistanceToPointTarget) visitContainingShapes(index *ShapeIndex, v shapePointVisitorFunc) bool { + // For furthest points, we visit the polygons whose interior contains + // the antipode of the target point. These are the polygons whose + // distance to the target is maxDistance.zero() + q := NewContainsPointQuery(index, VertexModelSemiOpen) + return q.visitContainingShapes(m.point, func(shape Shape) bool { + return v(shape, m.point) + }) +} + +func (m *MinDistanceToPointTarget) setMaxError(maxErr s1.ChordAngle) bool { return false } +func (m *MinDistanceToPointTarget) maxBruteForceIndexSize() int { return 30 } +func (m *MinDistanceToPointTarget) distance() distance { return m.dist } + +// ---------------------------------------------------------- + +// MinDistanceToEdgeTarget is a type for computing the minimum distance to an Edge. +type MinDistanceToEdgeTarget struct { + e Edge + dist distance +} + +// NewMinDistanceToEdgeTarget returns a new target for the given Edge. +func NewMinDistanceToEdgeTarget(e Edge) *MinDistanceToEdgeTarget { + m := minDistance(0) + return &MinDistanceToEdgeTarget{e: e, dist: m} +} + +// capBound returns a Cap that bounds the antipode of the target. (This +// is the set of points whose maxDistance to the target is maxDistance.zero) +func (m *MinDistanceToEdgeTarget) capBound() Cap { + // The following computes a radius equal to half the edge length in an + // efficient and numerically stable way. + d2 := float64(ChordAngleBetweenPoints(m.e.V0, m.e.V1)) + r2 := (0.5 * d2) / (1 + math.Sqrt(1-0.25*d2)) + return CapFromCenterChordAngle(Point{m.e.V0.Add(m.e.V1.Vector).Normalize()}, s1.ChordAngleFromSquaredLength(r2)) +} + +func (m *MinDistanceToEdgeTarget) updateDistanceToPoint(p Point, dist distance) (distance, bool) { + if d, ok := UpdateMinDistance(p, m.e.V0, m.e.V1, dist.chordAngle()); ok { + dist, _ = dist.updateDistance(minDistance(d)) + return dist, true + } + return dist, false +} + +func (m *MinDistanceToEdgeTarget) updateDistanceToEdge(edge Edge, dist distance) (distance, bool) { + if d, ok := updateEdgePairMinDistance(m.e.V0, m.e.V1, edge.V0, edge.V1, dist.chordAngle()); ok { + dist, _ = dist.updateDistance(minDistance(d)) + return dist, true + } + return dist, false +} + +func (m *MinDistanceToEdgeTarget) updateDistanceToCell(cell Cell, dist distance) (distance, bool) { + return dist.updateDistance(minDistance(cell.DistanceToEdge(m.e.V0, m.e.V1))) +} + +func (m *MinDistanceToEdgeTarget) visitContainingShapes(index *ShapeIndex, v shapePointVisitorFunc) bool { + // We test the center of the edge in order to ensure that edge targets AB + // and BA yield identical results (which is not guaranteed by the API but + // users might expect). Other options would be to test both endpoints, or + // return different results for AB and BA in some cases. + target := NewMinDistanceToPointTarget(Point{m.e.V0.Add(m.e.V1.Vector).Normalize()}) + return target.visitContainingShapes(index, v) +} + +func (m *MinDistanceToEdgeTarget) setMaxError(maxErr s1.ChordAngle) bool { return false } +func (m *MinDistanceToEdgeTarget) maxBruteForceIndexSize() int { return 30 } +func (m *MinDistanceToEdgeTarget) distance() distance { return m.dist } + +// ---------------------------------------------------------- + +// MinDistanceToCellTarget is a type for computing the minimum distance to a Cell. +type MinDistanceToCellTarget struct { + cell Cell + dist distance +} + +// NewMinDistanceToCellTarget returns a new target for the given Cell. +func NewMinDistanceToCellTarget(cell Cell) *MinDistanceToCellTarget { + m := minDistance(0) + return &MinDistanceToCellTarget{cell: cell, dist: m} +} + +func (m *MinDistanceToCellTarget) capBound() Cap { + return m.cell.CapBound() +} + +func (m *MinDistanceToCellTarget) updateDistanceToPoint(p Point, dist distance) (distance, bool) { + return dist.updateDistance(minDistance(m.cell.Distance(p))) +} + +func (m *MinDistanceToCellTarget) updateDistanceToEdge(edge Edge, dist distance) (distance, bool) { + return dist.updateDistance(minDistance(m.cell.DistanceToEdge(edge.V0, edge.V1))) +} + +func (m *MinDistanceToCellTarget) updateDistanceToCell(cell Cell, dist distance) (distance, bool) { + return dist.updateDistance(minDistance(m.cell.DistanceToCell(cell))) +} + +func (m *MinDistanceToCellTarget) visitContainingShapes(index *ShapeIndex, v shapePointVisitorFunc) bool { + // The simplest approach is simply to return the polygons that contain the + // cell center. Alternatively, if the index cell is smaller than the target + // cell then we could return all polygons that are present in the + // shapeIndexCell, but since the index is built conservatively this may + // include some polygons that don't quite intersect the cell. So we would + // either need to recheck for intersection more accurately, or weaken the + // VisitContainingShapes contract so that it only guarantees approximate + // intersection, neither of which seems like a good tradeoff. + target := NewMinDistanceToPointTarget(m.cell.Center()) + return target.visitContainingShapes(index, v) +} +func (m *MinDistanceToCellTarget) setMaxError(maxErr s1.ChordAngle) bool { return false } +func (m *MinDistanceToCellTarget) maxBruteForceIndexSize() int { return 30 } +func (m *MinDistanceToCellTarget) distance() distance { return m.dist } + +// ---------------------------------------------------------- + +/* +// MinDistanceToCellUnionTarget is a type for computing the minimum distance to a CellUnion. +type MinDistanceToCellUnionTarget struct { + cu CellUnion + query *ClosestCellQuery + dist distance +} + +// NewMinDistanceToCellUnionTarget returns a new target for the given CellUnion. +func NewMinDistanceToCellUnionTarget(cu CellUnion) *MinDistanceToCellUnionTarget { + m := minDistance(0) + return &MinDistanceToCellUnionTarget{cu: cu, dist: m} +} + +func (m *MinDistanceToCellUnionTarget) capBound() Cap { + return m.cu.CapBound() +} + +func (m *MinDistanceToCellUnionTarget) updateDistanceToCell(cell Cell, dist distance) (distance, bool) { + m.query.opts.DistanceLimit = dist.chordAngle() + target := NewMinDistanceToPointTarget(p) + r := m.query.findEdge(target) + if r.ShapeID < 0 { + return dist, false + } + return minDistance(r.Distance), true +} + +func (m *MinDistanceToCellUnionTarget) visitContainingShapes(index *ShapeIndex, v shapePointVisitorFunc) bool { + // We test the center of the edge in order to ensure that edge targets AB + // and BA yield identical results (which is not guaranteed by the API but + // users might expect). Other options would be to test both endpoints, or + // return different results for AB and BA in some cases. + target := NewMinDistanceToPointTarget(Point{m.e.V0.Add(m.e.V1.Vector).Normalize()}) + return target.visitContainingShapes(index, v) +} +func (m *MinDistanceToCellUnionTarget) setMaxError(maxErr s1.ChordAngle) bool { + m.query.opts.MaxError = maxErr + return true +} +func (m *MinDistanceToCellUnionTarget) maxBruteForceIndexSize() int { return 30 } +func (m *MinDistanceToCellUnionTarget) distance() distance { return m.dist } +*/ + +// ---------------------------------------------------------- + +// MinDistanceToShapeIndexTarget is a type for computing the minimum distance to a ShapeIndex. +type MinDistanceToShapeIndexTarget struct { + index *ShapeIndex + query *EdgeQuery + dist distance +} + +// NewMinDistanceToShapeIndexTarget returns a new target for the given ShapeIndex. +func NewMinDistanceToShapeIndexTarget(index *ShapeIndex) *MinDistanceToShapeIndexTarget { + m := minDistance(0) + return &MinDistanceToShapeIndexTarget{ + index: index, + dist: m, + query: NewClosestEdgeQuery(index, NewClosestEdgeQueryOptions()), + } +} + +func (m *MinDistanceToShapeIndexTarget) capBound() Cap { + // TODO(roberts): Depends on ShapeIndexRegion existing. + // c := makeS2ShapeIndexRegion(m.index).CapBound() + // return CapFromCenterRadius(Point{c.Center.Mul(-1)}, c.Radius()) + panic("not implemented yet") +} + +func (m *MinDistanceToShapeIndexTarget) updateDistanceToPoint(p Point, dist distance) (distance, bool) { + m.query.opts.distanceLimit = dist.chordAngle() + target := NewMinDistanceToPointTarget(p) + r := m.query.findEdge(target, m.query.opts) + if r.shapeID < 0 { + return dist, false + } + return r.distance, true +} + +func (m *MinDistanceToShapeIndexTarget) updateDistanceToEdge(edge Edge, dist distance) (distance, bool) { + m.query.opts.distanceLimit = dist.chordAngle() + target := NewMinDistanceToEdgeTarget(edge) + r := m.query.findEdge(target, m.query.opts) + if r.shapeID < 0 { + return dist, false + } + return r.distance, true +} + +func (m *MinDistanceToShapeIndexTarget) updateDistanceToCell(cell Cell, dist distance) (distance, bool) { + m.query.opts.distanceLimit = dist.chordAngle() + target := NewMinDistanceToCellTarget(cell) + r := m.query.findEdge(target, m.query.opts) + if r.shapeID < 0 { + return dist, false + } + return r.distance, true +} + +// For target types consisting of multiple connected components (such as this one), +// this method should return the polygons containing the antipodal reflection of +// *any* connected component. (It is sufficient to test containment of one vertex per +// connected component, since this allows us to also return any polygon whose +// boundary has distance.zero() to the target.) +func (m *MinDistanceToShapeIndexTarget) visitContainingShapes(index *ShapeIndex, v shapePointVisitorFunc) bool { + // It is sufficient to find the set of chain starts in the target index + // (i.e., one vertex per connected component of edges) that are contained by + // the query index, except for one special case to handle full polygons. + // + // TODO(roberts): Do this by merge-joining the two ShapeIndexes. + for _, shape := range m.index.shapes { + numChains := shape.NumChains() + // Shapes that don't have any edges require a special case (below). + testedPoint := false + for c := 0; c < numChains; c++ { + chain := shape.Chain(c) + if chain.Length == 0 { + continue + } + testedPoint = true + target := NewMinDistanceToPointTarget(shape.ChainEdge(c, 0).V0) + if !target.visitContainingShapes(index, v) { + return false + } + } + if !testedPoint { + // Special case to handle full polygons. + ref := shape.ReferencePoint() + if !ref.Contained { + continue + } + target := NewMinDistanceToPointTarget(ref.Point) + if !target.visitContainingShapes(index, v) { + return false + } + } + } + return true +} + +func (m *MinDistanceToShapeIndexTarget) setMaxError(maxErr s1.ChordAngle) bool { + m.query.opts.maxError = maxErr + return true +} +func (m *MinDistanceToShapeIndexTarget) maxBruteForceIndexSize() int { return 25 } +func (m *MinDistanceToShapeIndexTarget) distance() distance { return m.dist } +func (m *MinDistanceToShapeIndexTarget) setIncludeInteriors(b bool) { + m.query.opts.includeInteriors = b +} +func (m *MinDistanceToShapeIndexTarget) setUseBruteForce(b bool) { m.query.opts.useBruteForce = b } + +// TODO(roberts): Remaining methods +// +// func (m *MinDistanceToShapeIndexTarget) capBound() Cap { +// CellUnionTarget diff --git a/backend/vendor/github.com/blevesearch/geo/s2/nthderivative.go b/backend/vendor/github.com/blevesearch/geo/s2/nthderivative.go new file mode 100644 index 0000000000..73445d6c91 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/nthderivative.go @@ -0,0 +1,88 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +// nthDerivativeCoder provides Nth Derivative Coding. +// (In signal processing disciplines, this is known as N-th Delta Coding.) +// +// Good for varint coding integer sequences with polynomial trends. +// +// Instead of coding a sequence of values directly, code its nth-order discrete +// derivative. Overflow in integer addition and subtraction makes this a +// lossless transform. +// +// constant linear quadratic +// trend trend trend +// / \ / \ / \_ +// input |0 0 0 0 1 2 3 4 9 16 25 36 +// 0th derivative(identity) |0 0 0 0 1 2 3 4 9 16 25 36 +// 1st derivative(delta coding) | 0 0 0 1 1 1 1 5 7 9 11 +// 2nd derivative(linear prediction) | 0 0 1 0 0 0 4 2 2 2 +// ------------------------------------- +// 0 1 2 3 4 5 6 7 8 9 10 11 +// n in sequence +// +// Higher-order codings can break even or be detrimental on other sequences. +// +// random oscillating +// / \ / \_ +// input |5 9 6 1 8 8 2 -2 4 -4 6 -6 +// 0th derivative(identity) |5 9 6 1 8 8 2 -2 4 -4 6 -6 +// 1st derivative(delta coding) | 4 -3 -5 7 0 -6 -4 6 -8 10 -12 +// 2nd derivative(linear prediction) | -7 -2 12 -7 -6 2 10 -14 18 -22 +// --------------------------------------- +// 0 1 2 3 4 5 6 7 8 9 10 11 +// n in sequence +// +// Note that the nth derivative isn't available until sequence item n. Earlier +// values are coded at lower order. For the above table, read 5 4 -7 -2 12 ... +type nthDerivativeCoder struct { + n, m int + memory [10]int32 +} + +// newNthDerivativeCoder returns a new coder, where n is the derivative order of the encoder (the N in NthDerivative). +// n must be within [0,10]. +func newNthDerivativeCoder(n int) *nthDerivativeCoder { + c := &nthDerivativeCoder{n: n} + if n < 0 || n > len(c.memory) { + panic("unsupported n. Must be within [0,10].") + } + return c +} + +func (c *nthDerivativeCoder) encode(k int32) int32 { + for i := 0; i < c.m; i++ { + delta := k - c.memory[i] + c.memory[i] = k + k = delta + } + if c.m < c.n { + c.memory[c.m] = k + c.m++ + } + return k +} + +func (c *nthDerivativeCoder) decode(k int32) int32 { + if c.m < c.n { + c.m++ + } + for i := c.m - 1; i >= 0; i-- { + c.memory[i] += k + k = c.memory[i] + } + return k +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/paddedcell.go b/backend/vendor/github.com/blevesearch/geo/s2/paddedcell.go new file mode 100644 index 0000000000..ac304a6cc1 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/paddedcell.go @@ -0,0 +1,252 @@ +// Copyright 2016 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "github.com/golang/geo/r1" + "github.com/golang/geo/r2" +) + +// PaddedCell represents a Cell whose (u,v)-range has been expanded on +// all sides by a given amount of "padding". Unlike Cell, its methods and +// representation are optimized for clipping edges against Cell boundaries +// to determine which cells are intersected by a given set of edges. +type PaddedCell struct { + id CellID + padding float64 + bound r2.Rect + middle r2.Rect // A rect in (u, v)-space that belongs to all four children. + iLo, jLo int // Minimum (i,j)-coordinates of this cell before padding + orientation int // Hilbert curve orientation of this cell. + level int +} + +// PaddedCellFromCellID constructs a padded cell with the given padding. +func PaddedCellFromCellID(id CellID, padding float64) *PaddedCell { + p := &PaddedCell{ + id: id, + padding: padding, + middle: r2.EmptyRect(), + } + + // Fast path for constructing a top-level face (the most common case). + if id.isFace() { + limit := padding + 1 + p.bound = r2.Rect{r1.Interval{-limit, limit}, r1.Interval{-limit, limit}} + p.middle = r2.Rect{r1.Interval{-padding, padding}, r1.Interval{-padding, padding}} + p.orientation = id.Face() & 1 + return p + } + + _, p.iLo, p.jLo, p.orientation = id.faceIJOrientation() + p.level = id.Level() + p.bound = ijLevelToBoundUV(p.iLo, p.jLo, p.level).ExpandedByMargin(padding) + ijSize := sizeIJ(p.level) + p.iLo &= -ijSize + p.jLo &= -ijSize + + return p +} + +// PaddedCellFromParentIJ constructs the child of parent with the given (i,j) index. +// The four child cells have indices of (0,0), (0,1), (1,0), (1,1), where the i and j +// indices correspond to increasing u- and v-values respectively. +func PaddedCellFromParentIJ(parent *PaddedCell, i, j int) *PaddedCell { + // Compute the position and orientation of the child incrementally from the + // orientation of the parent. + pos := ijToPos[parent.orientation][2*i+j] + + p := &PaddedCell{ + id: parent.id.Children()[pos], + padding: parent.padding, + bound: parent.bound, + orientation: parent.orientation ^ posToOrientation[pos], + level: parent.level + 1, + middle: r2.EmptyRect(), + } + + ijSize := sizeIJ(p.level) + p.iLo = parent.iLo + i*ijSize + p.jLo = parent.jLo + j*ijSize + + // For each child, one corner of the bound is taken directly from the parent + // while the diagonally opposite corner is taken from middle(). + middle := parent.Middle() + if i == 1 { + p.bound.X.Lo = middle.X.Lo + } else { + p.bound.X.Hi = middle.X.Hi + } + if j == 1 { + p.bound.Y.Lo = middle.Y.Lo + } else { + p.bound.Y.Hi = middle.Y.Hi + } + + return p +} + +// CellID returns the CellID this padded cell represents. +func (p PaddedCell) CellID() CellID { + return p.id +} + +// Padding returns the amount of padding on this cell. +func (p PaddedCell) Padding() float64 { + return p.padding +} + +// Level returns the level this cell is at. +func (p PaddedCell) Level() int { + return p.level +} + +// Center returns the center of this cell. +func (p PaddedCell) Center() Point { + ijSize := sizeIJ(p.level) + si := uint32(2*p.iLo + ijSize) + ti := uint32(2*p.jLo + ijSize) + return Point{faceSiTiToXYZ(p.id.Face(), si, ti).Normalize()} +} + +// Middle returns the rectangle in the middle of this cell that belongs to +// all four of its children in (u,v)-space. +func (p *PaddedCell) Middle() r2.Rect { + // We compute this field lazily because it is not needed the majority of the + // time (i.e., for cells where the recursion terminates). + if p.middle.IsEmpty() { + ijSize := sizeIJ(p.level) + u := stToUV(siTiToST(uint32(2*p.iLo + ijSize))) + v := stToUV(siTiToST(uint32(2*p.jLo + ijSize))) + p.middle = r2.Rect{ + r1.Interval{u - p.padding, u + p.padding}, + r1.Interval{v - p.padding, v + p.padding}, + } + } + return p.middle +} + +// Bound returns the bounds for this cell in (u,v)-space including padding. +func (p PaddedCell) Bound() r2.Rect { + return p.bound +} + +// ChildIJ returns the (i,j) coordinates for the child cell at the given traversal +// position. The traversal position corresponds to the order in which child +// cells are visited by the Hilbert curve. +func (p PaddedCell) ChildIJ(pos int) (i, j int) { + ij := posToIJ[p.orientation][pos] + return ij >> 1, ij & 1 +} + +// EntryVertex return the vertex where the space-filling curve enters this cell. +func (p PaddedCell) EntryVertex() Point { + // The curve enters at the (0,0) vertex unless the axis directions are + // reversed, in which case it enters at the (1,1) vertex. + i := p.iLo + j := p.jLo + if p.orientation&invertMask != 0 { + ijSize := sizeIJ(p.level) + i += ijSize + j += ijSize + } + return Point{faceSiTiToXYZ(p.id.Face(), uint32(2*i), uint32(2*j)).Normalize()} +} + +// ExitVertex returns the vertex where the space-filling curve exits this cell. +func (p PaddedCell) ExitVertex() Point { + // The curve exits at the (1,0) vertex unless the axes are swapped or + // inverted but not both, in which case it exits at the (0,1) vertex. + i := p.iLo + j := p.jLo + ijSize := sizeIJ(p.level) + if p.orientation == 0 || p.orientation == swapMask+invertMask { + i += ijSize + } else { + j += ijSize + } + return Point{faceSiTiToXYZ(p.id.Face(), uint32(2*i), uint32(2*j)).Normalize()} +} + +// ShrinkToFit returns the smallest CellID that contains all descendants of this +// padded cell whose bounds intersect the given rect. For algorithms that use +// recursive subdivision to find the cells that intersect a particular object, this +// method can be used to skip all of the initial subdivision steps where only +// one child needs to be expanded. +// +// Note that this method is not the same as returning the smallest cell that contains +// the intersection of this cell with rect. Because of the padding, even if one child +// completely contains rect it is still possible that a neighboring child may also +// intersect the given rect. +// +// The provided Rect must intersect the bounds of this cell. +func (p *PaddedCell) ShrinkToFit(rect r2.Rect) CellID { + // Quick rejection test: if rect contains the center of this cell along + // either axis, then no further shrinking is possible. + if p.level == 0 { + // Fast path (most calls to this function start with a face cell). + if rect.X.Contains(0) || rect.Y.Contains(0) { + return p.id + } + } + + ijSize := sizeIJ(p.level) + if rect.X.Contains(stToUV(siTiToST(uint32(2*p.iLo+ijSize)))) || + rect.Y.Contains(stToUV(siTiToST(uint32(2*p.jLo+ijSize)))) { + return p.id + } + + // Otherwise we expand rect by the given padding on all sides and find + // the range of coordinates that it spans along the i- and j-axes. We then + // compute the highest bit position at which the min and max coordinates + // differ. This corresponds to the first cell level at which at least two + // children intersect rect. + + // Increase the padding to compensate for the error in uvToST. + // (The constant below is a provable upper bound on the additional error.) + padded := rect.ExpandedByMargin(p.padding + 1.5*dblEpsilon) + iMin, jMin := p.iLo, p.jLo // Min i- or j- coordinate spanned by padded + var iXor, jXor int // XOR of the min and max i- or j-coordinates + + if iMin < stToIJ(uvToST(padded.X.Lo)) { + iMin = stToIJ(uvToST(padded.X.Lo)) + } + if a, b := p.iLo+ijSize-1, stToIJ(uvToST(padded.X.Hi)); a <= b { + iXor = iMin ^ a + } else { + iXor = iMin ^ b + } + + if jMin < stToIJ(uvToST(padded.Y.Lo)) { + jMin = stToIJ(uvToST(padded.Y.Lo)) + } + if a, b := p.jLo+ijSize-1, stToIJ(uvToST(padded.Y.Hi)); a <= b { + jXor = jMin ^ a + } else { + jXor = jMin ^ b + } + + // Compute the highest bit position where the two i- or j-endpoints differ, + // and then choose the cell level that includes both of these endpoints. So + // if both pairs of endpoints are equal we choose maxLevel; if they differ + // only at bit 0, we choose (maxLevel - 1), and so on. + levelMSB := uint64(((iXor | jXor) << 1) + 1) + level := maxLevel - findMSBSetNonZero64(levelMSB) + if level <= p.level { + return p.id + } + + return cellIDFromFaceIJ(p.id.Face(), iMin, jMin).Parent(level) +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/point.go b/backend/vendor/github.com/blevesearch/geo/s2/point.go new file mode 100644 index 0000000000..89e7ae0ed2 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/point.go @@ -0,0 +1,258 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "fmt" + "io" + "math" + "sort" + + "github.com/golang/geo/r3" + "github.com/golang/geo/s1" +) + +// Point represents a point on the unit sphere as a normalized 3D vector. +// Fields should be treated as read-only. Use one of the factory methods for creation. +type Point struct { + r3.Vector +} + +// sortPoints sorts the slice of Points in place. +func sortPoints(e []Point) { + sort.Sort(points(e)) +} + +// points implements the Sort interface for slices of Point. +type points []Point + +func (p points) Len() int { return len(p) } +func (p points) Swap(i, j int) { p[i], p[j] = p[j], p[i] } +func (p points) Less(i, j int) bool { return p[i].Cmp(p[j].Vector) == -1 } + +// PointFromCoords creates a new normalized point from coordinates. +// +// This always returns a valid point. If the given coordinates can not be normalized +// the origin point will be returned. +// +// This behavior is different from the C++ construction of a S2Point from coordinates +// (i.e. S2Point(x, y, z)) in that in C++ they do not Normalize. +func PointFromCoords(x, y, z float64) Point { + if x == 0 && y == 0 && z == 0 { + return OriginPoint() + } + return Point{r3.Vector{x, y, z}.Normalize()} +} + +// OriginPoint returns a unique "origin" on the sphere for operations that need a fixed +// reference point. In particular, this is the "point at infinity" used for +// point-in-polygon testing (by counting the number of edge crossings). +// +// It should *not* be a point that is commonly used in edge tests in order +// to avoid triggering code to handle degenerate cases (this rules out the +// north and south poles). It should also not be on the boundary of any +// low-level S2Cell for the same reason. +func OriginPoint() Point { + return Point{r3.Vector{-0.0099994664350250197, 0.0025924542609324121, 0.99994664350250195}} +} + +// PointCross returns a Point that is orthogonal to both p and op. This is similar to +// p.Cross(op) (the true cross product) except that it does a better job of +// ensuring orthogonality when the Point is nearly parallel to op, it returns +// a non-zero result even when p == op or p == -op and the result is a Point. +// +// It satisfies the following properties (f == PointCross): +// +// (1) f(p, op) != 0 for all p, op +// (2) f(op,p) == -f(p,op) unless p == op or p == -op +// (3) f(-p,op) == -f(p,op) unless p == op or p == -op +// (4) f(p,-op) == -f(p,op) unless p == op or p == -op +func (p Point) PointCross(op Point) Point { + // NOTE(dnadasi): In the C++ API the equivalent method here was known as "RobustCrossProd", + // but PointCross more accurately describes how this method is used. + x := p.Add(op.Vector).Cross(op.Sub(p.Vector)) + + // Compare exactly to the 0 vector. + if x == (r3.Vector{}) { + // The only result that makes sense mathematically is to return zero, but + // we find it more convenient to return an arbitrary orthogonal vector. + return Point{p.Ortho()} + } + + return Point{x} +} + +// OrderedCCW returns true if the edges OA, OB, and OC are encountered in that +// order while sweeping CCW around the point O. +// +// You can think of this as testing whether A <= B <= C with respect to the +// CCW ordering around O that starts at A, or equivalently, whether B is +// contained in the range of angles (inclusive) that starts at A and extends +// CCW to C. Properties: +// +// (1) If OrderedCCW(a,b,c,o) && OrderedCCW(b,a,c,o), then a == b +// (2) If OrderedCCW(a,b,c,o) && OrderedCCW(a,c,b,o), then b == c +// (3) If OrderedCCW(a,b,c,o) && OrderedCCW(c,b,a,o), then a == b == c +// (4) If a == b or b == c, then OrderedCCW(a,b,c,o) is true +// (5) Otherwise if a == c, then OrderedCCW(a,b,c,o) is false +func OrderedCCW(a, b, c, o Point) bool { + sum := 0 + if RobustSign(b, o, a) != Clockwise { + sum++ + } + if RobustSign(c, o, b) != Clockwise { + sum++ + } + if RobustSign(a, o, c) == CounterClockwise { + sum++ + } + return sum >= 2 +} + +// Distance returns the angle between two points. +func (p Point) Distance(b Point) s1.Angle { + return p.Vector.Angle(b.Vector) +} + +// ApproxEqual reports whether the two points are similar enough to be equal. +func (p Point) ApproxEqual(other Point) bool { + return p.approxEqual(other, s1.Angle(epsilon)) +} + +// approxEqual reports whether the two points are within the given epsilon. +func (p Point) approxEqual(other Point, eps s1.Angle) bool { + return p.Vector.Angle(other.Vector) <= eps +} + +// ChordAngleBetweenPoints constructs a ChordAngle corresponding to the distance +// between the two given points. The points must be unit length. +func ChordAngleBetweenPoints(x, y Point) s1.ChordAngle { + return s1.ChordAngle(math.Min(4.0, x.Sub(y.Vector).Norm2())) +} + +// regularPoints generates a slice of points shaped as a regular polygon with +// the numVertices vertices, all located on a circle of the specified angular radius +// around the center. The radius is the actual distance from center to each vertex. +func regularPoints(center Point, radius s1.Angle, numVertices int) []Point { + return regularPointsForFrame(getFrame(center), radius, numVertices) +} + +// regularPointsForFrame generates a slice of points shaped as a regular polygon +// with numVertices vertices, all on a circle of the specified angular radius around +// the center. The radius is the actual distance from the center to each vertex. +func regularPointsForFrame(frame matrix3x3, radius s1.Angle, numVertices int) []Point { + // We construct the loop in the given frame coordinates, with the center at + // (0, 0, 1). For a loop of radius r, the loop vertices have the form + // (x, y, z) where x^2 + y^2 = sin(r) and z = cos(r). The distance on the + // sphere (arc length) from each vertex to the center is acos(cos(r)) = r. + z := math.Cos(radius.Radians()) + r := math.Sin(radius.Radians()) + radianStep := 2 * math.Pi / float64(numVertices) + var vertices []Point + + for i := 0; i < numVertices; i++ { + angle := float64(i) * radianStep + p := Point{r3.Vector{r * math.Cos(angle), r * math.Sin(angle), z}} + vertices = append(vertices, Point{fromFrame(frame, p).Normalize()}) + } + + return vertices +} + +// CapBound returns a bounding cap for this point. +func (p Point) CapBound() Cap { + return CapFromPoint(p) +} + +// RectBound returns a bounding latitude-longitude rectangle from this point. +func (p Point) RectBound() Rect { + return RectFromLatLng(LatLngFromPoint(p)) +} + +// ContainsCell returns false as Points do not contain any other S2 types. +func (p Point) ContainsCell(c Cell) bool { return false } + +// IntersectsCell reports whether this Point intersects the given cell. +func (p Point) IntersectsCell(c Cell) bool { + return c.ContainsPoint(p) +} + +// ContainsPoint reports if this Point contains the other Point. +// (This method is named to satisfy the Region interface.) +func (p Point) ContainsPoint(other Point) bool { + return p.Contains(other) +} + +// CellUnionBound computes a covering of the Point. +func (p Point) CellUnionBound() []CellID { + return p.CapBound().CellUnionBound() +} + +// Contains reports if this Point contains the other Point. +// (This method matches all other s2 types where the reflexive Contains +// method does not contain the type's name.) +func (p Point) Contains(other Point) bool { return p == other } + +// Encode encodes the Point. +func (p Point) Encode(w io.Writer) error { + e := &encoder{w: w} + p.encode(e) + return e.err +} + +func (p Point) encode(e *encoder) { + e.writeInt8(encodingVersion) + e.writeFloat64(p.X) + e.writeFloat64(p.Y) + e.writeFloat64(p.Z) +} + +// Decode decodes the Point. +func (p *Point) Decode(r io.Reader) error { + d := &decoder{r: asByteReader(r)} + p.decode(d) + return d.err +} + +func (p *Point) decode(d *decoder) { + version := d.readInt8() + if d.err != nil { + return + } + if version != encodingVersion { + d.err = fmt.Errorf("only version %d is supported", encodingVersion) + return + } + p.X = d.readFloat64() + p.Y = d.readFloat64() + p.Z = d.readFloat64() +} + +// Rotate the given point about the given axis by the given angle. p and +// axis must be unit length; angle has no restrictions (e.g., it can be +// positive, negative, greater than 360 degrees, etc). +func Rotate(p, axis Point, angle s1.Angle) Point { + // Let M be the plane through P that is perpendicular to axis, and let + // center be the point where M intersects axis. We construct a + // right-handed orthogonal frame (dx, dy, center) such that dx is the + // vector from center to P, and dy has the same length as dx. The + // result can then be expressed as (cos(angle)*dx + sin(angle)*dy + center). + center := axis.Mul(p.Dot(axis.Vector)) + dx := p.Sub(center) + dy := axis.Cross(p.Vector) + // Mathematically the result is unit length, but normalization is necessary + // to ensure that numerical errors don't accumulate. + return Point{dx.Mul(math.Cos(angle.Radians())).Add(dy.Mul(math.Sin(angle.Radians()))).Add(center).Normalize()} +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/point_measures.go b/backend/vendor/github.com/blevesearch/geo/s2/point_measures.go new file mode 100644 index 0000000000..6fa9b7ae4f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/point_measures.go @@ -0,0 +1,149 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "math" + + "github.com/golang/geo/s1" +) + +// PointArea returns the area of triangle ABC. This method combines two different +// algorithms to get accurate results for both large and small triangles. +// The maximum error is about 5e-15 (about 0.25 square meters on the Earth's +// surface), the same as GirardArea below, but unlike that method it is +// also accurate for small triangles. Example: when the true area is 100 +// square meters, PointArea yields an error about 1 trillion times smaller than +// GirardArea. +// +// All points should be unit length, and no two points should be antipodal. +// The area is always positive. +func PointArea(a, b, c Point) float64 { + // This method is based on l'Huilier's theorem, + // + // tan(E/4) = sqrt(tan(s/2) tan((s-a)/2) tan((s-b)/2) tan((s-c)/2)) + // + // where E is the spherical excess of the triangle (i.e. its area), + // a, b, c are the side lengths, and + // s is the semiperimeter (a + b + c) / 2. + // + // The only significant source of error using l'Huilier's method is the + // cancellation error of the terms (s-a), (s-b), (s-c). This leads to a + // *relative* error of about 1e-16 * s / min(s-a, s-b, s-c). This compares + // to a relative error of about 1e-15 / E using Girard's formula, where E is + // the true area of the triangle. Girard's formula can be even worse than + // this for very small triangles, e.g. a triangle with a true area of 1e-30 + // might evaluate to 1e-5. + // + // So, we prefer l'Huilier's formula unless dmin < s * (0.1 * E), where + // dmin = min(s-a, s-b, s-c). This basically includes all triangles + // except for extremely long and skinny ones. + // + // Since we don't know E, we would like a conservative upper bound on + // the triangle area in terms of s and dmin. It's possible to show that + // E <= k1 * s * sqrt(s * dmin), where k1 = 2*sqrt(3)/Pi (about 1). + // Using this, it's easy to show that we should always use l'Huilier's + // method if dmin >= k2 * s^5, where k2 is about 1e-2. Furthermore, + // if dmin < k2 * s^5, the triangle area is at most k3 * s^4, where + // k3 is about 0.1. Since the best case error using Girard's formula + // is about 1e-15, this means that we shouldn't even consider it unless + // s >= 3e-4 or so. + sa := float64(b.Angle(c.Vector)) + sb := float64(c.Angle(a.Vector)) + sc := float64(a.Angle(b.Vector)) + s := 0.5 * (sa + sb + sc) + if s >= 3e-4 { + // Consider whether Girard's formula might be more accurate. + dmin := s - math.Max(sa, math.Max(sb, sc)) + if dmin < 1e-2*s*s*s*s*s { + // This triangle is skinny enough to use Girard's formula. + area := GirardArea(a, b, c) + if dmin < s*0.1*area { + return area + } + } + } + + // Use l'Huilier's formula. + return 4 * math.Atan(math.Sqrt(math.Max(0.0, math.Tan(0.5*s)*math.Tan(0.5*(s-sa))* + math.Tan(0.5*(s-sb))*math.Tan(0.5*(s-sc))))) +} + +// GirardArea returns the area of the triangle computed using Girard's formula. +// All points should be unit length, and no two points should be antipodal. +// +// This method is about twice as fast as PointArea() but has poor relative +// accuracy for small triangles. The maximum error is about 5e-15 (about +// 0.25 square meters on the Earth's surface) and the average error is about +// 1e-15. These bounds apply to triangles of any size, even as the maximum +// edge length of the triangle approaches 180 degrees. But note that for +// such triangles, tiny perturbations of the input points can change the +// true mathematical area dramatically. +func GirardArea(a, b, c Point) float64 { + // This is equivalent to the usual Girard's formula but is slightly more + // accurate, faster to compute, and handles a == b == c without a special + // case. PointCross is necessary to get good accuracy when two of + // the input points are very close together. + ab := a.PointCross(b) + bc := b.PointCross(c) + ac := a.PointCross(c) + + area := float64(ab.Angle(ac.Vector) - ab.Angle(bc.Vector) + bc.Angle(ac.Vector)) + if area < 0 { + area = 0 + } + return area +} + +// SignedArea returns a positive value for counterclockwise triangles and a negative +// value otherwise (similar to PointArea). +func SignedArea(a, b, c Point) float64 { + return float64(RobustSign(a, b, c)) * PointArea(a, b, c) +} + +// Angle returns the interior angle at the vertex B in the triangle ABC. The +// return value is always in the range [0, pi]. All points should be +// normalized. Ensures that Angle(a,b,c) == Angle(c,b,a) for all a,b,c. +// +// The angle is undefined if A or C is diametrically opposite from B, and +// becomes numerically unstable as the length of edge AB or BC approaches +// 180 degrees. +func Angle(a, b, c Point) s1.Angle { + // PointCross is necessary to get good accuracy when two of the input + // points are very close together. + return a.PointCross(b).Angle(c.PointCross(b).Vector) +} + +// TurnAngle returns the exterior angle at vertex B in the triangle ABC. The +// return value is positive if ABC is counterclockwise and negative otherwise. +// If you imagine an ant walking from A to B to C, this is the angle that the +// ant turns at vertex B (positive = left = CCW, negative = right = CW). +// This quantity is also known as the "geodesic curvature" at B. +// +// Ensures that TurnAngle(a,b,c) == -TurnAngle(c,b,a) for all distinct +// a,b,c. The result is undefined if (a == b || b == c), but is either +// -Pi or Pi if (a == c). All points should be normalized. +func TurnAngle(a, b, c Point) s1.Angle { + // We use PointCross to get good accuracy when two points are very + // close together, and RobustSign to ensure that the sign is correct for + // turns that are close to 180 degrees. + angle := a.PointCross(b).Angle(b.PointCross(c).Vector) + + // Don't return RobustSign * angle because it is legal to have (a == c). + if RobustSign(a, b, c) == CounterClockwise { + return angle + } + return -angle +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/point_vector.go b/backend/vendor/github.com/blevesearch/geo/s2/point_vector.go new file mode 100644 index 0000000000..f8e6f65b51 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/point_vector.go @@ -0,0 +1,42 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +// Shape interface enforcement +var ( + _ Shape = (*PointVector)(nil) +) + +// PointVector is a Shape representing a set of Points. Each point +// is represented as a degenerate edge with the same starting and ending +// vertices. +// +// This type is useful for adding a collection of points to an ShapeIndex. +// +// Its methods are on *PointVector due to implementation details of ShapeIndex. +type PointVector []Point + +func (p *PointVector) NumEdges() int { return len(*p) } +func (p *PointVector) Edge(i int) Edge { return Edge{(*p)[i], (*p)[i]} } +func (p *PointVector) ReferencePoint() ReferencePoint { return OriginReferencePoint(false) } +func (p *PointVector) NumChains() int { return len(*p) } +func (p *PointVector) Chain(i int) Chain { return Chain{i, 1} } +func (p *PointVector) ChainEdge(i, j int) Edge { return Edge{(*p)[i], (*p)[j]} } +func (p *PointVector) ChainPosition(e int) ChainPosition { return ChainPosition{e, 0} } +func (p *PointVector) Dimension() int { return 0 } +func (p *PointVector) IsEmpty() bool { return defaultShapeIsEmpty(p) } +func (p *PointVector) IsFull() bool { return defaultShapeIsFull(p) } +func (p *PointVector) typeTag() typeTag { return typeTagPointVector } +func (p *PointVector) privateInterface() {} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/pointcompression.go b/backend/vendor/github.com/blevesearch/geo/s2/pointcompression.go new file mode 100644 index 0000000000..0183817993 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/pointcompression.go @@ -0,0 +1,319 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "errors" + "fmt" + + "github.com/golang/geo/r3" +) + +// maxEncodedVertices is the maximum number of vertices, in a row, to be encoded or decoded. +// On decode, this defends against malicious encodings that try and have us exceed RAM. +const maxEncodedVertices = 50000000 + +// xyzFaceSiTi represents the The XYZ and face,si,ti coordinates of a Point +// and, if this point is equal to the center of a Cell, the level of this cell +// (-1 otherwise). This is used for Loops and Polygons to store data in a more +// compressed format. +type xyzFaceSiTi struct { + xyz Point + face int + si, ti uint32 + level int +} + +const derivativeEncodingOrder = 2 + +func appendFace(faces []faceRun, face int) []faceRun { + if len(faces) == 0 || faces[len(faces)-1].face != face { + return append(faces, faceRun{face, 1}) + } + faces[len(faces)-1].count++ + return faces +} + +// encodePointsCompressed uses an optimized compressed format to encode the given values. +func encodePointsCompressed(e *encoder, vertices []xyzFaceSiTi, level int) { + var faces []faceRun + for _, v := range vertices { + faces = appendFace(faces, v.face) + } + encodeFaces(e, faces) + + type piQi struct { + pi, qi uint32 + } + verticesPiQi := make([]piQi, len(vertices)) + for i, v := range vertices { + verticesPiQi[i] = piQi{siTitoPiQi(v.si, level), siTitoPiQi(v.ti, level)} + } + piCoder, qiCoder := newNthDerivativeCoder(derivativeEncodingOrder), newNthDerivativeCoder(derivativeEncodingOrder) + for i, v := range verticesPiQi { + f := encodePointCompressed + if i == 0 { + // The first point will be just the (pi, qi) coordinates + // of the Point. NthDerivativeCoder will not save anything + // in that case, so we encode in fixed format rather than varint + // to avoid the varint overhead. + f = encodeFirstPointFixedLength + } + f(e, v.pi, v.qi, level, piCoder, qiCoder) + } + + var offCenter []int + for i, v := range vertices { + if v.level != level { + offCenter = append(offCenter, i) + } + } + e.writeUvarint(uint64(len(offCenter))) + for _, idx := range offCenter { + e.writeUvarint(uint64(idx)) + e.writeFloat64(vertices[idx].xyz.X) + e.writeFloat64(vertices[idx].xyz.Y) + e.writeFloat64(vertices[idx].xyz.Z) + } +} + +func encodeFirstPointFixedLength(e *encoder, pi, qi uint32, level int, piCoder, qiCoder *nthDerivativeCoder) { + // Do not ZigZagEncode the first point, since it cannot be negative. + codedPi, codedQi := piCoder.encode(int32(pi)), qiCoder.encode(int32(qi)) + // Interleave to reduce overhead from two partial bytes to one. + interleaved := interleaveUint32(uint32(codedPi), uint32(codedQi)) + + // Write as little endian. + bytesRequired := (level + 7) / 8 * 2 + for i := 0; i < bytesRequired; i++ { + e.writeUint8(uint8(interleaved)) + interleaved >>= 8 + } +} + +// encodePointCompressed encodes points into e. +// Given a sequence of Points assumed to be the center of level-k cells, +// compresses it into a stream using the following method: +// - decompose the points into (face, si, ti) tuples. +// - run-length encode the faces, combining face number and count into a +// varint32. See the faceRun struct. +// - right shift the (si, ti) to remove the part that's constant for all cells +// of level-k. The result is called the (pi, qi) space. +// - 2nd derivative encode the pi and qi sequences (linear prediction) +// - zig-zag encode all derivative values but the first, which cannot be +// negative +// - interleave the zig-zag encoded values +// - encode the first interleaved value in a fixed length encoding +// (varint would make this value larger) +// - encode the remaining interleaved values as varint64s, as the +// derivative encoding should make the values small. +// In addition, provides a lossless method to compress a sequence of points even +// if some points are not the center of level-k cells. These points are stored +// exactly, using 3 double precision values, after the above encoded string, +// together with their index in the sequence (this leads to some redundancy - it +// is expected that only a small fraction of the points are not cell centers). +// +// To encode leaf cells, this requires 8 bytes for the first vertex plus +// an average of 3.8 bytes for each additional vertex, when computed on +// Google's geographic repository. +func encodePointCompressed(e *encoder, pi, qi uint32, level int, piCoder, qiCoder *nthDerivativeCoder) { + // ZigZagEncode, as varint requires the maximum number of bytes for + // negative numbers. + zzPi := zigzagEncode(piCoder.encode(int32(pi))) + zzQi := zigzagEncode(qiCoder.encode(int32(qi))) + // Interleave to reduce overhead from two partial bytes to one. + interleaved := interleaveUint32(zzPi, zzQi) + e.writeUvarint(interleaved) +} + +type faceRun struct { + face, count int +} + +func decodeFaceRun(d *decoder) faceRun { + faceAndCount := d.readUvarint() + ret := faceRun{ + face: int(faceAndCount % numFaces), + count: int(faceAndCount / numFaces), + } + if ret.count <= 0 && d.err == nil { + d.err = errors.New("non-positive count for face run") + } + return ret +} + +func decodeFaces(numVertices int, d *decoder) []faceRun { + var frs []faceRun + for nparsed := 0; nparsed < numVertices; { + fr := decodeFaceRun(d) + if d.err != nil { + return nil + } + frs = append(frs, fr) + nparsed += fr.count + } + return frs +} + +// encodeFaceRun encodes each faceRun as a varint64 with value numFaces * count + face. +func encodeFaceRun(e *encoder, fr faceRun) { + // It isn't necessary to encode the number of faces left for the last run, + // but since this would only help if there were more than 21 faces, it will + // be a small overall savings, much smaller than the bound encoding. + coded := numFaces*uint64(fr.count) + uint64(fr.face) + e.writeUvarint(coded) +} + +func encodeFaces(e *encoder, frs []faceRun) { + for _, fr := range frs { + encodeFaceRun(e, fr) + } +} + +type facesIterator struct { + faces []faceRun + // How often have we yet shown the current face? + numCurrentFaceShown int + curFace int +} + +func (fi *facesIterator) next() (ok bool) { + if len(fi.faces) == 0 { + return false + } + fi.curFace = fi.faces[0].face + fi.numCurrentFaceShown++ + + // Advance fs if needed. + if fi.faces[0].count <= fi.numCurrentFaceShown { + fi.faces = fi.faces[1:] + fi.numCurrentFaceShown = 0 + } + + return true +} + +func decodePointsCompressed(d *decoder, level int, target []Point) { + faces := decodeFaces(len(target), d) + + piCoder := newNthDerivativeCoder(derivativeEncodingOrder) + qiCoder := newNthDerivativeCoder(derivativeEncodingOrder) + + iter := facesIterator{faces: faces} + for i := range target { + decodeFn := decodePointCompressed + if i == 0 { + decodeFn = decodeFirstPointFixedLength + } + pi, qi := decodeFn(d, level, piCoder, qiCoder) + if ok := iter.next(); !ok && d.err == nil { + d.err = fmt.Errorf("ran out of faces at target %d", i) + return + } + target[i] = Point{facePiQitoXYZ(iter.curFace, pi, qi, level)} + } + + numOffCenter := int(d.readUvarint()) + if d.err != nil { + return + } + if numOffCenter > len(target) { + d.err = fmt.Errorf("numOffCenter = %d, should be at most len(target) = %d", numOffCenter, len(target)) + return + } + for i := 0; i < numOffCenter; i++ { + idx := int(d.readUvarint()) + if d.err != nil { + return + } + if idx >= len(target) { + d.err = fmt.Errorf("off center index = %d, should be < len(target) = %d", idx, len(target)) + return + } + target[idx].X = d.readFloat64() + target[idx].Y = d.readFloat64() + target[idx].Z = d.readFloat64() + } +} + +func decodeFirstPointFixedLength(d *decoder, level int, piCoder, qiCoder *nthDerivativeCoder) (pi, qi uint32) { + bytesToRead := (level + 7) / 8 * 2 + var interleaved uint64 + for i := 0; i < bytesToRead; i++ { + rr := d.readUint8() + interleaved |= (uint64(rr) << uint(i*8)) + } + + piCoded, qiCoded := deinterleaveUint32(interleaved) + + return uint32(piCoder.decode(int32(piCoded))), uint32(qiCoder.decode(int32(qiCoded))) +} + +func zigzagEncode(x int32) uint32 { + return (uint32(x) << 1) ^ uint32(x>>31) +} + +func zigzagDecode(x uint32) int32 { + return int32((x >> 1) ^ uint32((int32(x&1)<<31)>>31)) +} + +func decodePointCompressed(d *decoder, level int, piCoder, qiCoder *nthDerivativeCoder) (pi, qi uint32) { + interleavedZigZagEncodedDerivPiQi := d.readUvarint() + piZigzag, qiZigzag := deinterleaveUint32(interleavedZigZagEncodedDerivPiQi) + return uint32(piCoder.decode(zigzagDecode(piZigzag))), uint32(qiCoder.decode(zigzagDecode(qiZigzag))) +} + +// We introduce a new coordinate system (pi, qi), which is (si, ti) +// with the bits that are constant for cells of that level shifted +// off to the right. +// si = round(s * 2^31) +// pi = si >> (31 - level) +// = floor(s * 2^level) +// If the point has been snapped to the level, the bits that are +// shifted off will be a 1 in the msb, then 0s after that, so the +// fractional part discarded by the cast is (close to) 0.5. + +// stToPiQi returns the value transformed to the PiQi coordinate space. +func stToPiQi(s float64, level uint) uint32 { + return uint32(s * float64(int(1)< max { + s = max + } + + return uint32(s >> (maxLevel + 1 - uint(level))) +} + +// piQiToST returns the value transformed to ST space. +func piQiToST(pi uint32, level int) float64 { + // We want to recover the position at the center of the cell. If the point + // was snapped to the center of the cell, then math.Modf(s * 2^level) == 0.5. + // Inverting STtoPiQi gives: + // s = (pi + 0.5) / 2^level. + return (float64(pi) + 0.5) / float64(int(1)< l.turningAngleMaxError() { + // Normalize the loop. + if angle < 0 { + l.Invert() + } + } else { + // Ensure that the loop does not contain the origin. + if l.ContainsOrigin() { + l.Invert() + } + } + } + + p := PolygonFromLoops(loops) + + if p.NumLoops() > 0 { + originLoop := p.Loop(0) + polygonContainsOrigin := false + for _, l := range p.Loops() { + if l.ContainsOrigin() { + polygonContainsOrigin = !polygonContainsOrigin + + originLoop = l + } + } + if containedOrigin[originLoop] != polygonContainsOrigin { + p.Invert() + } + } + + return p +} + +// Invert inverts the polygon (replaces it by its complement). +func (p *Polygon) Invert() { + // Inverting any one loop will invert the polygon. The best loop to invert + // is the one whose area is largest, since this yields the smallest area + // after inversion. The loop with the largest area is always at depth 0. + // The descendents of this loop all have their depth reduced by 1, while the + // former siblings of this loop all have their depth increased by 1. + + // The empty and full polygons are handled specially. + if p.IsEmpty() { + *p = *FullPolygon() + p.initLoopProperties() + return + } + if p.IsFull() { + *p = Polygon{} + p.initLoopProperties() + return + } + + // Find the loop whose area is largest (i.e., whose turning angle is + // smallest), minimizing calls to TurningAngle(). In particular, for + // polygons with a single shell at level 0 there is no need to call + // TurningAngle() at all. (This method is relatively expensive.) + best := 0 + const none = 10.0 // Flag that means "not computed yet" + bestAngle := none + for i := 1; i < p.NumLoops(); i++ { + if p.Loop(i).depth != 0 { + continue + } + // We defer computing the turning angle of loop 0 until we discover + // that the polygon has another top-level shell. + if bestAngle == none { + bestAngle = p.Loop(best).TurningAngle() + } + angle := p.Loop(i).TurningAngle() + // We break ties deterministically in order to avoid having the output + // depend on the input order of the loops. + if angle < bestAngle || (angle == bestAngle && compareLoops(p.Loop(i), p.Loop(best)) < 0) { + best = i + bestAngle = angle + } + } + // Build the new loops vector, starting with the inverted loop. + p.Loop(best).Invert() + newLoops := make([]*Loop, 0, p.NumLoops()) + // Add the former siblings of this loop as descendants. + lastBest := p.LastDescendant(best) + newLoops = append(newLoops, p.Loop(best)) + for i, l := range p.Loops() { + if i < best || i > lastBest { + l.depth++ + newLoops = append(newLoops, l) + } + } + // Add the former children of this loop as siblings. + for i, l := range p.Loops() { + if i > best && i <= lastBest { + l.depth-- + newLoops = append(newLoops, l) + } + } + + p.loops = newLoops + p.initLoopProperties() +} + +// Defines a total ordering on Loops that does not depend on the cyclic +// order of loop vertices. This function is used to choose which loop to +// invert in the case where several loops have exactly the same area. +func compareLoops(a, b *Loop) int { + if na, nb := a.NumVertices(), b.NumVertices(); na != nb { + return na - nb + } + ai, aDir := a.CanonicalFirstVertex() + bi, bDir := b.CanonicalFirstVertex() + if aDir != bDir { + return aDir - bDir + } + for n := a.NumVertices() - 1; n >= 0; n, ai, bi = n-1, ai+aDir, bi+bDir { + if cmp := a.Vertex(ai).Cmp(b.Vertex(bi).Vector); cmp != 0 { + return cmp + } + } + return 0 +} + +// PolygonFromCell returns a Polygon from a single loop created from the given Cell. +func PolygonFromCell(cell Cell) *Polygon { + return PolygonFromLoops([]*Loop{LoopFromCell(cell)}) +} + +// initNested takes the set of loops in this polygon and performs the nesting +// computations to set the proper nesting and parent/child relationships. +func (p *Polygon) initNested() { + if len(p.loops) == 1 { + p.initOneLoop() + return + } + + lm := make(loopMap) + + for _, l := range p.loops { + lm.insertLoop(l, nil) + } + // The loops have all been added to the loopMap for ordering. Clear the + // loops slice because we add all the loops in-order in initLoops. + p.loops = nil + + // Reorder the loops in depth-first traversal order. + p.initLoops(lm) + p.initLoopProperties() +} + +// loopMap is a map of a loop to its immediate children with respect to nesting. +// It is used to determine which loops are shells and which are holes. +type loopMap map[*Loop][]*Loop + +// insertLoop adds the given loop to the loop map under the specified parent. +// All children of the new entry are checked to see if the need to move up to +// a different level. +func (lm loopMap) insertLoop(newLoop, parent *Loop) { + var children []*Loop + for done := false; !done; { + children = lm[parent] + done = true + for _, child := range children { + if child.ContainsNested(newLoop) { + parent = child + done = false + break + } + } + } + + // Now, we have found a parent for this loop, it may be that some of the + // children of the parent of this loop may now be children of the new loop. + newChildren := lm[newLoop] + for i := 0; i < len(children); { + child := children[i] + if newLoop.ContainsNested(child) { + newChildren = append(newChildren, child) + children = append(children[0:i], children[i+1:]...) + } else { + i++ + } + } + + lm[newLoop] = newChildren + lm[parent] = append(children, newLoop) +} + +// loopStack simplifies access to the loops while being initialized. +type loopStack []*Loop + +func (s *loopStack) push(v *Loop) { + *s = append(*s, v) +} +func (s *loopStack) pop() *Loop { + l := len(*s) + r := (*s)[l-1] + *s = (*s)[:l-1] + return r +} + +// initLoops walks the mapping of loops to all of their children, and adds them in +// order into to the polygons set of loops. +func (p *Polygon) initLoops(lm loopMap) { + var stack loopStack + stack.push(nil) + depth := -1 + + for len(stack) > 0 { + loop := stack.pop() + if loop != nil { + depth = loop.depth + p.loops = append(p.loops, loop) + } + children := lm[loop] + for i := len(children) - 1; i >= 0; i-- { + child := children[i] + child.depth = depth + 1 + stack.push(child) + } + } +} + +// initOneLoop set the properties for a polygon made of a single loop. +// TODO(roberts): Can this be merged with initLoopProperties +func (p *Polygon) initOneLoop() { + p.hasHoles = false + p.numVertices = len(p.loops[0].vertices) + p.bound = p.loops[0].RectBound() + p.subregionBound = ExpandForSubregions(p.bound) + // Ensure the loops depth is set correctly. + p.loops[0].depth = 0 + + p.initEdgesAndIndex() +} + +// initLoopProperties sets the properties for polygons with multiple loops. +func (p *Polygon) initLoopProperties() { + p.numVertices = 0 + // the loops depths are set by initNested/initOriented prior to this. + p.bound = EmptyRect() + p.hasHoles = false + for _, l := range p.loops { + if l.IsHole() { + p.hasHoles = true + } else { + p.bound = p.bound.Union(l.RectBound()) + } + p.numVertices += l.NumVertices() + } + p.subregionBound = ExpandForSubregions(p.bound) + + p.initEdgesAndIndex() +} + +// initEdgesAndIndex performs the shape related initializations and adds the final +// polygon to the index. +func (p *Polygon) initEdgesAndIndex() { + p.numEdges = 0 + p.cumulativeEdges = nil + if p.IsFull() { + return + } + const maxLinearSearchLoops = 12 // Based on benchmarks. + if len(p.loops) > maxLinearSearchLoops { + p.cumulativeEdges = make([]int, 0, len(p.loops)) + } + + for _, l := range p.loops { + if p.cumulativeEdges != nil { + p.cumulativeEdges = append(p.cumulativeEdges, p.numEdges) + } + p.numEdges += len(l.vertices) + } + + p.index = NewShapeIndex() + p.index.Add(p) +} + +// FullPolygon returns a special "full" polygon. +func FullPolygon() *Polygon { + ret := &Polygon{ + loops: []*Loop{ + FullLoop(), + }, + numVertices: len(FullLoop().Vertices()), + bound: FullRect(), + subregionBound: FullRect(), + } + ret.initEdgesAndIndex() + return ret +} + +// Validate checks whether this is a valid polygon, +// including checking whether all the loops are themselves valid. +func (p *Polygon) Validate() error { + for i, l := range p.loops { + // Check for loop errors that don't require building a ShapeIndex. + if err := l.findValidationErrorNoIndex(); err != nil { + return fmt.Errorf("loop %d: %v", i, err) + } + // Check that no loop is empty, and that the full loop only appears in the + // full polygon. + if l.IsEmpty() { + return fmt.Errorf("loop %d: empty loops are not allowed", i) + } + if l.IsFull() && len(p.loops) > 1 { + return fmt.Errorf("loop %d: full loop appears in non-full polygon", i) + } + } + + // TODO(roberts): Uncomment the remaining checks when they are completed. + + // Check for loop self-intersections and loop pairs that cross + // (including duplicate edges and vertices). + // if findSelfIntersection(p.index) { + // return fmt.Errorf("polygon has loop pairs that cross") + // } + + // Check whether initOriented detected inconsistent loop orientations. + // if p.hasInconsistentLoopOrientations { + // return fmt.Errorf("inconsistent loop orientations detected") + // } + + // Finally, verify the loop nesting hierarchy. + return p.findLoopNestingError() +} + +// findLoopNestingError reports if there is an error in the loop nesting hierarchy. +func (p *Polygon) findLoopNestingError() error { + // First check that the loop depths make sense. + lastDepth := -1 + for i, l := range p.loops { + depth := l.depth + if depth < 0 || depth > lastDepth+1 { + return fmt.Errorf("loop %d: invalid loop depth (%d)", i, depth) + } + lastDepth = depth + } + // Then check that they correspond to the actual loop nesting. This test + // is quadratic in the number of loops but the cost per iteration is small. + for i, l := range p.loops { + last := p.LastDescendant(i) + for j, l2 := range p.loops { + if i == j { + continue + } + nested := (j >= i+1) && (j <= last) + const reverseB = false + + if l.containsNonCrossingBoundary(l2, reverseB) != nested { + nestedStr := "" + if !nested { + nestedStr = "not " + } + return fmt.Errorf("invalid nesting: loop %d should %scontain loop %d", i, nestedStr, j) + } + } + } + return nil +} + +// IsEmpty reports whether this is the special "empty" polygon (consisting of no loops). +func (p *Polygon) IsEmpty() bool { + return len(p.loops) == 0 +} + +// IsFull reports whether this is the special "full" polygon (consisting of a +// single loop that encompasses the entire sphere). +func (p *Polygon) IsFull() bool { + return len(p.loops) == 1 && p.loops[0].IsFull() +} + +// NumLoops returns the number of loops in this polygon. +func (p *Polygon) NumLoops() int { + return len(p.loops) +} + +// Loops returns the loops in this polygon. +func (p *Polygon) Loops() []*Loop { + return p.loops +} + +// Loop returns the loop at the given index. Note that during initialization, +// the given loops are reordered according to a pre-order traversal of the loop +// nesting hierarchy. This implies that every loop is immediately followed by +// its descendants. This hierarchy can be traversed using the methods Parent, +// LastDescendant, and Loop.depth. +func (p *Polygon) Loop(k int) *Loop { + return p.loops[k] +} + +// Parent returns the index of the parent of loop k. +// If the loop does not have a parent, ok=false is returned. +func (p *Polygon) Parent(k int) (index int, ok bool) { + // See where we are on the depth hierarchy. + depth := p.loops[k].depth + if depth == 0 { + return -1, false + } + + // There may be several loops at the same nesting level as us that share a + // parent loop with us. (Imagine a slice of swiss cheese, of which we are one loop. + // we don't know how many may be next to us before we get back to our parent loop.) + // Move up one position from us, and then begin traversing back through the set of loops + // until we find the one that is our parent or we get to the top of the polygon. + for k--; k >= 0 && p.loops[k].depth <= depth; k-- { + } + return k, true +} + +// LastDescendant returns the index of the last loop that is contained within loop k. +// If k is negative, it returns the last loop in the polygon. +// Note that loops are indexed according to a pre-order traversal of the nesting +// hierarchy, so the immediate children of loop k can be found by iterating over +// the loops (k+1)..LastDescendant(k) and selecting those whose depth is equal +// to Loop(k).depth+1. +func (p *Polygon) LastDescendant(k int) int { + if k < 0 { + return len(p.loops) - 1 + } + + depth := p.loops[k].depth + + // Find the next loop immediately past us in the set of loops, and then start + // moving down the list until we either get to the end or find the next loop + // that is higher up the hierarchy than we are. + for k++; k < len(p.loops) && p.loops[k].depth > depth; k++ { + } + return k - 1 +} + +// CapBound returns a bounding spherical cap. +func (p *Polygon) CapBound() Cap { return p.bound.CapBound() } + +// RectBound returns a bounding latitude-longitude rectangle. +func (p *Polygon) RectBound() Rect { return p.bound } + +// ContainsPoint reports whether the polygon contains the point. +func (p *Polygon) ContainsPoint(point Point) bool { + // NOTE: A bounds check slows down this function by about 50%. It is + // worthwhile only when it might allow us to delay building the index. + if !p.index.IsFresh() && !p.bound.ContainsPoint(point) { + return false + } + + // For small polygons, and during initial construction, it is faster to just + // check all the crossing. + const maxBruteForceVertices = 32 + if p.numVertices < maxBruteForceVertices || p.index == nil { + inside := false + for _, l := range p.loops { + // use loops bruteforce to avoid building the index on each loop. + inside = inside != l.bruteForceContainsPoint(point) + } + return inside + } + + // Otherwise we look up the ShapeIndex cell containing this point. + return NewContainsPointQuery(p.index, VertexModelSemiOpen).Contains(point) +} + +// ContainsCell reports whether the polygon contains the given cell. +func (p *Polygon) ContainsCell(cell Cell) bool { + it := p.index.Iterator() + relation := it.LocateCellID(cell.ID()) + + // If "cell" is disjoint from all index cells, it is not contained. + // Similarly, if "cell" is subdivided into one or more index cells then it + // is not contained, since index cells are subdivided only if they (nearly) + // intersect a sufficient number of edges. (But note that if "cell" itself + // is an index cell then it may be contained, since it could be a cell with + // no edges in the loop interior.) + if relation != Indexed { + return false + } + + // Otherwise check if any edges intersect "cell". + if p.boundaryApproxIntersects(it, cell) { + return false + } + + // Otherwise check if the loop contains the center of "cell". + return p.iteratorContainsPoint(it, cell.Center()) +} + +// IntersectsCell reports whether the polygon intersects the given cell. +func (p *Polygon) IntersectsCell(cell Cell) bool { + it := p.index.Iterator() + relation := it.LocateCellID(cell.ID()) + + // If cell does not overlap any index cell, there is no intersection. + if relation == Disjoint { + return false + } + // If cell is subdivided into one or more index cells, there is an + // intersection to within the S2ShapeIndex error bound (see Contains). + if relation == Subdivided { + return true + } + // If cell is an index cell, there is an intersection because index cells + // are created only if they have at least one edge or they are entirely + // contained by the loop. + if it.CellID() == cell.id { + return true + } + // Otherwise check if any edges intersect cell. + if p.boundaryApproxIntersects(it, cell) { + return true + } + // Otherwise check if the loop contains the center of cell. + return p.iteratorContainsPoint(it, cell.Center()) +} + +// CellUnionBound computes a covering of the Polygon. +func (p *Polygon) CellUnionBound() []CellID { + // TODO(roberts): Use ShapeIndexRegion when it's available. + return p.CapBound().CellUnionBound() +} + +// boundaryApproxIntersects reports whether the loop's boundary intersects cell. +// It may also return true when the loop boundary does not intersect cell but +// some edge comes within the worst-case error tolerance. +// +// This requires that it.Locate(cell) returned Indexed. +func (p *Polygon) boundaryApproxIntersects(it *ShapeIndexIterator, cell Cell) bool { + aClipped := it.IndexCell().findByShapeID(0) + + // If there are no edges, there is no intersection. + if len(aClipped.edges) == 0 { + return false + } + + // We can save some work if cell is the index cell itself. + if it.CellID() == cell.ID() { + return true + } + + // Otherwise check whether any of the edges intersect cell. + maxError := (faceClipErrorUVCoord + intersectsRectErrorUVDist) + bound := cell.BoundUV().ExpandedByMargin(maxError) + for _, e := range aClipped.edges { + edge := p.index.Shape(0).Edge(e) + v0, v1, ok := ClipToPaddedFace(edge.V0, edge.V1, cell.Face(), maxError) + if ok && edgeIntersectsRect(v0, v1, bound) { + return true + } + } + + return false +} + +// iteratorContainsPoint reports whether the iterator that is positioned at the +// ShapeIndexCell that may contain p, contains the point p. +func (p *Polygon) iteratorContainsPoint(it *ShapeIndexIterator, point Point) bool { + // Test containment by drawing a line segment from the cell center to the + // given point and counting edge crossings. + aClipped := it.IndexCell().findByShapeID(0) + inside := aClipped.containsCenter + + if len(aClipped.edges) == 0 { + return inside + } + + // This block requires ShapeIndex. + crosser := NewEdgeCrosser(it.Center(), point) + shape := p.index.Shape(0) + for _, e := range aClipped.edges { + edge := shape.Edge(e) + inside = inside != crosser.EdgeOrVertexCrossing(edge.V0, edge.V1) + } + + return inside +} + +// Shape Interface + +// NumEdges returns the number of edges in this shape. +func (p *Polygon) NumEdges() int { + return p.numEdges +} + +// Edge returns endpoints for the given edge index. +func (p *Polygon) Edge(e int) Edge { + var i int + + if len(p.cumulativeEdges) > 0 { + for i = range p.cumulativeEdges { + if i+1 >= len(p.cumulativeEdges) || e < p.cumulativeEdges[i+1] { + e -= p.cumulativeEdges[i] + break + } + } + } else { + // When the number of loops is small, use linear search. Most often + // there is exactly one loop and the code below executes zero times. + for i = 0; e >= len(p.Loop(i).vertices); i++ { + e -= len(p.Loop(i).vertices) + } + } + + return Edge{p.Loop(i).OrientedVertex(e), p.Loop(i).OrientedVertex(e + 1)} +} + +// ReferencePoint returns the reference point for this polygon. +func (p *Polygon) ReferencePoint() ReferencePoint { + containsOrigin := false + for _, l := range p.loops { + containsOrigin = containsOrigin != l.ContainsOrigin() + } + return OriginReferencePoint(containsOrigin) +} + +// NumChains reports the number of contiguous edge chains in the Polygon. +func (p *Polygon) NumChains() int { + return p.NumLoops() +} + +// Chain returns the i-th edge Chain (loop) in the Shape. +func (p *Polygon) Chain(chainID int) Chain { + if p.cumulativeEdges != nil { + return Chain{p.cumulativeEdges[chainID], len(p.Loop(chainID).vertices)} + } + e := 0 + for j := 0; j < chainID; j++ { + e += len(p.Loop(j).vertices) + } + + // Polygon represents a full loop as a loop with one vertex, while + // Shape represents a full loop as a chain with no vertices. + if numVertices := p.Loop(chainID).NumVertices(); numVertices != 1 { + return Chain{e, numVertices} + } + return Chain{e, 0} +} + +// ChainEdge returns the j-th edge of the i-th edge Chain (loop). +func (p *Polygon) ChainEdge(i, j int) Edge { + return Edge{p.Loop(i).OrientedVertex(j), p.Loop(i).OrientedVertex(j + 1)} +} + +// ChainPosition returns a pair (i, j) such that edgeID is the j-th edge +// of the i-th edge Chain. +func (p *Polygon) ChainPosition(edgeID int) ChainPosition { + var i int + + if len(p.cumulativeEdges) > 0 { + for i = range p.cumulativeEdges { + if i+1 >= len(p.cumulativeEdges) || edgeID < p.cumulativeEdges[i+1] { + edgeID -= p.cumulativeEdges[i] + break + } + } + } else { + // When the number of loops is small, use linear search. Most often + // there is exactly one loop and the code below executes zero times. + for i = 0; edgeID >= len(p.Loop(i).vertices); i++ { + edgeID -= len(p.Loop(i).vertices) + } + } + // TODO(roberts): unify this and Edge since they are mostly identical. + return ChainPosition{i, edgeID} +} + +// Dimension returns the dimension of the geometry represented by this Polygon. +func (p *Polygon) Dimension() int { return 2 } + +func (p *Polygon) typeTag() typeTag { return typeTagPolygon } + +func (p *Polygon) privateInterface() {} + +// Contains reports whether this polygon contains the other polygon. +// Specifically, it reports whether all the points in the other polygon +// are also in this polygon. +func (p *Polygon) Contains(o *Polygon) bool { + // If both polygons have one loop, use the more efficient Loop method. + // Note that Loop's Contains does its own bounding rectangle check. + if len(p.loops) == 1 && len(o.loops) == 1 { + return p.loops[0].Contains(o.loops[0]) + } + + // Otherwise if neither polygon has holes, we can still use the more + // efficient Loop's Contains method (rather than compareBoundary), + // but it's worthwhile to do our own bounds check first. + if !p.subregionBound.Contains(o.bound) { + // Even though Bound(A) does not contain Bound(B), it is still possible + // that A contains B. This can only happen when union of the two bounds + // spans all longitudes. For example, suppose that B consists of two + // shells with a longitude gap between them, while A consists of one shell + // that surrounds both shells of B but goes the other way around the + // sphere (so that it does not intersect the longitude gap). + if !p.bound.Lng.Union(o.bound.Lng).IsFull() { + return false + } + } + + if !p.hasHoles && !o.hasHoles { + for _, l := range o.loops { + if !p.anyLoopContains(l) { + return false + } + } + return true + } + + // Polygon A contains B iff B does not intersect the complement of A. From + // the intersection algorithm below, this means that the complement of A + // must exclude the entire boundary of B, and B must exclude all shell + // boundaries of the complement of A. (It can be shown that B must then + // exclude the entire boundary of the complement of A.) The first call + // below returns false if the boundaries cross, therefore the second call + // does not need to check for any crossing edges (which makes it cheaper). + return p.containsBoundary(o) && o.excludesNonCrossingComplementShells(p) +} + +// Intersects reports whether this polygon intersects the other polygon, i.e. +// if there is a point that is contained by both polygons. +func (p *Polygon) Intersects(o *Polygon) bool { + // If both polygons have one loop, use the more efficient Loop method. + // Note that Loop Intersects does its own bounding rectangle check. + if len(p.loops) == 1 && len(o.loops) == 1 { + return p.loops[0].Intersects(o.loops[0]) + } + + // Otherwise if neither polygon has holes, we can still use the more + // efficient Loop.Intersects method. The polygons intersect if and + // only if some pair of loop regions intersect. + if !p.bound.Intersects(o.bound) { + return false + } + + if !p.hasHoles && !o.hasHoles { + for _, l := range o.loops { + if p.anyLoopIntersects(l) { + return true + } + } + return false + } + + // Polygon A is disjoint from B if A excludes the entire boundary of B and B + // excludes all shell boundaries of A. (It can be shown that B must then + // exclude the entire boundary of A.) The first call below returns false if + // the boundaries cross, therefore the second call does not need to check + // for crossing edges. + return !p.excludesBoundary(o) || !o.excludesNonCrossingShells(p) +} + +// compareBoundary returns +1 if this polygon contains the boundary of B, -1 if A +// excludes the boundary of B, and 0 if the boundaries of A and B cross. +func (p *Polygon) compareBoundary(o *Loop) int { + result := -1 + for i := 0; i < len(p.loops) && result != 0; i++ { + // If B crosses any loop of A, the result is 0. Otherwise the result + // changes sign each time B is contained by a loop of A. + result *= -p.loops[i].compareBoundary(o) + } + return result +} + +// containsBoundary reports whether this polygon contains the entire boundary of B. +func (p *Polygon) containsBoundary(o *Polygon) bool { + for _, l := range o.loops { + if p.compareBoundary(l) <= 0 { + return false + } + } + return true +} + +// excludesBoundary reports whether this polygon excludes the entire boundary of B. +func (p *Polygon) excludesBoundary(o *Polygon) bool { + for _, l := range o.loops { + if p.compareBoundary(l) >= 0 { + return false + } + } + return true +} + +// containsNonCrossingBoundary reports whether polygon A contains the boundary of +// loop B. Shared edges are handled according to the rule described in loops +// containsNonCrossingBoundary. +func (p *Polygon) containsNonCrossingBoundary(o *Loop, reverse bool) bool { + var inside bool + for _, l := range p.loops { + x := l.containsNonCrossingBoundary(o, reverse) + inside = (inside != x) + } + return inside +} + +// excludesNonCrossingShells reports wheterh given two polygons A and B such that the +// boundary of A does not cross any loop of B, if A excludes all shell boundaries of B. +func (p *Polygon) excludesNonCrossingShells(o *Polygon) bool { + for _, l := range o.loops { + if l.IsHole() { + continue + } + if p.containsNonCrossingBoundary(l, false) { + return false + } + } + return true +} + +// excludesNonCrossingComplementShells reports whether given two polygons A and B +// such that the boundary of A does not cross any loop of B, if A excludes all +// shell boundaries of the complement of B. +func (p *Polygon) excludesNonCrossingComplementShells(o *Polygon) bool { + // Special case to handle the complement of the empty or full polygons. + if o.IsEmpty() { + return !p.IsFull() + } + if o.IsFull() { + return true + } + + // Otherwise the complement of B may be obtained by inverting loop(0) and + // then swapping the shell/hole status of all other loops. This implies + // that the shells of the complement consist of loop 0 plus all the holes of + // the original polygon. + for j, l := range o.loops { + if j > 0 && !l.IsHole() { + continue + } + + // The interior of the complement is to the right of loop 0, and to the + // left of the loops that were originally holes. + if p.containsNonCrossingBoundary(l, j == 0) { + return false + } + } + return true +} + +// anyLoopContains reports whether any loop in this polygon contains the given loop. +func (p *Polygon) anyLoopContains(o *Loop) bool { + for _, l := range p.loops { + if l.Contains(o) { + return true + } + } + return false +} + +// anyLoopIntersects reports whether any loop in this polygon intersects the given loop. +func (p *Polygon) anyLoopIntersects(o *Loop) bool { + for _, l := range p.loops { + if l.Intersects(o) { + return true + } + } + return false +} + +// Area returns the area of the polygon interior, i.e. the region on the left side +// of an odd number of loops. The return value is between 0 and 4*Pi. +func (p *Polygon) Area() float64 { + var area float64 + for _, loop := range p.loops { + area += float64(loop.Sign()) * loop.Area() + } + return area +} + +// Encode encodes the Polygon +func (p *Polygon) Encode(w io.Writer) error { + e := &encoder{w: w} + p.encode(e) + return e.err +} + +// encode only supports lossless encoding and not compressed format. +func (p *Polygon) encode(e *encoder) { + if p.numVertices == 0 { + p.encodeCompressed(e, maxLevel, nil) + return + } + + // Convert all the polygon vertices to XYZFaceSiTi format. + vs := make([]xyzFaceSiTi, 0, p.numVertices) + for _, l := range p.loops { + vs = append(vs, l.xyzFaceSiTiVertices()...) + } + + // Computes a histogram of the cell levels at which the vertices are snapped. + // (histogram[0] is the number of unsnapped vertices, histogram[i] the number + // of vertices snapped at level i-1). + histogram := make([]int, maxLevel+2) + for _, v := range vs { + histogram[v.level+1]++ + } + + // Compute the level at which most of the vertices are snapped. + // If multiple levels have the same maximum number of vertices + // snapped to it, the first one (lowest level number / largest + // area / smallest encoding length) will be chosen, so this + // is desired. + var snapLevel, numSnapped int + for level, h := range histogram[1:] { + if h > numSnapped { + snapLevel, numSnapped = level, h + } + } + + // Choose an encoding format based on the number of unsnapped vertices and a + // rough estimate of the encoded sizes. + numUnsnapped := p.numVertices - numSnapped // Number of vertices that won't be snapped at snapLevel. + const pointSize = 3 * 8 // s2.Point is an r3.Vector, which is 3 float64s. That's 3*8 = 24 bytes. + compressedSize := 4*p.numVertices + (pointSize+2)*numUnsnapped + losslessSize := pointSize * p.numVertices + if compressedSize < losslessSize { + p.encodeCompressed(e, snapLevel, vs) + } else { + p.encodeLossless(e) + } +} + +// encodeLossless encodes the polygon's Points as float64s. +func (p *Polygon) encodeLossless(e *encoder) { + e.writeInt8(encodingVersion) + e.writeBool(true) // a legacy c++ value. must be true. + e.writeBool(p.hasHoles) + e.writeUint32(uint32(len(p.loops))) + + if e.err != nil { + return + } + if len(p.loops) > maxEncodedLoops { + e.err = fmt.Errorf("too many loops (%d; max is %d)", len(p.loops), maxEncodedLoops) + return + } + for _, l := range p.loops { + l.encode(e) + } + + // Encode the bound. + p.bound.encode(e) +} + +func (p *Polygon) encodeCompressed(e *encoder, snapLevel int, vertices []xyzFaceSiTi) { + e.writeUint8(uint8(encodingCompressedVersion)) + e.writeUint8(uint8(snapLevel)) + e.writeUvarint(uint64(len(p.loops))) + + if e.err != nil { + return + } + if l := len(p.loops); l > maxEncodedLoops { + e.err = fmt.Errorf("too many loops to encode: %d; max is %d", l, maxEncodedLoops) + return + } + + for _, l := range p.loops { + l.encodeCompressed(e, snapLevel, vertices[:len(l.vertices)]) + vertices = vertices[len(l.vertices):] + } + // Do not write the bound, num_vertices, or has_holes_ as they can be + // cheaply recomputed by decodeCompressed. Microbenchmarks show the + // speed difference is inconsequential. +} + +// Decode decodes the Polygon. +func (p *Polygon) Decode(r io.Reader) error { + d := &decoder{r: asByteReader(r)} + version := int8(d.readUint8()) + var dec func(*decoder) + switch version { + case encodingVersion: + dec = p.decode + case encodingCompressedVersion: + dec = p.decodeCompressed + default: + return fmt.Errorf("unsupported version %d", version) + } + dec(d) + return d.err +} + +// maxEncodedLoops is the biggest supported number of loops in a polygon during encoding. +// Setting a maximum guards an allocation: it prevents an attacker from easily pushing us OOM. +const maxEncodedLoops = 10000000 + +func (p *Polygon) decode(d *decoder) { + *p = Polygon{} + d.readUint8() // Ignore irrelevant serialized owns_loops_ value. + + p.hasHoles = d.readBool() + + // Polygons with no loops are explicitly allowed here: a newly created + // polygon has zero loops and such polygons encode and decode properly. + nloops := d.readUint32() + if d.err != nil { + return + } + if nloops > maxEncodedLoops { + d.err = fmt.Errorf("too many loops (%d; max is %d)", nloops, maxEncodedLoops) + return + } + p.loops = make([]*Loop, nloops) + for i := range p.loops { + p.loops[i] = new(Loop) + p.loops[i].decode(d) + p.numVertices += len(p.loops[i].vertices) + } + + p.bound.decode(d) + if d.err != nil { + return + } + p.subregionBound = ExpandForSubregions(p.bound) + p.initEdgesAndIndex() +} + +func (p *Polygon) decodeCompressed(d *decoder) { + snapLevel := int(d.readUint8()) + + if snapLevel > maxLevel { + d.err = fmt.Errorf("snaplevel too big: %d", snapLevel) + return + } + // Polygons with no loops are explicitly allowed here: a newly created + // polygon has zero loops and such polygons encode and decode properly. + nloops := int(d.readUvarint()) + if nloops > maxEncodedLoops { + d.err = fmt.Errorf("too many loops (%d; max is %d)", nloops, maxEncodedLoops) + } + p.loops = make([]*Loop, nloops) + for i := range p.loops { + p.loops[i] = new(Loop) + p.loops[i].decodeCompressed(d, snapLevel) + } + p.initLoopProperties() +} + +func (p *Polygon) Project(point *Point) Point { + if p.ContainsPoint(*point) { + return *point + } + return p.ProjectToBoundary(point) +} + +func (p *Polygon) ProjectToBoundary(point *Point) Point { + options := NewClosestEdgeQueryOptions().MaxResults(1).IncludeInteriors(false) + q := NewClosestEdgeQuery(p.index, options) + target := NewMinDistanceToPointTarget(*point) + edges := q.FindEdges(target) + return q.Project(*point, edges[0]) +} + +// TODO(roberts): Differences from C++ +// Project - implemented in this fork. +// ProjectToBoundary - implemented in this fork. + +// Centroid +// SnapLevel +// DistanceToPoint +// DistanceToBoundary +// ApproxContains/ApproxDisjoint for Polygons +// InitTo{Intersection/ApproxIntersection/Union/ApproxUnion/Diff/ApproxDiff} +// InitToSimplified +// InitToSnapped +// IntersectWithPolyline +// ApproxIntersectWithPolyline +// SubtractFromPolyline +// ApproxSubtractFromPolyline +// DestructiveUnion +// DestructiveApproxUnion +// InitToCellUnionBorder +// IsNormalized +// Equal/BoundaryEqual/BoundaryApproxEqual/BoundaryNear Polygons +// BreakEdgesAndAddToBuilder +// +// clearLoops +// findLoopNestingError +// initToSimplifiedInternal +// internalClipPolyline +// clipBoundary diff --git a/backend/vendor/github.com/blevesearch/geo/s2/polyline.go b/backend/vendor/github.com/blevesearch/geo/s2/polyline.go new file mode 100644 index 0000000000..5179683427 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/polyline.go @@ -0,0 +1,589 @@ +// Copyright 2016 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "fmt" + "io" + "math" + + "github.com/golang/geo/s1" +) + +// Polyline represents a sequence of zero or more vertices connected by +// straight edges (geodesics). Edges of length 0 and 180 degrees are not +// allowed, i.e. adjacent vertices should not be identical or antipodal. +type Polyline []Point + +// PolylineFromLatLngs creates a new Polyline from the given LatLngs. +func PolylineFromLatLngs(points []LatLng) *Polyline { + p := make(Polyline, len(points)) + for k, v := range points { + p[k] = PointFromLatLng(v) + } + return &p +} + +// Reverse reverses the order of the Polyline vertices. +func (p *Polyline) Reverse() { + for i := 0; i < len(*p)/2; i++ { + (*p)[i], (*p)[len(*p)-i-1] = (*p)[len(*p)-i-1], (*p)[i] + } +} + +// Length returns the length of this Polyline. +func (p *Polyline) Length() s1.Angle { + var length s1.Angle + + for i := 1; i < len(*p); i++ { + length += (*p)[i-1].Distance((*p)[i]) + } + return length +} + +// Centroid returns the true centroid of the polyline multiplied by the length of the +// polyline. The result is not unit length, so you may wish to normalize it. +// +// Scaling by the Polyline length makes it easy to compute the centroid +// of several Polylines (by simply adding up their centroids). +func (p *Polyline) Centroid() Point { + var centroid Point + for i := 1; i < len(*p); i++ { + // The centroid (multiplied by length) is a vector toward the midpoint + // of the edge, whose length is twice the sin of half the angle between + // the two vertices. Defining theta to be this angle, we have: + vSum := (*p)[i-1].Add((*p)[i].Vector) // Length == 2*cos(theta) + vDiff := (*p)[i-1].Sub((*p)[i].Vector) // Length == 2*sin(theta) + + // Length == 2*sin(theta) + centroid = Point{centroid.Add(vSum.Mul(math.Sqrt(vDiff.Norm2() / vSum.Norm2())))} + } + return centroid +} + +// Equal reports whether the given Polyline is exactly the same as this one. +func (p *Polyline) Equal(b *Polyline) bool { + if len(*p) != len(*b) { + return false + } + for i, v := range *p { + if v != (*b)[i] { + return false + } + } + + return true +} + +// ApproxEqual reports whether two polylines have the same number of vertices, +// and corresponding vertex pairs are separated by no more the standard margin. +func (p *Polyline) ApproxEqual(o *Polyline) bool { + return p.approxEqual(o, s1.Angle(epsilon)) +} + +// approxEqual reports whether two polylines are equal within the given margin. +func (p *Polyline) approxEqual(o *Polyline, maxError s1.Angle) bool { + if len(*p) != len(*o) { + return false + } + for offset, val := range *p { + if !val.approxEqual((*o)[offset], maxError) { + return false + } + } + return true +} + +// CapBound returns the bounding Cap for this Polyline. +func (p *Polyline) CapBound() Cap { + return p.RectBound().CapBound() +} + +// RectBound returns the bounding Rect for this Polyline. +func (p *Polyline) RectBound() Rect { + rb := NewRectBounder() + for _, v := range *p { + rb.AddPoint(v) + } + return rb.RectBound() +} + +// ContainsCell reports whether this Polyline contains the given Cell. Always returns false +// because "containment" is not numerically well-defined except at the Polyline vertices. +func (p *Polyline) ContainsCell(cell Cell) bool { + return false +} + +// IntersectsCell reports whether this Polyline intersects the given Cell. +func (p *Polyline) IntersectsCell(cell Cell) bool { + if len(*p) == 0 { + return false + } + + // We only need to check whether the cell contains vertex 0 for correctness, + // but these tests are cheap compared to edge crossings so we might as well + // check all the vertices. + for _, v := range *p { + if cell.ContainsPoint(v) { + return true + } + } + + cellVertices := []Point{ + cell.Vertex(0), + cell.Vertex(1), + cell.Vertex(2), + cell.Vertex(3), + } + + for j := 0; j < 4; j++ { + crosser := NewChainEdgeCrosser(cellVertices[j], cellVertices[(j+1)&3], (*p)[0]) + for i := 1; i < len(*p); i++ { + if crosser.ChainCrossingSign((*p)[i]) != DoNotCross { + // There is a proper crossing, or two vertices were the same. + return true + } + } + } + return false +} + +// ContainsPoint returns false since Polylines are not closed. +func (p *Polyline) ContainsPoint(point Point) bool { + return false +} + +// CellUnionBound computes a covering of the Polyline. +func (p *Polyline) CellUnionBound() []CellID { + return p.CapBound().CellUnionBound() +} + +// NumEdges returns the number of edges in this shape. +func (p *Polyline) NumEdges() int { + if len(*p) == 0 { + return 0 + } + return len(*p) - 1 +} + +// Edge returns endpoints for the given edge index. +func (p *Polyline) Edge(i int) Edge { + return Edge{(*p)[i], (*p)[i+1]} +} + +// ReferencePoint returns the default reference point with negative containment because Polylines are not closed. +func (p *Polyline) ReferencePoint() ReferencePoint { + return OriginReferencePoint(false) +} + +// NumChains reports the number of contiguous edge chains in this Polyline. +func (p *Polyline) NumChains() int { + return minInt(1, p.NumEdges()) +} + +// Chain returns the i-th edge Chain in the Shape. +func (p *Polyline) Chain(chainID int) Chain { + return Chain{0, p.NumEdges()} +} + +// ChainEdge returns the j-th edge of the i-th edge Chain. +func (p *Polyline) ChainEdge(chainID, offset int) Edge { + return Edge{(*p)[offset], (*p)[offset+1]} +} + +// ChainPosition returns a pair (i, j) such that edgeID is the j-th edge +func (p *Polyline) ChainPosition(edgeID int) ChainPosition { + return ChainPosition{0, edgeID} +} + +// Dimension returns the dimension of the geometry represented by this Polyline. +func (p *Polyline) Dimension() int { return 1 } + +// IsEmpty reports whether this shape contains no points. +func (p *Polyline) IsEmpty() bool { return defaultShapeIsEmpty(p) } + +// IsFull reports whether this shape contains all points on the sphere. +func (p *Polyline) IsFull() bool { return defaultShapeIsFull(p) } + +func (p *Polyline) typeTag() typeTag { return typeTagPolyline } + +func (p *Polyline) privateInterface() {} + +// findEndVertex reports the maximal end index such that the line segment between +// the start index and this one such that the line segment between these two +// vertices passes within the given tolerance of all interior vertices, in order. +func findEndVertex(p Polyline, tolerance s1.Angle, index int) int { + // The basic idea is to keep track of the "pie wedge" of angles + // from the starting vertex such that a ray from the starting + // vertex at that angle will pass through the discs of radius + // tolerance centered around all vertices processed so far. + // + // First we define a coordinate frame for the tangent and normal + // spaces at the starting vertex. Essentially this means picking + // three orthonormal vectors X,Y,Z such that X and Y span the + // tangent plane at the starting vertex, and Z is up. We use + // the coordinate frame to define a mapping from 3D direction + // vectors to a one-dimensional ray angle in the range (-π, + // π]. The angle of a direction vector is computed by + // transforming it into the X,Y,Z basis, and then calculating + // atan2(y,x). This mapping allows us to represent a wedge of + // angles as a 1D interval. Since the interval wraps around, we + // represent it as an Interval, i.e. an interval on the unit + // circle. + origin := p[index] + frame := getFrame(origin) + + // As we go along, we keep track of the current wedge of angles + // and the distance to the last vertex (which must be + // non-decreasing). + currentWedge := s1.FullInterval() + var lastDistance s1.Angle + + for index++; index < len(p); index++ { + candidate := p[index] + distance := origin.Distance(candidate) + + // We don't allow simplification to create edges longer than + // 90 degrees, to avoid numeric instability as lengths + // approach 180 degrees. We do need to allow for original + // edges longer than 90 degrees, though. + if distance > math.Pi/2 && lastDistance > 0 { + break + } + + // Vertices must be in increasing order along the ray, except + // for the initial disc around the origin. + if distance < lastDistance && lastDistance > tolerance { + break + } + + lastDistance = distance + + // Points that are within the tolerance distance of the origin + // do not constrain the ray direction, so we can ignore them. + if distance <= tolerance { + continue + } + + // If the current wedge of angles does not contain the angle + // to this vertex, then stop right now. Note that the wedge + // of possible ray angles is not necessarily empty yet, but we + // can't continue unless we are willing to backtrack to the + // last vertex that was contained within the wedge (since we + // don't create new vertices). This would be more complicated + // and also make the worst-case running time more than linear. + direction := toFrame(frame, candidate) + center := math.Atan2(direction.Y, direction.X) + if !currentWedge.Contains(center) { + break + } + + // To determine how this vertex constrains the possible ray + // angles, consider the triangle ABC where A is the origin, B + // is the candidate vertex, and C is one of the two tangent + // points between A and the spherical cap of radius + // tolerance centered at B. Then from the spherical law of + // sines, sin(a)/sin(A) = sin(c)/sin(C), where a and c are + // the lengths of the edges opposite A and C. In our case C + // is a 90 degree angle, therefore A = asin(sin(a) / sin(c)). + // Angle A is the half-angle of the allowable wedge. + halfAngle := math.Asin(math.Sin(tolerance.Radians()) / math.Sin(distance.Radians())) + target := s1.IntervalFromPointPair(center, center).Expanded(halfAngle) + currentWedge = currentWedge.Intersection(target) + } + + // We break out of the loop when we reach a vertex index that + // can't be included in the line segment, so back up by one + // vertex. + return index - 1 +} + +// SubsampleVertices returns a subsequence of vertex indices such that the +// polyline connecting these vertices is never further than the given tolerance from +// the original polyline. Provided the first and last vertices are distinct, +// they are always preserved; if they are not, the subsequence may contain +// only a single index. +// +// Some useful properties of the algorithm: +// +// - It runs in linear time. +// +// - The output always represents a valid polyline. In particular, adjacent +// output vertices are never identical or antipodal. +// +// - The method is not optimal, but it tends to produce 2-3% fewer +// vertices than the Douglas-Peucker algorithm with the same tolerance. +// +// - The output is parametrically equivalent to the original polyline to +// within the given tolerance. For example, if a polyline backtracks on +// itself and then proceeds onwards, the backtracking will be preserved +// (to within the given tolerance). This is different than the +// Douglas-Peucker algorithm which only guarantees geometric equivalence. +func (p *Polyline) SubsampleVertices(tolerance s1.Angle) []int { + var result []int + + if len(*p) < 1 { + return result + } + + result = append(result, 0) + clampedTolerance := s1.Angle(math.Max(tolerance.Radians(), 0)) + + for index := 0; index+1 < len(*p); { + nextIndex := findEndVertex(*p, clampedTolerance, index) + // Don't create duplicate adjacent vertices. + if (*p)[nextIndex] != (*p)[index] { + result = append(result, nextIndex) + } + index = nextIndex + } + + return result +} + +// Encode encodes the Polyline. +func (p Polyline) Encode(w io.Writer) error { + e := &encoder{w: w} + p.encode(e) + return e.err +} + +func (p Polyline) encode(e *encoder) { + e.writeInt8(encodingVersion) + e.writeUint32(uint32(len(p))) + for _, v := range p { + e.writeFloat64(v.X) + e.writeFloat64(v.Y) + e.writeFloat64(v.Z) + } +} + +// Decode decodes the polyline. +func (p *Polyline) Decode(r io.Reader) error { + d := decoder{r: asByteReader(r)} + p.decode(d) + return d.err +} + +func (p *Polyline) decode(d decoder) { + version := d.readInt8() + if d.err != nil { + return + } + if int(version) != int(encodingVersion) { + d.err = fmt.Errorf("can't decode version %d; my version: %d", version, encodingVersion) + return + } + nvertices := d.readUint32() + if d.err != nil { + return + } + if nvertices > maxEncodedVertices { + d.err = fmt.Errorf("too many vertices (%d; max is %d)", nvertices, maxEncodedVertices) + return + } + *p = make([]Point, nvertices) + for i := range *p { + (*p)[i].X = d.readFloat64() + (*p)[i].Y = d.readFloat64() + (*p)[i].Z = d.readFloat64() + } +} + +// Project returns a point on the polyline that is closest to the given point, +// and the index of the next vertex after the projected point. The +// value of that index is always in the range [1, len(polyline)]. +// The polyline must not be empty. +func (p *Polyline) Project(point Point) (Point, int) { + if len(*p) == 1 { + // If there is only one vertex, it is always closest to any given point. + return (*p)[0], 1 + } + + // Initial value larger than any possible distance on the unit sphere. + minDist := 10 * s1.Radian + minIndex := -1 + + // Find the line segment in the polyline that is closest to the point given. + for i := 1; i < len(*p); i++ { + if dist := DistanceFromSegment(point, (*p)[i-1], (*p)[i]); dist < minDist { + minDist = dist + minIndex = i + } + } + + // Compute the point on the segment found that is closest to the point given. + closest := Project(point, (*p)[minIndex-1], (*p)[minIndex]) + if closest == (*p)[minIndex] { + minIndex++ + } + + return closest, minIndex +} + +// IsOnRight reports whether the point given is on the right hand side of the +// polyline, using a naive definition of "right-hand-sideness" where the point +// is on the RHS of the polyline iff the point is on the RHS of the line segment +// in the polyline which it is closest to. +// The polyline must have at least 2 vertices. +func (p *Polyline) IsOnRight(point Point) bool { + // If the closest point C is an interior vertex of the polyline, let B and D + // be the previous and next vertices. The given point P is on the right of + // the polyline (locally) if B, P, D are ordered CCW around vertex C. + closest, next := p.Project(point) + if closest == (*p)[next-1] && next > 1 && next < len(*p) { + if point == (*p)[next-1] { + // Polyline vertices are not on the RHS. + return false + } + return OrderedCCW((*p)[next-2], point, (*p)[next], (*p)[next-1]) + } + // Otherwise, the closest point C is incident to exactly one polyline edge. + // We test the point P against that edge. + if next == len(*p) { + next-- + } + return Sign(point, (*p)[next], (*p)[next-1]) +} + +// Validate checks whether this is a valid polyline or not. +func (p *Polyline) Validate() error { + // All vertices must be unit length. + for i, pt := range *p { + if !pt.IsUnit() { + return fmt.Errorf("vertex %d is not unit length", i) + } + } + + // Adjacent vertices must not be identical or antipodal. + for i := 1; i < len(*p); i++ { + prev, cur := (*p)[i-1], (*p)[i] + if prev == cur { + return fmt.Errorf("vertices %d and %d are identical", i-1, i) + } + if prev == (Point{cur.Mul(-1)}) { + return fmt.Errorf("vertices %d and %d are antipodal", i-1, i) + } + } + + return nil +} + +// Intersects reports whether this polyline intersects the given polyline. If +// the polylines share a vertex they are considered to be intersecting. When a +// polyline endpoint is the only intersection with the other polyline, the +// function may return true or false arbitrarily. +// +// The running time is quadratic in the number of vertices. +func (p *Polyline) Intersects(o *Polyline) bool { + if len(*p) == 0 || len(*o) == 0 { + return false + } + + if !p.RectBound().Intersects(o.RectBound()) { + return false + } + + // TODO(roberts): Use ShapeIndex here. + for i := 1; i < len(*p); i++ { + crosser := NewChainEdgeCrosser((*p)[i-1], (*p)[i], (*o)[0]) + for j := 1; j < len(*o); j++ { + if crosser.ChainCrossingSign((*o)[j]) != DoNotCross { + return true + } + } + } + return false +} + +// Interpolate returns the point whose distance from vertex 0 along the polyline is +// the given fraction of the polyline's total length, and the index of +// the next vertex after the interpolated point P. Fractions less than zero +// or greater than one are clamped. The return value is unit length. The cost of +// this function is currently linear in the number of vertices. +// +// This method allows the caller to easily construct a given suffix of the +// polyline by concatenating P with the polyline vertices starting at that next +// vertex. Note that P is guaranteed to be different than the point at the next +// vertex, so this will never result in a duplicate vertex. +// +// The polyline must not be empty. Note that if fraction >= 1.0, then the next +// vertex will be set to len(p) (indicating that no vertices from the polyline +// need to be appended). The value of the next vertex is always between 1 and +// len(p). +// +// This method can also be used to construct a prefix of the polyline, by +// taking the polyline vertices up to next vertex-1 and appending the +// returned point P if it is different from the last vertex (since in this +// case there is no guarantee of distinctness). +func (p *Polyline) Interpolate(fraction float64) (Point, int) { + // We intentionally let the (fraction >= 1) case fall through, since + // we need to handle it in the loop below in any case because of + // possible roundoff errors. + if fraction <= 0 { + return (*p)[0], 1 + } + target := s1.Angle(fraction) * p.Length() + + for i := 1; i < len(*p); i++ { + length := (*p)[i-1].Distance((*p)[i]) + if target < length { + // This interpolates with respect to arc length rather than + // straight-line distance, and produces a unit-length result. + result := InterpolateAtDistance(target, (*p)[i-1], (*p)[i]) + + // It is possible that (result == vertex(i)) due to rounding errors. + if result == (*p)[i] { + return result, i + 1 + } + return result, i + } + target -= length + } + + return (*p)[len(*p)-1], len(*p) +} + +// Uninterpolate is the inverse operation of Interpolate. Given a point on the +// polyline, it returns the ratio of the distance to the point from the +// beginning of the polyline over the length of the polyline. The return +// value is always betwen 0 and 1 inclusive. +// +// The polyline should not be empty. If it has fewer than 2 vertices, the +// return value is zero. +func (p *Polyline) Uninterpolate(point Point, nextVertex int) float64 { + if len(*p) < 2 { + return 0 + } + + var sum s1.Angle + for i := 1; i < nextVertex; i++ { + sum += (*p)[i-1].Distance((*p)[i]) + } + lengthToPoint := sum + (*p)[nextVertex-1].Distance(point) + for i := nextVertex; i < len(*p); i++ { + sum += (*p)[i-1].Distance((*p)[i]) + } + // The ratio can be greater than 1.0 due to rounding errors or because the + // point is not exactly on the polyline. + return minFloat64(1.0, float64(lengthToPoint/sum)) +} + +// TODO(roberts): Differences from C++. +// NearlyCoversPolyline +// InitToSnapped +// InitToSimplified +// SnapLevel +// encode/decode compressed diff --git a/backend/vendor/github.com/blevesearch/geo/s2/polyline_measures.go b/backend/vendor/github.com/blevesearch/geo/s2/polyline_measures.go new file mode 100644 index 0000000000..38ce991b5a --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/polyline_measures.go @@ -0,0 +1,53 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +// This file defines various measures for polylines on the sphere. These are +// low-level methods that work directly with arrays of Points. They are used to +// implement the methods in various other measures files. + +import ( + "github.com/golang/geo/r3" + "github.com/golang/geo/s1" +) + +// polylineLength returns the length of the given Polyline. +// It returns 0 for polylines with fewer than two vertices. +func polylineLength(p []Point) s1.Angle { + var length s1.Angle + + for i := 1; i < len(p); i++ { + length += p[i-1].Distance(p[i]) + } + return length +} + +// polylineCentroid returns the true centroid of the polyline multiplied by the +// length of the polyline. The result is not unit length, so you may wish to +// normalize it. +// +// Scaling by the Polyline length makes it easy to compute the centroid +// of several Polylines (by simply adding up their centroids). +// +// Note that for degenerate Polylines (e.g., AA) this returns Point(0, 0, 0). +// (This answer is correct; the result of this function is a line integral over +// the polyline, whose value is always zero if the polyline is degenerate.) +func polylineCentroid(p []Point) Point { + var centroid r3.Vector + for i := 1; i < len(p); i++ { + centroid = centroid.Add(EdgeTrueCentroid(p[i-1], p[i]).Vector) + } + return Point{centroid} +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/predicates.go b/backend/vendor/github.com/blevesearch/geo/s2/predicates.go new file mode 100644 index 0000000000..9fc5e1751a --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/predicates.go @@ -0,0 +1,701 @@ +// Copyright 2016 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +// This file contains various predicates that are guaranteed to produce +// correct, consistent results. They are also relatively efficient. This is +// achieved by computing conservative error bounds and falling back to high +// precision or even exact arithmetic when the result is uncertain. Such +// predicates are useful in implementing robust algorithms. +// +// See also EdgeCrosser, which implements various exact +// edge-crossing predicates more efficiently than can be done here. + +import ( + "math" + "math/big" + + "github.com/golang/geo/r3" + "github.com/golang/geo/s1" +) + +const ( + // If any other machine architectures need to be suppported, these next three + // values will need to be updated. + + // epsilon is a small number that represents a reasonable level of noise between two + // values that can be considered to be equal. + epsilon = 1e-15 + // dblEpsilon is a smaller number for values that require more precision. + // This is the C++ DBL_EPSILON equivalent. + dblEpsilon = 2.220446049250313e-16 + // dblError is the C++ value for S2 rounding_epsilon(). + dblError = 1.110223024625156e-16 + + // maxDeterminantError is the maximum error in computing (AxB).C where all vectors + // are unit length. Using standard inequalities, it can be shown that + // + // fl(AxB) = AxB + D where |D| <= (|AxB| + (2/sqrt(3))*|A|*|B|) * e + // + // where "fl()" denotes a calculation done in floating-point arithmetic, + // |x| denotes either absolute value or the L2-norm as appropriate, and + // e is a reasonably small value near the noise level of floating point + // number accuracy. Similarly, + // + // fl(B.C) = B.C + d where |d| <= (|B.C| + 2*|B|*|C|) * e . + // + // Applying these bounds to the unit-length vectors A,B,C and neglecting + // relative error (which does not affect the sign of the result), we get + // + // fl((AxB).C) = (AxB).C + d where |d| <= (3 + 2/sqrt(3)) * e + maxDeterminantError = 1.8274 * dblEpsilon + + // detErrorMultiplier is the factor to scale the magnitudes by when checking + // for the sign of set of points with certainty. Using a similar technique to + // the one used for maxDeterminantError, the error is at most: + // + // |d| <= (3 + 6/sqrt(3)) * |A-C| * |B-C| * e + // + // If the determinant magnitude is larger than this value then we know + // its sign with certainty. + detErrorMultiplier = 3.2321 * dblEpsilon +) + +// Direction is an indication of the ordering of a set of points. +type Direction int + +// These are the three options for the direction of a set of points. +const ( + Clockwise Direction = -1 + Indeterminate Direction = 0 + CounterClockwise Direction = 1 +) + +// newBigFloat constructs a new big.Float with maximum precision. +func newBigFloat() *big.Float { return new(big.Float).SetPrec(big.MaxPrec) } + +// Sign returns true if the points A, B, C are strictly counterclockwise, +// and returns false if the points are clockwise or collinear (i.e. if they are all +// contained on some great circle). +// +// Due to numerical errors, situations may arise that are mathematically +// impossible, e.g. ABC may be considered strictly CCW while BCA is not. +// However, the implementation guarantees the following: +// +// If Sign(a,b,c), then !Sign(c,b,a) for all a,b,c. +func Sign(a, b, c Point) bool { + // NOTE(dnadasi): In the C++ API the equivalent method here was known as "SimpleSign". + + // We compute the signed volume of the parallelepiped ABC. The usual + // formula for this is (A ⨯ B) · C, but we compute it here using (C ⨯ A) · B + // in order to ensure that ABC and CBA are not both CCW. This follows + // from the following identities (which are true numerically, not just + // mathematically): + // + // (1) x ⨯ y == -(y ⨯ x) + // (2) -x · y == -(x · y) + return c.Cross(a.Vector).Dot(b.Vector) > 0 +} + +// RobustSign returns a Direction representing the ordering of the points. +// CounterClockwise is returned if the points are in counter-clockwise order, +// Clockwise for clockwise, and Indeterminate if any two points are the same (collinear), +// or the sign could not completely be determined. +// +// This function has additional logic to make sure that the above properties hold even +// when the three points are coplanar, and to deal with the limitations of +// floating-point arithmetic. +// +// RobustSign satisfies the following conditions: +// +// (1) RobustSign(a,b,c) == Indeterminate if and only if a == b, b == c, or c == a +// (2) RobustSign(b,c,a) == RobustSign(a,b,c) for all a,b,c +// (3) RobustSign(c,b,a) == -RobustSign(a,b,c) for all a,b,c +// +// In other words: +// +// (1) The result is Indeterminate if and only if two points are the same. +// (2) Rotating the order of the arguments does not affect the result. +// (3) Exchanging any two arguments inverts the result. +// +// On the other hand, note that it is not true in general that +// RobustSign(-a,b,c) == -RobustSign(a,b,c), or any similar identities +// involving antipodal points. +func RobustSign(a, b, c Point) Direction { + sign := triageSign(a, b, c) + if sign == Indeterminate { + sign = expensiveSign(a, b, c) + } + return sign +} + +// stableSign reports the direction sign of the points in a numerically stable way. +// Unlike triageSign, this method can usually compute the correct determinant sign +// even when all three points are as collinear as possible. For example if three +// points are spaced 1km apart along a random line on the Earth's surface using +// the nearest representable points, there is only a 0.4% chance that this method +// will not be able to find the determinant sign. The probability of failure +// decreases as the points get closer together; if the collinear points are 1 meter +// apart, the failure rate drops to 0.0004%. +// +// This method could be extended to also handle nearly-antipodal points, but antipodal +// points are rare in practice so it seems better to simply fall back to +// exact arithmetic in that case. +func stableSign(a, b, c Point) Direction { + ab := b.Sub(a.Vector) + ab2 := ab.Norm2() + bc := c.Sub(b.Vector) + bc2 := bc.Norm2() + ca := a.Sub(c.Vector) + ca2 := ca.Norm2() + + // Now compute the determinant ((A-C)x(B-C)).C, where the vertices have been + // cyclically permuted if necessary so that AB is the longest edge. (This + // minimizes the magnitude of cross product.) At the same time we also + // compute the maximum error in the determinant. + + // The two shortest edges, pointing away from their common point. + var e1, e2, op r3.Vector + if ab2 >= bc2 && ab2 >= ca2 { + // AB is the longest edge. + e1, e2, op = ca, bc, c.Vector + } else if bc2 >= ca2 { + // BC is the longest edge. + e1, e2, op = ab, ca, a.Vector + } else { + // CA is the longest edge. + e1, e2, op = bc, ab, b.Vector + } + + det := -e1.Cross(e2).Dot(op) + maxErr := detErrorMultiplier * math.Sqrt(e1.Norm2()*e2.Norm2()) + + // If the determinant isn't zero, within maxErr, we know definitively the point ordering. + if det > maxErr { + return CounterClockwise + } + if det < -maxErr { + return Clockwise + } + return Indeterminate +} + +// triageSign returns the direction sign of the points. It returns Indeterminate if two +// points are identical or the result is uncertain. Uncertain cases can be resolved, if +// desired, by calling expensiveSign. +// +// The purpose of this method is to allow additional cheap tests to be done without +// calling expensiveSign. +func triageSign(a, b, c Point) Direction { + det := a.Cross(b.Vector).Dot(c.Vector) + if det > maxDeterminantError { + return CounterClockwise + } + if det < -maxDeterminantError { + return Clockwise + } + return Indeterminate +} + +// expensiveSign reports the direction sign of the points. It returns Indeterminate +// if two of the input points are the same. It uses multiple-precision arithmetic +// to ensure that its results are always self-consistent. +func expensiveSign(a, b, c Point) Direction { + // Return Indeterminate if and only if two points are the same. + // This ensures RobustSign(a,b,c) == Indeterminate if and only if a == b, b == c, or c == a. + // ie. Property 1 of RobustSign. + if a == b || b == c || c == a { + return Indeterminate + } + + // Next we try recomputing the determinant still using floating-point + // arithmetic but in a more precise way. This is more expensive than the + // simple calculation done by triageSign, but it is still *much* cheaper + // than using arbitrary-precision arithmetic. This optimization is able to + // compute the correct determinant sign in virtually all cases except when + // the three points are truly collinear (e.g., three points on the equator). + detSign := stableSign(a, b, c) + if detSign != Indeterminate { + return detSign + } + + // Otherwise fall back to exact arithmetic and symbolic permutations. + return exactSign(a, b, c, true) +} + +// exactSign reports the direction sign of the points computed using high-precision +// arithmetic and/or symbolic perturbations. +func exactSign(a, b, c Point, perturb bool) Direction { + // Sort the three points in lexicographic order, keeping track of the sign + // of the permutation. (Each exchange inverts the sign of the determinant.) + permSign := CounterClockwise + pa := &a + pb := &b + pc := &c + if pa.Cmp(pb.Vector) > 0 { + pa, pb = pb, pa + permSign = -permSign + } + if pb.Cmp(pc.Vector) > 0 { + pb, pc = pc, pb + permSign = -permSign + } + if pa.Cmp(pb.Vector) > 0 { + pa, pb = pb, pa + permSign = -permSign + } + + // Construct multiple-precision versions of the sorted points and compute + // their precise 3x3 determinant. + xa := r3.PreciseVectorFromVector(pa.Vector) + xb := r3.PreciseVectorFromVector(pb.Vector) + xc := r3.PreciseVectorFromVector(pc.Vector) + xbCrossXc := xb.Cross(xc) + det := xa.Dot(xbCrossXc) + + // The precision of big.Float is high enough that the result should always + // be exact enough (no rounding was performed). + + // If the exact determinant is non-zero, we're done. + detSign := Direction(det.Sign()) + if detSign == Indeterminate && perturb { + // Otherwise, we need to resort to symbolic perturbations to resolve the + // sign of the determinant. + detSign = symbolicallyPerturbedSign(xa, xb, xc, xbCrossXc) + } + return permSign * detSign +} + +// symbolicallyPerturbedSign reports the sign of the determinant of three points +// A, B, C under a model where every possible Point is slightly perturbed by +// a unique infinitesmal amount such that no three perturbed points are +// collinear and no four points are coplanar. The perturbations are so small +// that they do not change the sign of any determinant that was non-zero +// before the perturbations, and therefore can be safely ignored unless the +// determinant of three points is exactly zero (using multiple-precision +// arithmetic). This returns CounterClockwise or Clockwise according to the +// sign of the determinant after the symbolic perturbations are taken into account. +// +// Since the symbolic perturbation of a given point is fixed (i.e., the +// perturbation is the same for all calls to this method and does not depend +// on the other two arguments), the results of this method are always +// self-consistent. It will never return results that would correspond to an +// impossible configuration of non-degenerate points. +// +// This requires that the 3x3 determinant of A, B, C must be exactly zero. +// And the points must be distinct, with A < B < C in lexicographic order. +// +// Reference: +// "Simulation of Simplicity" (Edelsbrunner and Muecke, ACM Transactions on +// Graphics, 1990). +// +func symbolicallyPerturbedSign(a, b, c, bCrossC r3.PreciseVector) Direction { + // This method requires that the points are sorted in lexicographically + // increasing order. This is because every possible Point has its own + // symbolic perturbation such that if A < B then the symbolic perturbation + // for A is much larger than the perturbation for B. + // + // Alternatively, we could sort the points in this method and keep track of + // the sign of the permutation, but it is more efficient to do this before + // converting the inputs to the multi-precision representation, and this + // also lets us re-use the result of the cross product B x C. + // + // Every input coordinate x[i] is assigned a symbolic perturbation dx[i]. + // We then compute the sign of the determinant of the perturbed points, + // i.e. + // | a.X+da.X a.Y+da.Y a.Z+da.Z | + // | b.X+db.X b.Y+db.Y b.Z+db.Z | + // | c.X+dc.X c.Y+dc.Y c.Z+dc.Z | + // + // The perturbations are chosen such that + // + // da.Z > da.Y > da.X > db.Z > db.Y > db.X > dc.Z > dc.Y > dc.X + // + // where each perturbation is so much smaller than the previous one that we + // don't even need to consider it unless the coefficients of all previous + // perturbations are zero. In fact, it is so small that we don't need to + // consider it unless the coefficient of all products of the previous + // perturbations are zero. For example, we don't need to consider the + // coefficient of db.Y unless the coefficient of db.Z *da.X is zero. + // + // The follow code simply enumerates the coefficients of the perturbations + // (and products of perturbations) that appear in the determinant above, in + // order of decreasing perturbation magnitude. The first non-zero + // coefficient determines the sign of the result. The easiest way to + // enumerate the coefficients in the correct order is to pretend that each + // perturbation is some tiny value "eps" raised to a power of two: + // + // eps** 1 2 4 8 16 32 64 128 256 + // da.Z da.Y da.X db.Z db.Y db.X dc.Z dc.Y dc.X + // + // Essentially we can then just count in binary and test the corresponding + // subset of perturbations at each step. So for example, we must test the + // coefficient of db.Z*da.X before db.Y because eps**12 > eps**16. + // + // Of course, not all products of these perturbations appear in the + // determinant above, since the determinant only contains the products of + // elements in distinct rows and columns. Thus we don't need to consider + // da.Z*da.Y, db.Y *da.Y, etc. Furthermore, sometimes different pairs of + // perturbations have the same coefficient in the determinant; for example, + // da.Y*db.X and db.Y*da.X have the same coefficient (c.Z). Therefore + // we only need to test this coefficient the first time we encounter it in + // the binary order above (which will be db.Y*da.X). + // + // The sequence of tests below also appears in Table 4-ii of the paper + // referenced above, if you just want to look it up, with the following + // translations: [a,b,c] -> [i,j,k] and [0,1,2] -> [1,2,3]. Also note that + // some of the signs are different because the opposite cross product is + // used (e.g., B x C rather than C x B). + + detSign := bCrossC.Z.Sign() // da.Z + if detSign != 0 { + return Direction(detSign) + } + detSign = bCrossC.Y.Sign() // da.Y + if detSign != 0 { + return Direction(detSign) + } + detSign = bCrossC.X.Sign() // da.X + if detSign != 0 { + return Direction(detSign) + } + + detSign = newBigFloat().Sub(newBigFloat().Mul(c.X, a.Y), newBigFloat().Mul(c.Y, a.X)).Sign() // db.Z + if detSign != 0 { + return Direction(detSign) + } + detSign = c.X.Sign() // db.Z * da.Y + if detSign != 0 { + return Direction(detSign) + } + detSign = -(c.Y.Sign()) // db.Z * da.X + if detSign != 0 { + return Direction(detSign) + } + + detSign = newBigFloat().Sub(newBigFloat().Mul(c.Z, a.X), newBigFloat().Mul(c.X, a.Z)).Sign() // db.Y + if detSign != 0 { + return Direction(detSign) + } + detSign = c.Z.Sign() // db.Y * da.X + if detSign != 0 { + return Direction(detSign) + } + + // The following test is listed in the paper, but it is redundant because + // the previous tests guarantee that C == (0, 0, 0). + // (c.Y*a.Z - c.Z*a.Y).Sign() // db.X + + detSign = newBigFloat().Sub(newBigFloat().Mul(a.X, b.Y), newBigFloat().Mul(a.Y, b.X)).Sign() // dc.Z + if detSign != 0 { + return Direction(detSign) + } + detSign = -(b.X.Sign()) // dc.Z * da.Y + if detSign != 0 { + return Direction(detSign) + } + detSign = b.Y.Sign() // dc.Z * da.X + if detSign != 0 { + return Direction(detSign) + } + detSign = a.X.Sign() // dc.Z * db.Y + if detSign != 0 { + return Direction(detSign) + } + return CounterClockwise // dc.Z * db.Y * da.X +} + +// CompareDistances returns -1, 0, or +1 according to whether AX < BX, A == B, +// or AX > BX respectively. Distances are measured with respect to the positions +// of X, A, and B as though they were reprojected to lie exactly on the surface of +// the unit sphere. Furthermore, this method uses symbolic perturbations to +// ensure that the result is non-zero whenever A != B, even when AX == BX +// exactly, or even when A and B project to the same point on the sphere. +// Such results are guaranteed to be self-consistent, i.e. if AB < BC and +// BC < AC, then AB < AC. +func CompareDistances(x, a, b Point) int { + // We start by comparing distances using dot products (i.e., cosine of the + // angle), because (1) this is the cheapest technique, and (2) it is valid + // over the entire range of possible angles. (We can only use the sin^2 + // technique if both angles are less than 90 degrees or both angles are + // greater than 90 degrees.) + sign := triageCompareCosDistances(x, a, b) + if sign != 0 { + return sign + } + + // Optimization for (a == b) to avoid falling back to exact arithmetic. + if a == b { + return 0 + } + + // It is much better numerically to compare distances using cos(angle) if + // the distances are near 90 degrees and sin^2(angle) if the distances are + // near 0 or 180 degrees. We only need to check one of the two angles when + // making this decision because the fact that the test above failed means + // that angles "a" and "b" are very close together. + cosAX := a.Dot(x.Vector) + if cosAX > 1/math.Sqrt2 { + // Angles < 45 degrees. + sign = triageCompareSin2Distances(x, a, b) + } else if cosAX < -1/math.Sqrt2 { + // Angles > 135 degrees. sin^2(angle) is decreasing in this range. + sign = -triageCompareSin2Distances(x, a, b) + } + // C++ adds an additional check here using 80-bit floats. + // This is skipped in Go because we only have 32 and 64 bit floats. + + if sign != 0 { + return sign + } + + sign = exactCompareDistances(r3.PreciseVectorFromVector(x.Vector), r3.PreciseVectorFromVector(a.Vector), r3.PreciseVectorFromVector(b.Vector)) + if sign != 0 { + return sign + } + return symbolicCompareDistances(x, a, b) +} + +// cosDistance returns cos(XY) where XY is the angle between X and Y, and the +// maximum error amount in the result. This requires X and Y be normalized. +func cosDistance(x, y Point) (cos, err float64) { + cos = x.Dot(y.Vector) + return cos, 9.5*dblError*math.Abs(cos) + 1.5*dblError +} + +// sin2Distance returns sin**2(XY), where XY is the angle between X and Y, +// and the maximum error amount in the result. This requires X and Y be normalized. +func sin2Distance(x, y Point) (sin2, err float64) { + // The (x-y).Cross(x+y) trick eliminates almost all of error due to x + // and y being not quite unit length. This method is extremely accurate + // for small distances; the *relative* error in the result is O(dblError) for + // distances as small as dblError. + n := x.Sub(y.Vector).Cross(x.Add(y.Vector)) + sin2 = 0.25 * n.Norm2() + err = ((21+4*math.Sqrt(3))*dblError*sin2 + + 32*math.Sqrt(3)*dblError*dblError*math.Sqrt(sin2) + + 768*dblError*dblError*dblError*dblError) + return sin2, err +} + +// triageCompareCosDistances returns -1, 0, or +1 according to whether AX < BX, +// A == B, or AX > BX by comparing the distances between them using cosDistance. +func triageCompareCosDistances(x, a, b Point) int { + cosAX, cosAXerror := cosDistance(a, x) + cosBX, cosBXerror := cosDistance(b, x) + diff := cosAX - cosBX + err := cosAXerror + cosBXerror + if diff > err { + return -1 + } + if diff < -err { + return 1 + } + return 0 +} + +// triageCompareSin2Distances returns -1, 0, or +1 according to whether AX < BX, +// A == B, or AX > BX by comparing the distances between them using sin2Distance. +func triageCompareSin2Distances(x, a, b Point) int { + sin2AX, sin2AXerror := sin2Distance(a, x) + sin2BX, sin2BXerror := sin2Distance(b, x) + diff := sin2AX - sin2BX + err := sin2AXerror + sin2BXerror + if diff > err { + return 1 + } + if diff < -err { + return -1 + } + return 0 +} + +// exactCompareDistances returns -1, 0, or 1 after comparing using the values as +// PreciseVectors. +func exactCompareDistances(x, a, b r3.PreciseVector) int { + // This code produces the same result as though all points were reprojected + // to lie exactly on the surface of the unit sphere. It is based on testing + // whether x.Dot(a.Normalize()) < x.Dot(b.Normalize()), reformulated + // so that it can be evaluated using exact arithmetic. + cosAX := x.Dot(a) + cosBX := x.Dot(b) + + // If the two values have different signs, we need to handle that case now + // before squaring them below. + aSign := cosAX.Sign() + bSign := cosBX.Sign() + if aSign != bSign { + // If cos(AX) > cos(BX), then AX < BX. + if aSign > bSign { + return -1 + } + return 1 + } + cosAX2 := newBigFloat().Mul(cosAX, cosAX) + cosBX2 := newBigFloat().Mul(cosBX, cosBX) + cmp := newBigFloat().Sub(cosBX2.Mul(cosBX2, a.Norm2()), cosAX2.Mul(cosAX2, b.Norm2())) + return aSign * cmp.Sign() +} + +// symbolicCompareDistances returns -1, 0, or +1 given three points such that AX == BX +// (exactly) according to whether AX < BX, AX == BX, or AX > BX after symbolic +// perturbations are taken into account. +func symbolicCompareDistances(x, a, b Point) int { + // Our symbolic perturbation strategy is based on the following model. + // Similar to "simulation of simplicity", we assign a perturbation to every + // point such that if A < B, then the symbolic perturbation for A is much, + // much larger than the symbolic perturbation for B. We imagine that + // rather than projecting every point to lie exactly on the unit sphere, + // instead each point is positioned on its own tiny pedestal that raises it + // just off the surface of the unit sphere. This means that the distance AX + // is actually the true distance AX plus the (symbolic) heights of the + // pedestals for A and X. The pedestals are infinitesmally thin, so they do + // not affect distance measurements except at the two endpoints. If several + // points project to exactly the same point on the unit sphere, we imagine + // that they are placed on separate pedestals placed close together, where + // the distance between pedestals is much, much less than the height of any + // pedestal. (There are a finite number of Points, and therefore a finite + // number of pedestals, so this is possible.) + // + // If A < B, then A is on a higher pedestal than B, and therefore AX > BX. + switch a.Cmp(b.Vector) { + case -1: + return 1 + case 1: + return -1 + default: + return 0 + } +} + +var ( + // ca45Degrees is a predefined ChordAngle representing (approximately) 45 degrees. + ca45Degrees = s1.ChordAngleFromSquaredLength(2 - math.Sqrt2) +) + +// CompareDistance returns -1, 0, or +1 according to whether the distance XY is +// respectively less than, equal to, or greater than the provided chord angle. Distances are measured +// with respect to the positions of all points as though they are projected to lie +// exactly on the surface of the unit sphere. +func CompareDistance(x, y Point, r s1.ChordAngle) int { + // As with CompareDistances, we start by comparing dot products because + // the sin^2 method is only valid when the distance XY and the limit "r" are + // both less than 90 degrees. + sign := triageCompareCosDistance(x, y, float64(r)) + if sign != 0 { + return sign + } + + // Unlike with CompareDistances, it's not worth using the sin^2 method + // when the distance limit is near 180 degrees because the ChordAngle + // representation itself has has a rounding error of up to 2e-8 radians for + // distances near 180 degrees. + if r < ca45Degrees { + sign = triageCompareSin2Distance(x, y, float64(r)) + if sign != 0 { + return sign + } + } + return exactCompareDistance(r3.PreciseVectorFromVector(x.Vector), r3.PreciseVectorFromVector(y.Vector), big.NewFloat(float64(r)).SetPrec(big.MaxPrec)) +} + +// triageCompareCosDistance returns -1, 0, or +1 according to whether the distance XY is +// less than, equal to, or greater than r2 respectively using cos distance. +func triageCompareCosDistance(x, y Point, r2 float64) int { + cosXY, cosXYError := cosDistance(x, y) + cosR := 1.0 - 0.5*r2 + cosRError := 2.0 * dblError * cosR + diff := cosXY - cosR + err := cosXYError + cosRError + if diff > err { + return -1 + } + if diff < -err { + return 1 + } + return 0 +} + +// triageCompareSin2Distance returns -1, 0, or +1 according to whether the distance XY is +// less than, equal to, or greater than r2 respectively using sin^2 distance. +func triageCompareSin2Distance(x, y Point, r2 float64) int { + // Only valid for distance limits < 90 degrees. + sin2XY, sin2XYError := sin2Distance(x, y) + sin2R := r2 * (1.0 - 0.25*r2) + sin2RError := 3.0 * dblError * sin2R + diff := sin2XY - sin2R + err := sin2XYError + sin2RError + if diff > err { + return 1 + } + if diff < -err { + return -1 + } + return 0 +} + +var ( + bigOne = big.NewFloat(1.0).SetPrec(big.MaxPrec) + bigHalf = big.NewFloat(0.5).SetPrec(big.MaxPrec) +) + +// exactCompareDistance returns -1, 0, or +1 after comparing using PreciseVectors. +func exactCompareDistance(x, y r3.PreciseVector, r2 *big.Float) int { + // This code produces the same result as though all points were reprojected + // to lie exactly on the surface of the unit sphere. It is based on + // comparing the cosine of the angle XY (when both points are projected to + // lie exactly on the sphere) to the given threshold. + cosXY := x.Dot(y) + cosR := newBigFloat().Sub(bigOne, newBigFloat().Mul(bigHalf, r2)) + + // If the two values have different signs, we need to handle that case now + // before squaring them below. + xySign := cosXY.Sign() + rSign := cosR.Sign() + if xySign != rSign { + if xySign > rSign { + return -1 + } + return 1 // If cos(XY) > cos(r), then XY < r. + } + cmp := newBigFloat().Sub( + newBigFloat().Mul( + newBigFloat().Mul(cosR, cosR), newBigFloat().Mul(x.Norm2(), y.Norm2())), + newBigFloat().Mul(cosXY, cosXY)) + return xySign * cmp.Sign() +} + +// TODO(roberts): Differences from C++ +// CompareEdgeDistance +// CompareEdgeDirections +// EdgeCircumcenterSign +// GetVoronoiSiteExclusion +// GetClosestVertex +// TriageCompareLineSin2Distance +// TriageCompareLineCos2Distance +// TriageCompareLineDistance +// TriageCompareEdgeDistance +// ExactCompareLineDistance +// ExactCompareEdgeDistance +// TriageCompareEdgeDirections +// ExactCompareEdgeDirections +// ArePointsAntipodal +// ArePointsLinearlyDependent +// GetCircumcenter +// TriageEdgeCircumcenterSign +// ExactEdgeCircumcenterSign +// UnperturbedSign +// SymbolicEdgeCircumcenterSign +// ExactVoronoiSiteExclusion diff --git a/backend/vendor/github.com/blevesearch/geo/s2/projections.go b/backend/vendor/github.com/blevesearch/geo/s2/projections.go new file mode 100644 index 0000000000..f7273609cc --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/projections.go @@ -0,0 +1,241 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "math" + + "github.com/golang/geo/r2" + "github.com/golang/geo/s1" +) + +// Projection defines an interface for different ways of mapping between s2 and r2 Points. +// It can also define the coordinate wrapping behavior along each axis. +type Projection interface { + // Project converts a point on the sphere to a projected 2D point. + Project(p Point) r2.Point + + // Unproject converts a projected 2D point to a point on the sphere. + // + // If wrapping is defined for a given axis (see below), then this method + // should accept any real number for the corresponding coordinate. + Unproject(p r2.Point) Point + + // FromLatLng is a convenience function equivalent to Project(LatLngToPoint(ll)), + // but the implementation is more efficient. + FromLatLng(ll LatLng) r2.Point + + // ToLatLng is a convenience function equivalent to LatLngFromPoint(Unproject(p)), + // but the implementation is more efficient. + ToLatLng(p r2.Point) LatLng + + // Interpolate returns the point obtained by interpolating the given + // fraction of the distance along the line from A to B. + // Fractions < 0 or > 1 result in extrapolation instead. + Interpolate(f float64, a, b r2.Point) r2.Point + + // WrapDistance reports the coordinate wrapping distance along each axis. + // If this value is non-zero for a given axis, the coordinates are assumed + // to "wrap" with the given period. For example, if WrapDistance.Y == 360 + // then (x, y) and (x, y + 360) should map to the same Point. + // + // This information is used to ensure that edges takes the shortest path + // between two given points. For example, if coordinates represent + // (latitude, longitude) pairs in degrees and WrapDistance().Y == 360, + // then the edge (5:179, 5:-179) would be interpreted as spanning 2 degrees + // of longitude rather than 358 degrees. + // + // If a given axis does not wrap, its WrapDistance should be set to zero. + WrapDistance() r2.Point + + // WrapDestination that wraps the coordinates of B if necessary in order to + // obtain the shortest edge AB. For example, suppose that A = [170, 20], + // B = [-170, 20], and the projection wraps so that [x, y] == [x + 360, y]. + // Then this function would return [190, 20] for point B (reducing the edge + // length in the "x" direction from 340 to 20). + WrapDestination(a, b r2.Point) r2.Point + + // We do not support implementations of this interface outside this package. + privateInterface() +} + +// PlateCarreeProjection defines the "plate carree" (square plate) projection, +// which converts points on the sphere to (longitude, latitude) pairs. +// Coordinates can be scaled so that they represent radians, degrees, etc, but +// the projection is always centered around (latitude=0, longitude=0). +// +// Note that (x, y) coordinates are backwards compared to the usual (latitude, +// longitude) ordering, in order to match the usual convention for graphs in +// which "x" is horizontal and "y" is vertical. +type PlateCarreeProjection struct { + xWrap float64 + toRadians float64 // Multiplier to convert coordinates to radians. + fromRadians float64 // Multiplier to convert coordinates from radians. +} + +// NewPlateCarreeProjection constructs a plate carree projection where the +// x-coordinates (lng) span [-xScale, xScale] and the y coordinates (lat) +// span [-xScale/2, xScale/2]. For example if xScale==180 then the x +// range is [-180, 180] and the y range is [-90, 90]. +// +// By default coordinates are expressed in radians, i.e. the x range is +// [-Pi, Pi] and the y range is [-Pi/2, Pi/2]. +func NewPlateCarreeProjection(xScale float64) Projection { + return &PlateCarreeProjection{ + xWrap: 2 * xScale, + toRadians: math.Pi / xScale, + fromRadians: xScale / math.Pi, + } +} + +// Project converts a point on the sphere to a projected 2D point. +func (p *PlateCarreeProjection) Project(pt Point) r2.Point { + return p.FromLatLng(LatLngFromPoint(pt)) +} + +// Unproject converts a projected 2D point to a point on the sphere. +func (p *PlateCarreeProjection) Unproject(pt r2.Point) Point { + return PointFromLatLng(p.ToLatLng(pt)) +} + +// FromLatLng returns the LatLng projected into an R2 Point. +func (p *PlateCarreeProjection) FromLatLng(ll LatLng) r2.Point { + return r2.Point{ + X: p.fromRadians * ll.Lng.Radians(), + Y: p.fromRadians * ll.Lat.Radians(), + } +} + +// ToLatLng returns the LatLng projected from the given R2 Point. +func (p *PlateCarreeProjection) ToLatLng(pt r2.Point) LatLng { + return LatLng{ + Lat: s1.Angle(p.toRadians * pt.Y), + Lng: s1.Angle(p.toRadians * math.Remainder(pt.X, p.xWrap)), + } +} + +// Interpolate returns the point obtained by interpolating the given +// fraction of the distance along the line from A to B. +func (p *PlateCarreeProjection) Interpolate(f float64, a, b r2.Point) r2.Point { + return a.Mul(1 - f).Add(b.Mul(f)) +} + +// WrapDistance reports the coordinate wrapping distance along each axis. +func (p *PlateCarreeProjection) WrapDistance() r2.Point { + return r2.Point{p.xWrap, 0} +} + +// WrapDestination wraps the points if needed to get the shortest edge. +func (p *PlateCarreeProjection) WrapDestination(a, b r2.Point) r2.Point { + return wrapDestination(a, b, p.WrapDistance) +} + +func (p *PlateCarreeProjection) privateInterface() {} + +// MercatorProjection defines the spherical Mercator projection. Google Maps +// uses this projection together with WGS84 coordinates, in which case it is +// known as the "Web Mercator" projection (see Wikipedia). This class makes +// no assumptions regarding the coordinate system of its input points, but +// simply applies the spherical Mercator projection to them. +// +// The Mercator projection is finite in width (x) but infinite in height (y). +// "x" corresponds to longitude, and spans a finite range such as [-180, 180] +// (with coordinate wrapping), while "y" is a function of latitude and spans +// an infinite range. (As "y" coordinates get larger, points get closer to +// the north pole but never quite reach it.) The north and south poles have +// infinite "y" values. (Note that this will cause problems if you tessellate +// a Mercator edge where one endpoint is a pole. If you need to do this, clip +// the edge first so that the "y" coordinate is no more than about 5 * maxX.) +type MercatorProjection struct { + xWrap float64 + toRadians float64 // Multiplier to convert coordinates to radians. + fromRadians float64 // Multiplier to convert coordinates from radians. +} + +// NewMercatorProjection constructs a Mercator projection with the given maximum +// longitude axis value corresponding to a range of [-maxLng, maxLng]. +// The horizontal and vertical axes are scaled equally. +func NewMercatorProjection(maxLng float64) Projection { + return &MercatorProjection{ + xWrap: 2 * maxLng, + toRadians: math.Pi / maxLng, + fromRadians: maxLng / math.Pi, + } +} + +// Project converts a point on the sphere to a projected 2D point. +func (p *MercatorProjection) Project(pt Point) r2.Point { + return p.FromLatLng(LatLngFromPoint(pt)) +} + +// Unproject converts a projected 2D point to a point on the sphere. +func (p *MercatorProjection) Unproject(pt r2.Point) Point { + return PointFromLatLng(p.ToLatLng(pt)) +} + +// FromLatLng returns the LatLng projected into an R2 Point. +func (p *MercatorProjection) FromLatLng(ll LatLng) r2.Point { + // This formula is more accurate near zero than the log(tan()) version. + // Note that latitudes of +/- 90 degrees yield "y" values of +/- infinity. + sinPhi := math.Sin(float64(ll.Lat)) + y := 0.5 * math.Log((1+sinPhi)/(1-sinPhi)) + return r2.Point{p.fromRadians * float64(ll.Lng), p.fromRadians * y} +} + +// ToLatLng returns the LatLng projected from the given R2 Point. +func (p *MercatorProjection) ToLatLng(pt r2.Point) LatLng { + // This formula is more accurate near zero than the atan(exp()) version. + x := p.toRadians * math.Remainder(pt.X, p.xWrap) + k := math.Exp(2 * p.toRadians * pt.Y) + var y float64 + if math.IsInf(k, 0) { + y = math.Pi / 2 + } else { + y = math.Asin((k - 1) / (k + 1)) + } + return LatLng{s1.Angle(y), s1.Angle(x)} +} + +// Interpolate returns the point obtained by interpolating the given +// fraction of the distance along the line from A to B. +func (p *MercatorProjection) Interpolate(f float64, a, b r2.Point) r2.Point { + return a.Mul(1 - f).Add(b.Mul(f)) +} + +// WrapDistance reports the coordinate wrapping distance along each axis. +func (p *MercatorProjection) WrapDistance() r2.Point { + return r2.Point{p.xWrap, 0} +} + +// WrapDestination wraps the points if needed to get the shortest edge. +func (p *MercatorProjection) WrapDestination(a, b r2.Point) r2.Point { + return wrapDestination(a, b, p.WrapDistance) +} + +func (p *MercatorProjection) privateInterface() {} + +func wrapDestination(a, b r2.Point, wrapDistance func() r2.Point) r2.Point { + wrap := wrapDistance() + x := b.X + y := b.Y + // The code below ensures that "b" is unmodified unless wrapping is required. + if wrap.X > 0 && math.Abs(x-a.X) > 0.5*wrap.X { + x = a.X + math.Remainder(x-a.X, wrap.X) + } + if wrap.Y > 0 && math.Abs(y-a.Y) > 0.5*wrap.Y { + y = a.Y + math.Remainder(y-a.Y, wrap.Y) + } + return r2.Point{x, y} +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/query_entry.go b/backend/vendor/github.com/blevesearch/geo/s2/query_entry.go new file mode 100644 index 0000000000..65e819e3a0 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/query_entry.go @@ -0,0 +1,93 @@ +// Copyright 2020 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import "container/heap" + +// A queryQueueEntry stores CellIDs and distance from a target. It is used by the +// different S2 Query types to efficiently build their internal priority queue +// in the optimized algorithm implementations. +type queryQueueEntry struct { + // A lower bound on the distance from the target to ID. This is the key + // of the priority queue. + distance distance + + // The cell being queued. + id CellID + + // If the CellID belongs to a ShapeIndex, this field stores the + // corresponding ShapeIndexCell. Otherwise ID is a proper ancestor of + // one or more ShapeIndexCells and this field stores is nil. + indexCell *ShapeIndexCell +} + +// queryQueue is used by the optimized algorithm to maintain a priority queue of +// unprocessed CellIDs, sorted in increasing order of distance from the target. +type queryQueue struct { + queue queryPQ +} + +// newQueryQueue returns a new initialized queryQueue. +func newQueryQueue() *queryQueue { + q := &queryQueue{ + queue: make(queryPQ, 0), + } + heap.Init(&q.queue) + return q +} + +// push adds the given entry to the top of this queue. +func (q *queryQueue) push(e *queryQueueEntry) { + heap.Push(&q.queue, e) +} + +// pop returns the top element of this queue. +func (q *queryQueue) pop() *queryQueueEntry { + return heap.Pop(&q.queue).(*queryQueueEntry) +} + +func (q *queryQueue) size() int { + return q.queue.Len() +} + +func (q *queryQueue) reset() { + q.queue = q.queue[:0] +} + +// queryPQ is a priority queue that implements the heap interface. +type queryPQ []*queryQueueEntry + +func (q queryPQ) Len() int { return len(q) } +func (q queryPQ) Less(i, j int) bool { + return q[i].distance.less(q[j].distance) +} + +// Swap swaps the two entries. +func (q queryPQ) Swap(i, j int) { + q[i], q[j] = q[j], q[i] +} + +// Push adds the given entry to the queue. +func (q *queryPQ) Push(x interface{}) { + item := x.(*queryQueueEntry) + *q = append(*q, item) +} + +// Pop returns the top element of the queue. +func (q *queryPQ) Pop() interface{} { + item := (*q)[len(*q)-1] + *q = (*q)[:len(*q)-1] + return item +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/query_options.go b/backend/vendor/github.com/blevesearch/geo/s2/query_options.go new file mode 100644 index 0000000000..9b7e38d628 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/query_options.go @@ -0,0 +1,196 @@ +// Copyright 2019 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "math" + + "github.com/golang/geo/s1" +) + +const maxQueryResults = math.MaxInt32 + +// queryOptions represents the set of all configurable parameters used by all of +// the Query types. Most of these fields have non-zero defaults, so initialization +// is handled within each Query type. All of the exported methods accept user +// supplied sets of options to set or adjust as necessary. +// +// Several of the defaults depend on the distance interface type being used +// (e.g. minDistance, maxDistance, etc.) +// +// If a user sets an option value that a given query type doesn't use, it is ignored. +type queryOptions struct { + // maxResults specifies that at most MaxResults edges should be returned. + // This must be at least 1. + // + // The default value is to return all results. + maxResults int + + // distanceLimit specifies that only edges whose distance to the target is + // within this distance should be returned. + // + // Note that edges whose distance is exactly equal to this are + // not returned. In most cases this doesn't matter (since distances are + // not computed exactly in the first place), but if such edges are needed + // then you can retrieve them by specifying the distance as the next + // largest representable distance. i.e. distanceLimit.Successor(). + // + // The default value is the infinity value, such that all results will be + // returned. + distanceLimit s1.ChordAngle + + // maxError specifies that edges up to MaxError further away than the true + // closest edges may be substituted in the result set, as long as such + // edges satisfy all the remaining search criteria (such as DistanceLimit). + // This option only has an effect if MaxResults is also specified; + // otherwise all edges closer than MaxDistance will always be returned. + // + // Note that this does not affect how the distance between edges is + // computed; it simply gives the algorithm permission to stop the search + // early as soon as the best possible improvement drops below MaxError. + // + // This can be used to implement distance predicates efficiently. For + // example, to determine whether the minimum distance is less than D, set + // MaxResults == 1 and MaxDistance == MaxError == D. This causes + // the algorithm to terminate as soon as it finds any edge whose distance + // is less than D, rather than continuing to search for an edge that is + // even closer. + // + // The default value is zero. + maxError s1.ChordAngle + + // includeInteriors specifies that polygon interiors should be included + // when measuring distances. In other words, polygons that contain the target + // should have a distance of zero. (For targets consisting of multiple connected + // components, the distance is zero if any component is contained.) This + // is indicated in the results by returning a (ShapeID, EdgeID) pair + // with EdgeID == -1, i.e. this value denotes the polygons's interior. + // + // Note that for efficiency, any polygon that intersects the target may or + // may not have an EdgeID == -1 result. Such results are optional + // because in that case the distance to the polygon is already zero. + // + // The default value is true. + includeInteriors bool + + // specifies that distances should be computed by examining every edge + // rather than using the ShapeIndex. + // + // TODO(roberts): When optimized is implemented, update the default to false. + // The default value is true. + useBruteForce bool + + // region specifies that results must intersect the given Region. + // + // Note that if you want to set the region to a disc around a target + // point, it is faster to use a PointTarget with distanceLimit set + // instead. You can also set a distance limit and also require that results + // lie within a given rectangle. + // + // The default is nil (no region limits). + region Region +} + +// UseBruteForce sets or disables the use of brute force in a query. +func (q *queryOptions) UseBruteForce(x bool) *queryOptions { + q.useBruteForce = x + return q +} + +// IncludeInteriors specifies whether polygon interiors should be +// included when measuring distances. +func (q *queryOptions) IncludeInteriors(x bool) *queryOptions { + q.includeInteriors = x + return q +} + +// MaxError specifies that edges up to dist away than the true +// matching edges may be substituted in the result set, as long as such +// edges satisfy all the remaining search criteria (such as DistanceLimit). +// This option only has an effect if MaxResults is also specified; +// otherwise all edges closer than MaxDistance will always be returned. +func (q *queryOptions) MaxError(x s1.ChordAngle) *queryOptions { + q.maxError = x + return q +} + +// MaxResults specifies that at most MaxResults edges should be returned. +// This must be at least 1. +func (q *queryOptions) MaxResults(x int) *queryOptions { + // TODO(roberts): What should be done if the value is <= 0? + q.maxResults = int(x) + return q +} + +// DistanceLimit specifies that only edges whose distance to the target is +// within, this distance should be returned. Edges whose distance is equal +// are not returned. +// +// To include values that are equal, specify the limit with the next largest +// representable distance such as limit.Successor(), or set the option with +// Furthest/ClosestInclusiveDistanceLimit. +func (q *queryOptions) DistanceLimit(x s1.ChordAngle) *queryOptions { + q.distanceLimit = x + return q +} + +// ClosestInclusiveDistanceLimit sets the distance limit such that results whose +// distance is exactly equal to the limit are also returned. +func (q *queryOptions) ClosestInclusiveDistanceLimit(limit s1.ChordAngle) *queryOptions { + q.distanceLimit = limit.Successor() + return q +} + +// FurthestInclusiveDistanceLimit sets the distance limit such that results whose +// distance is exactly equal to the limit are also returned. +func (q *queryOptions) FurthestInclusiveDistanceLimit(limit s1.ChordAngle) *queryOptions { + q.distanceLimit = limit.Predecessor() + return q +} + +// ClosestConservativeDistanceLimit sets the distance limit such that results +// also incorporates the error in distance calculations. This ensures that all +// edges whose true distance is less than or equal to limit will be returned +// (along with some edges whose true distance is slightly greater). +// +// Algorithms that need to do exact distance comparisons can use this +// option to find a set of candidate edges that can then be filtered +// further (e.g., using CompareDistance). +func (q *queryOptions) ClosestConservativeDistanceLimit(limit s1.ChordAngle) *queryOptions { + q.distanceLimit = limit.Expanded(minUpdateDistanceMaxError(limit)) + return q +} + +// FurthestConservativeDistanceLimit sets the distance limit such that results +// also incorporates the error in distance calculations. This ensures that all +// edges whose true distance is greater than or equal to limit will be returned +// (along with some edges whose true distance is slightly less). +func (q *queryOptions) FurthestConservativeDistanceLimit(limit s1.ChordAngle) *queryOptions { + q.distanceLimit = limit.Expanded(-minUpdateDistanceMaxError(limit)) + return q +} + +// newQueryOptions returns a set of options using the given distance type +// with the proper default values. +func newQueryOptions(d distance) *queryOptions { + return &queryOptions{ + maxResults: maxQueryResults, + distanceLimit: d.infinity().chordAngle(), + maxError: 0, + includeInteriors: true, + useBruteForce: false, + region: nil, + } +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/rect.go b/backend/vendor/github.com/blevesearch/geo/s2/rect.go new file mode 100644 index 0000000000..d7b9aa5e4f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/rect.go @@ -0,0 +1,726 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "fmt" + "io" + "math" + + "github.com/golang/geo/r1" + "github.com/golang/geo/r3" + "github.com/golang/geo/s1" +) + +// Rect represents a closed latitude-longitude rectangle. +type Rect struct { + Lat r1.Interval + Lng s1.Interval +} + +var ( + validRectLatRange = r1.Interval{-math.Pi / 2, math.Pi / 2} + validRectLngRange = s1.FullInterval() +) + +// EmptyRect returns the empty rectangle. +func EmptyRect() Rect { return Rect{r1.EmptyInterval(), s1.EmptyInterval()} } + +// FullRect returns the full rectangle. +func FullRect() Rect { return Rect{validRectLatRange, validRectLngRange} } + +// RectFromLatLng constructs a rectangle containing a single point p. +func RectFromLatLng(p LatLng) Rect { + return Rect{ + Lat: r1.Interval{p.Lat.Radians(), p.Lat.Radians()}, + Lng: s1.Interval{p.Lng.Radians(), p.Lng.Radians()}, + } +} + +// RectFromCenterSize constructs a rectangle with the given size and center. +// center needs to be normalized, but size does not. The latitude +// interval of the result is clamped to [-90,90] degrees, and the longitude +// interval of the result is FullRect() if and only if the longitude size is +// 360 degrees or more. +// +// Examples of clamping (in degrees): +// center=(80,170), size=(40,60) -> lat=[60,90], lng=[140,-160] +// center=(10,40), size=(210,400) -> lat=[-90,90], lng=[-180,180] +// center=(-90,180), size=(20,50) -> lat=[-90,-80], lng=[155,-155] +func RectFromCenterSize(center, size LatLng) Rect { + half := LatLng{size.Lat / 2, size.Lng / 2} + return RectFromLatLng(center).expanded(half) +} + +// IsValid returns true iff the rectangle is valid. +// This requires Lat ⊆ [-π/2,π/2] and Lng ⊆ [-π,π], and Lat = ∅ iff Lng = ∅ +func (r Rect) IsValid() bool { + return math.Abs(r.Lat.Lo) <= math.Pi/2 && + math.Abs(r.Lat.Hi) <= math.Pi/2 && + r.Lng.IsValid() && + r.Lat.IsEmpty() == r.Lng.IsEmpty() +} + +// IsEmpty reports whether the rectangle is empty. +func (r Rect) IsEmpty() bool { return r.Lat.IsEmpty() } + +// IsFull reports whether the rectangle is full. +func (r Rect) IsFull() bool { return r.Lat.Equal(validRectLatRange) && r.Lng.IsFull() } + +// IsPoint reports whether the rectangle is a single point. +func (r Rect) IsPoint() bool { return r.Lat.Lo == r.Lat.Hi && r.Lng.Lo == r.Lng.Hi } + +// Vertex returns the i-th vertex of the rectangle (i = 0,1,2,3) in CCW order +// (lower left, lower right, upper right, upper left). +func (r Rect) Vertex(i int) LatLng { + var lat, lng float64 + + switch i { + case 0: + lat = r.Lat.Lo + lng = r.Lng.Lo + case 1: + lat = r.Lat.Lo + lng = r.Lng.Hi + case 2: + lat = r.Lat.Hi + lng = r.Lng.Hi + case 3: + lat = r.Lat.Hi + lng = r.Lng.Lo + } + return LatLng{s1.Angle(lat) * s1.Radian, s1.Angle(lng) * s1.Radian} +} + +// Lo returns one corner of the rectangle. +func (r Rect) Lo() LatLng { + return LatLng{s1.Angle(r.Lat.Lo) * s1.Radian, s1.Angle(r.Lng.Lo) * s1.Radian} +} + +// Hi returns the other corner of the rectangle. +func (r Rect) Hi() LatLng { + return LatLng{s1.Angle(r.Lat.Hi) * s1.Radian, s1.Angle(r.Lng.Hi) * s1.Radian} +} + +// Center returns the center of the rectangle. +func (r Rect) Center() LatLng { + return LatLng{s1.Angle(r.Lat.Center()) * s1.Radian, s1.Angle(r.Lng.Center()) * s1.Radian} +} + +// Size returns the size of the Rect. +func (r Rect) Size() LatLng { + return LatLng{s1.Angle(r.Lat.Length()) * s1.Radian, s1.Angle(r.Lng.Length()) * s1.Radian} +} + +// Area returns the surface area of the Rect. +func (r Rect) Area() float64 { + if r.IsEmpty() { + return 0 + } + capDiff := math.Abs(math.Sin(r.Lat.Hi) - math.Sin(r.Lat.Lo)) + return r.Lng.Length() * capDiff +} + +// AddPoint increases the size of the rectangle to include the given point. +func (r Rect) AddPoint(ll LatLng) Rect { + if !ll.IsValid() { + return r + } + return Rect{ + Lat: r.Lat.AddPoint(ll.Lat.Radians()), + Lng: r.Lng.AddPoint(ll.Lng.Radians()), + } +} + +// expanded returns a rectangle that has been expanded by margin.Lat on each side +// in the latitude direction, and by margin.Lng on each side in the longitude +// direction. If either margin is negative, then it shrinks the rectangle on +// the corresponding sides instead. The resulting rectangle may be empty. +// +// The latitude-longitude space has the topology of a cylinder. Longitudes +// "wrap around" at +/-180 degrees, while latitudes are clamped to range [-90, 90]. +// This means that any expansion (positive or negative) of the full longitude range +// remains full (since the "rectangle" is actually a continuous band around the +// cylinder), while expansion of the full latitude range remains full only if the +// margin is positive. +// +// If either the latitude or longitude interval becomes empty after +// expansion by a negative margin, the result is empty. +// +// Note that if an expanded rectangle contains a pole, it may not contain +// all possible lat/lng representations of that pole, e.g., both points [π/2,0] +// and [π/2,1] represent the same pole, but they might not be contained by the +// same Rect. +// +// If you are trying to grow a rectangle by a certain distance on the +// sphere (e.g. 5km), refer to the ExpandedByDistance() C++ method implementation +// instead. +func (r Rect) expanded(margin LatLng) Rect { + lat := r.Lat.Expanded(margin.Lat.Radians()) + lng := r.Lng.Expanded(margin.Lng.Radians()) + + if lat.IsEmpty() || lng.IsEmpty() { + return EmptyRect() + } + + return Rect{ + Lat: lat.Intersection(validRectLatRange), + Lng: lng, + } +} + +func (r Rect) String() string { return fmt.Sprintf("[Lo%v, Hi%v]", r.Lo(), r.Hi()) } + +// PolarClosure returns the rectangle unmodified if it does not include either pole. +// If it includes either pole, PolarClosure returns an expansion of the rectangle along +// the longitudinal range to include all possible representations of the contained poles. +func (r Rect) PolarClosure() Rect { + if r.Lat.Lo == -math.Pi/2 || r.Lat.Hi == math.Pi/2 { + return Rect{r.Lat, s1.FullInterval()} + } + return r +} + +// Union returns the smallest Rect containing the union of this rectangle and the given rectangle. +func (r Rect) Union(other Rect) Rect { + return Rect{ + Lat: r.Lat.Union(other.Lat), + Lng: r.Lng.Union(other.Lng), + } +} + +// Intersection returns the smallest rectangle containing the intersection of +// this rectangle and the given rectangle. Note that the region of intersection +// may consist of two disjoint rectangles, in which case a single rectangle +// spanning both of them is returned. +func (r Rect) Intersection(other Rect) Rect { + lat := r.Lat.Intersection(other.Lat) + lng := r.Lng.Intersection(other.Lng) + + if lat.IsEmpty() || lng.IsEmpty() { + return EmptyRect() + } + return Rect{lat, lng} +} + +// Intersects reports whether this rectangle and the other have any points in common. +func (r Rect) Intersects(other Rect) bool { + return r.Lat.Intersects(other.Lat) && r.Lng.Intersects(other.Lng) +} + +// CapBound returns a cap that contains Rect. +func (r Rect) CapBound() Cap { + // We consider two possible bounding caps, one whose axis passes + // through the center of the lat-long rectangle and one whose axis + // is the north or south pole. We return the smaller of the two caps. + + if r.IsEmpty() { + return EmptyCap() + } + + var poleZ, poleAngle float64 + if r.Lat.Hi+r.Lat.Lo < 0 { + // South pole axis yields smaller cap. + poleZ = -1 + poleAngle = math.Pi/2 + r.Lat.Hi + } else { + poleZ = 1 + poleAngle = math.Pi/2 - r.Lat.Lo + } + poleCap := CapFromCenterAngle(Point{r3.Vector{0, 0, poleZ}}, s1.Angle(poleAngle)*s1.Radian) + + // For bounding rectangles that span 180 degrees or less in longitude, the + // maximum cap size is achieved at one of the rectangle vertices. For + // rectangles that are larger than 180 degrees, we punt and always return a + // bounding cap centered at one of the two poles. + if math.Remainder(r.Lng.Hi-r.Lng.Lo, 2*math.Pi) >= 0 && r.Lng.Hi-r.Lng.Lo < 2*math.Pi { + midCap := CapFromPoint(PointFromLatLng(r.Center())).AddPoint(PointFromLatLng(r.Lo())).AddPoint(PointFromLatLng(r.Hi())) + if midCap.Height() < poleCap.Height() { + return midCap + } + } + return poleCap +} + +// RectBound returns itself. +func (r Rect) RectBound() Rect { + return r +} + +// Contains reports whether this Rect contains the other Rect. +func (r Rect) Contains(other Rect) bool { + return r.Lat.ContainsInterval(other.Lat) && r.Lng.ContainsInterval(other.Lng) +} + +// ContainsCell reports whether the given Cell is contained by this Rect. +func (r Rect) ContainsCell(c Cell) bool { + // A latitude-longitude rectangle contains a cell if and only if it contains + // the cell's bounding rectangle. This test is exact from a mathematical + // point of view, assuming that the bounds returned by Cell.RectBound() + // are tight. However, note that there can be a loss of precision when + // converting between representations -- for example, if an s2.Cell is + // converted to a polygon, the polygon's bounding rectangle may not contain + // the cell's bounding rectangle. This has some slightly unexpected side + // effects; for instance, if one creates an s2.Polygon from an s2.Cell, the + // polygon will contain the cell, but the polygon's bounding box will not. + return r.Contains(c.RectBound()) +} + +// ContainsLatLng reports whether the given LatLng is within the Rect. +func (r Rect) ContainsLatLng(ll LatLng) bool { + if !ll.IsValid() { + return false + } + return r.Lat.Contains(ll.Lat.Radians()) && r.Lng.Contains(ll.Lng.Radians()) +} + +// ContainsPoint reports whether the given Point is within the Rect. +func (r Rect) ContainsPoint(p Point) bool { + return r.ContainsLatLng(LatLngFromPoint(p)) +} + +// CellUnionBound computes a covering of the Rect. +func (r Rect) CellUnionBound() []CellID { + return r.CapBound().CellUnionBound() +} + +// intersectsLatEdge reports whether the edge AB intersects the given edge of constant +// latitude. Requires the points to have unit length. +func intersectsLatEdge(a, b Point, lat s1.Angle, lng s1.Interval) bool { + // Unfortunately, lines of constant latitude are curves on + // the sphere. They can intersect a straight edge in 0, 1, or 2 points. + + // First, compute the normal to the plane AB that points vaguely north. + z := Point{a.PointCross(b).Normalize()} + if z.Z < 0 { + z = Point{z.Mul(-1)} + } + + // Extend this to an orthonormal frame (x,y,z) where x is the direction + // where the great circle through AB achieves its maximium latitude. + y := Point{z.PointCross(PointFromCoords(0, 0, 1)).Normalize()} + x := y.Cross(z.Vector) + + // Compute the angle "theta" from the x-axis (in the x-y plane defined + // above) where the great circle intersects the given line of latitude. + sinLat := math.Sin(float64(lat)) + if math.Abs(sinLat) >= x.Z { + // The great circle does not reach the given latitude. + return false + } + + cosTheta := sinLat / x.Z + sinTheta := math.Sqrt(1 - cosTheta*cosTheta) + theta := math.Atan2(sinTheta, cosTheta) + + // The candidate intersection points are located +/- theta in the x-y + // plane. For an intersection to be valid, we need to check that the + // intersection point is contained in the interior of the edge AB and + // also that it is contained within the given longitude interval "lng". + + // Compute the range of theta values spanned by the edge AB. + abTheta := s1.IntervalFromPointPair( + math.Atan2(a.Dot(y.Vector), a.Dot(x)), + math.Atan2(b.Dot(y.Vector), b.Dot(x))) + + if abTheta.Contains(theta) { + // Check if the intersection point is also in the given lng interval. + isect := x.Mul(cosTheta).Add(y.Mul(sinTheta)) + if lng.Contains(math.Atan2(isect.Y, isect.X)) { + return true + } + } + + if abTheta.Contains(-theta) { + // Check if the other intersection point is also in the given lng interval. + isect := x.Mul(cosTheta).Sub(y.Mul(sinTheta)) + if lng.Contains(math.Atan2(isect.Y, isect.X)) { + return true + } + } + return false +} + +// intersectsLngEdge reports whether the edge AB intersects the given edge of constant +// longitude. Requires the points to have unit length. +func intersectsLngEdge(a, b Point, lat r1.Interval, lng s1.Angle) bool { + // The nice thing about edges of constant longitude is that + // they are straight lines on the sphere (geodesics). + return CrossingSign(a, b, PointFromLatLng(LatLng{s1.Angle(lat.Lo), lng}), + PointFromLatLng(LatLng{s1.Angle(lat.Hi), lng})) == Cross +} + +// IntersectsCell reports whether this rectangle intersects the given cell. This is an +// exact test and may be fairly expensive. +func (r Rect) IntersectsCell(c Cell) bool { + // First we eliminate the cases where one region completely contains the + // other. Once these are disposed of, then the regions will intersect + // if and only if their boundaries intersect. + if r.IsEmpty() { + return false + } + if r.ContainsPoint(Point{c.id.rawPoint()}) { + return true + } + if c.ContainsPoint(PointFromLatLng(r.Center())) { + return true + } + + // Quick rejection test (not required for correctness). + if !r.Intersects(c.RectBound()) { + return false + } + + // Precompute the cell vertices as points and latitude-longitudes. We also + // check whether the Cell contains any corner of the rectangle, or + // vice-versa, since the edge-crossing tests only check the edge interiors. + vertices := [4]Point{} + latlngs := [4]LatLng{} + + for i := range vertices { + vertices[i] = c.Vertex(i) + latlngs[i] = LatLngFromPoint(vertices[i]) + if r.ContainsLatLng(latlngs[i]) { + return true + } + if c.ContainsPoint(PointFromLatLng(r.Vertex(i))) { + return true + } + } + + // Now check whether the boundaries intersect. Unfortunately, a + // latitude-longitude rectangle does not have straight edges: two edges + // are curved, and at least one of them is concave. + for i := range vertices { + edgeLng := s1.IntervalFromEndpoints(latlngs[i].Lng.Radians(), latlngs[(i+1)&3].Lng.Radians()) + if !r.Lng.Intersects(edgeLng) { + continue + } + + a := vertices[i] + b := vertices[(i+1)&3] + if edgeLng.Contains(r.Lng.Lo) && intersectsLngEdge(a, b, r.Lat, s1.Angle(r.Lng.Lo)) { + return true + } + if edgeLng.Contains(r.Lng.Hi) && intersectsLngEdge(a, b, r.Lat, s1.Angle(r.Lng.Hi)) { + return true + } + if intersectsLatEdge(a, b, s1.Angle(r.Lat.Lo), r.Lng) { + return true + } + if intersectsLatEdge(a, b, s1.Angle(r.Lat.Hi), r.Lng) { + return true + } + } + return false +} + +// Encode encodes the Rect. +func (r Rect) Encode(w io.Writer) error { + e := &encoder{w: w} + r.encode(e) + return e.err +} + +func (r Rect) encode(e *encoder) { + e.writeInt8(encodingVersion) + e.writeFloat64(r.Lat.Lo) + e.writeFloat64(r.Lat.Hi) + e.writeFloat64(r.Lng.Lo) + e.writeFloat64(r.Lng.Hi) +} + +// Decode decodes a rectangle. +func (r *Rect) Decode(rd io.Reader) error { + d := &decoder{r: asByteReader(rd)} + r.decode(d) + return d.err +} + +func (r *Rect) decode(d *decoder) { + if version := d.readUint8(); int8(version) != encodingVersion && d.err == nil { + d.err = fmt.Errorf("can't decode version %d; my version: %d", version, encodingVersion) + return + } + r.Lat.Lo = d.readFloat64() + r.Lat.Hi = d.readFloat64() + r.Lng.Lo = d.readFloat64() + r.Lng.Hi = d.readFloat64() + return +} + +// DistanceToLatLng returns the minimum distance (measured along the surface of the sphere) +// from a given point to the rectangle (both its boundary and its interior). +// If r is empty, the result is meaningless. +// The latlng must be valid. +func (r Rect) DistanceToLatLng(ll LatLng) s1.Angle { + if r.Lng.Contains(float64(ll.Lng)) { + return maxAngle(0, ll.Lat-s1.Angle(r.Lat.Hi), s1.Angle(r.Lat.Lo)-ll.Lat) + } + + i := s1.IntervalFromEndpoints(r.Lng.Hi, r.Lng.ComplementCenter()) + rectLng := r.Lng.Lo + if i.Contains(float64(ll.Lng)) { + rectLng = r.Lng.Hi + } + + lo := LatLng{s1.Angle(r.Lat.Lo) * s1.Radian, s1.Angle(rectLng) * s1.Radian} + hi := LatLng{s1.Angle(r.Lat.Hi) * s1.Radian, s1.Angle(rectLng) * s1.Radian} + return DistanceFromSegment(PointFromLatLng(ll), PointFromLatLng(lo), PointFromLatLng(hi)) +} + +// DirectedHausdorffDistance returns the directed Hausdorff distance (measured along the +// surface of the sphere) to the given Rect. The directed Hausdorff +// distance from rectangle A to rectangle B is given by +// h(A, B) = max_{p in A} min_{q in B} d(p, q). +func (r Rect) DirectedHausdorffDistance(other Rect) s1.Angle { + if r.IsEmpty() { + return 0 * s1.Radian + } + if other.IsEmpty() { + return math.Pi * s1.Radian + } + + lng := r.Lng.DirectedHausdorffDistance(other.Lng) + return directedHausdorffDistance(lng, r.Lat, other.Lat) +} + +// HausdorffDistance returns the undirected Hausdorff distance (measured along the +// surface of the sphere) to the given Rect. +// The Hausdorff distance between rectangle A and rectangle B is given by +// H(A, B) = max{h(A, B), h(B, A)}. +func (r Rect) HausdorffDistance(other Rect) s1.Angle { + return maxAngle(r.DirectedHausdorffDistance(other), + other.DirectedHausdorffDistance(r)) +} + +// ApproxEqual reports whether the latitude and longitude intervals of the two rectangles +// are the same up to a small tolerance. +func (r Rect) ApproxEqual(other Rect) bool { + return r.Lat.ApproxEqual(other.Lat) && r.Lng.ApproxEqual(other.Lng) +} + +// directedHausdorffDistance returns the directed Hausdorff distance +// from one longitudinal edge spanning latitude range 'a' to the other +// longitudinal edge spanning latitude range 'b', with their longitudinal +// difference given by 'lngDiff'. +func directedHausdorffDistance(lngDiff s1.Angle, a, b r1.Interval) s1.Angle { + // By symmetry, we can assume a's longitude is 0 and b's longitude is + // lngDiff. Call b's two endpoints bLo and bHi. Let H be the hemisphere + // containing a and delimited by the longitude line of b. The Voronoi diagram + // of b on H has three edges (portions of great circles) all orthogonal to b + // and meeting at bLo cross bHi. + // E1: (bLo, bLo cross bHi) + // E2: (bHi, bLo cross bHi) + // E3: (-bMid, bLo cross bHi), where bMid is the midpoint of b + // + // They subdivide H into three Voronoi regions. Depending on how longitude 0 + // (which contains edge a) intersects these regions, we distinguish two cases: + // Case 1: it intersects three regions. This occurs when lngDiff <= π/2. + // Case 2: it intersects only two regions. This occurs when lngDiff > π/2. + // + // In the first case, the directed Hausdorff distance to edge b can only be + // realized by the following points on a: + // A1: two endpoints of a. + // A2: intersection of a with the equator, if b also intersects the equator. + // + // In the second case, the directed Hausdorff distance to edge b can only be + // realized by the following points on a: + // B1: two endpoints of a. + // B2: intersection of a with E3 + // B3: farthest point from bLo to the interior of D, and farthest point from + // bHi to the interior of U, if any, where D (resp. U) is the portion + // of edge a below (resp. above) the intersection point from B2. + + if lngDiff < 0 { + panic("impossible: negative lngDiff") + } + if lngDiff > math.Pi { + panic("impossible: lngDiff > Pi") + } + + if lngDiff == 0 { + return s1.Angle(a.DirectedHausdorffDistance(b)) + } + + // Assumed longitude of b. + bLng := lngDiff + // Two endpoints of b. + bLo := PointFromLatLng(LatLng{s1.Angle(b.Lo), bLng}) + bHi := PointFromLatLng(LatLng{s1.Angle(b.Hi), bLng}) + + // Cases A1 and B1. + aLo := PointFromLatLng(LatLng{s1.Angle(a.Lo), 0}) + aHi := PointFromLatLng(LatLng{s1.Angle(a.Hi), 0}) + maxDistance := maxAngle( + DistanceFromSegment(aLo, bLo, bHi), + DistanceFromSegment(aHi, bLo, bHi)) + + if lngDiff <= math.Pi/2 { + // Case A2. + if a.Contains(0) && b.Contains(0) { + maxDistance = maxAngle(maxDistance, lngDiff) + } + return maxDistance + } + + // Case B2. + p := bisectorIntersection(b, bLng) + pLat := LatLngFromPoint(p).Lat + if a.Contains(float64(pLat)) { + maxDistance = maxAngle(maxDistance, p.Angle(bLo.Vector)) + } + + // Case B3. + if pLat > s1.Angle(a.Lo) { + intDist, ok := interiorMaxDistance(r1.Interval{a.Lo, math.Min(float64(pLat), a.Hi)}, bLo) + if ok { + maxDistance = maxAngle(maxDistance, intDist) + } + } + if pLat < s1.Angle(a.Hi) { + intDist, ok := interiorMaxDistance(r1.Interval{math.Max(float64(pLat), a.Lo), a.Hi}, bHi) + if ok { + maxDistance = maxAngle(maxDistance, intDist) + } + } + + return maxDistance +} + +// interiorMaxDistance returns the max distance from a point b to the segment spanning latitude range +// aLat on longitude 0 if the max occurs in the interior of aLat. Otherwise, returns (0, false). +func interiorMaxDistance(aLat r1.Interval, b Point) (a s1.Angle, ok bool) { + // Longitude 0 is in the y=0 plane. b.X >= 0 implies that the maximum + // does not occur in the interior of aLat. + if aLat.IsEmpty() || b.X >= 0 { + return 0, false + } + + // Project b to the y=0 plane. The antipodal of the normalized projection is + // the point at which the maxium distance from b occurs, if it is contained + // in aLat. + intersectionPoint := PointFromCoords(-b.X, 0, -b.Z) + if !aLat.InteriorContains(float64(LatLngFromPoint(intersectionPoint).Lat)) { + return 0, false + } + return b.Angle(intersectionPoint.Vector), true +} + +// bisectorIntersection return the intersection of longitude 0 with the bisector of an edge +// on longitude 'lng' and spanning latitude range 'lat'. +func bisectorIntersection(lat r1.Interval, lng s1.Angle) Point { + lng = s1.Angle(math.Abs(float64(lng))) + latCenter := s1.Angle(lat.Center()) + + // A vector orthogonal to the bisector of the given longitudinal edge. + orthoBisector := LatLng{latCenter - math.Pi/2, lng} + if latCenter < 0 { + orthoBisector = LatLng{-latCenter - math.Pi/2, lng - math.Pi} + } + + // A vector orthogonal to longitude 0. + orthoLng := Point{r3.Vector{0, -1, 0}} + + return orthoLng.PointCross(PointFromLatLng(orthoBisector)) +} + +// Centroid returns the true centroid of the given Rect multiplied by its +// surface area. The result is not unit length, so you may want to normalize it. +// Note that in general the centroid is *not* at the center of the rectangle, and +// in fact it may not even be contained by the rectangle. (It is the "center of +// mass" of the rectangle viewed as subset of the unit sphere, i.e. it is the +// point in space about which this curved shape would rotate.) +// +// The reason for multiplying the result by the rectangle area is to make it +// easier to compute the centroid of more complicated shapes. The centroid +// of a union of disjoint regions can be computed simply by adding their +// Centroid results. +func (r Rect) Centroid() Point { + // When a sphere is divided into slices of constant thickness by a set + // of parallel planes, all slices have the same surface area. This + // implies that the z-component of the centroid is simply the midpoint + // of the z-interval spanned by the Rect. + // + // Similarly, it is easy to see that the (x,y) of the centroid lies in + // the plane through the midpoint of the rectangle's longitude interval. + // We only need to determine the distance "d" of this point from the + // z-axis. + // + // Let's restrict our attention to a particular z-value. In this + // z-plane, the Rect is a circular arc. The centroid of this arc + // lies on a radial line through the midpoint of the arc, and at a + // distance from the z-axis of + // + // r * (sin(alpha) / alpha) + // + // where r = sqrt(1-z^2) is the radius of the arc, and "alpha" is half + // of the arc length (i.e., the arc covers longitudes [-alpha, alpha]). + // + // To find the centroid distance from the z-axis for the entire + // rectangle, we just need to integrate over the z-interval. This gives + // + // d = Integrate[sqrt(1-z^2)*sin(alpha)/alpha, z1..z2] / (z2 - z1) + // + // where [z1, z2] is the range of z-values covered by the rectangle. + // This simplifies to + // + // d = sin(alpha)/(2*alpha*(z2-z1))*(z2*r2 - z1*r1 + theta2 - theta1) + // + // where [theta1, theta2] is the latitude interval, z1=sin(theta1), + // z2=sin(theta2), r1=cos(theta1), and r2=cos(theta2). + // + // Finally, we want to return not the centroid itself, but the centroid + // scaled by the area of the rectangle. The area of the rectangle is + // + // A = 2 * alpha * (z2 - z1) + // + // which fortunately appears in the denominator of "d". + + if r.IsEmpty() { + return Point{} + } + + z1 := math.Sin(r.Lat.Lo) + z2 := math.Sin(r.Lat.Hi) + r1 := math.Cos(r.Lat.Lo) + r2 := math.Cos(r.Lat.Hi) + + alpha := 0.5 * r.Lng.Length() + r0 := math.Sin(alpha) * (r2*z2 - r1*z1 + r.Lat.Length()) + lng := r.Lng.Center() + z := alpha * (z2 + z1) * (z2 - z1) // scaled by the area + + return Point{r3.Vector{r0 * math.Cos(lng), r0 * math.Sin(lng), z}} +} + +// BUG: The major differences from the C++ version are: +// - Get*Distance, Vertex, InteriorContains(LatLng|Rect|Point) + +func RectFromDegrees(latLo, lngLo, latHi, lngHi float64) Rect { + // Convenience method to construct a rectangle. This method is + // intentionally *not* in the S2LatLngRect interface because the + // argument order is ambiguous, but is fine for the test. + return Rect{ + Lat: r1.Interval{ + Lo: (s1.Angle(latLo) * s1.Degree).Radians(), + Hi: (s1.Angle(latHi) * s1.Degree).Radians(), + }, + Lng: s1.IntervalFromEndpoints( + (s1.Angle(lngLo) * s1.Degree).Radians(), + (s1.Angle(lngHi) * s1.Degree).Radians(), + ), + } +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/rect_bounder.go b/backend/vendor/github.com/blevesearch/geo/s2/rect_bounder.go new file mode 100644 index 0000000000..419dea0c15 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/rect_bounder.go @@ -0,0 +1,352 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "math" + + "github.com/golang/geo/r1" + "github.com/golang/geo/r3" + "github.com/golang/geo/s1" +) + +// RectBounder is used to compute a bounding rectangle that contains all edges +// defined by a vertex chain (v0, v1, v2, ...). All vertices must be unit length. +// Note that the bounding rectangle of an edge can be larger than the bounding +// rectangle of its endpoints, e.g. consider an edge that passes through the North Pole. +// +// The bounds are calculated conservatively to account for numerical errors +// when points are converted to LatLngs. More precisely, this function +// guarantees the following: +// Let L be a closed edge chain (Loop) such that the interior of the loop does +// not contain either pole. Now if P is any point such that L.ContainsPoint(P), +// then RectBound(L).ContainsPoint(LatLngFromPoint(P)). +type RectBounder struct { + // The previous vertex in the chain. + a Point + // The previous vertex latitude longitude. + aLL LatLng + bound Rect +} + +// NewRectBounder returns a new instance of a RectBounder. +func NewRectBounder() *RectBounder { + return &RectBounder{ + bound: EmptyRect(), + } +} + +// maxErrorForTests returns the maximum error in RectBound provided that the +// result does not include either pole. It is only used for testing purposes +func (r *RectBounder) maxErrorForTests() LatLng { + // The maximum error in the latitude calculation is + // 3.84 * dblEpsilon for the PointCross calculation + // 0.96 * dblEpsilon for the Latitude calculation + // 5 * dblEpsilon added by AddPoint/RectBound to compensate for error + // ----------------- + // 9.80 * dblEpsilon maximum error in result + // + // The maximum error in the longitude calculation is dblEpsilon. RectBound + // does not do any expansion because this isn't necessary in order to + // bound the *rounded* longitudes of contained points. + return LatLng{10 * dblEpsilon * s1.Radian, 1 * dblEpsilon * s1.Radian} +} + +// AddPoint adds the given point to the chain. The Point must be unit length. +func (r *RectBounder) AddPoint(b Point) { + bLL := LatLngFromPoint(b) + + if r.bound.IsEmpty() { + r.a = b + r.aLL = bLL + r.bound = r.bound.AddPoint(bLL) + return + } + + // First compute the cross product N = A x B robustly. This is the normal + // to the great circle through A and B. We don't use RobustSign + // since that method returns an arbitrary vector orthogonal to A if the two + // vectors are proportional, and we want the zero vector in that case. + n := r.a.Sub(b.Vector).Cross(r.a.Add(b.Vector)) // N = 2 * (A x B) + + // The relative error in N gets large as its norm gets very small (i.e., + // when the two points are nearly identical or antipodal). We handle this + // by choosing a maximum allowable error, and if the error is greater than + // this we fall back to a different technique. Since it turns out that + // the other sources of error in converting the normal to a maximum + // latitude add up to at most 1.16 * dblEpsilon, and it is desirable to + // have the total error be a multiple of dblEpsilon, we have chosen to + // limit the maximum error in the normal to be 3.84 * dblEpsilon. + // It is possible to show that the error is less than this when + // + // n.Norm() >= 8 * sqrt(3) / (3.84 - 0.5 - sqrt(3)) * dblEpsilon + // = 1.91346e-15 (about 8.618 * dblEpsilon) + nNorm := n.Norm() + if nNorm < 1.91346e-15 { + // A and B are either nearly identical or nearly antipodal (to within + // 4.309 * dblEpsilon, or about 6 nanometers on the earth's surface). + if r.a.Dot(b.Vector) < 0 { + // The two points are nearly antipodal. The easiest solution is to + // assume that the edge between A and B could go in any direction + // around the sphere. + r.bound = FullRect() + } else { + // The two points are nearly identical (to within 4.309 * dblEpsilon). + // In this case we can just use the bounding rectangle of the points, + // since after the expansion done by GetBound this Rect is + // guaranteed to include the (lat,lng) values of all points along AB. + r.bound = r.bound.Union(RectFromLatLng(r.aLL).AddPoint(bLL)) + } + r.a = b + r.aLL = bLL + return + } + + // Compute the longitude range spanned by AB. + lngAB := s1.EmptyInterval().AddPoint(r.aLL.Lng.Radians()).AddPoint(bLL.Lng.Radians()) + if lngAB.Length() >= math.Pi-2*dblEpsilon { + // The points lie on nearly opposite lines of longitude to within the + // maximum error of the calculation. The easiest solution is to assume + // that AB could go on either side of the pole. + lngAB = s1.FullInterval() + } + + // Next we compute the latitude range spanned by the edge AB. We start + // with the range spanning the two endpoints of the edge: + latAB := r1.IntervalFromPoint(r.aLL.Lat.Radians()).AddPoint(bLL.Lat.Radians()) + + // This is the desired range unless the edge AB crosses the plane + // through N and the Z-axis (which is where the great circle through A + // and B attains its minimum and maximum latitudes). To test whether AB + // crosses this plane, we compute a vector M perpendicular to this + // plane and then project A and B onto it. + m := n.Cross(r3.Vector{0, 0, 1}) + mA := m.Dot(r.a.Vector) + mB := m.Dot(b.Vector) + + // We want to test the signs of "mA" and "mB", so we need to bound + // the error in these calculations. It is possible to show that the + // total error is bounded by + // + // (1 + sqrt(3)) * dblEpsilon * nNorm + 8 * sqrt(3) * (dblEpsilon**2) + // = 6.06638e-16 * nNorm + 6.83174e-31 + + mError := 6.06638e-16*nNorm + 6.83174e-31 + if mA*mB < 0 || math.Abs(mA) <= mError || math.Abs(mB) <= mError { + // Minimum/maximum latitude *may* occur in the edge interior. + // + // The maximum latitude is 90 degrees minus the latitude of N. We + // compute this directly using atan2 in order to get maximum accuracy + // near the poles. + // + // Our goal is compute a bound that contains the computed latitudes of + // all S2Points P that pass the point-in-polygon containment test. + // There are three sources of error we need to consider: + // - the directional error in N (at most 3.84 * dblEpsilon) + // - converting N to a maximum latitude + // - computing the latitude of the test point P + // The latter two sources of error are at most 0.955 * dblEpsilon + // individually, but it is possible to show by a more complex analysis + // that together they can add up to at most 1.16 * dblEpsilon, for a + // total error of 5 * dblEpsilon. + // + // We add 3 * dblEpsilon to the bound here, and GetBound() will pad + // the bound by another 2 * dblEpsilon. + maxLat := math.Min( + math.Atan2(math.Sqrt(n.X*n.X+n.Y*n.Y), math.Abs(n.Z))+3*dblEpsilon, + math.Pi/2) + + // In order to get tight bounds when the two points are close together, + // we also bound the min/max latitude relative to the latitudes of the + // endpoints A and B. First we compute the distance between A and B, + // and then we compute the maximum change in latitude between any two + // points along the great circle that are separated by this distance. + // This gives us a latitude change "budget". Some of this budget must + // be spent getting from A to B; the remainder bounds the round-trip + // distance (in latitude) from A or B to the min or max latitude + // attained along the edge AB. + latBudget := 2 * math.Asin(0.5*(r.a.Sub(b.Vector)).Norm()*math.Sin(maxLat)) + maxDelta := 0.5*(latBudget-latAB.Length()) + dblEpsilon + + // Test whether AB passes through the point of maximum latitude or + // minimum latitude. If the dot product(s) are small enough then the + // result may be ambiguous. + if mA <= mError && mB >= -mError { + latAB.Hi = math.Min(maxLat, latAB.Hi+maxDelta) + } + if mB <= mError && mA >= -mError { + latAB.Lo = math.Max(-maxLat, latAB.Lo-maxDelta) + } + } + r.a = b + r.aLL = bLL + r.bound = r.bound.Union(Rect{latAB, lngAB}) +} + +// RectBound returns the bounding rectangle of the edge chain that connects the +// vertices defined so far. This bound satisfies the guarantee made +// above, i.e. if the edge chain defines a Loop, then the bound contains +// the LatLng coordinates of all Points contained by the loop. +func (r *RectBounder) RectBound() Rect { + return r.bound.expanded(LatLng{s1.Angle(2 * dblEpsilon), 0}).PolarClosure() +} + +// ExpandForSubregions expands a bounding Rect so that it is guaranteed to +// contain the bounds of any subregion whose bounds are computed using +// ComputeRectBound. For example, consider a loop L that defines a square. +// GetBound ensures that if a point P is contained by this square, then +// LatLngFromPoint(P) is contained by the bound. But now consider a diamond +// shaped loop S contained by L. It is possible that GetBound returns a +// *larger* bound for S than it does for L, due to rounding errors. This +// method expands the bound for L so that it is guaranteed to contain the +// bounds of any subregion S. +// +// More precisely, if L is a loop that does not contain either pole, and S +// is a loop such that L.Contains(S), then +// +// ExpandForSubregions(L.RectBound).Contains(S.RectBound). +// +func ExpandForSubregions(bound Rect) Rect { + // Empty bounds don't need expansion. + if bound.IsEmpty() { + return bound + } + + // First we need to check whether the bound B contains any nearly-antipodal + // points (to within 4.309 * dblEpsilon). If so then we need to return + // FullRect, since the subregion might have an edge between two + // such points, and AddPoint returns Full for such edges. Note that + // this can happen even if B is not Full for example, consider a loop + // that defines a 10km strip straddling the equator extending from + // longitudes -100 to +100 degrees. + // + // It is easy to check whether B contains any antipodal points, but checking + // for nearly-antipodal points is trickier. Essentially we consider the + // original bound B and its reflection through the origin B', and then test + // whether the minimum distance between B and B' is less than 4.309 * dblEpsilon. + + // lngGap is a lower bound on the longitudinal distance between B and its + // reflection B'. (2.5 * dblEpsilon is the maximum combined error of the + // endpoint longitude calculations and the Length call.) + lngGap := math.Max(0, math.Pi-bound.Lng.Length()-2.5*dblEpsilon) + + // minAbsLat is the minimum distance from B to the equator (if zero or + // negative, then B straddles the equator). + minAbsLat := math.Max(bound.Lat.Lo, -bound.Lat.Hi) + + // latGapSouth and latGapNorth measure the minimum distance from B to the + // south and north poles respectively. + latGapSouth := math.Pi/2 + bound.Lat.Lo + latGapNorth := math.Pi/2 - bound.Lat.Hi + + if minAbsLat >= 0 { + // The bound B does not straddle the equator. In this case the minimum + // distance is between one endpoint of the latitude edge in B closest to + // the equator and the other endpoint of that edge in B'. The latitude + // distance between these two points is 2*minAbsLat, and the longitude + // distance is lngGap. We could compute the distance exactly using the + // Haversine formula, but then we would need to bound the errors in that + // calculation. Since we only need accuracy when the distance is very + // small (close to 4.309 * dblEpsilon), we substitute the Euclidean + // distance instead. This gives us a right triangle XYZ with two edges of + // length x = 2*minAbsLat and y ~= lngGap. The desired distance is the + // length of the third edge z, and we have + // + // z ~= sqrt(x^2 + y^2) >= (x + y) / sqrt(2) + // + // Therefore the region may contain nearly antipodal points only if + // + // 2*minAbsLat + lngGap < sqrt(2) * 4.309 * dblEpsilon + // ~= 1.354e-15 + // + // Note that because the given bound B is conservative, minAbsLat and + // lngGap are both lower bounds on their true values so we do not need + // to make any adjustments for their errors. + if 2*minAbsLat+lngGap < 1.354e-15 { + return FullRect() + } + } else if lngGap >= math.Pi/2 { + // B spans at most Pi/2 in longitude. The minimum distance is always + // between one corner of B and the diagonally opposite corner of B'. We + // use the same distance approximation that we used above; in this case + // we have an obtuse triangle XYZ with two edges of length x = latGapSouth + // and y = latGapNorth, and angle Z >= Pi/2 between them. We then have + // + // z >= sqrt(x^2 + y^2) >= (x + y) / sqrt(2) + // + // Unlike the case above, latGapSouth and latGapNorth are not lower bounds + // (because of the extra addition operation, and because math.Pi/2 is not + // exactly equal to Pi/2); they can exceed their true values by up to + // 0.75 * dblEpsilon. Putting this all together, the region may contain + // nearly antipodal points only if + // + // latGapSouth + latGapNorth < (sqrt(2) * 4.309 + 1.5) * dblEpsilon + // ~= 1.687e-15 + if latGapSouth+latGapNorth < 1.687e-15 { + return FullRect() + } + } else { + // Otherwise we know that (1) the bound straddles the equator and (2) its + // width in longitude is at least Pi/2. In this case the minimum + // distance can occur either between a corner of B and the diagonally + // opposite corner of B' (as in the case above), or between a corner of B + // and the opposite longitudinal edge reflected in B'. It is sufficient + // to only consider the corner-edge case, since this distance is also a + // lower bound on the corner-corner distance when that case applies. + + // Consider the spherical triangle XYZ where X is a corner of B with + // minimum absolute latitude, Y is the closest pole to X, and Z is the + // point closest to X on the opposite longitudinal edge of B'. This is a + // right triangle (Z = Pi/2), and from the spherical law of sines we have + // + // sin(z) / sin(Z) = sin(y) / sin(Y) + // sin(maxLatGap) / 1 = sin(dMin) / sin(lngGap) + // sin(dMin) = sin(maxLatGap) * sin(lngGap) + // + // where "maxLatGap" = max(latGapSouth, latGapNorth) and "dMin" is the + // desired minimum distance. Now using the facts that sin(t) >= (2/Pi)*t + // for 0 <= t <= Pi/2, that we only need an accurate approximation when + // at least one of "maxLatGap" or lngGap is extremely small (in which + // case sin(t) ~= t), and recalling that "maxLatGap" has an error of up + // to 0.75 * dblEpsilon, we want to test whether + // + // maxLatGap * lngGap < (4.309 + 0.75) * (Pi/2) * dblEpsilon + // ~= 1.765e-15 + if math.Max(latGapSouth, latGapNorth)*lngGap < 1.765e-15 { + return FullRect() + } + } + // Next we need to check whether the subregion might contain any edges that + // span (math.Pi - 2 * dblEpsilon) radians or more in longitude, since AddPoint + // sets the longitude bound to Full in that case. This corresponds to + // testing whether (lngGap <= 0) in lngExpansion below. + + // Otherwise, the maximum latitude error in AddPoint is 4.8 * dblEpsilon. + // In the worst case, the errors when computing the latitude bound for a + // subregion could go in the opposite direction as the errors when computing + // the bound for the original region, so we need to double this value. + // (More analysis shows that it's okay to round down to a multiple of + // dblEpsilon.) + // + // For longitude, we rely on the fact that atan2 is correctly rounded and + // therefore no additional bounds expansion is necessary. + + latExpansion := 9 * dblEpsilon + lngExpansion := 0.0 + if lngGap <= 0 { + lngExpansion = math.Pi + } + return bound.expanded(LatLng{s1.Angle(latExpansion), s1.Angle(lngExpansion)}).PolarClosure() +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/region.go b/backend/vendor/github.com/blevesearch/geo/s2/region.go new file mode 100644 index 0000000000..9ea3de1ca8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/region.go @@ -0,0 +1,71 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +// A Region represents a two-dimensional region on the unit sphere. +// +// The purpose of this interface is to allow complex regions to be +// approximated as simpler regions. The interface is restricted to methods +// that are useful for computing approximations. +type Region interface { + // CapBound returns a bounding spherical cap. This is not guaranteed to be exact. + CapBound() Cap + + // RectBound returns a bounding latitude-longitude rectangle that contains + // the region. The bounds are not guaranteed to be tight. + RectBound() Rect + + // ContainsCell reports whether the region completely contains the given region. + // It returns false if containment could not be determined. + ContainsCell(c Cell) bool + + // IntersectsCell reports whether the region intersects the given cell or + // if intersection could not be determined. It returns false if the region + // does not intersect. + IntersectsCell(c Cell) bool + + // ContainsPoint reports whether the region contains the given point or not. + // The point should be unit length, although some implementations may relax + // this restriction. + ContainsPoint(p Point) bool + + // CellUnionBound returns a small collection of CellIDs whose union covers + // the region. The cells are not sorted, may have redundancies (such as cells + // that contain other cells), and may cover much more area than necessary. + // + // This method is not intended for direct use by client code. Clients + // should typically use Covering, which has options to control the size and + // accuracy of the covering. Alternatively, if you want a fast covering and + // don't care about accuracy, consider calling FastCovering (which returns a + // cleaned-up version of the covering computed by this method). + // + // CellUnionBound implementations should attempt to return a small + // covering (ideally 4 cells or fewer) that covers the region and can be + // computed quickly. The result is used by RegionCoverer as a starting + // point for further refinement. + CellUnionBound() []CellID +} + +// Enforce Region interface satisfaction. +var ( + _ Region = Cap{} + _ Region = Cell{} + _ Region = (*CellUnion)(nil) + _ Region = (*Loop)(nil) + _ Region = Point{} + _ Region = (*Polygon)(nil) + _ Region = (*Polyline)(nil) + _ Region = Rect{} +) diff --git a/backend/vendor/github.com/blevesearch/geo/s2/region_term_indexer.go b/backend/vendor/github.com/blevesearch/geo/s2/region_term_indexer.go new file mode 100644 index 0000000000..aa0b6aaef2 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/region_term_indexer.go @@ -0,0 +1,441 @@ +// Copyright 2021 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +// Indexing Strategy +// ----------------- +// +// Given a query region, we want to find all of the document regions that +// intersect it. The first step is to represent all the regions as S2Cell +// coverings (see S2RegionCoverer). We then split the problem into two parts, +// namely finding the document regions that are "smaller" than the query +// region and those that are "larger" than the query region. +// +// We do this by defining two terms for each S2CellId: a "covering term" and +// an "ancestor term". (In the implementation below, covering terms are +// distinguished by prefixing a '$' to them.) For each document region, we +// insert a covering term for every cell in the region's covering, and we +// insert an ancestor term for these cells *and* all of their ancestors. +// +// Then given a query region, we can look up all the document regions that +// intersect its covering by querying the union of the following terms: +// +// 1. An "ancestor term" for each cell in the query region. These terms +// ensure that we find all document regions that are "smaller" than the +// query region, i.e. where the query region contains a cell that is either +// a cell of a document region or one of its ancestors. +// +// 2. A "covering term" for every ancestor of the cells in the query region. +// These terms ensure that we find all the document regions that are +// "larger" than the query region, i.e. where document region contains a +// cell that is a (proper) ancestor of a cell in the query region. +// +// Together, these terms find all of the document regions that intersect the +// query region. Furthermore, the number of terms to be indexed and queried +// are both fairly small, and can be bounded in terms of max_cells() and the +// number of cell levels used. +// +// Optimizations +// ------------- +// +// + Cells at the maximum level being indexed (max_level()) have the special +// property that they will never be an ancestor of a cell in the query +// region. Therefore we can safely skip generating "covering terms" for +// these cells (see query step 2 above). +// +// + If the index will contain only points (rather than general regions), then +// we can skip all the covering terms mentioned above because there will +// never be any document regions larger than the query region. This can +// significantly reduce the size of queries. +// +// + If it is more important to optimize index size rather than query speed, +// the number of index terms can be reduced by creating ancestor terms only +// for the *proper* ancestors of the cells in a document region, and +// compensating for this by including covering terms for all cells in the +// query region (in addition to their ancestors). +// +// Effectively, when the query region and a document region contain exactly +// the same cell, we have a choice about whether to treat this match as a +// "covering term" or an "ancestor term". One choice minimizes query size +// while the other minimizes index size. + +package s2 + +import ( + "strings" + + "github.com/golang/geo/s1" +) + +type TermType int + +var marker = string('$') + +const ( + ANCESTOR TermType = iota + 1 + COVERING +) + +var defaultMaxCells = int(8) + +type Options struct { + ///////////////// Options Inherited From S2RegionCoverer //////////////// + + // maxCells controls the maximum number of cells when approximating + // each region. This parameter value may be changed as often as desired. + // e.g. to approximate some regions more accurately than others. + // + // Increasing this value during indexing will make indexes more accurate + // but larger. Increasing this value for queries will make queries more + // accurate but slower. (See regioncoverer.go for details on how this + // parameter affects accuracy.) For example, if you don't mind large + // indexes but want fast serving, it might be reasonable to set + // max_cells() == 100 during indexing and max_cells() == 8 for queries. + // + // DEFAULT: 8 (coarse approximations) + maxCells int + + // minLevel and maxLevel control the minimum and maximum size of the + // S2Cells used to approximate regions. Setting these parameters + // appropriately can reduce the size of the index and speed up queries by + // reducing the number of terms needed. For example, if you know that + // your query regions will rarely be less than 100 meters in width, then + // you could set maxLevel to 100. + // + // This restricts the index to S2Cells that are approximately 100 meters + // across or larger. Similar, if you know that query regions will rarely + // be larger than 1000km across, then you could set minLevel similarly. + // + // If minLevel is set too high, then large regions may generate too + // many query terms. If maxLevel() set too low, then small query + // regions will not be able to discriminate which regions they intersect + // very precisely and may return many more candidates than necessary. + // + // If you have no idea about the scale of the regions being queried, + // it is perfectly fine to set minLevel to 0 and maxLevel to 30. + // The only drawback is that may result in a larger index and slower queries. + // + // The default parameter values are suitable for query regions ranging + // from about 100 meters to 3000 km across. + // + // DEFAULT: 4 (average cell width == 600km) + minLevel int + + // DEFAULT: 16 (average cell width == 150m) + maxLevel int + + // Setting levelMod to a value greater than 1 increases the effective + // branching factor of the S2Cell hierarchy by skipping some levels. For + // example, if levelMod to 2 then every second level is skipped (which + // increases the effective branching factor to 16). You might want to + // consider doing this if your query regions are typically very small + // (e.g., single points) and you don't mind increasing the index size + // (since skipping levels will reduce the accuracy of cell coverings for a + // given maxCells limit). + // + // DEFAULT: 1 (don't skip any cell levels) + levelMod int + + // If your index will only contain points (rather than regions), be sure + // to set this flag. This will generate smaller and faster queries that + // are specialized for the points-only case. + // + // With the default quality settings, this flag reduces the number of + // query terms by about a factor of two. (The improvement gets smaller + // as maxCells is increased, but there is really no reason not to use + // this flag if your index consists entirely of points.) + // + // DEFAULT: false + pointsOnly bool + + // If true, the index will be optimized for space rather than for query + // time. With the default quality settings, this flag reduces the number + // of index terms and increases the number of query terms by the same + // factor (approximately 1.3). The factor increases up to a limiting + // ratio of 2.0 as maxCells is increased. + // + // CAVEAT: This option has no effect if the index contains only points. + // + // DEFAULT: false + optimizeSpace bool +} + +func (o *Options) MaxCells() int { + return o.maxCells +} + +func (o *Options) SetMaxCells(mc int) { + o.maxCells = mc +} + +func (o *Options) MinLevel() int { + return o.minLevel +} + +func (o *Options) SetMinLevel(ml int) { + o.minLevel = ml +} + +func (o *Options) MaxLevel() int { + return o.maxLevel +} + +func (o *Options) SetMaxLevel(ml int) { + o.maxLevel = ml +} + +func (o *Options) LevelMod() int { + return o.levelMod +} + +func (o *Options) SetLevelMod(lm int) { + o.levelMod = lm +} + +func (o *Options) SetPointsOnly(v bool) { + o.pointsOnly = v +} + +func (o *Options) SetOptimizeSpace(v bool) { + o.optimizeSpace = v +} + +func (o *Options) trueMaxLevel() int { + trueMax := o.maxLevel + if o.levelMod != 1 { + trueMax = o.maxLevel - (o.maxLevel-o.minLevel)%o.levelMod + } + return trueMax +} + +// RegionTermIndexer is a helper struct for adding spatial data to an +// information retrieval system. Such systems work by converting documents +// into a collection of "index terms" (e.g., representing words or phrases), +// and then building an "inverted index" that maps each term to a list of +// documents (and document positions) where that term occurs. +// +// This class deals with the problem of converting spatial data into index +// terms, which can then be indexed along with the other document information. +// +// Spatial data is represented using the S2Region type. Useful S2Region +// subtypes include: +// +// S2Cap +// - a disc-shaped region +// +// S2LatLngRect +// - a rectangle in latitude-longitude coordinates +// +// S2Polyline +// - a polyline +// +// S2Polygon +// - a polygon, possibly with multiple holes and/or shells +// +// S2CellUnion +// - a region approximated as a collection of S2CellIds +// +// S2ShapeIndexRegion +// - an arbitrary collection of points, polylines, and polygons +// +// S2ShapeIndexBufferedRegion +// - like the above, but expanded by a given radius +// +// S2RegionUnion, S2RegionIntersection +// - the union or intersection of arbitrary other regions +// +// So for example, if you want to query documents that are within 500 meters +// of a polyline, you could use an S2ShapeIndexBufferedRegion containing the +// polyline with a radius of 500 meters. +// +// For example usage refer: +// https://github.com/google/s2geometry/blob/ad1489e898f369ca09e2099353ccd55bd0fd7a26/src/s2/s2region_term_indexer.h#L58 + +type RegionTermIndexer struct { + options Options + regionCoverer RegionCoverer +} + +func NewRegionTermIndexer() *RegionTermIndexer { + rv := &RegionTermIndexer{ + options: Options{ + maxCells: 8, + minLevel: 4, + maxLevel: 16, + levelMod: 1, + }, + } + return rv +} + +func NewRegionTermIndexerWithOptions(option Options) *RegionTermIndexer { + return &RegionTermIndexer{options: option} +} + +func (rti *RegionTermIndexer) GetTerm(termTyp TermType, id CellID, + prefix string) string { + if termTyp == ANCESTOR { + return prefix + id.ToToken() + } + return prefix + marker + id.ToToken() +} + +func (rti *RegionTermIndexer) GetIndexTermsForPoint(p Point, prefix string) []string { + // See the top of this file for an overview of the indexing strategy. + // + // The last cell generated by this loop is effectively the covering for + // the given point. You might expect that this cell would be indexed as a + // covering term, but as an optimization we always index these cells as + // ancestor terms only. This is possible because query regions will never + // contain a descendant of such cells. Note that this is true even when + // max_level() != true_max_level() (see S2RegionCoverer::Options). + cellID := cellIDFromPoint(p) + var rv []string + for l := rti.options.minLevel; l <= rti.options.maxLevel; l += rti.options.levelMod { + rv = append(rv, rti.GetTerm(ANCESTOR, cellID.Parent(l), prefix)) + } + return rv +} + +func (rti *RegionTermIndexer) GetIndexTermsForRegion(region Region, + prefix string) []string { + rti.regionCoverer.LevelMod = rti.options.levelMod + rti.regionCoverer.MaxLevel = rti.options.maxLevel + rti.regionCoverer.MinLevel = rti.options.minLevel + rti.regionCoverer.MaxCells = rti.options.maxCells + + covering := rti.regionCoverer.Covering(region) + return rti.GetIndexTermsForCanonicalCovering(covering, prefix) +} + +func (rti *RegionTermIndexer) GetIndexTermsForCanonicalCovering( + covering CellUnion, prefix string) []string { + // See the top of this file for an overview of the indexing strategy. + // + // Cells in the covering are normally indexed as covering terms. If we are + // optimizing for query time rather than index space, they are also indexed + // as ancestor terms (since this lets us reduce the number of terms in the + // query). Finally, as an optimization we always index true_max_level() + // cells as ancestor cells only, since these cells have the special property + // that query regions will never contain a descendant of these cells. + var rv []string + prevID := CellID(0) + tml := rti.options.trueMaxLevel() + + for _, cellID := range covering { + level := cellID.Level() + if level < tml { + rv = append(rv, rti.GetTerm(COVERING, cellID, prefix)) + } + + if level == tml || !rti.options.optimizeSpace { + rv = append(rv, rti.GetTerm(ANCESTOR, cellID.Parent(level), prefix)) + } + + for (level - rti.options.levelMod) >= rti.options.minLevel { + level -= rti.options.levelMod + ancestorID := cellID.Parent(level) + if prevID != CellID(0) && prevID.Level() > level && + prevID.Parent(level) == ancestorID { + break + } + rv = append(rv, rti.GetTerm(ANCESTOR, ancestorID, prefix)) + } + prevID = cellID + } + + return rv +} + +func (rti *RegionTermIndexer) GetQueryTermsForPoint(p Point, prefix string) []string { + cellID := cellIDFromPoint(p) + var rv []string + + level := rti.options.trueMaxLevel() + rv = append(rv, rti.GetTerm(ANCESTOR, cellID.Parent(level), prefix)) + if rti.options.pointsOnly { + return rv + } + + for level >= rti.options.minLevel { + rv = append(rv, rti.GetTerm(COVERING, cellID.Parent(level), prefix)) + level -= rti.options.levelMod + } + + return rv +} + +func (rti *RegionTermIndexer) GetQueryTermsForRegion(region Region, + prefix string) []string { + rti.regionCoverer.LevelMod = rti.options.levelMod + rti.regionCoverer.MaxLevel = rti.options.maxLevel + rti.regionCoverer.MinLevel = rti.options.minLevel + rti.regionCoverer.MaxCells = rti.options.maxCells + + covering := rti.regionCoverer.Covering(region) + return rti.GetQueryTermsForCanonicalCovering(covering, prefix) + +} + +func (rti *RegionTermIndexer) GetQueryTermsForCanonicalCovering( + covering CellUnion, prefix string) []string { + var rv []string + prevID := CellID(0) + tml := rti.options.trueMaxLevel() + for _, cellID := range covering { + level := cellID.Level() + rv = append(rv, rti.GetTerm(ANCESTOR, cellID, prefix)) + + if rti.options.pointsOnly { + continue + } + + if rti.options.optimizeSpace && level < tml { + rv = append(rv, rti.GetTerm(COVERING, cellID, prefix)) + } + + for level-rti.options.levelMod >= rti.options.minLevel { + level -= rti.options.levelMod + ancestorID := cellID.Parent(level) + if prevID != CellID(0) && prevID.Level() > level && + prevID.Parent(level) == ancestorID { + break + } + rv = append(rv, rti.GetTerm(COVERING, ancestorID, prefix)) + } + + prevID = cellID + } + + return rv +} + +func CapFromCenterAndRadius(centerLat, centerLon, dist float64) Cap { + return CapFromCenterAngle(PointFromLatLng( + LatLngFromDegrees(centerLat, centerLon)), s1.Angle((dist/1000)/6378)) +} + +// FilterOutCoveringTerms filters out the covering terms so that +// it helps to reduce the search terms while searching in a one +// dimensional space. (point only indexing usecase) +func FilterOutCoveringTerms(terms []string) []string { + rv := make([]string, 0, len(terms)) + for _, term := range terms { + if strings.HasPrefix(term, marker) { + continue + } + rv = append(rv, term) + } + return rv +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/regioncoverer.go b/backend/vendor/github.com/blevesearch/geo/s2/regioncoverer.go new file mode 100644 index 0000000000..de5b0c20dc --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/regioncoverer.go @@ -0,0 +1,615 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "container/heap" + "sort" +) + +// RegionCoverer allows arbitrary regions to be approximated as unions of cells (CellUnion). +// This is useful for implementing various sorts of search and precomputation operations. +// +// Typical usage: +// +// rc := &s2.RegionCoverer{MaxLevel: 30, MaxCells: 5} +// r := s2.Region(CapFromCenterArea(center, area)) +// covering := rc.Covering(r) +// +// This yields a CellUnion of at most 5 cells that is guaranteed to cover the +// given region (a disc-shaped region on the sphere). +// +// For covering, only cells where (level - MinLevel) is a multiple of LevelMod will be used. +// This effectively allows the branching factor of the S2 CellID hierarchy to be increased. +// Currently the only parameter values allowed are 1, 2, or 3, corresponding to +// branching factors of 4, 16, and 64 respectively. +// +// Note the following: +// +// - MinLevel takes priority over MaxCells, i.e. cells below the given level will +// never be used even if this causes a large number of cells to be returned. +// +// - For any setting of MaxCells, up to 6 cells may be returned if that +// is the minimum number of cells required (e.g. if the region intersects +// all six face cells). Up to 3 cells may be returned even for very tiny +// convex regions if they happen to be located at the intersection of +// three cube faces. +// +// - For any setting of MaxCells, an arbitrary number of cells may be +// returned if MinLevel is too high for the region being approximated. +// +// - If MaxCells is less than 4, the area of the covering may be +// arbitrarily large compared to the area of the original region even if +// the region is convex (e.g. a Cap or Rect). +// +// The approximation algorithm is not optimal but does a pretty good job in +// practice. The output does not always use the maximum number of cells +// allowed, both because this would not always yield a better approximation, +// and because MaxCells is a limit on how much work is done exploring the +// possible covering as well as a limit on the final output size. +// +// Because it is an approximation algorithm, one should not rely on the +// stability of the output. In particular, the output of the covering algorithm +// may change across different versions of the library. +// +// One can also generate interior coverings, which are sets of cells which +// are entirely contained within a region. Interior coverings can be +// empty, even for non-empty regions, if there are no cells that satisfy +// the provided constraints and are contained by the region. Note that for +// performance reasons, it is wise to specify a MaxLevel when computing +// interior coverings - otherwise for regions with small or zero area, the +// algorithm may spend a lot of time subdividing cells all the way to leaf +// level to try to find contained cells. +type RegionCoverer struct { + MinLevel int // the minimum cell level to be used. + MaxLevel int // the maximum cell level to be used. + LevelMod int // the LevelMod to be used. + MaxCells int // the maximum desired number of cells in the approximation. +} + +// NewRegionCoverer returns a region coverer with the appropriate defaults. +func NewRegionCoverer() *RegionCoverer { + return &RegionCoverer{ + MinLevel: 0, + MaxLevel: maxLevel, + LevelMod: 1, + MaxCells: 8, + } +} + +type coverer struct { + minLevel int // the minimum cell level to be used. + maxLevel int // the maximum cell level to be used. + levelMod int // the LevelMod to be used. + maxCells int // the maximum desired number of cells in the approximation. + region Region + result CellUnion + pq priorityQueue + interiorCovering bool +} + +type candidate struct { + cell Cell + terminal bool // Cell should not be expanded further. + numChildren int // Number of children that intersect the region. + children []*candidate // Actual size may be 0, 4, 16, or 64 elements. + priority int // Priority of the candidate. +} + +type priorityQueue []*candidate + +func (pq priorityQueue) Len() int { + return len(pq) +} + +func (pq priorityQueue) Less(i, j int) bool { + // We want Pop to give us the highest, not lowest, priority so we use greater than here. + return pq[i].priority > pq[j].priority +} + +func (pq priorityQueue) Swap(i, j int) { + pq[i], pq[j] = pq[j], pq[i] +} + +func (pq *priorityQueue) Push(x interface{}) { + item := x.(*candidate) + *pq = append(*pq, item) +} + +func (pq *priorityQueue) Pop() interface{} { + item := (*pq)[len(*pq)-1] + *pq = (*pq)[:len(*pq)-1] + return item +} + +func (pq *priorityQueue) Reset() { + *pq = (*pq)[:0] +} + +// newCandidate returns a new candidate with no children if the cell intersects the given region. +// The candidate is marked as terminal if it should not be expanded further. +func (c *coverer) newCandidate(cell Cell) *candidate { + if !c.region.IntersectsCell(cell) { + return nil + } + cand := &candidate{cell: cell} + level := int(cell.level) + if level >= c.minLevel { + if c.interiorCovering { + if c.region.ContainsCell(cell) { + cand.terminal = true + } else if level+c.levelMod > c.maxLevel { + return nil + } + } else if level+c.levelMod > c.maxLevel || c.region.ContainsCell(cell) { + cand.terminal = true + } + } + return cand +} + +// expandChildren populates the children of the candidate by expanding the given number of +// levels from the given cell. Returns the number of children that were marked "terminal". +func (c *coverer) expandChildren(cand *candidate, cell Cell, numLevels int) int { + numLevels-- + var numTerminals int + last := cell.id.ChildEnd() + for ci := cell.id.ChildBegin(); ci != last; ci = ci.Next() { + childCell := CellFromCellID(ci) + if numLevels > 0 { + if c.region.IntersectsCell(childCell) { + numTerminals += c.expandChildren(cand, childCell, numLevels) + } + continue + } + if child := c.newCandidate(childCell); child != nil { + cand.children = append(cand.children, child) + cand.numChildren++ + if child.terminal { + numTerminals++ + } + } + } + return numTerminals +} + +// addCandidate adds the given candidate to the result if it is marked as "terminal", +// otherwise expands its children and inserts it into the priority queue. +// Passing an argument of nil does nothing. +func (c *coverer) addCandidate(cand *candidate) { + if cand == nil { + return + } + + if cand.terminal { + c.result = append(c.result, cand.cell.id) + return + } + + // Expand one level at a time until we hit minLevel to ensure that we don't skip over it. + numLevels := c.levelMod + level := int(cand.cell.level) + if level < c.minLevel { + numLevels = 1 + } + + numTerminals := c.expandChildren(cand, cand.cell, numLevels) + maxChildrenShift := uint(2 * c.levelMod) + if cand.numChildren == 0 { + return + } else if !c.interiorCovering && numTerminals == 1<= c.minLevel { + // Optimization: add the parent cell rather than all of its children. + // We can't do this for interior coverings, since the children just + // intersect the region, but may not be contained by it - we need to + // subdivide them further. + cand.terminal = true + c.addCandidate(cand) + } else { + // We negate the priority so that smaller absolute priorities are returned + // first. The heuristic is designed to refine the largest cells first, + // since those are where we have the largest potential gain. Among cells + // of the same size, we prefer the cells with the fewest children. + // Finally, among cells with equal numbers of children we prefer those + // with the smallest number of children that cannot be refined further. + cand.priority = -(((level< 1 && level > c.minLevel { + level -= (level - c.minLevel) % c.levelMod + } + return level +} + +// adjustCellLevels ensures that all cells with level > minLevel also satisfy levelMod, +// by replacing them with an ancestor if necessary. Cell levels smaller +// than minLevel are not modified (see AdjustLevel). The output is +// then normalized to ensure that no redundant cells are present. +func (c *coverer) adjustCellLevels(cells *CellUnion) { + if c.levelMod == 1 { + return + } + + var out int + for _, ci := range *cells { + level := ci.Level() + newLevel := c.adjustLevel(level) + if newLevel != level { + ci = ci.Parent(newLevel) + } + if out > 0 && (*cells)[out-1].Contains(ci) { + continue + } + for out > 0 && ci.Contains((*cells)[out-1]) { + out-- + } + (*cells)[out] = ci + out++ + } + *cells = (*cells)[:out] +} + +// initialCandidates computes a set of initial candidates that cover the given region. +func (c *coverer) initialCandidates() { + // Optimization: start with a small (usually 4 cell) covering of the region's bounding cap. + temp := &RegionCoverer{MaxLevel: c.maxLevel, LevelMod: 1, MaxCells: minInt(4, c.maxCells)} + + cells := temp.FastCovering(c.region) + c.adjustCellLevels(&cells) + for _, ci := range cells { + c.addCandidate(c.newCandidate(CellFromCellID(ci))) + } +} + +// coveringInternal generates a covering and stores it in result. +// Strategy: Start with the 6 faces of the cube. Discard any +// that do not intersect the shape. Then repeatedly choose the +// largest cell that intersects the shape and subdivide it. +// +// result contains the cells that will be part of the output, while pq +// contains cells that we may still subdivide further. Cells that are +// entirely contained within the region are immediately added to the output, +// while cells that do not intersect the region are immediately discarded. +// Therefore pq only contains cells that partially intersect the region. +// Candidates are prioritized first according to cell size (larger cells +// first), then by the number of intersecting children they have (fewest +// children first), and then by the number of fully contained children +// (fewest children first). +func (c *coverer) coveringInternal(region Region) { + c.region = region + + c.initialCandidates() + for c.pq.Len() > 0 && (!c.interiorCovering || len(c.result) < c.maxCells) { + cand := heap.Pop(&c.pq).(*candidate) + + // For interior covering we keep subdividing no matter how many children + // candidate has. If we reach MaxCells before expanding all children, + // we will just use some of them. + // For exterior covering we cannot do this, because result has to cover the + // whole region, so all children have to be used. + // candidate.numChildren == 1 case takes care of the situation when we + // already have more than MaxCells in result (minLevel is too high). + // Subdividing of the candidate with one child does no harm in this case. + if c.interiorCovering || int(cand.cell.level) < c.minLevel || cand.numChildren == 1 || len(c.result)+c.pq.Len()+cand.numChildren <= c.maxCells { + for _, child := range cand.children { + if !c.interiorCovering || len(c.result) < c.maxCells { + c.addCandidate(child) + } + } + } else { + cand.terminal = true + c.addCandidate(cand) + } + } + + c.pq.Reset() + c.region = nil + + // Rather than just returning the raw list of cell ids, we construct a cell + // union and then denormalize it. This has the effect of replacing four + // child cells with their parent whenever this does not violate the covering + // parameters specified (min_level, level_mod, etc). This significantly + // reduces the number of cells returned in many cases, and it is cheap + // compared to computing the covering in the first place. + c.result.Normalize() + if c.minLevel > 0 || c.levelMod > 1 { + c.result.Denormalize(c.minLevel, c.levelMod) + } +} + +// newCoverer returns an instance of coverer. +func (rc *RegionCoverer) newCoverer() *coverer { + return &coverer{ + minLevel: maxInt(0, minInt(maxLevel, rc.MinLevel)), + maxLevel: maxInt(0, minInt(maxLevel, rc.MaxLevel)), + levelMod: maxInt(1, minInt(3, rc.LevelMod)), + maxCells: rc.MaxCells, + } +} + +// Covering returns a CellUnion that covers the given region and satisfies the various restrictions. +func (rc *RegionCoverer) Covering(region Region) CellUnion { + covering := rc.CellUnion(region) + covering.Denormalize(maxInt(0, minInt(maxLevel, rc.MinLevel)), maxInt(1, minInt(3, rc.LevelMod))) + return covering +} + +// InteriorCovering returns a CellUnion that is contained within the given region and satisfies the various restrictions. +func (rc *RegionCoverer) InteriorCovering(region Region) CellUnion { + intCovering := rc.InteriorCellUnion(region) + intCovering.Denormalize(maxInt(0, minInt(maxLevel, rc.MinLevel)), maxInt(1, minInt(3, rc.LevelMod))) + return intCovering +} + +// CellUnion returns a normalized CellUnion that covers the given region and +// satisfies the restrictions except for minLevel and levelMod. These criteria +// cannot be satisfied using a cell union because cell unions are +// automatically normalized by replacing four child cells with their parent +// whenever possible. (Note that the list of cell ids passed to the CellUnion +// constructor does in fact satisfy all the given restrictions.) +func (rc *RegionCoverer) CellUnion(region Region) CellUnion { + c := rc.newCoverer() + c.coveringInternal(region) + cu := c.result + cu.Normalize() + return cu +} + +// InteriorCellUnion returns a normalized CellUnion that is contained within the given region and +// satisfies the restrictions except for minLevel and levelMod. These criteria +// cannot be satisfied using a cell union because cell unions are +// automatically normalized by replacing four child cells with their parent +// whenever possible. (Note that the list of cell ids passed to the CellUnion +// constructor does in fact satisfy all the given restrictions.) +func (rc *RegionCoverer) InteriorCellUnion(region Region) CellUnion { + c := rc.newCoverer() + c.interiorCovering = true + c.coveringInternal(region) + cu := c.result + cu.Normalize() + return cu +} + +// FastCovering returns a CellUnion that covers the given region similar to Covering, +// except that this method is much faster and the coverings are not as tight. +// All of the usual parameters are respected (MaxCells, MinLevel, MaxLevel, and LevelMod), +// except that the implementation makes no attempt to take advantage of large values of +// MaxCells. (A small number of cells will always be returned.) +// +// This function is useful as a starting point for algorithms that +// recursively subdivide cells. +func (rc *RegionCoverer) FastCovering(region Region) CellUnion { + c := rc.newCoverer() + cu := CellUnion(region.CellUnionBound()) + c.normalizeCovering(&cu) + return cu +} + +// IsCanonical reports whether the given CellUnion represents a valid covering +// that conforms to the current covering parameters. In particular: +// +// - All CellIDs must be valid. +// +// - CellIDs must be sorted and non-overlapping. +// +// - CellID levels must satisfy MinLevel, MaxLevel, and LevelMod. +// +// - If the covering has more than MaxCells, there must be no two cells with +// a common ancestor at MinLevel or higher. +// +// - There must be no sequence of cells that could be replaced by an +// ancestor (i.e. with LevelMod == 1, the 4 child cells of a parent). +func (rc *RegionCoverer) IsCanonical(covering CellUnion) bool { + return rc.newCoverer().isCanonical(covering) +} + +// normalizeCovering normalizes the "covering" so that it conforms to the +// current covering parameters (maxCells, minLevel, maxLevel, and levelMod). +// This method makes no attempt to be optimal. In particular, if +// minLevel > 0 or levelMod > 1 then it may return more than the +// desired number of cells even when this isn't necessary. +// +// Note that when the covering parameters have their default values, almost +// all of the code in this function is skipped. +func (c *coverer) normalizeCovering(covering *CellUnion) { + // If any cells are too small, or don't satisfy levelMod, then replace them with ancestors. + if c.maxLevel < maxLevel || c.levelMod > 1 { + for i, ci := range *covering { + level := ci.Level() + newLevel := c.adjustLevel(minInt(level, c.maxLevel)) + if newLevel != level { + (*covering)[i] = ci.Parent(newLevel) + } + } + } + // Sort the cells and simplify them. + covering.Normalize() + + // Make sure that the covering satisfies minLevel and levelMod, + // possibly at the expense of satisfying MaxCells. + if c.minLevel > 0 || c.levelMod > 1 { + covering.Denormalize(c.minLevel, c.levelMod) + } + + // If there are too many cells and the covering is very large, use the + // RegionCoverer to compute a new covering. (This avoids possible O(n^2) + // behavior of the simpler algorithm below.) + excess := len(*covering) - c.maxCells + if excess <= 0 || c.isCanonical(*covering) { + return + } + if excess*len(*covering) > 10000 { + rc := NewRegionCoverer() + (*covering) = rc.Covering(covering) + return + } + + // If there are still too many cells, then repeatedly replace two adjacent + // cells in CellID order by their lowest common ancestor. + for len(*covering) > c.maxCells { + bestIndex := -1 + bestLevel := -1 + for i := 0; i+1 < len(*covering); i++ { + level, ok := (*covering)[i].CommonAncestorLevel((*covering)[i+1]) + if !ok { + continue + } + level = c.adjustLevel(level) + if level > bestLevel { + bestLevel = level + bestIndex = i + } + } + + if bestLevel < c.minLevel { + break + } + + // Replace all cells contained by the new ancestor cell. + id := (*covering)[bestIndex].Parent(bestLevel) + (*covering) = c.replaceCellsWithAncestor(*covering, id) + + // Now repeatedly check whether all children of the parent cell are + // present, in which case we can replace those cells with their parent. + for bestLevel > c.minLevel { + bestLevel -= c.levelMod + id = id.Parent(bestLevel) + if !c.containsAllChildren(*covering, id) { + break + } + (*covering) = c.replaceCellsWithAncestor(*covering, id) + } + } +} + +// isCanonical reports whether the covering is canonical. +func (c *coverer) isCanonical(covering CellUnion) bool { + trueMax := c.maxLevel + if c.levelMod != 1 { + trueMax = c.maxLevel - (c.maxLevel-c.minLevel)%c.levelMod + } + tooManyCells := len(covering) > c.maxCells + sameParentCount := 1 + + prevID := CellID(0) + for _, id := range covering { + if !id.IsValid() { + return false + } + + // Check that the CellID level is acceptable. + level := id.Level() + if level < c.minLevel || level > trueMax { + return false + } + if c.levelMod > 1 && (level-c.minLevel)%c.levelMod != 0 { + return false + } + + if prevID != 0 { + // Check that cells are sorted and non-overlapping. + if prevID.RangeMax() >= id.RangeMin() { + return false + } + + lev, ok := id.CommonAncestorLevel(prevID) + // If there are too many cells, check that no pair of adjacent cells + // could be replaced by an ancestor. + if tooManyCells && (ok && lev >= c.minLevel) { + return false + } + + // Check that there are no sequences of (4 ** level_mod) cells that all + // have the same parent (considering only multiples of "level_mod"). + pLevel := level - c.levelMod + if pLevel < c.minLevel || level != prevID.Level() || + id.Parent(pLevel) != prevID.Parent(pLevel) { + sameParentCount = 1 + } else { + sameParentCount++ + if sameParentCount == 1<= id.RangeMin() }) + level := id.Level() + c.levelMod + for child := id.ChildBeginAtLevel(level); child != id.ChildEndAtLevel(level); child = child.Next() { + if pos == len(covering) || covering[pos] != child { + return false + } + pos++ + } + return true +} + +// replaceCellsWithAncestor replaces all descendants of the given id in covering +// with id. This requires the covering contains at least one descendant of id. +func (c *coverer) replaceCellsWithAncestor(covering []CellID, id CellID) []CellID { + begin := sort.Search(len(covering), func(i int) bool { return covering[i] > id.RangeMin() }) + end := sort.Search(len(covering), func(i int) bool { return covering[i] > id.RangeMax() }) + + return append(append(covering[:begin], id), covering[end:]...) +} + +// SimpleRegionCovering returns a set of cells at the given level that cover +// the connected region and a starting point on the boundary or inside the +// region. The cells are returned in arbitrary order. +// +// Note that this method is not faster than the regular Covering +// method for most region types, such as Cap or Polygon, and in fact it +// can be much slower when the output consists of a large number of cells. +// Currently it can be faster at generating coverings of long narrow regions +// such as polylines, but this may change in the future. +func SimpleRegionCovering(region Region, start Point, level int) []CellID { + return FloodFillRegionCovering(region, cellIDFromPoint(start).Parent(level)) +} + +// FloodFillRegionCovering returns all edge-connected cells at the same level as +// the given CellID that intersect the given region, in arbitrary order. +func FloodFillRegionCovering(region Region, start CellID) []CellID { + var output []CellID + all := map[CellID]bool{ + start: true, + } + frontier := []CellID{start} + for len(frontier) > 0 { + id := frontier[len(frontier)-1] + frontier = frontier[:len(frontier)-1] + if !region.IntersectsCell(CellFromCellID(id)) { + continue + } + output = append(output, id) + for _, nbr := range id.EdgeNeighbors() { + if !all[nbr] { + all[nbr] = true + frontier = append(frontier, nbr) + } + } + } + + return output +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/regionunion.go b/backend/vendor/github.com/blevesearch/geo/s2/regionunion.go new file mode 100644 index 0000000000..915b7c330e --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/regionunion.go @@ -0,0 +1,66 @@ +// Copyright 2020 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +// A RegionUnion represents a union of possibly overlapping regions. +// It is convenient for computing a covering of a set of regions. +type RegionUnion []Region + +// CapBound returns a bounding cap for this RegionUnion. +func (ru RegionUnion) CapBound() Cap { return ru.RectBound().CapBound() } + +// RectBound returns a bounding latitude-longitude rectangle for this RegionUnion. +func (ru RegionUnion) RectBound() Rect { + ret := EmptyRect() + for _, reg := range ru { + ret = ret.Union(reg.RectBound()) + } + return ret +} + +// ContainsCell reports whether the given Cell is contained by this RegionUnion. +func (ru RegionUnion) ContainsCell(c Cell) bool { + for _, reg := range ru { + if reg.ContainsCell(c) { + return true + } + } + return false +} + +// IntersectsCell reports whether this RegionUnion intersects the given cell. +func (ru RegionUnion) IntersectsCell(c Cell) bool { + for _, reg := range ru { + if reg.IntersectsCell(c) { + return true + } + } + return false +} + +// ContainsPoint reports whether this RegionUnion contains the Point. +func (ru RegionUnion) ContainsPoint(p Point) bool { + for _, reg := range ru { + if reg.ContainsPoint(p) { + return true + } + } + return false +} + +// CellUnionBound computes a covering of the RegionUnion. +func (ru RegionUnion) CellUnionBound() []CellID { + return ru.CapBound().CellUnionBound() +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/shape.go b/backend/vendor/github.com/blevesearch/geo/s2/shape.go new file mode 100644 index 0000000000..2cbf170c32 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/shape.go @@ -0,0 +1,263 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "sort" +) + +// Edge represents a geodesic edge consisting of two vertices. Zero-length edges are +// allowed, and can be used to represent points. +type Edge struct { + V0, V1 Point +} + +// Cmp compares the two edges using the underlying Points Cmp method and returns +// +// -1 if e < other +// 0 if e == other +// +1 if e > other +// +// The two edges are compared by first vertex, and then by the second vertex. +func (e Edge) Cmp(other Edge) int { + if v0cmp := e.V0.Cmp(other.V0.Vector); v0cmp != 0 { + return v0cmp + } + return e.V1.Cmp(other.V1.Vector) +} + +// sortEdges sorts the slice of Edges in place. +func sortEdges(e []Edge) { + sort.Sort(edges(e)) +} + +// edges implements the Sort interface for slices of Edge. +type edges []Edge + +func (e edges) Len() int { return len(e) } +func (e edges) Swap(i, j int) { e[i], e[j] = e[j], e[i] } +func (e edges) Less(i, j int) bool { return e[i].Cmp(e[j]) == -1 } + +// ShapeEdgeID is a unique identifier for an Edge within an ShapeIndex, +// consisting of a (shapeID, edgeID) pair. +type ShapeEdgeID struct { + ShapeID int32 + EdgeID int32 +} + +// Cmp compares the two ShapeEdgeIDs and returns +// +// -1 if s < other +// 0 if s == other +// +1 if s > other +// +// The two are compared first by shape id and then by edge id. +func (s ShapeEdgeID) Cmp(other ShapeEdgeID) int { + switch { + case s.ShapeID < other.ShapeID: + return -1 + case s.ShapeID > other.ShapeID: + return 1 + } + switch { + case s.EdgeID < other.EdgeID: + return -1 + case s.EdgeID > other.EdgeID: + return 1 + } + return 0 +} + +// ShapeEdge represents a ShapeEdgeID with the two endpoints of that Edge. +type ShapeEdge struct { + ID ShapeEdgeID + Edge Edge +} + +// Chain represents a range of edge IDs corresponding to a chain of connected +// edges, specified as a (start, length) pair. The chain is defined to consist of +// edge IDs {start, start + 1, ..., start + length - 1}. +type Chain struct { + Start, Length int +} + +// ChainPosition represents the position of an edge within a given edge chain, +// specified as a (chainID, offset) pair. Chains are numbered sequentially +// starting from zero, and offsets are measured from the start of each chain. +type ChainPosition struct { + ChainID, Offset int +} + +// A ReferencePoint consists of a point and a boolean indicating whether the point +// is contained by a particular shape. +type ReferencePoint struct { + Point Point + Contained bool +} + +// OriginReferencePoint returns a ReferencePoint with the given value for +// contained and the origin point. It should be used when all points or no +// points are contained. +func OriginReferencePoint(contained bool) ReferencePoint { + return ReferencePoint{Point: OriginPoint(), Contained: contained} +} + +// typeTag is a 32-bit tag that can be used to identify the type of an encoded +// Shape. All encodable types have a non-zero type tag. The tag associated with +type typeTag uint32 + +const ( + // Indicates that a given Shape type cannot be encoded. + typeTagNone typeTag = 0 + typeTagPolygon typeTag = 1 + typeTagPolyline typeTag = 2 + typeTagPointVector typeTag = 3 + typeTagLaxPolyline typeTag = 4 + typeTagLaxPolygon typeTag = 5 + + // The minimum allowable tag for future user-defined Shape types. + typeTagMinUser typeTag = 8192 +) + +// Shape represents polygonal geometry in a flexible way. It is organized as a +// collection of edges that optionally defines an interior. All geometry +// represented by a given Shape must have the same dimension, which means that +// an Shape can represent either a set of points, a set of polylines, or a set +// of polygons. +// +// Shape is defined as an interface in order to give clients control over the +// underlying data representation. Sometimes an Shape does not have any data of +// its own, but instead wraps some other type. +// +// Shape operations are typically defined on a ShapeIndex rather than +// individual shapes. An ShapeIndex is simply a collection of Shapes, +// possibly of different dimensions (e.g. 10 points and 3 polygons), organized +// into a data structure for efficient edge access. +// +// The edges of a Shape are indexed by a contiguous range of edge IDs +// starting at 0. The edges are further subdivided into chains, where each +// chain consists of a sequence of edges connected end-to-end (a polyline). +// For example, a Shape representing two polylines AB and CDE would have +// three edges (AB, CD, DE) grouped into two chains: (AB) and (CD, DE). +// Similarly, an Shape representing 5 points would have 5 chains consisting +// of one edge each. +// +// Shape has methods that allow edges to be accessed either using the global +// numbering (edge ID) or within a particular chain. The global numbering is +// sufficient for most purposes, but the chain representation is useful for +// certain algorithms such as intersection (see BooleanOperation). +type Shape interface { + // NumEdges returns the number of edges in this shape. + NumEdges() int + + // Edge returns the edge for the given edge index. + Edge(i int) Edge + + // ReferencePoint returns an arbitrary reference point for the shape. (The + // containment boolean value must be false for shapes that do not have an interior.) + // + // This reference point may then be used to compute the containment of other + // points by counting edge crossings. + ReferencePoint() ReferencePoint + + // NumChains reports the number of contiguous edge chains in the shape. + // For example, a shape whose edges are [AB, BC, CD, AE, EF] would consist + // of two chains (AB,BC,CD and AE,EF). Every chain is assigned a chain Id + // numbered sequentially starting from zero. + // + // Note that it is always acceptable to implement this method by returning + // NumEdges, i.e. every chain consists of a single edge, but this may + // reduce the efficiency of some algorithms. + NumChains() int + + // Chain returns the range of edge IDs corresponding to the given edge chain. + // Edge chains must form contiguous, non-overlapping ranges that cover + // the entire range of edge IDs. This is spelled out more formally below: + // + // 0 <= i < NumChains() + // Chain(i).length > 0, for all i + // Chain(0).start == 0 + // Chain(i).start + Chain(i).length == Chain(i+1).start, for i < NumChains()-1 + // Chain(i).start + Chain(i).length == NumEdges(), for i == NumChains()-1 + Chain(chainID int) Chain + + // ChainEdgeReturns the edge at offset "offset" within edge chain "chainID". + // Equivalent to "shape.Edge(shape.Chain(chainID).start + offset)" + // but more efficient. + ChainEdge(chainID, offset int) Edge + + // ChainPosition finds the chain containing the given edge, and returns the + // position of that edge as a ChainPosition(chainID, offset) pair. + // + // shape.Chain(pos.chainID).start + pos.offset == edgeID + // shape.Chain(pos.chainID+1).start > edgeID + // + // where pos == shape.ChainPosition(edgeID). + ChainPosition(edgeID int) ChainPosition + + // Dimension returns the dimension of the geometry represented by this shape, + // either 0, 1 or 2 for point, polyline and polygon geometry respectively. + // + // 0 - Point geometry. Each point is represented as a degenerate edge. + // + // 1 - Polyline geometry. Polyline edges may be degenerate. A shape may + // represent any number of polylines. Polylines edges may intersect. + // + // 2 - Polygon geometry. Edges should be oriented such that the polygon + // interior is always on the left. In theory the edges may be returned + // in any order, but typically the edges are organized as a collection + // of edge chains where each chain represents one polygon loop. + // Polygons may have degeneracies (e.g., degenerate edges or sibling + // pairs consisting of an edge and its corresponding reversed edge). + // A polygon loop may also be full (containing all points on the + // sphere); by convention this is represented as a chain with no edges. + // (See laxPolygon for details.) + // + // This method allows degenerate geometry of different dimensions + // to be distinguished, e.g. it allows a point to be distinguished from a + // polyline or polygon that has been simplified to a single point. + Dimension() int + + // IsEmpty reports whether the Shape contains no points. (Note that the full + // polygon is represented as a chain with zero edges.) + IsEmpty() bool + + // IsFull reports whether the Shape contains all points on the sphere. + IsFull() bool + + // typeTag returns a value that can be used to identify the type of an + // encoded Shape. + typeTag() typeTag + + // We do not support implementations of this interface outside this package. + privateInterface() +} + +// defaultShapeIsEmpty reports whether this shape contains no points. +func defaultShapeIsEmpty(s Shape) bool { + return s.NumEdges() == 0 && (s.Dimension() != 2 || s.NumChains() == 0) +} + +// defaultShapeIsFull reports whether this shape contains all points on the sphere. +func defaultShapeIsFull(s Shape) bool { + return s.NumEdges() == 0 && s.Dimension() == 2 && s.NumChains() > 0 +} + +// A minimal check for types that should satisfy the Shape interface. +var ( + _ Shape = &Loop{} + _ Shape = &Polygon{} + _ Shape = &Polyline{} +) diff --git a/backend/vendor/github.com/blevesearch/geo/s2/shapeindex.go b/backend/vendor/github.com/blevesearch/geo/s2/shapeindex.go new file mode 100644 index 0000000000..6efa213aba --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/shapeindex.go @@ -0,0 +1,1526 @@ +// Copyright 2016 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "math" + "sort" + "sync" + "sync/atomic" + + "github.com/golang/geo/r1" + "github.com/golang/geo/r2" +) + +// CellRelation describes the possible relationships between a target cell +// and the cells of the ShapeIndex. If the target is an index cell or is +// contained by an index cell, it is Indexed. If the target is subdivided +// into one or more index cells, it is Subdivided. Otherwise it is Disjoint. +type CellRelation int + +// The possible CellRelations for a ShapeIndex. +const ( + Indexed CellRelation = iota + Subdivided + Disjoint +) + +const ( + // cellPadding defines the total error when clipping an edge which comes + // from two sources: + // (1) Clipping the original spherical edge to a cube face (the face edge). + // The maximum error in this step is faceClipErrorUVCoord. + // (2) Clipping the face edge to the u- or v-coordinate of a cell boundary. + // The maximum error in this step is edgeClipErrorUVCoord. + // Finally, since we encounter the same errors when clipping query edges, we + // double the total error so that we only need to pad edges during indexing + // and not at query time. + cellPadding = 2.0 * (faceClipErrorUVCoord + edgeClipErrorUVCoord) + + // cellSizeToLongEdgeRatio defines the cell size relative to the length of an + // edge at which it is first considered to be long. Long edges do not + // contribute toward the decision to subdivide a cell further. For example, + // a value of 2.0 means that the cell must be at least twice the size of the + // edge in order for that edge to be counted. There are two reasons for not + // counting long edges: (1) such edges typically need to be propagated to + // several children, which increases time and memory costs without much benefit, + // and (2) in pathological cases, many long edges close together could force + // subdivision to continue all the way to the leaf cell level. + cellSizeToLongEdgeRatio = 1.0 +) + +// clippedShape represents the part of a shape that intersects a Cell. +// It consists of the set of edge IDs that intersect that cell and a boolean +// indicating whether the center of the cell is inside the shape (for shapes +// that have an interior). +// +// Note that the edges themselves are not clipped; we always use the original +// edges for intersection tests so that the results will be the same as the +// original shape. +type clippedShape struct { + // shapeID is the index of the shape this clipped shape is a part of. + shapeID int32 + + // containsCenter indicates if the center of the CellID this shape has been + // clipped to falls inside this shape. This is false for shapes that do not + // have an interior. + containsCenter bool + + // edges is the ordered set of ShapeIndex original edge IDs. Edges + // are stored in increasing order of edge ID. + edges []int +} + +// newClippedShape returns a new clipped shape for the given shapeID and number of expected edges. +func newClippedShape(id int32, numEdges int) *clippedShape { + return &clippedShape{ + shapeID: id, + edges: make([]int, numEdges), + } +} + +// numEdges returns the number of edges that intersect the CellID of the Cell this was clipped to. +func (c *clippedShape) numEdges() int { + return len(c.edges) +} + +// containsEdge reports if this clipped shape contains the given edge ID. +func (c *clippedShape) containsEdge(id int) bool { + // Linear search is fast because the number of edges per shape is typically + // very small (less than 10). + for _, e := range c.edges { + if e == id { + return true + } + } + return false +} + +// ShapeIndexCell stores the index contents for a particular CellID. +type ShapeIndexCell struct { + shapes []*clippedShape +} + +// NewShapeIndexCell creates a new cell that is sized to hold the given number of shapes. +func NewShapeIndexCell(numShapes int) *ShapeIndexCell { + return &ShapeIndexCell{ + shapes: make([]*clippedShape, numShapes), + } +} + +// numEdges reports the total number of edges in all clipped shapes in this cell. +func (s *ShapeIndexCell) numEdges() int { + var e int + for _, cs := range s.shapes { + e += cs.numEdges() + } + return e +} + +// add adds the given clipped shape to this index cell. +func (s *ShapeIndexCell) add(c *clippedShape) { + // C++ uses a set, so it's ordered and unique. We don't currently catch + // the case when a duplicate value is added. + s.shapes = append(s.shapes, c) +} + +// findByShapeID returns the clipped shape that contains the given shapeID, +// or nil if none of the clipped shapes contain it. +func (s *ShapeIndexCell) findByShapeID(shapeID int32) *clippedShape { + // Linear search is fine because the number of shapes per cell is typically + // very small (most often 1), and is large only for pathological inputs + // (e.g. very deeply nested loops). + for _, clipped := range s.shapes { + if clipped.shapeID == shapeID { + return clipped + } + } + return nil +} + +// faceEdge and clippedEdge store temporary edge data while the index is being +// updated. +// +// While it would be possible to combine all the edge information into one +// structure, there are two good reasons for separating it: +// +// - Memory usage. Separating the two means that we only need to +// store one copy of the per-face data no matter how many times an edge is +// subdivided, and it also lets us delay computing bounding boxes until +// they are needed for processing each face (when the dataset spans +// multiple faces). +// +// - Performance. UpdateEdges is significantly faster on large polygons when +// the data is separated, because it often only needs to access the data in +// clippedEdge and this data is cached more successfully. + +// faceEdge represents an edge that has been projected onto a given face, +type faceEdge struct { + shapeID int32 // The ID of shape that this edge belongs to + edgeID int // Edge ID within that shape + maxLevel int // Not desirable to subdivide this edge beyond this level + hasInterior bool // Belongs to a shape that has a dimension of 2 + a, b r2.Point // The edge endpoints, clipped to a given face + edge Edge // The original edge. +} + +// clippedEdge represents the portion of that edge that has been clipped to a given Cell. +type clippedEdge struct { + faceEdge *faceEdge // The original unclipped edge + bound r2.Rect // Bounding box for the clipped portion +} + +// ShapeIndexIteratorPos defines the set of possible iterator starting positions. By +// default iterators are unpositioned, since this avoids an extra seek in this +// situation where one of the seek methods (such as Locate) is immediately called. +type ShapeIndexIteratorPos int + +const ( + // IteratorBegin specifies the iterator should be positioned at the beginning of the index. + IteratorBegin ShapeIndexIteratorPos = iota + // IteratorEnd specifies the iterator should be positioned at the end of the index. + IteratorEnd +) + +// ShapeIndexIterator is an iterator that provides low-level access to +// the cells of the index. Cells are returned in increasing order of CellID. +// +// for it := index.Iterator(); !it.Done(); it.Next() { +// fmt.Print(it.CellID()) +// } +// +type ShapeIndexIterator struct { + index *ShapeIndex + position int + id CellID + cell *ShapeIndexCell +} + +// NewShapeIndexIterator creates a new iterator for the given index. If a starting +// position is specified, the iterator is positioned at the given spot. +func NewShapeIndexIterator(index *ShapeIndex, pos ...ShapeIndexIteratorPos) *ShapeIndexIterator { + s := &ShapeIndexIterator{ + index: index, + } + + if len(pos) > 0 { + if len(pos) > 1 { + panic("too many ShapeIndexIteratorPos arguments") + } + switch pos[0] { + case IteratorBegin: + s.Begin() + case IteratorEnd: + s.End() + default: + panic("unknown ShapeIndexIteratorPos value") + } + } + + return s +} + +func (s *ShapeIndexIterator) clone() *ShapeIndexIterator { + return &ShapeIndexIterator{ + index: s.index, + position: s.position, + id: s.id, + cell: s.cell, + } +} + +// CellID returns the CellID of the current index cell. +// If s.Done() is true, a value larger than any valid CellID is returned. +func (s *ShapeIndexIterator) CellID() CellID { + return s.id +} + +// IndexCell returns the current index cell. +func (s *ShapeIndexIterator) IndexCell() *ShapeIndexCell { + // TODO(roberts): C++ has this call a virtual method to allow subclasses + // of ShapeIndexIterator to do other work before returning the cell. Do + // we need such a thing? + return s.cell +} + +// Center returns the Point at the center of the current position of the iterator. +func (s *ShapeIndexIterator) Center() Point { + return s.CellID().Point() +} + +// Begin positions the iterator at the beginning of the index. +func (s *ShapeIndexIterator) Begin() { + if !s.index.IsFresh() { + s.index.maybeApplyUpdates() + } + s.position = 0 + s.refresh() +} + +// Next positions the iterator at the next index cell. +func (s *ShapeIndexIterator) Next() { + s.position++ + s.refresh() +} + +// Prev advances the iterator to the previous cell in the index and returns true to +// indicate it was not yet at the beginning of the index. If the iterator is at the +// first cell the call does nothing and returns false. +func (s *ShapeIndexIterator) Prev() bool { + if s.position <= 0 { + return false + } + + s.position-- + s.refresh() + return true +} + +// End positions the iterator at the end of the index. +func (s *ShapeIndexIterator) End() { + s.position = len(s.index.cells) + s.refresh() +} + +// Done reports if the iterator is positioned at or after the last index cell. +func (s *ShapeIndexIterator) Done() bool { + return s.id == SentinelCellID +} + +// refresh updates the stored internal iterator values. +func (s *ShapeIndexIterator) refresh() { + if s.position < len(s.index.cells) { + s.id = s.index.cells[s.position] + s.cell = s.index.cellMap[s.CellID()] + } else { + s.id = SentinelCellID + s.cell = nil + } +} + +// seek positions the iterator at the first cell whose ID >= target, or at the +// end of the index if no such cell exists. +func (s *ShapeIndexIterator) seek(target CellID) { + s.position = sort.Search(len(s.index.cells), func(i int) bool { + return s.index.cells[i] >= target + }) + s.refresh() +} + +// LocatePoint positions the iterator at the cell that contains the given Point. +// If no such cell exists, the iterator position is unspecified, and false is returned. +// The cell at the matched position is guaranteed to contain all edges that might +// intersect the line segment between target and the cell's center. +func (s *ShapeIndexIterator) LocatePoint(p Point) bool { + // Let I = cellMap.LowerBound(T), where T is the leaf cell containing + // point P. Then if T is contained by an index cell, then the + // containing cell is either I or I'. We test for containment by comparing + // the ranges of leaf cells spanned by T, I, and I'. + target := cellIDFromPoint(p) + s.seek(target) + if !s.Done() && s.CellID().RangeMin() <= target { + return true + } + + if s.Prev() && s.CellID().RangeMax() >= target { + return true + } + return false +} + +// LocateCellID attempts to position the iterator at the first matching index cell +// in the index that has some relation to the given CellID. Let T be the target CellID. +// If T is contained by (or equal to) some index cell I, then the iterator is positioned +// at I and returns Indexed. Otherwise if T contains one or more (smaller) index cells, +// then the iterator is positioned at the first such cell I and return Subdivided. +// Otherwise Disjoint is returned and the iterator position is undefined. +func (s *ShapeIndexIterator) LocateCellID(target CellID) CellRelation { + // Let T be the target, let I = cellMap.LowerBound(T.RangeMin()), and + // let I' be the predecessor of I. If T contains any index cells, then T + // contains I. Similarly, if T is contained by an index cell, then the + // containing cell is either I or I'. We test for containment by comparing + // the ranges of leaf cells spanned by T, I, and I'. + s.seek(target.RangeMin()) + if !s.Done() { + if s.CellID() >= target && s.CellID().RangeMin() <= target { + return Indexed + } + if s.CellID() <= target.RangeMax() { + return Subdivided + } + } + if s.Prev() && s.CellID().RangeMax() >= target { + return Indexed + } + return Disjoint +} + +// tracker keeps track of which shapes in a given set contain a particular point +// (the focus). It provides an efficient way to move the focus from one point +// to another and incrementally update the set of shapes which contain it. We use +// this to compute which shapes contain the center of every CellID in the index, +// by advancing the focus from one cell center to the next. +// +// Initially the focus is at the start of the CellID space-filling curve. We then +// visit all the cells that are being added to the ShapeIndex in increasing order +// of CellID. For each cell, we draw two edges: one from the entry vertex to the +// center, and another from the center to the exit vertex (where entry and exit +// refer to the points where the space-filling curve enters and exits the cell). +// By counting edge crossings we can incrementally compute which shapes contain +// the cell center. Note that the same set of shapes will always contain the exit +// point of one cell and the entry point of the next cell in the index, because +// either (a) these two points are actually the same, or (b) the intervening +// cells in CellID order are all empty, and therefore there are no edge crossings +// if we follow this path from one cell to the other. +// +// In C++, this is S2ShapeIndex::InteriorTracker. +type tracker struct { + isActive bool + a Point + b Point + nextCellID CellID + crosser *EdgeCrosser + shapeIDs []int32 + + // Shape ids saved by saveAndClearStateBefore. The state is never saved + // recursively so we don't need to worry about maintaining a stack. + savedIDs []int32 +} + +// newTracker returns a new tracker with the appropriate defaults. +func newTracker() *tracker { + // As shapes are added, we compute which ones contain the start of the + // CellID space-filling curve by drawing an edge from OriginPoint to this + // point and counting how many shape edges cross this edge. + t := &tracker{ + isActive: false, + b: trackerOrigin(), + nextCellID: CellIDFromFace(0).ChildBeginAtLevel(maxLevel), + } + t.drawTo(Point{faceUVToXYZ(0, -1, -1).Normalize()}) // CellID curve start + + return t +} + +// trackerOrigin returns the initial focus point when the tracker is created +// (corresponding to the start of the CellID space-filling curve). +func trackerOrigin() Point { + // The start of the S2CellId space-filling curve. + return Point{faceUVToXYZ(0, -1, -1).Normalize()} +} + +// focus returns the current focus point of the tracker. +func (t *tracker) focus() Point { return t.b } + +// addShape adds a shape whose interior should be tracked. containsOrigin indicates +// whether the current focus point is inside the shape. Alternatively, if +// the focus point is in the process of being moved (via moveTo/drawTo), you +// can also specify containsOrigin at the old focus point and call testEdge +// for every edge of the shape that might cross the current drawTo line. +// This updates the state to correspond to the new focus point. +// +// This requires shape.HasInterior +func (t *tracker) addShape(shapeID int32, containsFocus bool) { + t.isActive = true + if containsFocus { + t.toggleShape(shapeID) + } +} + +// moveTo moves the focus of the tracker to the given point. This method should +// only be used when it is known that there are no edge crossings between the old +// and new focus locations; otherwise use drawTo. +func (t *tracker) moveTo(b Point) { t.b = b } + +// drawTo moves the focus of the tracker to the given point. After this method is +// called, testEdge should be called with all edges that may cross the line +// segment between the old and new focus locations. +func (t *tracker) drawTo(b Point) { + t.a = t.b + t.b = b + // TODO: the edge crosser may need an in-place Init method if this gets expensive + t.crosser = NewEdgeCrosser(t.a, t.b) +} + +// testEdge checks if the given edge crosses the current edge, and if so, then +// toggle the state of the given shapeID. +// This requires shape to have an interior. +func (t *tracker) testEdge(shapeID int32, edge Edge) { + if t.crosser.EdgeOrVertexCrossing(edge.V0, edge.V1) { + t.toggleShape(shapeID) + } +} + +// setNextCellID is used to indicate that the last argument to moveTo or drawTo +// was the entry vertex of the given CellID, i.e. the tracker is positioned at the +// start of this cell. By using this method together with atCellID, the caller +// can avoid calling moveTo in cases where the exit vertex of the previous cell +// is the same as the entry vertex of the current cell. +func (t *tracker) setNextCellID(nextCellID CellID) { + t.nextCellID = nextCellID.RangeMin() +} + +// atCellID reports if the focus is already at the entry vertex of the given +// CellID (provided that the caller calls setNextCellID as each cell is processed). +func (t *tracker) atCellID(cellid CellID) bool { + return cellid.RangeMin() == t.nextCellID +} + +// toggleShape adds or removes the given shapeID from the set of IDs it is tracking. +func (t *tracker) toggleShape(shapeID int32) { + // Most shapeIDs slices are small, so special case the common steps. + + // If there is nothing here, add it. + if len(t.shapeIDs) == 0 { + t.shapeIDs = append(t.shapeIDs, shapeID) + return + } + + // If it's the first element, drop it from the slice. + if t.shapeIDs[0] == shapeID { + t.shapeIDs = t.shapeIDs[1:] + return + } + + for i, s := range t.shapeIDs { + if s < shapeID { + continue + } + + // If it's in the set, cut it out. + if s == shapeID { + copy(t.shapeIDs[i:], t.shapeIDs[i+1:]) // overwrite the ith element + t.shapeIDs = t.shapeIDs[:len(t.shapeIDs)-1] + return + } + + // We've got to a point in the slice where we should be inserted. + // (the given shapeID is now less than the current positions id.) + t.shapeIDs = append(t.shapeIDs[0:i], + append([]int32{shapeID}, t.shapeIDs[i:len(t.shapeIDs)]...)...) + return + } + + // We got to the end and didn't find it, so add it to the list. + t.shapeIDs = append(t.shapeIDs, shapeID) +} + +// saveAndClearStateBefore makes an internal copy of the state for shape ids below +// the given limit, and then clear the state for those shapes. This is used during +// incremental updates to track the state of added and removed shapes separately. +func (t *tracker) saveAndClearStateBefore(limitShapeID int32) { + limit := t.lowerBound(limitShapeID) + t.savedIDs = append([]int32(nil), t.shapeIDs[:limit]...) + t.shapeIDs = t.shapeIDs[limit:] +} + +// restoreStateBefore restores the state previously saved by saveAndClearStateBefore. +// This only affects the state for shapeIDs below "limitShapeID". +func (t *tracker) restoreStateBefore(limitShapeID int32) { + limit := t.lowerBound(limitShapeID) + t.shapeIDs = append(append([]int32(nil), t.savedIDs...), t.shapeIDs[limit:]...) + t.savedIDs = nil +} + +// lowerBound returns the shapeID of the first entry x where x >= shapeID. +func (t *tracker) lowerBound(shapeID int32) int32 { + panic("not implemented") +} + +// removedShape represents a set of edges from the given shape that is queued for removal. +type removedShape struct { + shapeID int32 + hasInterior bool + containsTrackerOrigin bool + edges []Edge +} + +// There are three basic states the index can be in. +const ( + stale int32 = iota // There are pending updates. + updating // Updates are currently being applied. + fresh // There are no pending updates. +) + +// ShapeIndex indexes a set of Shapes, where a Shape is some collection of edges +// that optionally defines an interior. It can be used to represent a set of +// points, a set of polylines, or a set of polygons. For Shapes that have +// interiors, the index makes it very fast to determine which Shape(s) contain +// a given point or region. +// +// The index can be updated incrementally by adding or removing shapes. It is +// designed to handle up to hundreds of millions of edges. All data structures +// are designed to be small, so the index is compact; generally it is smaller +// than the underlying data being indexed. The index is also fast to construct. +// +// Polygon, Loop, and Polyline implement Shape which allows these objects to +// be indexed easily. You can find useful query methods in CrossingEdgeQuery +// and ClosestEdgeQuery (Not yet implemented in Go). +// +// Example showing how to build an index of Polylines: +// +// index := NewShapeIndex() +// for _, polyline := range polylines { +// index.Add(polyline); +// } +// // Now you can use a CrossingEdgeQuery or ClosestEdgeQuery here. +// +type ShapeIndex struct { + // shapes is a map of shape ID to shape. + shapes map[int32]Shape + + // The maximum number of edges per cell. + // TODO(roberts): Update the comments when the usage of this is implemented. + maxEdgesPerCell int + + // nextID tracks the next ID to hand out. IDs are not reused when shapes + // are removed from the index. + nextID int32 + + // cellMap is a map from CellID to the set of clipped shapes that intersect that + // cell. The cell IDs cover a set of non-overlapping regions on the sphere. + // In C++, this is a BTree, so the cells are ordered naturally by the data structure. + cellMap map[CellID]*ShapeIndexCell + // Track the ordered list of cell IDs. + cells []CellID + + // The current status of the index; accessed atomically. + status int32 + + // Additions and removals are queued and processed on the first subsequent + // query. There are several reasons to do this: + // + // - It is significantly more efficient to process updates in batches if + // the amount of entities added grows. + // - Often the index will never be queried, in which case we can save both + // the time and memory required to build it. Examples: + // + Loops that are created simply to pass to an Polygon. (We don't + // need the Loop index, because Polygon builds its own index.) + // + Applications that load a database of geometry and then query only + // a small fraction of it. + // + // The main drawback is that we need to go to some extra work to ensure that + // some methods are still thread-safe. Note that the goal is *not* to + // make this thread-safe in general, but simply to hide the fact that + // we defer some of the indexing work until query time. + // + // This mutex protects all of following fields in the index. + mu sync.RWMutex + + // pendingAdditionsPos is the index of the first entry that has not been processed + // via applyUpdatesInternal. + pendingAdditionsPos int32 + + // The set of shapes that have been queued for removal but not processed yet by + // applyUpdatesInternal. + pendingRemovals []*removedShape +} + +// NewShapeIndex creates a new ShapeIndex. +func NewShapeIndex() *ShapeIndex { + return &ShapeIndex{ + maxEdgesPerCell: 10, + shapes: make(map[int32]Shape), + cellMap: make(map[CellID]*ShapeIndexCell), + cells: nil, + status: fresh, + } +} + +// Iterator returns an iterator for this index. +func (s *ShapeIndex) Iterator() *ShapeIndexIterator { + s.maybeApplyUpdates() + return NewShapeIndexIterator(s, IteratorBegin) +} + +// Begin positions the iterator at the first cell in the index. +func (s *ShapeIndex) Begin() *ShapeIndexIterator { + s.maybeApplyUpdates() + return NewShapeIndexIterator(s, IteratorBegin) +} + +// End positions the iterator at the last cell in the index. +func (s *ShapeIndex) End() *ShapeIndexIterator { + // TODO(roberts): It's possible that updates could happen to the index between + // the time this is called and the time the iterators position is used and this + // will be invalid or not the end. For now, things will be undefined if this + // happens. See about referencing the IsFresh to guard for this in the future. + s.maybeApplyUpdates() + return NewShapeIndexIterator(s, IteratorEnd) +} + +// Len reports the number of Shapes in this index. +func (s *ShapeIndex) Len() int { + return len(s.shapes) +} + +// Reset resets the index to its original state. +func (s *ShapeIndex) Reset() { + s.shapes = make(map[int32]Shape) + s.nextID = 0 + s.cellMap = make(map[CellID]*ShapeIndexCell) + s.cells = nil + atomic.StoreInt32(&s.status, fresh) +} + +// NumEdges returns the number of edges in this index. +func (s *ShapeIndex) NumEdges() int { + numEdges := 0 + for _, shape := range s.shapes { + numEdges += shape.NumEdges() + } + return numEdges +} + +// NumEdgesUpTo returns the number of edges in the given index, up to the given +// limit. If the limit is encountered, the current running total is returned, +// which may be more than the limit. +func (s *ShapeIndex) NumEdgesUpTo(limit int) int { + var numEdges int + // We choose to iterate over the shapes in order to match the counting + // up behavior in C++ and for test compatibility instead of using a + // more idiomatic range over the shape map. + for i := int32(0); i <= s.nextID; i++ { + s := s.Shape(i) + if s == nil { + continue + } + numEdges += s.NumEdges() + if numEdges >= limit { + break + } + } + + return numEdges +} + +// Shape returns the shape with the given ID, or nil if the shape has been removed from the index. +func (s *ShapeIndex) Shape(id int32) Shape { return s.shapes[id] } + +// idForShape returns the id of the given shape in this index, or -1 if it is +// not in the index. +// +// TODO(roberts): Need to figure out an appropriate way to expose this on a Shape. +// C++ allows a given S2 type (Loop, Polygon, etc) to be part of multiple indexes. +// By having each type extend S2Shape which has an id element, they all inherit their +// own id field rather than having to track it themselves. +func (s *ShapeIndex) idForShape(shape Shape) int32 { + for k, v := range s.shapes { + if v == shape { + return k + } + } + return -1 +} + +// Add adds the given shape to the index and returns the assigned ID.. +func (s *ShapeIndex) Add(shape Shape) int32 { + s.shapes[s.nextID] = shape + s.nextID++ + atomic.StoreInt32(&s.status, stale) + return s.nextID - 1 +} + +// Remove removes the given shape from the index. +func (s *ShapeIndex) Remove(shape Shape) { + // The index updates itself lazily because it is much more efficient to + // process additions and removals in batches. + id := s.idForShape(shape) + + // If the shape wasn't found, it's already been removed or was not in the index. + if s.shapes[id] == nil { + return + } + + // Remove the shape from the shapes map. + delete(s.shapes, id) + + // We are removing a shape that has not yet been added to the index, + // so there is nothing else to do. + if id >= s.pendingAdditionsPos { + return + } + + numEdges := shape.NumEdges() + removed := &removedShape{ + shapeID: id, + hasInterior: shape.Dimension() == 2, + containsTrackerOrigin: shape.ReferencePoint().Contained, + edges: make([]Edge, numEdges), + } + + for e := 0; e < numEdges; e++ { + removed.edges[e] = shape.Edge(e) + } + + s.pendingRemovals = append(s.pendingRemovals, removed) + atomic.StoreInt32(&s.status, stale) +} + +// Build triggers the update of the index. Calls to Add and Release are normally +// queued and processed on the first subsequent query. This has many advantages, +// the most important of which is that sometimes there *is* no subsequent +// query, which lets us avoid building the index completely. +// +// This method forces any pending updates to be applied immediately. +func (s *ShapeIndex) Build() { + s.maybeApplyUpdates() +} + +// IsFresh reports if there are no pending updates that need to be applied. +// This can be useful to avoid building the index unnecessarily, or for +// choosing between two different algorithms depending on whether the index +// is available. +// +// The returned index status may be slightly out of date if the index was +// built in a different thread. This is fine for the intended use (as an +// efficiency hint), but it should not be used by internal methods. +func (s *ShapeIndex) IsFresh() bool { + return atomic.LoadInt32(&s.status) == fresh +} + +// isFirstUpdate reports if this is the first update to the index. +func (s *ShapeIndex) isFirstUpdate() bool { + // Note that it is not sufficient to check whether cellMap is empty, since + // entries are added to it during the update process. + return s.pendingAdditionsPos == 0 +} + +// isShapeBeingRemoved reports if the shape with the given ID is currently slated for removal. +func (s *ShapeIndex) isShapeBeingRemoved(shapeID int32) bool { + // All shape ids being removed fall below the index position of shapes being added. + return shapeID < s.pendingAdditionsPos +} + +// maybeApplyUpdates checks if the index pieces have changed, and if so, applies pending updates. +func (s *ShapeIndex) maybeApplyUpdates() { + // TODO(roberts): To avoid acquiring and releasing the mutex on every + // query, we should use atomic operations when testing whether the status + // is fresh and when updating the status to be fresh. This guarantees + // that any thread that sees a status of fresh will also see the + // corresponding index updates. + if atomic.LoadInt32(&s.status) != fresh { + s.mu.Lock() + s.applyUpdatesInternal() + atomic.StoreInt32(&s.status, fresh) + s.mu.Unlock() + } +} + +// applyUpdatesInternal does the actual work of updating the index by applying all +// pending additions and removals. It does *not* update the indexes status. +func (s *ShapeIndex) applyUpdatesInternal() { + // TODO(roberts): Building the index can use up to 20x as much memory per + // edge as the final index memory size. If this causes issues, add in + // batched updating to limit the amount of items per batch to a + // configurable memory footprint overhead. + t := newTracker() + + // allEdges maps a Face to a collection of faceEdges. + allEdges := make([][]faceEdge, 6) + + for _, p := range s.pendingRemovals { + s.removeShapeInternal(p, allEdges, t) + } + + for id := s.pendingAdditionsPos; id < int32(len(s.shapes)); id++ { + s.addShapeInternal(id, allEdges, t) + } + + for face := 0; face < 6; face++ { + s.updateFaceEdges(face, allEdges[face], t) + } + + s.pendingRemovals = s.pendingRemovals[:0] + s.pendingAdditionsPos = int32(len(s.shapes)) + // It is the caller's responsibility to update the index status. +} + +// addShapeInternal clips all edges of the given shape to the six cube faces, +// adds the clipped edges to the set of allEdges, and starts tracking its +// interior if necessary. +func (s *ShapeIndex) addShapeInternal(shapeID int32, allEdges [][]faceEdge, t *tracker) { + shape, ok := s.shapes[shapeID] + if !ok { + // This shape has already been removed. + return + } + + faceEdge := faceEdge{ + shapeID: shapeID, + hasInterior: shape.Dimension() == 2, + } + + if faceEdge.hasInterior { + t.addShape(shapeID, containsBruteForce(shape, t.focus())) + } + + numEdges := shape.NumEdges() + for e := 0; e < numEdges; e++ { + edge := shape.Edge(e) + + faceEdge.edgeID = e + faceEdge.edge = edge + faceEdge.maxLevel = maxLevelForEdge(edge) + s.addFaceEdge(faceEdge, allEdges) + } +} + +// addFaceEdge adds the given faceEdge into the collection of all edges. +func (s *ShapeIndex) addFaceEdge(fe faceEdge, allEdges [][]faceEdge) { + aFace := face(fe.edge.V0.Vector) + // See if both endpoints are on the same face, and are far enough from + // the edge of the face that they don't intersect any (padded) adjacent face. + if aFace == face(fe.edge.V1.Vector) { + x, y := validFaceXYZToUV(aFace, fe.edge.V0.Vector) + fe.a = r2.Point{x, y} + x, y = validFaceXYZToUV(aFace, fe.edge.V1.Vector) + fe.b = r2.Point{x, y} + + maxUV := 1 - cellPadding + if math.Abs(fe.a.X) <= maxUV && math.Abs(fe.a.Y) <= maxUV && + math.Abs(fe.b.X) <= maxUV && math.Abs(fe.b.Y) <= maxUV { + allEdges[aFace] = append(allEdges[aFace], fe) + return + } + } + + // Otherwise, we simply clip the edge to all six faces. + for face := 0; face < 6; face++ { + if aClip, bClip, intersects := ClipToPaddedFace(fe.edge.V0, fe.edge.V1, face, cellPadding); intersects { + fe.a = aClip + fe.b = bClip + allEdges[face] = append(allEdges[face], fe) + } + } +} + +// updateFaceEdges adds or removes the various edges from the index. +// An edge is added if shapes[id] is not nil, and removed otherwise. +func (s *ShapeIndex) updateFaceEdges(face int, faceEdges []faceEdge, t *tracker) { + numEdges := len(faceEdges) + if numEdges == 0 && len(t.shapeIDs) == 0 { + return + } + + // Create the initial clippedEdge for each faceEdge. Additional clipped + // edges are created when edges are split between child cells. We create + // two arrays, one containing the edge data and another containing pointers + // to those edges, so that during the recursion we only need to copy + // pointers in order to propagate an edge to the correct child. + clippedEdges := make([]*clippedEdge, numEdges) + bound := r2.EmptyRect() + for e := 0; e < numEdges; e++ { + clipped := &clippedEdge{ + faceEdge: &faceEdges[e], + } + clipped.bound = r2.RectFromPoints(faceEdges[e].a, faceEdges[e].b) + clippedEdges[e] = clipped + bound = bound.AddRect(clipped.bound) + } + + // Construct the initial face cell containing all the edges, and then update + // all the edges in the index recursively. + faceID := CellIDFromFace(face) + pcell := PaddedCellFromCellID(faceID, cellPadding) + + disjointFromIndex := s.isFirstUpdate() + if numEdges > 0 { + shrunkID := s.shrinkToFit(pcell, bound) + if shrunkID != pcell.id { + // All the edges are contained by some descendant of the face cell. We + // can save a lot of work by starting directly with that cell, but if we + // are in the interior of at least one shape then we need to create + // index entries for the cells we are skipping over. + s.skipCellRange(faceID.RangeMin(), shrunkID.RangeMin(), t, disjointFromIndex) + pcell = PaddedCellFromCellID(shrunkID, cellPadding) + s.updateEdges(pcell, clippedEdges, t, disjointFromIndex) + s.skipCellRange(shrunkID.RangeMax().Next(), faceID.RangeMax().Next(), t, disjointFromIndex) + return + } + } + + // Otherwise (no edges, or no shrinking is possible), subdivide normally. + s.updateEdges(pcell, clippedEdges, t, disjointFromIndex) +} + +// shrinkToFit shrinks the PaddedCell to fit within the given bounds. +func (s *ShapeIndex) shrinkToFit(pcell *PaddedCell, bound r2.Rect) CellID { + shrunkID := pcell.ShrinkToFit(bound) + + if !s.isFirstUpdate() && shrunkID != pcell.CellID() { + // Don't shrink any smaller than the existing index cells, since we need + // to combine the new edges with those cells. + iter := s.Iterator() + if iter.LocateCellID(shrunkID) == Indexed { + shrunkID = iter.CellID() + } + } + return shrunkID +} + +// skipCellRange skips over the cells in the given range, creating index cells if we are +// currently in the interior of at least one shape. +func (s *ShapeIndex) skipCellRange(begin, end CellID, t *tracker, disjointFromIndex bool) { + // If we aren't in the interior of a shape, then skipping over cells is easy. + if len(t.shapeIDs) == 0 { + return + } + + // Otherwise generate the list of cell ids that we need to visit, and create + // an index entry for each one. + skipped := CellUnionFromRange(begin, end) + for _, cell := range skipped { + var clippedEdges []*clippedEdge + s.updateEdges(PaddedCellFromCellID(cell, cellPadding), clippedEdges, t, disjointFromIndex) + } +} + +// updateEdges adds or removes the given edges whose bounding boxes intersect a +// given cell. disjointFromIndex is an optimization hint indicating that cellMap +// does not contain any entries that overlap the given cell. +func (s *ShapeIndex) updateEdges(pcell *PaddedCell, edges []*clippedEdge, t *tracker, disjointFromIndex bool) { + // This function is recursive with a maximum recursion depth of 30 (maxLevel). + + // Incremental updates are handled as follows. All edges being added or + // removed are combined together in edges, and all shapes with interiors + // are tracked using tracker. We subdivide recursively as usual until we + // encounter an existing index cell. At this point we absorb the index + // cell as follows: + // + // - Edges and shapes that are being removed are deleted from edges and + // tracker. + // - All remaining edges and shapes from the index cell are added to + // edges and tracker. + // - Continue subdividing recursively, creating new index cells as needed. + // - When the recursion gets back to the cell that was absorbed, we + // restore edges and tracker to their previous state. + // + // Note that the only reason that we include removed shapes in the recursive + // subdivision process is so that we can find all of the index cells that + // contain those shapes efficiently, without maintaining an explicit list of + // index cells for each shape (which would be expensive in terms of memory). + indexCellAbsorbed := false + if !disjointFromIndex { + // There may be existing index cells contained inside pcell. If we + // encounter such a cell, we need to combine the edges being updated with + // the existing cell contents by absorbing the cell. + iter := s.Iterator() + r := iter.LocateCellID(pcell.id) + if r == Disjoint { + disjointFromIndex = true + } else if r == Indexed { + // Absorb the index cell by transferring its contents to edges and + // deleting it. We also start tracking the interior of any new shapes. + s.absorbIndexCell(pcell, iter, edges, t) + indexCellAbsorbed = true + disjointFromIndex = true + } else { + // DCHECK_EQ(SUBDIVIDED, r) + } + } + + // If there are existing index cells below us, then we need to keep + // subdividing so that we can merge with those cells. Otherwise, + // makeIndexCell checks if the number of edges is small enough, and creates + // an index cell if possible (returning true when it does so). + if !disjointFromIndex || !s.makeIndexCell(pcell, edges, t) { + // TODO(roberts): If it turns out to have memory problems when there + // are 10M+ edges in the index, look into pre-allocating space so we + // are not always appending. + childEdges := [2][2][]*clippedEdge{} // [i][j] + + // Compute the middle of the padded cell, defined as the rectangle in + // (u,v)-space that belongs to all four (padded) children. By comparing + // against the four boundaries of middle we can determine which children + // each edge needs to be propagated to. + middle := pcell.Middle() + + // Build up a vector edges to be passed to each child cell. The (i,j) + // directions are left (i=0), right (i=1), lower (j=0), and upper (j=1). + // Note that the vast majority of edges are propagated to a single child. + for _, edge := range edges { + if edge.bound.X.Hi <= middle.X.Lo { + // Edge is entirely contained in the two left children. + a, b := s.clipVAxis(edge, middle.Y) + if a != nil { + childEdges[0][0] = append(childEdges[0][0], a) + } + if b != nil { + childEdges[0][1] = append(childEdges[0][1], b) + } + } else if edge.bound.X.Lo >= middle.X.Hi { + // Edge is entirely contained in the two right children. + a, b := s.clipVAxis(edge, middle.Y) + if a != nil { + childEdges[1][0] = append(childEdges[1][0], a) + } + if b != nil { + childEdges[1][1] = append(childEdges[1][1], b) + } + } else if edge.bound.Y.Hi <= middle.Y.Lo { + // Edge is entirely contained in the two lower children. + if a := s.clipUBound(edge, 1, middle.X.Hi); a != nil { + childEdges[0][0] = append(childEdges[0][0], a) + } + if b := s.clipUBound(edge, 0, middle.X.Lo); b != nil { + childEdges[1][0] = append(childEdges[1][0], b) + } + } else if edge.bound.Y.Lo >= middle.Y.Hi { + // Edge is entirely contained in the two upper children. + if a := s.clipUBound(edge, 1, middle.X.Hi); a != nil { + childEdges[0][1] = append(childEdges[0][1], a) + } + if b := s.clipUBound(edge, 0, middle.X.Lo); b != nil { + childEdges[1][1] = append(childEdges[1][1], b) + } + } else { + // The edge bound spans all four children. The edge + // itself intersects either three or four padded children. + left := s.clipUBound(edge, 1, middle.X.Hi) + a, b := s.clipVAxis(left, middle.Y) + if a != nil { + childEdges[0][0] = append(childEdges[0][0], a) + } + if b != nil { + childEdges[0][1] = append(childEdges[0][1], b) + } + right := s.clipUBound(edge, 0, middle.X.Lo) + a, b = s.clipVAxis(right, middle.Y) + if a != nil { + childEdges[1][0] = append(childEdges[1][0], a) + } + if b != nil { + childEdges[1][1] = append(childEdges[1][1], b) + } + } + } + + // Now recursively update the edges in each child. We call the children in + // increasing order of CellID so that when the index is first constructed, + // all insertions into cellMap are at the end (which is much faster). + for pos := 0; pos < 4; pos++ { + i, j := pcell.ChildIJ(pos) + if len(childEdges[i][j]) > 0 || len(t.shapeIDs) > 0 { + s.updateEdges(PaddedCellFromParentIJ(pcell, i, j), childEdges[i][j], + t, disjointFromIndex) + } + } + } + + if indexCellAbsorbed { + // Restore the state for any edges being removed that we are tracking. + t.restoreStateBefore(s.pendingAdditionsPos) + } +} + +// makeIndexCell builds an indexCell from the given padded cell and set of edges and adds +// it to the index. If the cell or edges are empty, no cell is added. +func (s *ShapeIndex) makeIndexCell(p *PaddedCell, edges []*clippedEdge, t *tracker) bool { + // If the cell is empty, no index cell is needed. (In most cases this + // situation is detected before we get to this point, but this can happen + // when all shapes in a cell are removed.) + if len(edges) == 0 && len(t.shapeIDs) == 0 { + return true + } + + // Count the number of edges that have not reached their maximum level yet. + // Return false if there are too many such edges. + count := 0 + for _, ce := range edges { + if p.Level() < ce.faceEdge.maxLevel { + count++ + } + + if count > s.maxEdgesPerCell { + return false + } + } + + // Possible optimization: Continue subdividing as long as exactly one child + // of the padded cell intersects the given edges. This can be done by finding + // the bounding box of all the edges and calling ShrinkToFit: + // + // cellID = p.ShrinkToFit(RectBound(edges)); + // + // Currently this is not beneficial; it slows down construction by 4-25% + // (mainly computing the union of the bounding rectangles) and also slows + // down queries (since more recursive clipping is required to get down to + // the level of a spatial index cell). But it may be worth trying again + // once containsCenter is computed and all algorithms are modified to + // take advantage of it. + + // We update the InteriorTracker as follows. For every Cell in the index + // we construct two edges: one edge from entry vertex of the cell to its + // center, and one from the cell center to its exit vertex. Here entry + // and exit refer the CellID ordering, i.e. the order in which points + // are encountered along the 2 space-filling curve. The exit vertex then + // becomes the entry vertex for the next cell in the index, unless there are + // one or more empty intervening cells, in which case the InteriorTracker + // state is unchanged because the intervening cells have no edges. + + // Shift the InteriorTracker focus point to the center of the current cell. + if t.isActive && len(edges) != 0 { + if !t.atCellID(p.id) { + t.moveTo(p.EntryVertex()) + } + t.drawTo(p.Center()) + s.testAllEdges(edges, t) + } + + // Allocate and fill a new index cell. To get the total number of shapes we + // need to merge the shapes associated with the intersecting edges together + // with the shapes that happen to contain the cell center. + cshapeIDs := t.shapeIDs + numShapes := s.countShapes(edges, cshapeIDs) + cell := NewShapeIndexCell(numShapes) + + // To fill the index cell we merge the two sources of shapes: edge shapes + // (those that have at least one edge that intersects this cell), and + // containing shapes (those that contain the cell center). We keep track + // of the index of the next intersecting edge and the next containing shape + // as we go along. Both sets of shape ids are already sorted. + eNext := 0 + cNextIdx := 0 + for i := 0; i < numShapes; i++ { + var clipped *clippedShape + // advance to next value base + i + eshapeID := int32(s.Len()) + cshapeID := eshapeID // Sentinels + + if eNext != len(edges) { + eshapeID = edges[eNext].faceEdge.shapeID + } + if cNextIdx < len(cshapeIDs) { + cshapeID = cshapeIDs[cNextIdx] + } + eBegin := eNext + if cshapeID < eshapeID { + // The entire cell is in the shape interior. + clipped = newClippedShape(cshapeID, 0) + clipped.containsCenter = true + cNextIdx++ + } else { + // Count the number of edges for this shape and allocate space for them. + for eNext < len(edges) && edges[eNext].faceEdge.shapeID == eshapeID { + eNext++ + } + clipped = newClippedShape(eshapeID, eNext-eBegin) + for e := eBegin; e < eNext; e++ { + clipped.edges[e-eBegin] = edges[e].faceEdge.edgeID + } + if cshapeID == eshapeID { + clipped.containsCenter = true + cNextIdx++ + } + } + cell.shapes[i] = clipped + } + + // Add this cell to the map. + s.cellMap[p.id] = cell + s.cells = append(s.cells, p.id) + + // Shift the tracker focus point to the exit vertex of this cell. + if t.isActive && len(edges) != 0 { + t.drawTo(p.ExitVertex()) + s.testAllEdges(edges, t) + t.setNextCellID(p.id.Next()) + } + return true +} + +// updateBound updates the specified endpoint of the given clipped edge and returns the +// resulting clipped edge. +func (s *ShapeIndex) updateBound(edge *clippedEdge, uEnd int, u float64, vEnd int, v float64) *clippedEdge { + c := &clippedEdge{faceEdge: edge.faceEdge} + if uEnd == 0 { + c.bound.X.Lo = u + c.bound.X.Hi = edge.bound.X.Hi + } else { + c.bound.X.Lo = edge.bound.X.Lo + c.bound.X.Hi = u + } + + if vEnd == 0 { + c.bound.Y.Lo = v + c.bound.Y.Hi = edge.bound.Y.Hi + } else { + c.bound.Y.Lo = edge.bound.Y.Lo + c.bound.Y.Hi = v + } + + return c +} + +// clipUBound clips the given endpoint (lo=0, hi=1) of the u-axis so that +// it does not extend past the given value of the given edge. +func (s *ShapeIndex) clipUBound(edge *clippedEdge, uEnd int, u float64) *clippedEdge { + // First check whether the edge actually requires any clipping. (Sometimes + // this method is called when clipping is not necessary, e.g. when one edge + // endpoint is in the overlap area between two padded child cells.) + if uEnd == 0 { + if edge.bound.X.Lo >= u { + return edge + } + } else { + if edge.bound.X.Hi <= u { + return edge + } + } + // We interpolate the new v-value from the endpoints of the original edge. + // This has two advantages: (1) we don't need to store the clipped endpoints + // at all, just their bounding box; and (2) it avoids the accumulation of + // roundoff errors due to repeated interpolations. The result needs to be + // clamped to ensure that it is in the appropriate range. + e := edge.faceEdge + v := edge.bound.Y.ClampPoint(interpolateFloat64(u, e.a.X, e.b.X, e.a.Y, e.b.Y)) + + // Determine which endpoint of the v-axis bound to update. If the edge + // slope is positive we update the same endpoint, otherwise we update the + // opposite endpoint. + var vEnd int + positiveSlope := (e.a.X > e.b.X) == (e.a.Y > e.b.Y) + if (uEnd == 1) == positiveSlope { + vEnd = 1 + } + return s.updateBound(edge, uEnd, u, vEnd, v) +} + +// clipVBound clips the given endpoint (lo=0, hi=1) of the v-axis so that +// it does not extend past the given value of the given edge. +func (s *ShapeIndex) clipVBound(edge *clippedEdge, vEnd int, v float64) *clippedEdge { + if vEnd == 0 { + if edge.bound.Y.Lo >= v { + return edge + } + } else { + if edge.bound.Y.Hi <= v { + return edge + } + } + + // We interpolate the new v-value from the endpoints of the original edge. + // This has two advantages: (1) we don't need to store the clipped endpoints + // at all, just their bounding box; and (2) it avoids the accumulation of + // roundoff errors due to repeated interpolations. The result needs to be + // clamped to ensure that it is in the appropriate range. + e := edge.faceEdge + u := edge.bound.X.ClampPoint(interpolateFloat64(v, e.a.Y, e.b.Y, e.a.X, e.b.X)) + + // Determine which endpoint of the v-axis bound to update. If the edge + // slope is positive we update the same endpoint, otherwise we update the + // opposite endpoint. + var uEnd int + positiveSlope := (e.a.X > e.b.X) == (e.a.Y > e.b.Y) + if (vEnd == 1) == positiveSlope { + uEnd = 1 + } + return s.updateBound(edge, uEnd, u, vEnd, v) +} + +// cliupVAxis returns the given edge clipped to within the boundaries of the middle +// interval along the v-axis, and adds the result to its children. +func (s *ShapeIndex) clipVAxis(edge *clippedEdge, middle r1.Interval) (a, b *clippedEdge) { + if edge.bound.Y.Hi <= middle.Lo { + // Edge is entirely contained in the lower child. + return edge, nil + } else if edge.bound.Y.Lo >= middle.Hi { + // Edge is entirely contained in the upper child. + return nil, edge + } + // The edge bound spans both children. + return s.clipVBound(edge, 1, middle.Hi), s.clipVBound(edge, 0, middle.Lo) +} + +// absorbIndexCell absorbs an index cell by transferring its contents to edges +// and/or "tracker", and then delete this cell from the index. If edges includes +// any edges that are being removed, this method also updates their +// InteriorTracker state to correspond to the exit vertex of this cell. +func (s *ShapeIndex) absorbIndexCell(p *PaddedCell, iter *ShapeIndexIterator, edges []*clippedEdge, t *tracker) { + // When we absorb a cell, we erase all the edges that are being removed. + // However when we are finished with this cell, we want to restore the state + // of those edges (since that is how we find all the index cells that need + // to be updated). The edges themselves are restored automatically when + // UpdateEdges returns from its recursive call, but the InteriorTracker + // state needs to be restored explicitly. + // + // Here we first update the InteriorTracker state for removed edges to + // correspond to the exit vertex of this cell, and then save the + // InteriorTracker state. This state will be restored by UpdateEdges when + // it is finished processing the contents of this cell. + if t.isActive && len(edges) != 0 && s.isShapeBeingRemoved(edges[0].faceEdge.shapeID) { + // We probably need to update the tracker. ("Probably" because + // it's possible that all shapes being removed do not have interiors.) + if !t.atCellID(p.id) { + t.moveTo(p.EntryVertex()) + } + t.drawTo(p.ExitVertex()) + t.setNextCellID(p.id.Next()) + for _, edge := range edges { + fe := edge.faceEdge + if !s.isShapeBeingRemoved(fe.shapeID) { + break // All shapes being removed come first. + } + if fe.hasInterior { + t.testEdge(fe.shapeID, fe.edge) + } + } + } + + // Save the state of the edges being removed, so that it can be restored + // when we are finished processing this cell and its children. We don't + // need to save the state of the edges being added because they aren't being + // removed from "edges" and will therefore be updated normally as we visit + // this cell and its children. + t.saveAndClearStateBefore(s.pendingAdditionsPos) + + // Create a faceEdge for each edge in this cell that isn't being removed. + var faceEdges []*faceEdge + trackerMoved := false + + cell := iter.IndexCell() + for _, clipped := range cell.shapes { + shapeID := clipped.shapeID + shape := s.Shape(shapeID) + if shape == nil { + continue // This shape is being removed. + } + + numClipped := clipped.numEdges() + + // If this shape has an interior, start tracking whether we are inside the + // shape. updateEdges wants to know whether the entry vertex of this + // cell is inside the shape, but we only know whether the center of the + // cell is inside the shape, so we need to test all the edges against the + // line segment from the cell center to the entry vertex. + edge := &faceEdge{ + shapeID: shapeID, + hasInterior: shape.Dimension() == 2, + } + + if edge.hasInterior { + t.addShape(shapeID, clipped.containsCenter) + // There might not be any edges in this entire cell (i.e., it might be + // in the interior of all shapes), so we delay updating the tracker + // until we see the first edge. + if !trackerMoved && numClipped > 0 { + t.moveTo(p.Center()) + t.drawTo(p.EntryVertex()) + t.setNextCellID(p.id) + trackerMoved = true + } + } + for i := 0; i < numClipped; i++ { + edgeID := clipped.edges[i] + edge.edgeID = edgeID + edge.edge = shape.Edge(edgeID) + edge.maxLevel = maxLevelForEdge(edge.edge) + if edge.hasInterior { + t.testEdge(shapeID, edge.edge) + } + var ok bool + edge.a, edge.b, ok = ClipToPaddedFace(edge.edge.V0, edge.edge.V1, p.id.Face(), cellPadding) + if !ok { + panic("invariant failure in ShapeIndex") + } + faceEdges = append(faceEdges, edge) + } + } + // Now create a clippedEdge for each faceEdge, and put them in "new_edges". + var newEdges []*clippedEdge + for _, faceEdge := range faceEdges { + clipped := &clippedEdge{ + faceEdge: faceEdge, + bound: clippedEdgeBound(faceEdge.a, faceEdge.b, p.bound), + } + newEdges = append(newEdges, clipped) + } + + // Discard any edges from "edges" that are being removed, and append the + // remainder to "newEdges" (This keeps the edges sorted by shape id.) + for i, clipped := range edges { + if !s.isShapeBeingRemoved(clipped.faceEdge.shapeID) { + newEdges = append(newEdges, edges[i:]...) + break + } + } + + // Update the edge list and delete this cell from the index. + edges, newEdges = newEdges, edges + delete(s.cellMap, p.id) + // TODO(roberts): delete from s.Cells +} + +// testAllEdges calls the trackers testEdge on all edges from shapes that have interiors. +func (s *ShapeIndex) testAllEdges(edges []*clippedEdge, t *tracker) { + for _, edge := range edges { + if edge.faceEdge.hasInterior { + t.testEdge(edge.faceEdge.shapeID, edge.faceEdge.edge) + } + } +} + +// countShapes reports the number of distinct shapes that are either associated with the +// given edges, or that are currently stored in the InteriorTracker. +func (s *ShapeIndex) countShapes(edges []*clippedEdge, shapeIDs []int32) int { + count := 0 + lastShapeID := int32(-1) + + // next clipped shape id in the shapeIDs list. + clippedNext := int32(0) + // index of the current element in the shapeIDs list. + shapeIDidx := 0 + for _, edge := range edges { + if edge.faceEdge.shapeID == lastShapeID { + continue + } + + count++ + lastShapeID = edge.faceEdge.shapeID + + // Skip over any containing shapes up to and including this one, + // updating count as appropriate. + for ; shapeIDidx < len(shapeIDs); shapeIDidx++ { + clippedNext = shapeIDs[shapeIDidx] + if clippedNext > lastShapeID { + break + } + if clippedNext < lastShapeID { + count++ + } + } + } + + // Count any remaining containing shapes. + count += len(shapeIDs) - shapeIDidx + return count +} + +// maxLevelForEdge reports the maximum level for a given edge. +func maxLevelForEdge(edge Edge) int { + // Compute the maximum cell size for which this edge is considered long. + // The calculation does not need to be perfectly accurate, so we use Norm + // rather than Angle for speed. + cellSize := edge.V0.Sub(edge.V1.Vector).Norm() * cellSizeToLongEdgeRatio + // Now return the first level encountered during subdivision where the + // average cell size is at most cellSize. + return AvgEdgeMetric.MinLevel(cellSize) +} + +// removeShapeInternal does the actual work for removing a given shape from the index. +func (s *ShapeIndex) removeShapeInternal(removed *removedShape, allEdges [][]faceEdge, t *tracker) { + // TODO(roberts): finish the implementation of this. +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/shapeutil.go b/backend/vendor/github.com/blevesearch/geo/s2/shapeutil.go new file mode 100644 index 0000000000..64245dfa1a --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/shapeutil.go @@ -0,0 +1,228 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +// CrossingType defines different ways of reporting edge intersections. +type CrossingType int + +const ( + // CrossingTypeInterior reports intersections that occur at a point + // interior to both edges (i.e., not at a vertex). + CrossingTypeInterior CrossingType = iota + + // CrossingTypeAll reports all intersections, even those where two edges + // intersect only because they share a common vertex. + CrossingTypeAll + + // CrossingTypeNonAdjacent reports all intersections except for pairs of + // the form (AB, BC) where both edges are from the same ShapeIndex. + CrossingTypeNonAdjacent +) + +// rangeIterator is a wrapper over ShapeIndexIterator with extra methods +// that are useful for merging the contents of two or more ShapeIndexes. +type rangeIterator struct { + it *ShapeIndexIterator + // The min and max leaf cell ids covered by the current cell. If done() is + // true, these methods return a value larger than any valid cell id. + rangeMin CellID + rangeMax CellID +} + +// newRangeIterator creates a new rangeIterator positioned at the first cell of the given index. +func newRangeIterator(index *ShapeIndex) *rangeIterator { + r := &rangeIterator{ + it: index.Iterator(), + } + r.refresh() + return r +} + +func (r *rangeIterator) cellID() CellID { return r.it.CellID() } +func (r *rangeIterator) indexCell() *ShapeIndexCell { return r.it.IndexCell() } +func (r *rangeIterator) next() { r.it.Next(); r.refresh() } +func (r *rangeIterator) done() bool { return r.it.Done() } + +// seekTo positions the iterator at the first cell that overlaps or follows +// the current range minimum of the target iterator, i.e. such that its +// rangeMax >= target.rangeMin. +func (r *rangeIterator) seekTo(target *rangeIterator) { + r.it.seek(target.rangeMin) + // If the current cell does not overlap target, it is possible that the + // previous cell is the one we are looking for. This can only happen when + // the previous cell contains target but has a smaller CellID. + if r.it.Done() || r.it.CellID().RangeMin() > target.rangeMax { + if r.it.Prev() && r.it.CellID().RangeMax() < target.cellID() { + r.it.Next() + } + } + r.refresh() +} + +// seekBeyond positions the iterator at the first cell that follows the current +// range minimum of the target iterator. i.e. the first cell such that its +// rangeMin > target.rangeMax. +func (r *rangeIterator) seekBeyond(target *rangeIterator) { + r.it.seek(target.rangeMax.Next()) + if !r.it.Done() && r.it.CellID().RangeMin() <= target.rangeMax { + r.it.Next() + } + r.refresh() +} + +// refresh updates the iterators min and max values. +func (r *rangeIterator) refresh() { + r.rangeMin = r.cellID().RangeMin() + r.rangeMax = r.cellID().RangeMax() +} + +// referencePointForShape is a helper function for implementing various Shapes +// ReferencePoint functions. +// +// Given a shape consisting of closed polygonal loops, the interior of the +// shape is defined as the region to the left of all edges (which must be +// oriented consistently). This function then chooses an arbitrary point and +// returns true if that point is contained by the shape. +// +// Unlike Loop and Polygon, this method allows duplicate vertices and +// edges, which requires some extra care with definitions. The rule that we +// apply is that an edge and its reverse edge cancel each other: the result +// is the same as if that edge pair were not present. Therefore shapes that +// consist only of degenerate loop(s) are either empty or full; by convention, +// the shape is considered full if and only if it contains an empty loop (see +// laxPolygon for details). +// +// Determining whether a loop on the sphere contains a point is harder than +// the corresponding problem in 2D plane geometry. It cannot be implemented +// just by counting edge crossings because there is no such thing as a point +// at infinity that is guaranteed to be outside the loop. +// +// This function requires that the given Shape have an interior. +func referencePointForShape(shape Shape) ReferencePoint { + if shape.NumEdges() == 0 { + // A shape with no edges is defined to be full if and only if it + // contains at least one chain. + return OriginReferencePoint(shape.NumChains() > 0) + } + // Define a "matched" edge as one that can be paired with a corresponding + // reversed edge. Define a vertex as "balanced" if all of its edges are + // matched. In order to determine containment, we must find an unbalanced + // vertex. Often every vertex is unbalanced, so we start by trying an + // arbitrary vertex. + edge := shape.Edge(0) + + if ref, ok := referencePointAtVertex(shape, edge.V0); ok { + return ref + } + + // That didn't work, so now we do some extra work to find an unbalanced + // vertex (if any). Essentially we gather a list of edges and a list of + // reversed edges, and then sort them. The first edge that appears in one + // list but not the other is guaranteed to be unmatched. + n := shape.NumEdges() + var edges = make([]Edge, n) + var revEdges = make([]Edge, n) + for i := 0; i < n; i++ { + edge := shape.Edge(i) + edges[i] = edge + revEdges[i] = Edge{V0: edge.V1, V1: edge.V0} + } + + sortEdges(edges) + sortEdges(revEdges) + + for i := 0; i < n; i++ { + if edges[i].Cmp(revEdges[i]) == -1 { // edges[i] is unmatched + if ref, ok := referencePointAtVertex(shape, edges[i].V0); ok { + return ref + } + } + if revEdges[i].Cmp(edges[i]) == -1 { // revEdges[i] is unmatched + if ref, ok := referencePointAtVertex(shape, revEdges[i].V0); ok { + return ref + } + } + } + + // All vertices are balanced, so this polygon is either empty or full except + // for degeneracies. By convention it is defined to be full if it contains + // any chain with no edges. + for i := 0; i < shape.NumChains(); i++ { + if shape.Chain(i).Length == 0 { + return OriginReferencePoint(true) + } + } + + return OriginReferencePoint(false) +} + +// referencePointAtVertex reports whether the given vertex is unbalanced, and +// returns a ReferencePoint indicating if the point is contained. +// Otherwise returns false. +func referencePointAtVertex(shape Shape, vTest Point) (ReferencePoint, bool) { + var ref ReferencePoint + + // Let P be an unbalanced vertex. Vertex P is defined to be inside the + // region if the region contains a particular direction vector starting from + // P, namely the direction p.Ortho(). This can be calculated using + // ContainsVertexQuery. + + containsQuery := NewContainsVertexQuery(vTest) + n := shape.NumEdges() + for e := 0; e < n; e++ { + edge := shape.Edge(e) + if edge.V0 == vTest { + containsQuery.AddEdge(edge.V1, 1) + } + if edge.V1 == vTest { + containsQuery.AddEdge(edge.V0, -1) + } + } + containsSign := containsQuery.ContainsVertex() + if containsSign == 0 { + return ref, false // There are no unmatched edges incident to this vertex. + } + ref.Point = vTest + ref.Contained = containsSign > 0 + + return ref, true +} + +// containsBruteForce reports whether the given shape contains the given point. +// Most clients should not use this method, since its running time is linear in +// the number of shape edges. Instead clients should create a ShapeIndex and use +// ContainsPointQuery, since this strategy is much more efficient when many +// points need to be tested. +// +// Polygon boundaries are treated as being semi-open (see ContainsPointQuery +// and VertexModel for other options). +func containsBruteForce(shape Shape, point Point) bool { + if shape.Dimension() != 2 { + return false + } + + refPoint := shape.ReferencePoint() + if refPoint.Point == point { + return refPoint.Contained + } + + crosser := NewEdgeCrosser(refPoint.Point, point) + inside := refPoint.Contained + for e := 0; e < shape.NumEdges(); e++ { + edge := shape.Edge(e) + inside = inside != crosser.EdgeOrVertexCrossing(edge.V0, edge.V1) + } + return inside +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/shapeutil_edge_iterator.go b/backend/vendor/github.com/blevesearch/geo/s2/shapeutil_edge_iterator.go new file mode 100644 index 0000000000..2a0d823611 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/shapeutil_edge_iterator.go @@ -0,0 +1,72 @@ +// Copyright 2020 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +// EdgeIterator is an iterator that advances through all edges in an ShapeIndex. +// This is different to the ShapeIndexIterator, which advances through the cells in the +// ShapeIndex. +type EdgeIterator struct { + index *ShapeIndex + shapeID int32 + numEdges int32 + edgeID int32 +} + +// NewEdgeIterator creates a new edge iterator for the given index. +func NewEdgeIterator(index *ShapeIndex) *EdgeIterator { + e := &EdgeIterator{ + index: index, + shapeID: -1, + edgeID: -1, + } + + e.Next() + return e +} + +// ShapeID returns the current shape ID. +func (e *EdgeIterator) ShapeID() int32 { return e.shapeID } + +// EdgeID returns the current edge ID. +func (e *EdgeIterator) EdgeID() int32 { return e.edgeID } + +// ShapeEdgeID returns the current (shapeID, edgeID). +func (e *EdgeIterator) ShapeEdgeID() ShapeEdgeID { return ShapeEdgeID{e.shapeID, e.edgeID} } + +// Edge returns the current edge. +func (e *EdgeIterator) Edge() Edge { + return e.index.Shape(e.shapeID).Edge(int(e.edgeID)) +} + +// Done reports if the iterator is positioned at or after the last index edge. +func (e *EdgeIterator) Done() bool { return e.shapeID >= int32(len(e.index.shapes)) } + +// Next positions the iterator at the next index edge. +func (e *EdgeIterator) Next() { + e.edgeID++ + for ; e.edgeID >= e.numEdges; e.edgeID++ { + e.shapeID++ + if e.shapeID >= int32(len(e.index.shapes)) { + break + } + shape := e.index.Shape(e.shapeID) + if shape == nil { + e.numEdges = 0 + } else { + e.numEdges = int32(shape.NumEdges()) + } + e.edgeID = -1 + } +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/stuv.go b/backend/vendor/github.com/blevesearch/geo/s2/stuv.go new file mode 100644 index 0000000000..7663bb398a --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/stuv.go @@ -0,0 +1,427 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "math" + + "github.com/golang/geo/r3" +) + +// +// This file contains documentation of the various coordinate systems used +// throughout the library. Most importantly, S2 defines a framework for +// decomposing the unit sphere into a hierarchy of "cells". Each cell is a +// quadrilateral bounded by four geodesics. The top level of the hierarchy is +// obtained by projecting the six faces of a cube onto the unit sphere, and +// lower levels are obtained by subdividing each cell into four children +// recursively. Cells are numbered such that sequentially increasing cells +// follow a continuous space-filling curve over the entire sphere. The +// transformation is designed to make the cells at each level fairly uniform +// in size. +// +////////////////////////// S2 Cell Decomposition ///////////////////////// +// +// The following methods define the cube-to-sphere projection used by +// the Cell decomposition. +// +// In the process of converting a latitude-longitude pair to a 64-bit cell +// id, the following coordinate systems are used: +// +// (id) +// An CellID is a 64-bit encoding of a face and a Hilbert curve position +// on that face. The Hilbert curve position implicitly encodes both the +// position of a cell and its subdivision level (see s2cellid.go). +// +// (face, i, j) +// Leaf-cell coordinates. "i" and "j" are integers in the range +// [0,(2**30)-1] that identify a particular leaf cell on the given face. +// The (i, j) coordinate system is right-handed on each face, and the +// faces are oriented such that Hilbert curves connect continuously from +// one face to the next. +// +// (face, s, t) +// Cell-space coordinates. "s" and "t" are real numbers in the range +// [0,1] that identify a point on the given face. For example, the point +// (s, t) = (0.5, 0.5) corresponds to the center of the top-level face +// cell. This point is also a vertex of exactly four cells at each +// subdivision level greater than zero. +// +// (face, si, ti) +// Discrete cell-space coordinates. These are obtained by multiplying +// "s" and "t" by 2**31 and rounding to the nearest unsigned integer. +// Discrete coordinates lie in the range [0,2**31]. This coordinate +// system can represent the edge and center positions of all cells with +// no loss of precision (including non-leaf cells). In binary, each +// coordinate of a level-k cell center ends with a 1 followed by +// (30 - k) 0s. The coordinates of its edges end with (at least) +// (31 - k) 0s. +// +// (face, u, v) +// Cube-space coordinates in the range [-1,1]. To make the cells at each +// level more uniform in size after they are projected onto the sphere, +// we apply a nonlinear transformation of the form u=f(s), v=f(t). +// The (u, v) coordinates after this transformation give the actual +// coordinates on the cube face (modulo some 90 degree rotations) before +// it is projected onto the unit sphere. +// +// (face, u, v, w) +// Per-face coordinate frame. This is an extension of the (face, u, v) +// cube-space coordinates that adds a third axis "w" in the direction of +// the face normal. It is always a right-handed 3D coordinate system. +// Cube-space coordinates can be converted to this frame by setting w=1, +// while (u,v,w) coordinates can be projected onto the cube face by +// dividing by w, i.e. (face, u/w, v/w). +// +// (x, y, z) +// Direction vector (Point). Direction vectors are not necessarily unit +// length, and are often chosen to be points on the biunit cube +// [-1,+1]x[-1,+1]x[-1,+1]. They can be be normalized to obtain the +// corresponding point on the unit sphere. +// +// (lat, lng) +// Latitude and longitude (LatLng). Latitudes must be between -90 and +// 90 degrees inclusive, and longitudes must be between -180 and 180 +// degrees inclusive. +// +// Note that the (i, j), (s, t), (si, ti), and (u, v) coordinate systems are +// right-handed on all six faces. +// +// +// There are a number of different projections from cell-space (s,t) to +// cube-space (u,v): linear, quadratic, and tangent. They have the following +// tradeoffs: +// +// Linear - This is the fastest transformation, but also produces the least +// uniform cell sizes. Cell areas vary by a factor of about 5.2, with the +// largest cells at the center of each face and the smallest cells in +// the corners. +// +// Tangent - Transforming the coordinates via Atan makes the cell sizes +// more uniform. The areas vary by a maximum ratio of 1.4 as opposed to a +// maximum ratio of 5.2. However, each call to Atan is about as expensive +// as all of the other calculations combined when converting from points to +// cell ids, i.e. it reduces performance by a factor of 3. +// +// Quadratic - This is an approximation of the tangent projection that +// is much faster and produces cells that are almost as uniform in size. +// It is about 3 times faster than the tangent projection for converting +// cell ids to points or vice versa. Cell areas vary by a maximum ratio of +// about 2.1. +// +// Here is a table comparing the cell uniformity using each projection. Area +// Ratio is the maximum ratio over all subdivision levels of the largest cell +// area to the smallest cell area at that level, Edge Ratio is the maximum +// ratio of the longest edge of any cell to the shortest edge of any cell at +// the same level, and Diag Ratio is the ratio of the longest diagonal of +// any cell to the shortest diagonal of any cell at the same level. +// +// Area Edge Diag +// Ratio Ratio Ratio +// ----------------------------------- +// Linear: 5.200 2.117 2.959 +// Tangent: 1.414 1.414 1.704 +// Quadratic: 2.082 1.802 1.932 +// +// The worst-case cell aspect ratios are about the same with all three +// projections. The maximum ratio of the longest edge to the shortest edge +// within the same cell is about 1.4 and the maximum ratio of the diagonals +// within the same cell is about 1.7. +// +// For Go we have chosen to use only the Quadratic approach. Other language +// implementations may offer other choices. + +const ( + // maxSiTi is the maximum value of an si- or ti-coordinate. + // It is one shift more than maxSize. The range of valid (si,ti) + // values is [0..maxSiTi]. + maxSiTi = maxSize << 1 +) + +// siTiToST converts an si- or ti-value to the corresponding s- or t-value. +// Value is capped at 1.0 because there is no DCHECK in Go. +func siTiToST(si uint32) float64 { + if si > maxSiTi { + return 1.0 + } + return float64(si) / float64(maxSiTi) +} + +// stToSiTi converts the s- or t-value to the nearest si- or ti-coordinate. +// The result may be outside the range of valid (si,ti)-values. Value of +// 0.49999999999999994 (math.NextAfter(0.5, -1)), will be incorrectly rounded up. +func stToSiTi(s float64) uint32 { + if s < 0 { + return uint32(s*maxSiTi - 0.5) + } + return uint32(s*maxSiTi + 0.5) +} + +// stToUV converts an s or t value to the corresponding u or v value. +// This is a non-linear transformation from [-1,1] to [-1,1] that +// attempts to make the cell sizes more uniform. +// This uses what the C++ version calls 'the quadratic transform'. +func stToUV(s float64) float64 { + if s >= 0.5 { + return (1 / 3.) * (4*s*s - 1) + } + return (1 / 3.) * (1 - 4*(1-s)*(1-s)) +} + +// uvToST is the inverse of the stToUV transformation. Note that it +// is not always true that uvToST(stToUV(x)) == x due to numerical +// errors. +func uvToST(u float64) float64 { + if u >= 0 { + return 0.5 * math.Sqrt(1+3*u) + } + return 1 - 0.5*math.Sqrt(1-3*u) +} + +// face returns face ID from 0 to 5 containing the r. For points on the +// boundary between faces, the result is arbitrary but deterministic. +func face(r r3.Vector) int { + f := r.LargestComponent() + switch { + case f == r3.XAxis && r.X < 0: + f += 3 + case f == r3.YAxis && r.Y < 0: + f += 3 + case f == r3.ZAxis && r.Z < 0: + f += 3 + } + return int(f) +} + +// validFaceXYZToUV given a valid face for the given point r (meaning that +// dot product of r with the face normal is positive), returns +// the corresponding u and v values, which may lie outside the range [-1,1]. +func validFaceXYZToUV(face int, r r3.Vector) (float64, float64) { + switch face { + case 0: + return r.Y / r.X, r.Z / r.X + case 1: + return -r.X / r.Y, r.Z / r.Y + case 2: + return -r.X / r.Z, -r.Y / r.Z + case 3: + return r.Z / r.X, r.Y / r.X + case 4: + return r.Z / r.Y, -r.X / r.Y + } + return -r.Y / r.Z, -r.X / r.Z +} + +// xyzToFaceUV converts a direction vector (not necessarily unit length) to +// (face, u, v) coordinates. +func xyzToFaceUV(r r3.Vector) (f int, u, v float64) { + f = face(r) + u, v = validFaceXYZToUV(f, r) + return f, u, v +} + +// faceUVToXYZ turns face and UV coordinates into an unnormalized 3 vector. +func faceUVToXYZ(face int, u, v float64) r3.Vector { + switch face { + case 0: + return r3.Vector{1, u, v} + case 1: + return r3.Vector{-u, 1, v} + case 2: + return r3.Vector{-u, -v, 1} + case 3: + return r3.Vector{-1, -v, -u} + case 4: + return r3.Vector{v, -1, -u} + default: + return r3.Vector{v, u, -1} + } +} + +// faceXYZToUV returns the u and v values (which may lie outside the range +// [-1, 1]) if the dot product of the point p with the given face normal is positive. +func faceXYZToUV(face int, p Point) (u, v float64, ok bool) { + switch face { + case 0: + if p.X <= 0 { + return 0, 0, false + } + case 1: + if p.Y <= 0 { + return 0, 0, false + } + case 2: + if p.Z <= 0 { + return 0, 0, false + } + case 3: + if p.X >= 0 { + return 0, 0, false + } + case 4: + if p.Y >= 0 { + return 0, 0, false + } + default: + if p.Z >= 0 { + return 0, 0, false + } + } + + u, v = validFaceXYZToUV(face, p.Vector) + return u, v, true +} + +// faceXYZtoUVW transforms the given point P to the (u,v,w) coordinate frame of the given +// face where the w-axis represents the face normal. +func faceXYZtoUVW(face int, p Point) Point { + // The result coordinates are simply the dot products of P with the (u,v,w) + // axes for the given face (see faceUVWAxes). + switch face { + case 0: + return Point{r3.Vector{p.Y, p.Z, p.X}} + case 1: + return Point{r3.Vector{-p.X, p.Z, p.Y}} + case 2: + return Point{r3.Vector{-p.X, -p.Y, p.Z}} + case 3: + return Point{r3.Vector{-p.Z, -p.Y, -p.X}} + case 4: + return Point{r3.Vector{-p.Z, p.X, -p.Y}} + default: + return Point{r3.Vector{p.Y, p.X, -p.Z}} + } +} + +// faceSiTiToXYZ transforms the (si, ti) coordinates to a (not necessarily +// unit length) Point on the given face. +func faceSiTiToXYZ(face int, si, ti uint32) Point { + return Point{faceUVToXYZ(face, stToUV(siTiToST(si)), stToUV(siTiToST(ti)))} +} + +// xyzToFaceSiTi transforms the (not necessarily unit length) Point to +// (face, si, ti) coordinates and the level the Point is at. +func xyzToFaceSiTi(p Point) (face int, si, ti uint32, level int) { + face, u, v := xyzToFaceUV(p.Vector) + si = stToSiTi(uvToST(u)) + ti = stToSiTi(uvToST(v)) + + // If the levels corresponding to si,ti are not equal, then p is not a cell + // center. The si,ti values of 0 and maxSiTi need to be handled specially + // because they do not correspond to cell centers at any valid level; they + // are mapped to level -1 by the code at the end. + level = maxLevel - findLSBSetNonZero64(uint64(si|maxSiTi)) + if level < 0 || level != maxLevel-findLSBSetNonZero64(uint64(ti|maxSiTi)) { + return face, si, ti, -1 + } + + // In infinite precision, this test could be changed to ST == SiTi. However, + // due to rounding errors, uvToST(xyzToFaceUV(faceUVToXYZ(stToUV(...)))) is + // not idempotent. On the other hand, the center is computed exactly the same + // way p was originally computed (if it is indeed the center of a Cell); + // the comparison can be exact. + if p.Vector == faceSiTiToXYZ(face, si, ti).Normalize() { + return face, si, ti, level + } + + return face, si, ti, -1 +} + +// uNorm returns the right-handed normal (not necessarily unit length) for an +// edge in the direction of the positive v-axis at the given u-value on +// the given face. (This vector is perpendicular to the plane through +// the sphere origin that contains the given edge.) +func uNorm(face int, u float64) r3.Vector { + switch face { + case 0: + return r3.Vector{u, -1, 0} + case 1: + return r3.Vector{1, u, 0} + case 2: + return r3.Vector{1, 0, u} + case 3: + return r3.Vector{-u, 0, 1} + case 4: + return r3.Vector{0, -u, 1} + default: + return r3.Vector{0, -1, -u} + } +} + +// vNorm returns the right-handed normal (not necessarily unit length) for an +// edge in the direction of the positive u-axis at the given v-value on +// the given face. +func vNorm(face int, v float64) r3.Vector { + switch face { + case 0: + return r3.Vector{-v, 0, 1} + case 1: + return r3.Vector{0, -v, 1} + case 2: + return r3.Vector{0, -1, -v} + case 3: + return r3.Vector{v, -1, 0} + case 4: + return r3.Vector{1, v, 0} + default: + return r3.Vector{1, 0, v} + } +} + +// faceUVWAxes are the U, V, and W axes for each face. +var faceUVWAxes = [6][3]Point{ + {Point{r3.Vector{0, 1, 0}}, Point{r3.Vector{0, 0, 1}}, Point{r3.Vector{1, 0, 0}}}, + {Point{r3.Vector{-1, 0, 0}}, Point{r3.Vector{0, 0, 1}}, Point{r3.Vector{0, 1, 0}}}, + {Point{r3.Vector{-1, 0, 0}}, Point{r3.Vector{0, -1, 0}}, Point{r3.Vector{0, 0, 1}}}, + {Point{r3.Vector{0, 0, -1}}, Point{r3.Vector{0, -1, 0}}, Point{r3.Vector{-1, 0, 0}}}, + {Point{r3.Vector{0, 0, -1}}, Point{r3.Vector{1, 0, 0}}, Point{r3.Vector{0, -1, 0}}}, + {Point{r3.Vector{0, 1, 0}}, Point{r3.Vector{1, 0, 0}}, Point{r3.Vector{0, 0, -1}}}, +} + +// faceUVWFaces are the precomputed neighbors of each face. +var faceUVWFaces = [6][3][2]int{ + {{4, 1}, {5, 2}, {3, 0}}, + {{0, 3}, {5, 2}, {4, 1}}, + {{0, 3}, {1, 4}, {5, 2}}, + {{2, 5}, {1, 4}, {0, 3}}, + {{2, 5}, {3, 0}, {1, 4}}, + {{4, 1}, {3, 0}, {2, 5}}, +} + +// uvwAxis returns the given axis of the given face. +func uvwAxis(face, axis int) Point { + return faceUVWAxes[face][axis] +} + +// uvwFaces returns the face in the (u,v,w) coordinate system on the given axis +// in the given direction. +func uvwFace(face, axis, direction int) int { + return faceUVWFaces[face][axis][direction] +} + +// uAxis returns the u-axis for the given face. +func uAxis(face int) Point { + return uvwAxis(face, 0) +} + +// vAxis returns the v-axis for the given face. +func vAxis(face int) Point { + return uvwAxis(face, 1) +} + +// Return the unit-length normal for the given face. +func unitNorm(face int) Point { + return uvwAxis(face, 2) +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/util.go b/backend/vendor/github.com/blevesearch/geo/s2/util.go new file mode 100644 index 0000000000..7cab746d8b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/util.go @@ -0,0 +1,125 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import "github.com/golang/geo/s1" + +// roundAngle returns the value rounded to nearest as an int32. +// This does not match C++ exactly for the case of x.5. +func roundAngle(val s1.Angle) int32 { + if val < 0 { + return int32(val - 0.5) + } + return int32(val + 0.5) +} + +// minAngle returns the smallest of the given values. +func minAngle(x s1.Angle, others ...s1.Angle) s1.Angle { + min := x + for _, y := range others { + if y < min { + min = y + } + } + return min +} + +// maxAngle returns the largest of the given values. +func maxAngle(x s1.Angle, others ...s1.Angle) s1.Angle { + max := x + for _, y := range others { + if y > max { + max = y + } + } + return max +} + +// minChordAngle returns the smallest of the given values. +func minChordAngle(x s1.ChordAngle, others ...s1.ChordAngle) s1.ChordAngle { + min := x + for _, y := range others { + if y < min { + min = y + } + } + return min +} + +// maxChordAngle returns the largest of the given values. +func maxChordAngle(x s1.ChordAngle, others ...s1.ChordAngle) s1.ChordAngle { + max := x + for _, y := range others { + if y > max { + max = y + } + } + return max +} + +// minFloat64 returns the smallest of the given values. +func minFloat64(x float64, others ...float64) float64 { + min := x + for _, y := range others { + if y < min { + min = y + } + } + return min +} + +// maxFloat64 returns the largest of the given values. +func maxFloat64(x float64, others ...float64) float64 { + max := x + for _, y := range others { + if y > max { + max = y + } + } + return max +} + +// minInt returns the smallest of the given values. +func minInt(x int, others ...int) int { + min := x + for _, y := range others { + if y < min { + min = y + } + } + return min +} + +// maxInt returns the largest of the given values. +func maxInt(x int, others ...int) int { + max := x + for _, y := range others { + if y > max { + max = y + } + } + return max +} + +// clampInt returns the number closest to x within the range min..max. +func clampInt(x, min, max int) int { + if x < min { + return min + } + if x > max { + return max + } + return x +} diff --git a/backend/vendor/github.com/blevesearch/geo/s2/wedge_relations.go b/backend/vendor/github.com/blevesearch/geo/s2/wedge_relations.go new file mode 100644 index 0000000000..d637bb68cd --- /dev/null +++ b/backend/vendor/github.com/blevesearch/geo/s2/wedge_relations.go @@ -0,0 +1,97 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +// WedgeRel enumerates the possible relation between two wedges A and B. +type WedgeRel int + +// Define the different possible relationships between two wedges. +// +// Given an edge chain (x0, x1, x2), the wedge at x1 is the region to the +// left of the edges. More precisely, it is the set of all rays from x1x0 +// (inclusive) to x1x2 (exclusive) in the *clockwise* direction. +const ( + WedgeEquals WedgeRel = iota // A and B are equal. + WedgeProperlyContains // A is a strict superset of B. + WedgeIsProperlyContained // A is a strict subset of B. + WedgeProperlyOverlaps // A-B, B-A, and A intersect B are non-empty. + WedgeIsDisjoint // A and B are disjoint. +) + +// WedgeRelation reports the relation between two non-empty wedges +// A=(a0, ab1, a2) and B=(b0, ab1, b2). +func WedgeRelation(a0, ab1, a2, b0, b2 Point) WedgeRel { + // There are 6 possible edge orderings at a shared vertex (all + // of these orderings are circular, i.e. abcd == bcda): + // + // (1) a2 b2 b0 a0: A contains B + // (2) a2 a0 b0 b2: B contains A + // (3) a2 a0 b2 b0: A and B are disjoint + // (4) a2 b0 a0 b2: A and B intersect in one wedge + // (5) a2 b2 a0 b0: A and B intersect in one wedge + // (6) a2 b0 b2 a0: A and B intersect in two wedges + // + // We do not distinguish between 4, 5, and 6. + // We pay extra attention when some of the edges overlap. When edges + // overlap, several of these orderings can be satisfied, and we take + // the most specific. + if a0 == b0 && a2 == b2 { + return WedgeEquals + } + + // Cases 1, 2, 5, and 6 + if OrderedCCW(a0, a2, b2, ab1) { + // The cases with this vertex ordering are 1, 5, and 6, + if OrderedCCW(b2, b0, a0, ab1) { + return WedgeProperlyContains + } + + // We are in case 5 or 6, or case 2 if a2 == b2. + if a2 == b2 { + return WedgeIsProperlyContained + } + return WedgeProperlyOverlaps + + } + // We are in case 2, 3, or 4. + if OrderedCCW(a0, b0, b2, ab1) { + return WedgeIsProperlyContained + } + + if OrderedCCW(a0, b0, a2, ab1) { + return WedgeIsDisjoint + } + return WedgeProperlyOverlaps +} + +// WedgeContains reports whether non-empty wedge A=(a0, ab1, a2) contains B=(b0, ab1, b2). +// Equivalent to WedgeRelation == WedgeProperlyContains || WedgeEquals. +func WedgeContains(a0, ab1, a2, b0, b2 Point) bool { + // For A to contain B (where each loop interior is defined to be its left + // side), the CCW edge order around ab1 must be a2 b2 b0 a0. We split + // this test into two parts that test three vertices each. + return OrderedCCW(a2, b2, b0, ab1) && OrderedCCW(b0, a0, a2, ab1) +} + +// WedgeIntersects reports whether non-empty wedge A=(a0, ab1, a2) intersects B=(b0, ab1, b2). +// Equivalent but faster than WedgeRelation != WedgeIsDisjoint +func WedgeIntersects(a0, ab1, a2, b0, b2 Point) bool { + // For A not to intersect B (where each loop interior is defined to be + // its left side), the CCW edge order around ab1 must be a0 b2 b0 a2. + // Note that it's important to write these conditions as negatives + // (!OrderedCCW(a,b,c,o) rather than Ordered(c,b,a,o)) to get correct + // results when two vertices are the same. + return !(OrderedCCW(a0, b2, b0, ab1) && OrderedCCW(b0, a2, a0, ab1)) +} diff --git a/backend/vendor/github.com/blevesearch/go-porterstemmer/.gitignore b/backend/vendor/github.com/blevesearch/go-porterstemmer/.gitignore new file mode 100644 index 0000000000..d1ffcc5dc7 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/go-porterstemmer/.gitignore @@ -0,0 +1,8 @@ +#* +*.sublime-* +*~ +.#* +.project +.settings +.DS_Store +/testdata diff --git a/backend/vendor/github.com/blevesearch/go-porterstemmer/.travis.yml b/backend/vendor/github.com/blevesearch/go-porterstemmer/.travis.yml new file mode 100644 index 0000000000..d032f234ef --- /dev/null +++ b/backend/vendor/github.com/blevesearch/go-porterstemmer/.travis.yml @@ -0,0 +1,16 @@ +language: go + +go: + - 1.4 + +script: + - go get golang.org/x/tools/cmd/vet + - go get golang.org/x/tools/cmd/cover + - go get github.com/mattn/goveralls + - go test -v -covermode=count -coverprofile=profile.out + - go vet + - goveralls -service drone.io -coverprofile=profile.out -repotoken $COVERALLS + +notifications: + email: + - marty.schoch@gmail.com diff --git a/backend/vendor/github.com/blevesearch/go-porterstemmer/LICENSE b/backend/vendor/github.com/blevesearch/go-porterstemmer/LICENSE new file mode 100644 index 0000000000..8d2999cced --- /dev/null +++ b/backend/vendor/github.com/blevesearch/go-porterstemmer/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013 Charles Iliya Krempeaux :: http://changelog.ca/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/backend/vendor/github.com/blevesearch/go-porterstemmer/README.md b/backend/vendor/github.com/blevesearch/go-porterstemmer/README.md new file mode 100644 index 0000000000..d96911ace5 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/go-porterstemmer/README.md @@ -0,0 +1,118 @@ +# This fork... + +I'm maintaining this fork because the original author was not replying to issues or pull requests. For now I plan on maintaining this fork as necessary. + +## Status + +[![Build Status](https://travis-ci.org/blevesearch/go-porterstemmer.svg?branch=master)](https://travis-ci.org/blevesearch/go-porterstemmer) + +[![Coverage Status](https://coveralls.io/repos/blevesearch/go-porterstemmer/badge.png?branch=HEAD)](https://coveralls.io/r/blevesearch/go-porterstemmer?branch=HEAD) + +# Go Porter Stemmer + +A native Go clean room implementation of the Porter Stemming Algorithm. + +This algorithm is of interest to people doing Machine Learning or +Natural Language Processing (NLP). + +This is NOT a port. This is a native Go implementation from the human-readable +description of the algorithm. + +I've tried to make it (more) efficient by NOT internally using string's, but +instead internally using []rune's and using the same (array) buffer used by +the []rune slice (and sub-slices) at all steps of the algorithm. + +For Porter Stemmer algorithm, see: + +http://tartarus.org/martin/PorterStemmer/def.txt (URL #1) + +http://tartarus.org/martin/PorterStemmer/ (URL #2) + +# Departures + +Also, since when I initially implemented it, it failed the tests at... + +http://tartarus.org/martin/PorterStemmer/voc.txt (URL #3) + +http://tartarus.org/martin/PorterStemmer/output.txt (URL #4) + +... after reading the human-readble text over and over again to try to figure out +what the error I made was (and doing all sorts of things to debug it) I came to the +conclusion that the some of these tests were wrong according to the human-readable +description of the algorithm. + +This led me to wonder if maybe other people's code that was passing these tests had +rules that were not in the human-readable description. Which led me to look at the source +code here... + +http://tartarus.org/martin/PorterStemmer/c.txt (URL #5) + +... When I looked there I noticed that there are some items marked as a "DEPARTURE", +which differ from the original algorithm. (There are 2 of these.) + +I implemented these departures, and the tests at URL #3 and URL #4 all passed. + +## Usage + +To use this Golang library, use with something like: + + package main + + import ( + "fmt" + "github.com/reiver/go-porterstemmer" + ) + + func main() { + + word := "Waxes" + + stem := porterstemmer.StemString(word) + + fmt.Printf("The word [%s] has the stem [%s].\n", word, stem) + } + +Alternatively, if you want to be a bit more efficient, use []rune slices instead, with code like: + + package main + + import ( + "fmt" + "github.com/reiver/go-porterstemmer" + ) + + func main() { + + word := []rune("Waxes") + + stem := porterstemmer.Stem(word) + + fmt.Printf("The word [%s] has the stem [%s].\n", string(word), string(stem)) + } + +Although NOTE that the above code may modify original slice (named "word" in the example) as a side +effect, for efficiency reasons. And that the slice named "stem" in the example above may be a +sub-slice of the slice named "word". + +Also alternatively, if you already know that your word is already lowercase (and you don't need +this library to lowercase your word for you) you can instead use code like: + + package main + + import ( + "fmt" + "github.com/reiver/go-porterstemmer" + ) + + func main() { + + word := []rune("waxes") + + stem := porterstemmer.StemWithoutLowerCasing(word) + + fmt.Printf("The word [%s] has the stem [%s].\n", string(word), string(stem)) + } + +Again NOTE (like with the previous example) that the above code may modify original slice (named +"word" in the example) as a side effect, for efficiency reasons. And that the slice named "stem" +in the example above may be a sub-slice of the slice named "word". diff --git a/backend/vendor/github.com/blevesearch/go-porterstemmer/porterstemmer.go b/backend/vendor/github.com/blevesearch/go-porterstemmer/porterstemmer.go new file mode 100644 index 0000000000..d1f77e6f2a --- /dev/null +++ b/backend/vendor/github.com/blevesearch/go-porterstemmer/porterstemmer.go @@ -0,0 +1,839 @@ +package porterstemmer + +import ( + // "log" + "unicode" +) + +func isConsonant(s []rune, i int) bool { + + //DEBUG + //log.Printf("isConsonant: [%+v]", string(s[i])) + + result := true + + switch s[i] { + case 'a', 'e', 'i', 'o', 'u': + result = false + case 'y': + if 0 == i { + result = true + } else { + result = !isConsonant(s, i-1) + } + default: + result = true + } + + return result +} + +func measure(s []rune) uint { + + // Initialize. + lenS := len(s) + result := uint(0) + i := 0 + + // Short Circuit. + if 0 == lenS { + /////////// RETURN + return result + } + + // Ignore (potential) consonant sequence at the beginning of word. + for isConsonant(s, i) { + + //DEBUG + //log.Printf("[measure([%s])] Eat Consonant [%d] -> [%s]", string(s), i, string(s[i])) + + i++ + if i >= lenS { + /////////////// RETURN + return result + } + } + + // For each pair of a vowel sequence followed by a consonant sequence, increment result. +Outer: + for i < lenS { + + for !isConsonant(s, i) { + + //DEBUG + //log.Printf("[measure([%s])] VOWEL [%d] -> [%s]", string(s), i, string(s[i])) + + i++ + if i >= lenS { + /////////// BREAK + break Outer + } + } + for isConsonant(s, i) { + + //DEBUG + //log.Printf("[measure([%s])] CONSONANT [%d] -> [%s]", string(s), i, string(s[i])) + + i++ + if i >= lenS { + result++ + /////////// BREAK + break Outer + } + } + result++ + } + + // Return + return result +} + +func hasSuffix(s, suffix []rune) bool { + + lenSMinusOne := len(s) - 1 + lenSuffixMinusOne := len(suffix) - 1 + + if lenSMinusOne <= lenSuffixMinusOne { + return false + } else if s[lenSMinusOne] != suffix[lenSuffixMinusOne] { // I suspect checking this first should speed this function up in practice. + /////// RETURN + return false + } else { + + for i := 0; i < lenSuffixMinusOne; i++ { + + if suffix[i] != s[lenSMinusOne-lenSuffixMinusOne+i] { + /////////////// RETURN + return false + } + + } + + } + + return true +} + +func containsVowel(s []rune) bool { + + lenS := len(s) + + for i := 0; i < lenS; i++ { + + if !isConsonant(s, i) { + /////////// RETURN + return true + } + + } + + return false +} + +func hasRepeatDoubleConsonantSuffix(s []rune) bool { + + // Initialize. + lenS := len(s) + + result := false + + // Do it! + if 2 > lenS { + result = false + } else if s[lenS-1] == s[lenS-2] && isConsonant(s, lenS-1) { // Will using isConsonant() cause a problem with "YY"? + result = true + } else { + result = false + } + + // Return, + return result +} + +func hasConsonantVowelConsonantSuffix(s []rune) bool { + + // Initialize. + lenS := len(s) + + result := false + + // Do it! + if 3 > lenS { + result = false + } else if isConsonant(s, lenS-3) && !isConsonant(s, lenS-2) && isConsonant(s, lenS-1) { + result = true + } else { + result = false + } + + // Return + return result +} + +func step1a(s []rune) []rune { + + // Initialize. + var result []rune = s + + lenS := len(s) + + // Do it! + if suffix := []rune("sses"); hasSuffix(s, suffix) { + + lenTrim := 2 + + subSlice := s[:lenS-lenTrim] + + result = subSlice + } else if suffix := []rune("ies"); hasSuffix(s, suffix) { + lenTrim := 2 + + subSlice := s[:lenS-lenTrim] + + result = subSlice + } else if suffix := []rune("ss"); hasSuffix(s, suffix) { + + result = s + } else if suffix := []rune("s"); hasSuffix(s, suffix) { + + lenSuffix := 1 + + subSlice := s[:lenS-lenSuffix] + + result = subSlice + } + + // Return. + return result +} + +func step1b(s []rune) []rune { + + // Initialize. + var result []rune = s + + lenS := len(s) + + // Do it! + if suffix := []rune("eed"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 0 < m { + lenTrim := 1 + + result = s[:lenS-lenTrim] + } + } else if suffix := []rune("ed"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + if containsVowel(subSlice) { + + if suffix2 := []rune("at"); hasSuffix(subSlice, suffix2) { + lenTrim := -1 + + result = s[:lenS-lenSuffix-lenTrim] + } else if suffix2 := []rune("bl"); hasSuffix(subSlice, suffix2) { + lenTrim := -1 + + result = s[:lenS-lenSuffix-lenTrim] + } else if suffix2 := []rune("iz"); hasSuffix(subSlice, suffix2) { + lenTrim := -1 + + result = s[:lenS-lenSuffix-lenTrim] + } else if c := subSlice[len(subSlice)-1]; 'l' != c && 's' != c && 'z' != c && hasRepeatDoubleConsonantSuffix(subSlice) { + lenTrim := 1 + + lenSubSlice := len(subSlice) + + result = subSlice[:lenSubSlice-lenTrim] + } else if c := subSlice[len(subSlice)-1]; 1 == measure(subSlice) && hasConsonantVowelConsonantSuffix(subSlice) && 'w' != c && 'x' != c && 'y' != c { + lenTrim := -1 + + result = s[:lenS-lenSuffix-lenTrim] + + result[len(result)-1] = 'e' + } else { + result = subSlice + } + + } + } else if suffix := []rune("ing"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + if containsVowel(subSlice) { + + if suffix2 := []rune("at"); hasSuffix(subSlice, suffix2) { + lenTrim := -1 + + result = s[:lenS-lenSuffix-lenTrim] + + result[len(result)-1] = 'e' + } else if suffix2 := []rune("bl"); hasSuffix(subSlice, suffix2) { + lenTrim := -1 + + result = s[:lenS-lenSuffix-lenTrim] + + result[len(result)-1] = 'e' + } else if suffix2 := []rune("iz"); hasSuffix(subSlice, suffix2) { + lenTrim := -1 + + result = s[:lenS-lenSuffix-lenTrim] + + result[len(result)-1] = 'e' + } else if c := subSlice[len(subSlice)-1]; 'l' != c && 's' != c && 'z' != c && hasRepeatDoubleConsonantSuffix(subSlice) { + lenTrim := 1 + + lenSubSlice := len(subSlice) + + result = subSlice[:lenSubSlice-lenTrim] + } else if c := subSlice[len(subSlice)-1]; 1 == measure(subSlice) && hasConsonantVowelConsonantSuffix(subSlice) && 'w' != c && 'x' != c && 'y' != c { + lenTrim := -1 + + result = s[:lenS-lenSuffix-lenTrim] + + result[len(result)-1] = 'e' + } else { + result = subSlice + } + + } + } + + // Return. + return result +} + +func step1c(s []rune) []rune { + + // Initialize. + lenS := len(s) + + result := s + + // Do it! + if 2 > lenS { + /////////// RETURN + return result + } + + if 'y' == s[lenS-1] && containsVowel(s[:lenS-1]) { + + result[lenS-1] = 'i' + + } else if 'Y' == s[lenS-1] && containsVowel(s[:lenS-1]) { + + result[lenS-1] = 'I' + + } + + // Return. + return result +} + +func step2(s []rune) []rune { + + // Initialize. + lenS := len(s) + + result := s + + // Do it! + if suffix := []rune("ational"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result[lenS-5] = 'e' + result = result[:lenS-4] + } + } else if suffix := []rune("tional"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result = result[:lenS-2] + } + } else if suffix := []rune("enci"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result[lenS-1] = 'e' + } + } else if suffix := []rune("anci"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result[lenS-1] = 'e' + } + } else if suffix := []rune("izer"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result = s[:lenS-1] + } + } else if suffix := []rune("bli"); hasSuffix(s, suffix) { // --DEPARTURE-- + // } else if suffix := []rune("abli") ; hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result[lenS-1] = 'e' + } + } else if suffix := []rune("alli"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result = s[:lenS-2] + } + } else if suffix := []rune("entli"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result = s[:lenS-2] + } + } else if suffix := []rune("eli"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result = s[:lenS-2] + } + } else if suffix := []rune("ousli"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result = s[:lenS-2] + } + } else if suffix := []rune("ization"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result[lenS-5] = 'e' + + result = s[:lenS-4] + } + } else if suffix := []rune("ation"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result[lenS-3] = 'e' + + result = s[:lenS-2] + } + } else if suffix := []rune("ator"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result[lenS-2] = 'e' + + result = s[:lenS-1] + } + } else if suffix := []rune("alism"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result = s[:lenS-3] + } + } else if suffix := []rune("iveness"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result = s[:lenS-4] + } + } else if suffix := []rune("fulness"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result = s[:lenS-4] + } + } else if suffix := []rune("ousness"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result = s[:lenS-4] + } + } else if suffix := []rune("aliti"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result = s[:lenS-3] + } + } else if suffix := []rune("iviti"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result[lenS-3] = 'e' + + result = result[:lenS-2] + } + } else if suffix := []rune("biliti"); hasSuffix(s, suffix) { + if 0 < measure(s[:lenS-len(suffix)]) { + result[lenS-5] = 'l' + result[lenS-4] = 'e' + + result = result[:lenS-3] + } + } else if suffix := []rune("logi"); hasSuffix(s, suffix) { // --DEPARTURE-- + if 0 < measure(s[:lenS-len(suffix)]) { + lenTrim := 1 + + result = s[:lenS-lenTrim] + } + } + + // Return. + return result +} + +func step3(s []rune) []rune { + + // Initialize. + lenS := len(s) + result := s + + // Do it! + if suffix := []rune("icate"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + if 0 < measure(s[:lenS-lenSuffix]) { + result = result[:lenS-3] + } + } else if suffix := []rune("ative"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 0 < m { + result = subSlice + } + } else if suffix := []rune("alize"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + if 0 < measure(s[:lenS-lenSuffix]) { + result = result[:lenS-3] + } + } else if suffix := []rune("iciti"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + if 0 < measure(s[:lenS-lenSuffix]) { + result = result[:lenS-3] + } + } else if suffix := []rune("ical"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + if 0 < measure(s[:lenS-lenSuffix]) { + result = result[:lenS-2] + } + } else if suffix := []rune("ful"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 0 < m { + result = subSlice + } + } else if suffix := []rune("ness"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 0 < m { + result = subSlice + } + } + + // Return. + return result +} + +func step4(s []rune) []rune { + + // Initialize. + lenS := len(s) + result := s + + // Do it! + if suffix := []rune("al"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = result[:lenS-lenSuffix] + } + } else if suffix := []rune("ance"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = result[:lenS-lenSuffix] + } + } else if suffix := []rune("ence"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = result[:lenS-lenSuffix] + } + } else if suffix := []rune("er"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = subSlice + } + } else if suffix := []rune("ic"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = subSlice + } + } else if suffix := []rune("able"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = subSlice + } + } else if suffix := []rune("ible"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = subSlice + } + } else if suffix := []rune("ant"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = subSlice + } + } else if suffix := []rune("ement"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = subSlice + } + } else if suffix := []rune("ment"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = subSlice + } + } else if suffix := []rune("ent"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = subSlice + } + } else if suffix := []rune("ion"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + c := subSlice[len(subSlice)-1] + + if 1 < m && ('s' == c || 't' == c) { + result = subSlice + } + } else if suffix := []rune("ou"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = subSlice + } + } else if suffix := []rune("ism"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = subSlice + } + } else if suffix := []rune("ate"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = subSlice + } + } else if suffix := []rune("iti"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = subSlice + } + } else if suffix := []rune("ous"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = subSlice + } + } else if suffix := []rune("ive"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = subSlice + } + } else if suffix := []rune("ize"); hasSuffix(s, suffix) { + lenSuffix := len(suffix) + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = subSlice + } + } + + // Return. + return result +} + +func step5a(s []rune) []rune { + + // Initialize. + lenS := len(s) + result := s + + // Do it! + if 'e' == s[lenS-1] { + lenSuffix := 1 + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = subSlice + } else if 1 == m { + if c := subSlice[len(subSlice)-1]; !(hasConsonantVowelConsonantSuffix(subSlice) && 'w' != c && 'x' != c && 'y' != c) { + result = subSlice + } + } + } + + // Return. + return result +} + +func step5b(s []rune) []rune { + + // Initialize. + lenS := len(s) + result := s + + // Do it! + if 2 < lenS && 'l' == s[lenS-2] && 'l' == s[lenS-1] { + + lenSuffix := 1 + + subSlice := s[:lenS-lenSuffix] + + m := measure(subSlice) + + if 1 < m { + result = subSlice + } + } + + // Return. + return result +} + +func StemString(s string) string { + + // Convert string to []rune + runeArr := []rune(s) + + // Stem. + runeArr = Stem(runeArr) + + // Convert []rune to string + str := string(runeArr) + + // Return. + return str +} + +func Stem(s []rune) []rune { + + // Initialize. + lenS := len(s) + + // Short circuit. + if 0 == lenS { + /////////// RETURN + return s + } + + // Make all runes lowercase. + for i := 0; i < lenS; i++ { + s[i] = unicode.ToLower(s[i]) + } + + // Stem + result := StemWithoutLowerCasing(s) + + // Return. + return result +} + +func StemWithoutLowerCasing(s []rune) []rune { + + // Initialize. + lenS := len(s) + + // Words that are of length 2 or less is already stemmed. + // Don't do anything. + if 2 >= lenS { + /////////// RETURN + return s + } + + // Stem + s = step1a(s) + s = step1b(s) + s = step1c(s) + s = step2(s) + s = step3(s) + s = step4(s) + s = step5a(s) + s = step5b(s) + + // Return. + return s +} diff --git a/backend/vendor/github.com/blevesearch/gtreap/.gitignore b/backend/vendor/github.com/blevesearch/gtreap/.gitignore new file mode 100644 index 0000000000..94b2ac31be --- /dev/null +++ b/backend/vendor/github.com/blevesearch/gtreap/.gitignore @@ -0,0 +1,5 @@ +#* +*~ +*.test +tmp + diff --git a/backend/vendor/github.com/blevesearch/gtreap/LICENSE b/backend/vendor/github.com/blevesearch/gtreap/LICENSE new file mode 100644 index 0000000000..26656306f1 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/gtreap/LICENSE @@ -0,0 +1,20 @@ +Copyright (C) 2012 Steve Yen + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/backend/vendor/github.com/blevesearch/gtreap/README.md b/backend/vendor/github.com/blevesearch/gtreap/README.md new file mode 100644 index 0000000000..4cd8de7c75 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/gtreap/README.md @@ -0,0 +1,90 @@ +gtreap +------ + +gtreap is an immutable treap implementation in the Go Language + +[![GoDoc](https://godoc.org/github.com/steveyen/gtreap?status.svg)](https://godoc.org/github.com/steveyen/gtreap) [![Build Status](https://drone.io/github.com/steveyen/gtreap/status.png)](https://drone.io/github.com/steveyen/gtreap/latest) [![Coverage Status](https://coveralls.io/repos/steveyen/gtreap/badge.png)](https://coveralls.io/r/steveyen/gtreap) + +Overview +======== + +gtreap implements an immutable treap data structure in golang. + +By treap, this data structure is both a heap and a binary search tree. + +By immutable, any updates/deletes to a treap will return a new treap +which can share internal nodes with the previous treap. All nodes in +this implementation are read-only after their creation. This allows +concurrent readers to operate safely with concurrent writers as +modifications only create new data structures and never modify +existing data structures. This is a simple approach to achieving MVCC +or multi-version concurrency control. + +By heap, items in the treap follow the heap-priority property, where a +parent node will have higher priority than its left and right children +nodes. + +By binary search tree, items are store lexigraphically, ordered by a +user-supplied Compare function. + +To get a probabilistic O(lg N) tree height, you should use a random +priority number during the Upsert() operation. + +LICENSE +======= + +MIT + +Example +======= + + import ( + "math/rand" + "github.com/steveyen/gtreap" + ) + + func stringCompare(a, b interface{}) int { + return bytes.Compare([]byte(a.(string)), []byte(b.(string))) + } + + t := gtreap.NewTreap(stringCompare) + t = t.Upsert("hi", rand.Int()) + t = t.Upsert("hola", rand.Int()) + t = t.Upsert("bye", rand.Int()) + t = t.Upsert("adios", rand.Int()) + + hi = t.Get("hi") + bye = t.Get("bye") + + // Some example Delete()'s... + t = t.Delete("bye") + nilValueHere = t.Get("bye") + t2 = t.Delete("hi") + nilValueHere2 = t2.Get("hi") + + // Since we still hold onto treap t, we can still access "hi". + hiStillExistsInTreapT = t.Get("hi") + + t.VisitAscend("cya", func(i Item) bool { + // This visitor callback will be invoked with every item + // from "cya" onwards. So: "hi", "hola". + // If we want to stop visiting, return false; + // otherwise a true return result means keep visiting items. + return true + }) + +Tips +==== + +The Upsert() method takes both an Item (an interface{}) and a heap +priority. Usually, that priority should be a random int +(math/rand.Int()) or perhaps even a hash of the item. However, if you +want to shuffle more commonly accessed items nearer to the top of the +treap for faster access, at the potential cost of not approaching a +probabilistic O(lg N) tree height, then you might tweak the priority. + +See also +======== + +For a simple, ordered, key-value storage or persistence library built +on immutable treaps, see: https://github.com/steveyen/gkvlite diff --git a/backend/vendor/github.com/blevesearch/gtreap/treap.go b/backend/vendor/github.com/blevesearch/gtreap/treap.go new file mode 100644 index 0000000000..1f8002c287 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/gtreap/treap.go @@ -0,0 +1,207 @@ +package gtreap + +type Treap struct { + compare Compare + root *node +} + +// Compare returns an integer comparing the two items +// lexicographically. The result will be 0 if a==b, -1 if a < b, and +// +1 if a > b. +type Compare func(a, b interface{}) int + +// Item can be anything. +type Item interface{} + +type node struct { + item Item + priority int + left *node + right *node +} + +func NewTreap(c Compare) *Treap { + return &Treap{compare: c, root: nil} +} + +func (t *Treap) Min() Item { + n := t.root + if n == nil { + return nil + } + for n.left != nil { + n = n.left + } + return n.item +} + +func (t *Treap) Max() Item { + n := t.root + if n == nil { + return nil + } + for n.right != nil { + n = n.right + } + return n.item +} + +func (t *Treap) Get(target Item) Item { + n := t.root + for n != nil { + c := t.compare(target, n.item) + if c < 0 { + n = n.left + } else if c > 0 { + n = n.right + } else { + return n.item + } + } + return nil +} + +// Note: only the priority of the first insert of an item is used. +// Priorities from future updates on already existing items are +// ignored. To change the priority for an item, you need to do a +// Delete then an Upsert. +func (t *Treap) Upsert(item Item, itemPriority int) *Treap { + r := t.union(t.root, &node{item: item, priority: itemPriority}) + return &Treap{compare: t.compare, root: r} +} + +func (t *Treap) union(this *node, that *node) *node { + if this == nil { + return that + } + if that == nil { + return this + } + if this.priority > that.priority { + left, middle, right := t.split(that, this.item) + if middle == nil { + return &node{ + item: this.item, + priority: this.priority, + left: t.union(this.left, left), + right: t.union(this.right, right), + } + } + return &node{ + item: middle.item, + priority: this.priority, + left: t.union(this.left, left), + right: t.union(this.right, right), + } + } + // We don't use middle because the "that" has precendence. + left, _, right := t.split(this, that.item) + return &node{ + item: that.item, + priority: that.priority, + left: t.union(left, that.left), + right: t.union(right, that.right), + } +} + +// Splits a treap into two treaps based on a split item "s". +// The result tuple-3 means (left, X, right), where X is either... +// nil - meaning the item s was not in the original treap. +// non-nil - returning the node that had item s. +// The tuple-3's left result treap has items < s, +// and the tuple-3's right result treap has items > s. +func (t *Treap) split(n *node, s Item) (*node, *node, *node) { + if n == nil { + return nil, nil, nil + } + c := t.compare(s, n.item) + if c == 0 { + return n.left, n, n.right + } + if c < 0 { + left, middle, right := t.split(n.left, s) + return left, middle, &node{ + item: n.item, + priority: n.priority, + left: right, + right: n.right, + } + } + left, middle, right := t.split(n.right, s) + return &node{ + item: n.item, + priority: n.priority, + left: n.left, + right: left, + }, middle, right +} + +func (t *Treap) Delete(target Item) *Treap { + left, _, right := t.split(t.root, target) + return &Treap{compare: t.compare, root: t.join(left, right)} +} + +// All the items from this are < items from that. +func (t *Treap) join(this *node, that *node) *node { + if this == nil { + return that + } + if that == nil { + return this + } + if this.priority > that.priority { + return &node{ + item: this.item, + priority: this.priority, + left: this.left, + right: t.join(this.right, that), + } + } + return &node{ + item: that.item, + priority: that.priority, + left: t.join(this, that.left), + right: that.right, + } +} + +// ItemVistor callback should return true to keep going on the visitation. +type ItemVisitor func(i Item) bool + +// Visit items greater-than-or-equal to the pivot, in ascending order. +func (t *Treap) VisitAscend(pivot Item, visitor ItemVisitor) { + t.visitAscend(t.root, pivot, visitor) +} + +func (t *Treap) visitAscend(n *node, pivot Item, visitor ItemVisitor) bool { + if n == nil { + return true + } + c := t.compare(pivot, n.item) + if c < 0 && !t.visitAscend(n.left, pivot, visitor) { + return false + } + if c <= 0 && !visitor(n.item) { + return false + } + return t.visitAscend(n.right, pivot, visitor) +} + +// Visit items less-than-or-equal to the pivot, in descending order. +func (t *Treap) VisitDescend(pivot Item, visitor ItemVisitor) { + t.visitDescend(t.root, pivot, visitor) +} + +func (t *Treap) visitDescend(n *node, pivot Item, visitor ItemVisitor) bool { + if n == nil { + return true + } + c := t.compare(pivot, n.item) + if c > 0 && !t.visitDescend(n.right, pivot, visitor) { + return false + } + if c >= 0 && !visitor(n.item) { + return false + } + return t.visitDescend(n.left, pivot, visitor) +} diff --git a/backend/vendor/github.com/blevesearch/mmap-go/.gitignore b/backend/vendor/github.com/blevesearch/mmap-go/.gitignore new file mode 100644 index 0000000000..0c0a5e4916 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/mmap-go/.gitignore @@ -0,0 +1,10 @@ +*.out +*.5 +*.6 +*.8 +*.swp +_obj +_test +testdata +/.idea +*.iml \ No newline at end of file diff --git a/backend/vendor/github.com/blevesearch/mmap-go/.travis.yml b/backend/vendor/github.com/blevesearch/mmap-go/.travis.yml new file mode 100644 index 0000000000..169eb1f354 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/mmap-go/.travis.yml @@ -0,0 +1,16 @@ +language: go +os: + - linux + - osx + - windows +go: + - 1.11.4 +env: + global: + - GO111MODULE=on +install: + - go mod download + - go get github.com/mattn/goveralls +script: + - go test -v -covermode=count -coverprofile=coverage.out -bench . -cpu 1,4 + - '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci -repotoken $COVERALLS_TOKEN || true' diff --git a/backend/vendor/github.com/blevesearch/mmap-go/LICENSE b/backend/vendor/github.com/blevesearch/mmap-go/LICENSE new file mode 100644 index 0000000000..8f05f338ac --- /dev/null +++ b/backend/vendor/github.com/blevesearch/mmap-go/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2011, Evan Shaw +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/backend/vendor/github.com/blevesearch/mmap-go/README.md b/backend/vendor/github.com/blevesearch/mmap-go/README.md new file mode 100644 index 0000000000..4cc2bfe1c8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/mmap-go/README.md @@ -0,0 +1,12 @@ +mmap-go +======= + +mmap-go is a portable mmap package for the [Go programming language](http://golang.org). +It has been tested on Linux (386, amd64), OS X, and Windows (386). It should also +work on other Unix-like platforms, but hasn't been tested with them. I'm interested +to hear about the results. + +I haven't been able to add more features without adding significant complexity, +so mmap-go doesn't support mprotect, mincore, and maybe a few other things. +If you're running on a Unix-like platform and need some of these features, +I suggest Gustavo Niemeyer's [gommap](http://labix.org/gommap). diff --git a/backend/vendor/github.com/blevesearch/mmap-go/mmap.go b/backend/vendor/github.com/blevesearch/mmap-go/mmap.go new file mode 100644 index 0000000000..29655bd222 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/mmap-go/mmap.go @@ -0,0 +1,117 @@ +// Copyright 2011 Evan Shaw. 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 defines the common package interface and contains a little bit of +// factored out logic. + +// Package mmap allows mapping files into memory. It tries to provide a simple, reasonably portable interface, +// but doesn't go out of its way to abstract away every little platform detail. +// This specifically means: +// * forked processes may or may not inherit mappings +// * a file's timestamp may or may not be updated by writes through mappings +// * specifying a size larger than the file's actual size can increase the file's size +// * If the mapped file is being modified by another process while your program's running, don't expect consistent results between platforms +package mmap + +import ( + "errors" + "os" + "reflect" + "unsafe" +) + +const ( + // RDONLY maps the memory read-only. + // Attempts to write to the MMap object will result in undefined behavior. + RDONLY = 0 + // RDWR maps the memory as read-write. Writes to the MMap object will update the + // underlying file. + RDWR = 1 << iota + // COPY maps the memory as copy-on-write. Writes to the MMap object will affect + // memory, but the underlying file will remain unchanged. + COPY + // If EXEC is set, the mapped memory is marked as executable. + EXEC +) + +const ( + // If the ANON flag is set, the mapped memory will not be backed by a file. + ANON = 1 << iota +) + +// MMap represents a file mapped into memory. +type MMap []byte + +// Map maps an entire file into memory. +// If ANON is set in flags, f is ignored. +func Map(f *os.File, prot, flags int) (MMap, error) { + return MapRegion(f, -1, prot, flags, 0) +} + +// MapRegion maps part of a file into memory. +// The offset parameter must be a multiple of the system's page size. +// If length < 0, the entire file will be mapped. +// If ANON is set in flags, f is ignored. +func MapRegion(f *os.File, length int, prot, flags int, offset int64) (MMap, error) { + if offset%int64(os.Getpagesize()) != 0 { + return nil, errors.New("offset parameter must be a multiple of the system's page size") + } + + var fd uintptr + if flags&ANON == 0 { + fd = uintptr(f.Fd()) + if length < 0 { + fi, err := f.Stat() + if err != nil { + return nil, err + } + length = int(fi.Size()) + } + } else { + if length <= 0 { + return nil, errors.New("anonymous mapping requires non-zero length") + } + fd = ^uintptr(0) + } + return mmap(length, uintptr(prot), uintptr(flags), fd, offset) +} + +func (m *MMap) header() *reflect.SliceHeader { + return (*reflect.SliceHeader)(unsafe.Pointer(m)) +} + +func (m *MMap) addrLen() (uintptr, uintptr) { + header := m.header() + return header.Data, uintptr(header.Len) +} + +// Lock keeps the mapped region in physical memory, ensuring that it will not be +// swapped out. +func (m MMap) Lock() error { + return m.lock() +} + +// Unlock reverses the effect of Lock, allowing the mapped region to potentially +// be swapped out. +// If m is already unlocked, aan error will result. +func (m MMap) Unlock() error { + return m.unlock() +} + +// Flush synchronizes the mapping's contents to the file's contents on disk. +func (m MMap) Flush() error { + return m.flush() +} + +// Unmap deletes the memory mapped region, flushes any remaining changes, and sets +// m to nil. +// Trying to read or write any remaining references to m after Unmap is called will +// result in undefined behavior. +// Unmap should only be called on the slice value that was originally returned from +// a call to Map. Calling Unmap on a derived slice may cause errors. +func (m *MMap) Unmap() error { + err := m.unmap() + *m = nil + return err +} diff --git a/backend/vendor/github.com/blevesearch/mmap-go/mmap_unix.go b/backend/vendor/github.com/blevesearch/mmap-go/mmap_unix.go new file mode 100644 index 0000000000..25b13e51fd --- /dev/null +++ b/backend/vendor/github.com/blevesearch/mmap-go/mmap_unix.go @@ -0,0 +1,51 @@ +// Copyright 2011 Evan Shaw. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd linux openbsd solaris netbsd + +package mmap + +import ( + "golang.org/x/sys/unix" +) + +func mmap(len int, inprot, inflags, fd uintptr, off int64) ([]byte, error) { + flags := unix.MAP_SHARED + prot := unix.PROT_READ + switch { + case inprot© != 0: + prot |= unix.PROT_WRITE + flags = unix.MAP_PRIVATE + case inprot&RDWR != 0: + prot |= unix.PROT_WRITE + } + if inprot&EXEC != 0 { + prot |= unix.PROT_EXEC + } + if inflags&ANON != 0 { + flags |= unix.MAP_ANON + } + + b, err := unix.Mmap(int(fd), off, len, prot, flags) + if err != nil { + return nil, err + } + return b, nil +} + +func (m MMap) flush() error { + return unix.Msync([]byte(m), unix.MS_SYNC) +} + +func (m MMap) lock() error { + return unix.Mlock([]byte(m)) +} + +func (m MMap) unlock() error { + return unix.Munlock([]byte(m)) +} + +func (m MMap) unmap() error { + return unix.Munmap([]byte(m)) +} diff --git a/backend/vendor/github.com/blevesearch/mmap-go/mmap_windows.go b/backend/vendor/github.com/blevesearch/mmap-go/mmap_windows.go new file mode 100644 index 0000000000..631b3825f9 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/mmap-go/mmap_windows.go @@ -0,0 +1,153 @@ +// Copyright 2011 Evan Shaw. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mmap + +import ( + "errors" + "os" + "sync" + + "golang.org/x/sys/windows" +) + +// mmap on Windows is a two-step process. +// First, we call CreateFileMapping to get a handle. +// Then, we call MapviewToFile to get an actual pointer into memory. +// Because we want to emulate a POSIX-style mmap, we don't want to expose +// the handle -- only the pointer. We also want to return only a byte slice, +// not a struct, so it's convenient to manipulate. + +// We keep this map so that we can get back the original handle from the memory address. + +type addrinfo struct { + file windows.Handle + mapview windows.Handle + writable bool +} + +var handleLock sync.Mutex +var handleMap = map[uintptr]*addrinfo{} + +func mmap(len int, prot, flags, hfile uintptr, off int64) ([]byte, error) { + flProtect := uint32(windows.PAGE_READONLY) + dwDesiredAccess := uint32(windows.FILE_MAP_READ) + writable := false + switch { + case prot© != 0: + flProtect = windows.PAGE_WRITECOPY + dwDesiredAccess = windows.FILE_MAP_COPY + writable = true + case prot&RDWR != 0: + flProtect = windows.PAGE_READWRITE + dwDesiredAccess = windows.FILE_MAP_WRITE + writable = true + } + if prot&EXEC != 0 { + flProtect <<= 4 + dwDesiredAccess |= windows.FILE_MAP_EXECUTE + } + + // The maximum size is the area of the file, starting from 0, + // that we wish to allow to be mappable. It is the sum of + // the length the user requested, plus the offset where that length + // is starting from. This does not map the data into memory. + maxSizeHigh := uint32((off + int64(len)) >> 32) + maxSizeLow := uint32((off + int64(len)) & 0xFFFFFFFF) + // TODO: Do we need to set some security attributes? It might help portability. + h, errno := windows.CreateFileMapping(windows.Handle(hfile), nil, flProtect, maxSizeHigh, maxSizeLow, nil) + if h == 0 { + return nil, os.NewSyscallError("CreateFileMapping", errno) + } + + // Actually map a view of the data into memory. The view's size + // is the length the user requested. + fileOffsetHigh := uint32(off >> 32) + fileOffsetLow := uint32(off & 0xFFFFFFFF) + addr, errno := windows.MapViewOfFile(h, dwDesiredAccess, fileOffsetHigh, fileOffsetLow, uintptr(len)) + if addr == 0 { + return nil, os.NewSyscallError("MapViewOfFile", errno) + } + handleLock.Lock() + handleMap[addr] = &addrinfo{ + file: windows.Handle(hfile), + mapview: h, + writable: writable, + } + handleLock.Unlock() + + m := MMap{} + dh := m.header() + dh.Data = addr + dh.Len = len + dh.Cap = dh.Len + + return m, nil +} + +func (m MMap) flush() error { + addr, len := m.addrLen() + errno := windows.FlushViewOfFile(addr, len) + if errno != nil { + return os.NewSyscallError("FlushViewOfFile", errno) + } + + handleLock.Lock() + defer handleLock.Unlock() + handle, ok := handleMap[addr] + if !ok { + // should be impossible; we would've errored above + return errors.New("unknown base address") + } + + if handle.writable { + if err := windows.FlushFileBuffers(handle.file); err != nil { + return os.NewSyscallError("FlushFileBuffers", err) + } + } + + return nil +} + +func (m MMap) lock() error { + addr, len := m.addrLen() + errno := windows.VirtualLock(addr, len) + return os.NewSyscallError("VirtualLock", errno) +} + +func (m MMap) unlock() error { + addr, len := m.addrLen() + errno := windows.VirtualUnlock(addr, len) + return os.NewSyscallError("VirtualUnlock", errno) +} + +func (m MMap) unmap() error { + err := m.flush() + if err != nil { + return err + } + + addr := m.header().Data + // Lock the UnmapViewOfFile along with the handleMap deletion. + // As soon as we unmap the view, the OS is free to give the + // same addr to another new map. We don't want another goroutine + // to insert and remove the same addr into handleMap while + // we're trying to remove our old addr/handle pair. + handleLock.Lock() + defer handleLock.Unlock() + err = windows.UnmapViewOfFile(addr) + if err != nil { + return err + } + + handle, ok := handleMap[addr] + if !ok { + // should be impossible; we would've errored above + return errors.New("unknown base address") + } + delete(handleMap, addr) + + e := windows.CloseHandle(windows.Handle(handle.mapview)) + return os.NewSyscallError("CloseHandle", e) +} diff --git a/backend/vendor/github.com/blevesearch/scorch_segment_api/v2/.golangci.yml b/backend/vendor/github.com/blevesearch/scorch_segment_api/v2/.golangci.yml new file mode 100644 index 0000000000..664f35f27e --- /dev/null +++ b/backend/vendor/github.com/blevesearch/scorch_segment_api/v2/.golangci.yml @@ -0,0 +1,42 @@ +linters: + # please, do not use `enable-all`: it's deprecated and will be removed soon. + # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint + disable-all: true + enable: + - bodyclose + - deadcode + - depguard + - dogsled + - dupl + - errcheck + - funlen + - gochecknoinits + - goconst + - gocritic + - gocyclo + - gofmt + - goimports + - golint + - gomnd + - goprintffuncname + - gosec + - gosimple + - govet + - ineffassign + - interfacer + - lll + - misspell + - nakedret + - nolintlint + - rowserrcheck + - scopelint + - staticcheck + - structcheck + - stylecheck + - typecheck + - unconvert + - unparam + - unused + - varcheck + - whitespace + diff --git a/backend/vendor/github.com/blevesearch/scorch_segment_api/v2/LICENSE b/backend/vendor/github.com/blevesearch/scorch_segment_api/v2/LICENSE new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/scorch_segment_api/v2/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/backend/vendor/github.com/blevesearch/scorch_segment_api/v2/README.md b/backend/vendor/github.com/blevesearch/scorch_segment_api/v2/README.md new file mode 100644 index 0000000000..dc33b004ed --- /dev/null +++ b/backend/vendor/github.com/blevesearch/scorch_segment_api/v2/README.md @@ -0,0 +1,11 @@ +# Scorch Segment API + +[![PkgGoDev](https://pkg.go.dev/badge/github.com/blevesearch/scorch_segment_api)](https://pkg.go.dev/github.com/blevesearch/scorch_segment_api) +[![Tests](https://github.com/blevesearch/scorch_segment_api/workflows/Tests/badge.svg?branch=master&event=push)](https://github.com/blevesearch/scorch_segment_api/actions?query=workflow%3ATests+event%3Apush+branch%3Amaster) +[![Lint](https://github.com/blevesearch/scorch_segment_api/workflows/Lint/badge.svg?branch=master&event=push)](https://github.com/blevesearch/scorch_segment_api/actions?query=workflow%3ALint+event%3Apush+branch%3Amaster) + +Scorch supports a pluggable Segment interface. + +By placing these interfaces in their own, *hopefully* slowly evolving module, it frees up Scorch and the underlying segment to each introduce new major versions without interfering with one another. + +With that in mind, we anticipate introducing non-breaking changes only to this module, and keeping the major version at 1.x for some time. diff --git a/backend/vendor/github.com/blevesearch/scorch_segment_api/v2/automaton.go b/backend/vendor/github.com/blevesearch/scorch_segment_api/v2/automaton.go new file mode 100644 index 0000000000..4577ceb2e6 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/scorch_segment_api/v2/automaton.go @@ -0,0 +1,36 @@ +// Copyright (c) 2021 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package segment + +// Automaton represents the general contract of a byte-based finite automaton +type Automaton interface { + + // Start returns the start state + Start() int + + // IsMatch returns true if and only if the state is a match + IsMatch(int) bool + + // CanMatch returns true if and only if it is possible to reach a match + // in zero or more steps + CanMatch(int) bool + + // WillAlwaysMatch returns true if and only if the current state matches + // and will always match no matter what steps are taken + WillAlwaysMatch(int) bool + + // Accept returns the next state given the input to the specified state + Accept(int, byte) int +} diff --git a/backend/vendor/github.com/blevesearch/scorch_segment_api/v2/segment.go b/backend/vendor/github.com/blevesearch/scorch_segment_api/v2/segment.go new file mode 100644 index 0000000000..37d04c47ef --- /dev/null +++ b/backend/vendor/github.com/blevesearch/scorch_segment_api/v2/segment.go @@ -0,0 +1,170 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package segment + +import ( + "fmt" + + "github.com/RoaringBitmap/roaring" + index "github.com/blevesearch/bleve_index_api" +) + +var ErrClosed = fmt.Errorf("index closed") + +// StoredFieldValueVisitor defines a callback to be visited for each +// stored field value. The return value determines if the visitor +// should keep going. Returning true continues visiting, false stops. +type StoredFieldValueVisitor func(field string, typ byte, value []byte, pos []uint64) bool + +type Segment interface { + DiskStatsReporter + + Dictionary(field string) (TermDictionary, error) + + VisitStoredFields(num uint64, visitor StoredFieldValueVisitor) error + + DocID(num uint64) ([]byte, error) + + Count() uint64 + + DocNumbers([]string) (*roaring.Bitmap, error) + + Fields() []string + + Close() error + + Size() int + + AddRef() + DecRef() error +} + +type UnpersistedSegment interface { + Segment + Persist(path string) error +} + +type PersistedSegment interface { + Segment + Path() string +} + +type TermDictionary interface { + PostingsList(term []byte, except *roaring.Bitmap, prealloc PostingsList) (PostingsList, error) + + AutomatonIterator(a Automaton, + startKeyInclusive, endKeyExclusive []byte) DictionaryIterator + + Contains(key []byte) (bool, error) +} + +type DictionaryIterator interface { + Next() (*index.DictEntry, error) +} + +type PostingsList interface { + DiskStatsReporter + + Iterator(includeFreq, includeNorm, includeLocations bool, prealloc PostingsIterator) PostingsIterator + + Size() int + + Count() uint64 + + // NOTE deferred for future work + + // And(other PostingsList) PostingsList + // Or(other PostingsList) PostingsList +} + +type PostingsIterator interface { + DiskStatsReporter + + // The caller is responsible for copying whatever it needs from + // the returned Posting instance before calling Next(), as some + // implementations may return a shared instance to reduce memory + // allocations. + Next() (Posting, error) + + // Advance will return the posting with the specified doc number + // or if there is no such posting, the next posting. + // Callers MUST NOT attempt to pass a docNum that is less than or + // equal to the currently visited posting doc Num. + Advance(docNum uint64) (Posting, error) + + Size() int +} + +type DiskStatsReporter interface { + // BytesRead returns the bytes read from the disk as + // part of the current running query. + BytesRead() uint64 + + // ResetBytesRead is used by the parent layer + // to reset the bytes read value to a consistent + // value during operations such as merging of segments. + ResetBytesRead(uint64) + + // BytesWritten returns the bytes written to disk while + // building an index + BytesWritten() uint64 +} + +type OptimizablePostingsIterator interface { + ActualBitmap() *roaring.Bitmap + DocNum1Hit() (uint64, bool) + ReplaceActual(*roaring.Bitmap) +} + +type Posting interface { + Number() uint64 + + Frequency() uint64 + Norm() float64 + + Locations() []Location + + Size() int +} + +type Location interface { + Field() string + Start() uint64 + End() uint64 + Pos() uint64 + ArrayPositions() []uint64 + Size() int +} + +// DocValueVisitable is implemented by various scorch segment +// implementations with persistence for the un inverting of the +// postings or other indexed values. +type DocValueVisitable interface { + VisitDocValues(localDocNum uint64, fields []string, + visitor index.DocValueVisitor, optional DocVisitState) (DocVisitState, error) + + // VisitableDocValueFields implementation should return + // the list of fields which are document value persisted and + // therefore visitable by the above VisitDocValues method. + VisitableDocValueFields() ([]string, error) +} + +type DocVisitState interface { + DiskStatsReporter +} + +type StatsReporter interface { + ReportBytesWritten(bytesWritten uint64) +} diff --git a/backend/vendor/github.com/blevesearch/segment/.gitignore b/backend/vendor/github.com/blevesearch/segment/.gitignore new file mode 100644 index 0000000000..b4ccb07eaf --- /dev/null +++ b/backend/vendor/github.com/blevesearch/segment/.gitignore @@ -0,0 +1,10 @@ +#* +*.sublime-* +*~ +.#* +.project +.settings +.DS_Store +/maketesttables +/workdir +/segment-fuzz.zip \ No newline at end of file diff --git a/backend/vendor/github.com/blevesearch/segment/LICENSE b/backend/vendor/github.com/blevesearch/segment/LICENSE new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/segment/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/backend/vendor/github.com/blevesearch/segment/README.md b/backend/vendor/github.com/blevesearch/segment/README.md new file mode 100644 index 0000000000..b24dfb4638 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/segment/README.md @@ -0,0 +1,94 @@ +# segment + +[![Tests](https://github.com/blevesearch/segment/workflows/Tests/badge.svg?branch=master&event=push)](https://github.com/blevesearch/segment/actions?query=workflow%3ATests+event%3Apush+branch%3Amaster) + +A Go library for performing Unicode Text Segmentation +as described in [Unicode Standard Annex #29](http://www.unicode.org/reports/tr29/) + +## Features + +* Currently only segmentation at Word Boundaries is supported. + +## License + +Apache License Version 2.0 + +## Usage + +The functionality is exposed in two ways: + +1. You can use a bufio.Scanner with the SplitWords implementation of SplitFunc. +The SplitWords function will identify the appropriate word boundaries in the input +text and the Scanner will return tokens at the appropriate place. + + scanner := bufio.NewScanner(...) + scanner.Split(segment.SplitWords) + for scanner.Scan() { + tokenBytes := scanner.Bytes() + } + if err := scanner.Err(); err != nil { + t.Fatal(err) + } + +2. Sometimes you would also like information returned about the type of token. +To do this we have introduce a new type named Segmenter. It works just like Scanner +but additionally a token type is returned. + + segmenter := segment.NewWordSegmenter(...) + for segmenter.Segment() { + tokenBytes := segmenter.Bytes()) + tokenType := segmenter.Type() + } + if err := segmenter.Err(); err != nil { + t.Fatal(err) + } + +## Choosing Implementation + +By default segment does NOT use the fastest runtime implementation. The reason is that it adds approximately 5s to compilation time and may require more than 1GB of ram on the machine performing compilation. + +However, you can choose to build with the fastest runtime implementation by passing the build tag as follows: + + -tags 'prod' + +## Generating Code + +Several components in this package are generated. + +1. Several Ragel rules files are generated from Unicode properties files. +2. Ragel machine is generated from the Ragel rules. +3. Test tables are generated from the Unicode test files. + +All of these can be generated by running: + + go generate + +## Fuzzing + +There is support for fuzzing the segment library with [go-fuzz](https://github.com/dvyukov/go-fuzz). + +1. Install go-fuzz if you haven't already: + + go get github.com/dvyukov/go-fuzz/go-fuzz + go get github.com/dvyukov/go-fuzz/go-fuzz-build + +2. Build the package with go-fuzz: + + go-fuzz-build github.com/blevesearch/segment + +3. Convert the Unicode provided test cases into the initial corpus for go-fuzz: + + go test -v -run=TestGenerateWordSegmentFuzz -tags gofuzz_generate + +4. Run go-fuzz: + + go-fuzz -bin=segment-fuzz.zip -workdir=workdir + +## Status + + +[![Build Status](https://travis-ci.org/blevesearch/segment.svg?branch=master)](https://travis-ci.org/blevesearch/segment) + +[![Coverage Status](https://img.shields.io/coveralls/blevesearch/segment.svg)](https://coveralls.io/r/blevesearch/segment?branch=master) + +[![GoDoc](https://godoc.org/github.com/blevesearch/segment?status.svg)](https://godoc.org/github.com/blevesearch/segment) \ No newline at end of file diff --git a/backend/vendor/github.com/blevesearch/segment/doc.go b/backend/vendor/github.com/blevesearch/segment/doc.go new file mode 100644 index 0000000000..6eed3e3ad2 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/segment/doc.go @@ -0,0 +1,45 @@ +// Copyright (c) 2014 Couchbase, Inc. +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software distributed under the +// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. + +/* +Package segment is a library for performing Unicode Text Segmentation +as described in Unicode Standard Annex #29 http://www.unicode.org/reports/tr29/ + +Currently only segmentation at Word Boundaries is supported. + +The functionality is exposed in two ways: + +1. You can use a bufio.Scanner with the SplitWords implementation of SplitFunc. +The SplitWords function will identify the appropriate word boundaries in the input +text and the Scanner will return tokens at the appropriate place. + + scanner := bufio.NewScanner(...) + scanner.Split(segment.SplitWords) + for scanner.Scan() { + tokenBytes := scanner.Bytes() + } + if err := scanner.Err(); err != nil { + t.Fatal(err) + } + +2. Sometimes you would also like information returned about the type of token. +To do this we have introduce a new type named Segmenter. It works just like Scanner +but additionally a token type is returned. + + segmenter := segment.NewWordSegmenter(...) + for segmenter.Segment() { + tokenBytes := segmenter.Bytes()) + tokenType := segmenter.Type() + } + if err := segmenter.Err(); err != nil { + t.Fatal(err) + } + +*/ +package segment diff --git a/backend/vendor/github.com/blevesearch/segment/segment.go b/backend/vendor/github.com/blevesearch/segment/segment.go new file mode 100644 index 0000000000..42ab482b25 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/segment/segment.go @@ -0,0 +1,284 @@ +// Copyright (c) 2015 Couchbase, Inc. +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software distributed under the +// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. + +package segment + +import ( + "errors" + "io" +) + +// Autogenerate the following: +// 1. Ragel rules from subset of Unicode script properties +// 2. Ragel rules from Unicode word segmentation properties +// 3. Ragel machine for word segmentation +// 4. Test tables from Unicode +// +// Requires: +// 1. Ruby (to generate ragel rules from unicode spec) +// 2. Ragel (only v6.9 tested) +// 3. sed (to rewrite build tags) +// +//go:generate ragel/unicode2ragel.rb -u http://www.unicode.org/Public/8.0.0/ucd/Scripts.txt -m SCRIPTS -p Hangul,Han,Hiragana -o ragel/uscript.rl +//go:generate ragel/unicode2ragel.rb -u http://www.unicode.org/Public/8.0.0/ucd/auxiliary/WordBreakProperty.txt -m WB -p Double_Quote,Single_Quote,Hebrew_Letter,CR,LF,Newline,Extend,Format,Katakana,ALetter,MidLetter,MidNum,MidNumLet,Numeric,ExtendNumLet,Regional_Indicator -o ragel/uwb.rl +//go:generate ragel -T1 -Z segment_words.rl -o segment_words.go +//go:generate sed -i "" -e "s/BUILDTAGS/!prod/" segment_words.go +//go:generate sed -i "" -e "s/RAGELFLAGS/-T1/" segment_words.go +//go:generate ragel -G2 -Z segment_words.rl -o segment_words_prod.go +//go:generate sed -i "" -e "s/BUILDTAGS/prod/" segment_words_prod.go +//go:generate sed -i "" -e "s/RAGELFLAGS/-G2/" segment_words_prod.go +//go:generate go run maketesttables.go -output tables_test.go + +// NewWordSegmenter returns a new Segmenter to read from r. +func NewWordSegmenter(r io.Reader) *Segmenter { + return NewSegmenter(r) +} + +// NewWordSegmenterDirect returns a new Segmenter to work directly with buf. +func NewWordSegmenterDirect(buf []byte) *Segmenter { + return NewSegmenterDirect(buf) +} + +func SplitWords(data []byte, atEOF bool) (int, []byte, error) { + advance, token, _, err := SegmentWords(data, atEOF) + return advance, token, err +} + +func SegmentWords(data []byte, atEOF bool) (int, []byte, int, error) { + vals := make([][]byte, 0, 1) + types := make([]int, 0, 1) + tokens, types, advance, err := segmentWords(data, 1, atEOF, vals, types) + if len(tokens) > 0 { + return advance, tokens[0], types[0], err + } + return advance, nil, 0, err +} + +func SegmentWordsDirect(data []byte, val [][]byte, types []int) ([][]byte, []int, int, error) { + return segmentWords(data, -1, true, val, types) +} + +// *** Core Segmenter + +const maxConsecutiveEmptyReads = 100 + +// NewSegmenter returns a new Segmenter to read from r. +// Defaults to segment using SegmentWords +func NewSegmenter(r io.Reader) *Segmenter { + return &Segmenter{ + r: r, + segment: SegmentWords, + maxTokenSize: MaxScanTokenSize, + buf: make([]byte, 4096), // Plausible starting size; needn't be large. + } +} + +// NewSegmenterDirect returns a new Segmenter to work directly with buf. +// Defaults to segment using SegmentWords +func NewSegmenterDirect(buf []byte) *Segmenter { + return &Segmenter{ + segment: SegmentWords, + maxTokenSize: MaxScanTokenSize, + buf: buf, + start: 0, + end: len(buf), + err: io.EOF, + } +} + +// Segmenter provides a convenient interface for reading data such as +// a file of newline-delimited lines of text. Successive calls to +// the Segment method will step through the 'tokens' of a file, skipping +// the bytes between the tokens. The specification of a token is +// defined by a split function of type SplitFunc; the default split +// function breaks the input into lines with line termination stripped. Split +// functions are defined in this package for scanning a file into +// lines, bytes, UTF-8-encoded runes, and space-delimited words. The +// client may instead provide a custom split function. +// +// Segmenting stops unrecoverably at EOF, the first I/O error, or a token too +// large to fit in the buffer. When a scan stops, the reader may have +// advanced arbitrarily far past the last token. Programs that need more +// control over error handling or large tokens, or must run sequential scans +// on a reader, should use bufio.Reader instead. +// +type Segmenter struct { + r io.Reader // The reader provided by the client. + segment SegmentFunc // The function to split the tokens. + maxTokenSize int // Maximum size of a token; modified by tests. + token []byte // Last token returned by split. + buf []byte // Buffer used as argument to split. + start int // First non-processed byte in buf. + end int // End of data in buf. + typ int // The token type + err error // Sticky error. +} + +// SegmentFunc is the signature of the segmenting function used to tokenize the +// input. The arguments are an initial substring of the remaining unprocessed +// data and a flag, atEOF, that reports whether the Reader has no more data +// to give. The return values are the number of bytes to advance the input +// and the next token to return to the user, plus an error, if any. If the +// data does not yet hold a complete token, for instance if it has no newline +// while scanning lines, SegmentFunc can return (0, nil, nil) to signal the +// Segmenter to read more data into the slice and try again with a longer slice +// starting at the same point in the input. +// +// If the returned error is non-nil, segmenting stops and the error +// is returned to the client. +// +// The function is never called with an empty data slice unless atEOF +// is true. If atEOF is true, however, data may be non-empty and, +// as always, holds unprocessed text. +type SegmentFunc func(data []byte, atEOF bool) (advance int, token []byte, segmentType int, err error) + +// Errors returned by Segmenter. +var ( + ErrTooLong = errors.New("bufio.Segmenter: token too long") + ErrNegativeAdvance = errors.New("bufio.Segmenter: SplitFunc returns negative advance count") + ErrAdvanceTooFar = errors.New("bufio.Segmenter: SplitFunc returns advance count beyond input") +) + +const ( + // Maximum size used to buffer a token. The actual maximum token size + // may be smaller as the buffer may need to include, for instance, a newline. + MaxScanTokenSize = 64 * 1024 +) + +// Err returns the first non-EOF error that was encountered by the Segmenter. +func (s *Segmenter) Err() error { + if s.err == io.EOF { + return nil + } + return s.err +} + +func (s *Segmenter) Type() int { + return s.typ +} + +// Bytes returns the most recent token generated by a call to Segment. +// The underlying array may point to data that will be overwritten +// by a subsequent call to Segment. It does no allocation. +func (s *Segmenter) Bytes() []byte { + return s.token +} + +// Text returns the most recent token generated by a call to Segment +// as a newly allocated string holding its bytes. +func (s *Segmenter) Text() string { + return string(s.token) +} + +// Segment advances the Segmenter to the next token, which will then be +// available through the Bytes or Text method. It returns false when the +// scan stops, either by reaching the end of the input or an error. +// After Segment returns false, the Err method will return any error that +// occurred during scanning, except that if it was io.EOF, Err +// will return nil. +func (s *Segmenter) Segment() bool { + // Loop until we have a token. + for { + // See if we can get a token with what we already have. + if s.end > s.start { + advance, token, typ, err := s.segment(s.buf[s.start:s.end], s.err != nil) + if err != nil { + s.setErr(err) + return false + } + s.typ = typ + if !s.advance(advance) { + return false + } + s.token = token + if token != nil { + return true + } + } + // We cannot generate a token with what we are holding. + // If we've already hit EOF or an I/O error, we are done. + if s.err != nil { + // Shut it down. + s.start = 0 + s.end = 0 + return false + } + // Must read more data. + // First, shift data to beginning of buffer if there's lots of empty space + // or space is needed. + if s.start > 0 && (s.end == len(s.buf) || s.start > len(s.buf)/2) { + copy(s.buf, s.buf[s.start:s.end]) + s.end -= s.start + s.start = 0 + } + // Is the buffer full? If so, resize. + if s.end == len(s.buf) { + if len(s.buf) >= s.maxTokenSize { + s.setErr(ErrTooLong) + return false + } + newSize := len(s.buf) * 2 + if newSize > s.maxTokenSize { + newSize = s.maxTokenSize + } + newBuf := make([]byte, newSize) + copy(newBuf, s.buf[s.start:s.end]) + s.buf = newBuf + s.end -= s.start + s.start = 0 + continue + } + // Finally we can read some input. Make sure we don't get stuck with + // a misbehaving Reader. Officially we don't need to do this, but let's + // be extra careful: Segmenter is for safe, simple jobs. + for loop := 0; ; { + n, err := s.r.Read(s.buf[s.end:len(s.buf)]) + s.end += n + if err != nil { + s.setErr(err) + break + } + if n > 0 { + break + } + loop++ + if loop > maxConsecutiveEmptyReads { + s.setErr(io.ErrNoProgress) + break + } + } + } +} + +// advance consumes n bytes of the buffer. It reports whether the advance was legal. +func (s *Segmenter) advance(n int) bool { + if n < 0 { + s.setErr(ErrNegativeAdvance) + return false + } + if n > s.end-s.start { + s.setErr(ErrAdvanceTooFar) + return false + } + s.start += n + return true +} + +// setErr records the first error encountered. +func (s *Segmenter) setErr(err error) { + if s.err == nil || s.err == io.EOF { + s.err = err + } +} + +// SetSegmenter sets the segment function for the Segmenter. If called, it must be +// called before Segment. +func (s *Segmenter) SetSegmenter(segmenter SegmentFunc) { + s.segment = segmenter +} diff --git a/backend/vendor/github.com/blevesearch/segment/segment_fuzz.go b/backend/vendor/github.com/blevesearch/segment/segment_fuzz.go new file mode 100644 index 0000000000..748b3d69ed --- /dev/null +++ b/backend/vendor/github.com/blevesearch/segment/segment_fuzz.go @@ -0,0 +1,22 @@ +// Copyright (c) 2015 Couchbase, Inc. +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software distributed under the +// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. + +// +build gofuzz + +package segment + +func Fuzz(data []byte) int { + + vals := make([][]byte, 0, 10000) + types := make([]int, 0, 10000) + if _, _, _, err := SegmentWordsDirect(data, vals, types); err != nil { + return 0 + } + return 1 +} diff --git a/backend/vendor/github.com/blevesearch/segment/segment_words.go b/backend/vendor/github.com/blevesearch/segment/segment_words.go new file mode 100644 index 0000000000..4328b52db8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/segment/segment_words.go @@ -0,0 +1,19542 @@ + +//line segment_words.rl:1 +// Copyright (c) 2015 Couchbase, Inc. +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software distributed under the +// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. + +// +build !prod + +package segment + +import ( + "fmt" + "unicode/utf8" +) + +var RagelFlags = "-T1" + +var ParseError = fmt.Errorf("unicode word segmentation parse error") + +// Word Types +const ( + None = iota + Number + Letter + Kana + Ideo +) + + +//line segment_words.go:36 +var _s_key_offsets []uint16 = []uint16{ + 0, 1, 3, 5, 7, 10, 15, 20, + 23, 31, 35, 37, 39, 41, 71, 79, + 81, 83, 86, 91, 96, 106, 118, 124, + 129, 139, 142, 149, 153, 161, 171, 175, + 183, 185, 193, 196, 198, 203, 205, 212, + 214, 222, 223, 244, 246, 256, 261, 263, + 267, 271, 273, 277, 279, 280, 284, 286, + 291, 293, 297, 301, 305, 307, 309, 318, + 322, 328, 332, 336, 338, 340, 341, 343, + 345, 347, 349, 364, 368, 370, 372, 377, + 381, 385, 387, 389, 393, 397, 399, 404, + 411, 416, 420, 425, 426, 430, 432, 438, + 443, 444, 445, 447, 456, 458, 477, 481, + 483, 489, 493, 494, 498, 502, 504, 506, + 511, 524, 526, 528, 532, 536, 538, 540, + 542, 546, 548, 550, 552, 554, 555, 559, + 565, 569, 575, 577, 581, 585, 590, 591, + 593, 594, 600, 603, 605, 605, 628, 666, + 670, 676, 676, 678, 680, 689, 691, 701, + 709, 710, 713, 714, 718, 725, 734, 741, + 748, 761, 768, 772, 776, 783, 815, 822, + 826, 828, 830, 833, 840, 856, 874, 893, + 910, 927, 937, 954, 969, 990, 998, 1011, + 1024, 1039, 1054, 1065, 1080, 1089, 1099, 1102, + 1104, 1109, 1111, 1119, 1125, 1135, 1136, 1183, + 1185, 1195, 1202, 1208, 1215, 1223, 1230, 1233, + 1239, 1243, 1247, 1249, 1253, 1257, 1261, 1271, + 1281, 1283, 1287, 1291, 1293, 1298, 1300, 1306, + 1310, 1315, 1317, 1323, 1329, 1339, 1343, 1347, + 1351, 1364, 1368, 1372, 1382, 1387, 1401, 1419, + 1423, 1429, 1431, 1433, 1449, 1454, 1456, 1458, + 1460, 1464, 1465, 1471, 1477, 1482, 1492, 1502, + 1503, 1508, 1513, 1515, 1519, 1523, 1553, 1555, + 1557, 1563, 1570, 1576, 1580, 1584, 1590, 1592, + 1599, 1601, 1607, 1615, 1621, 1627, 1633, 1638, + 1642, 1649, 1656, 1665, 1677, 1680, 1686, 1686, + 1690, 1692, 1696, 1713, 1725, 1731, 1733, 1735, + 1737, 1739, 1741, 1745, 1749, 1753, 1756, 1758, + 1760, 1764, 1774, 1784, 1823, 1833, 1837, 1839, + 1841, 1842, 1846, 1849, 1853, 1859, 1863, 1868, + 1870, 1874, 1876, 1878, 1882, 1892, 1896, 1898, + 1902, 1906, 1910, 1926, 1928, 1930, 1936, 1938, + 1942, 1944, 1946, 1970, 1976, 1978, 1984, 1986, + 1992, 1996, 2002, 2010, 2016, 2027, 2031, 2048, + 2064, 2068, 2073, 2079, 2085, 2088, 2092, 2094, + 2096, 2100, 2102, 2112, 2114, 2116, 2118, 2122, + 2126, 2128, 2140, 2142, 2146, 2150, 2156, 2158, + 2164, 2168, 2171, 2175, 2183, 2203, 2207, 2213, + 2215, 2216, 2226, 2227, 2235, 2242, 2244, 2247, + 2249, 2251, 2253, 2256, 2260, 2264, 2269, 2276, + 2282, 2296, 2322, 2332, 2335, 2337, 2341, 2343, + 2344, 2350, 2353, 2355, 2355, 2357, 2380, 2381, + 2383, 2385, 2387, 2390, 2395, 2400, 2406, 2416, + 2420, 2422, 2424, 2428, 2458, 2466, 2468, 2470, + 2473, 2482, 2487, 2501, 2515, 2525, 2530, 2542, + 2545, 2554, 2558, 2570, 2582, 2586, 2598, 2600, + 2610, 2613, 2617, 2622, 2626, 2635, 2637, 2645, + 2646, 2670, 2672, 2684, 2691, 2693, 2697, 2701, + 2703, 2711, 2715, 2716, 2720, 2722, 2724, 2726, + 2731, 2737, 2741, 2749, 2755, 2757, 2759, 2763, + 2772, 2776, 2782, 2786, 2790, 2792, 2794, 2795, + 2797, 2799, 2801, 2803, 2819, 2821, 2825, 2827, + 2829, 2834, 2838, 2846, 2850, 2852, 2856, 2868, + 2870, 2877, 2884, 2889, 2895, 2900, 2901, 2905, + 2907, 2913, 2919, 2920, 2921, 2923, 2932, 2934, + 2956, 2960, 2966, 2972, 2974, 2980, 2981, 2985, + 2993, 2995, 2999, 3004, 3017, 3019, 3025, 3029, + 3033, 3039, 3041, 3043, 3047, 3053, 3055, 3057, + 3059, 3061, 3062, 3066, 3073, 3077, 3083, 3085, + 3087, 3091, 3095, 3100, 3101, 3103, 3104, 3110, + 3113, 3115, 3115, 3119, 3121, 3131, 3134, 3141, + 3151, 3172, 3173, 3175, 3177, 3179, 3182, 3191, + 3195, 3197, 3207, 3210, 3217, 3227, 3234, 3244, + 3257, 3264, 3268, 3272, 3281, 3313, 3320, 3324, + 3326, 3329, 3339, 3355, 3375, 3394, 3413, 3430, + 3444, 3461, 3478, 3499, 3509, 3522, 3539, 3554, + 3571, 3582, 3601, 3610, 3622, 3625, 3629, 3634, + 3638, 3648, 3654, 3664, 3665, 3714, 3716, 3728, + 3737, 3743, 3753, 3763, 3765, 3773, 3779, 3784, + 3790, 3794, 3799, 3805, 3811, 3821, 3833, 3837, + 3841, 3849, 3862, 3866, 3884, 3890, 3901, 3903, + 3909, 3914, 3924, 3929, 3934, 3936, 3966, 3972, + 3979, 3985, 3989, 3996, 4002, 4014, 4022, 4028, + 4034, 4047, 4051, 4060, 4067, 4076, 4084, 4101, + 4113, 4121, 4127, 4133, 4136, 4139, 4143, 4153, + 4163, 4202, 4203, 4206, 4212, 4218, 4234, 4240, + 4265, 4271, 4277, 4283, 4287, 4295, 4299, 4305, + 4318, 4324, 4332, 4349, 4365, 4369, 4378, 4384, + 4390, 4397, 4401, 4405, 4411, 4423, 4427, 4431, + 4435, 4443, 4449, 4453, 4456, 4464, 4484, 4488, + 4494, 4496, 4503, 4507, 4511, 4516, 4523, 4529, + 4530, 4536, 4539, 4541, 4541, 4543, 4548, 4551, + 4559, 4563, 4565, 4567, 4569, 4599, 4607, 4609, + 4611, 4614, 4619, 4624, 4634, 4646, 4652, 4657, + 4667, 4670, 4677, 4681, 4689, 4699, 4703, 4711, + 4713, 4721, 4724, 4726, 4731, 4733, 4740, 4742, + 4750, 4751, 4772, 4774, 4784, 4789, 4791, 4795, + 4799, 4801, 4805, 4807, 4808, 4812, 4814, 4819, + 4821, 4825, 4829, 4833, 4835, 4837, 4846, 4850, + 4856, 4860, 4864, 4866, 4868, 4869, 4871, 4873, + 4875, 4877, 4892, 4896, 4898, 4900, 4905, 4909, + 4913, 4915, 4917, 4921, 4925, 4927, 4932, 4939, + 4944, 4948, 4954, 4962, 4968, 4972, 4974, 4980, + 4985, 4986, 4987, 4989, 4998, 5000, 5019, 5023, + 5025, 5031, 5035, 5036, 5040, 5044, 5046, 5048, + 5053, 5066, 5068, 5070, 5074, 5078, 5080, 5082, + 5084, 5088, 5090, 5092, 5094, 5096, 5097, 5101, + 5107, 5111, 5117, 5119, 5123, 5127, 5132, 5133, + 5135, 5136, 5142, 5145, 5147, 5147, 5152, 5162, + 5164, 5174, 5182, 5185, 5192, 5203, 5210, 5220, + 5233, 5240, 5244, 5248, 5257, 5289, 5296, 5300, + 5302, 5305, 5315, 5331, 5351, 5370, 5389, 5406, + 5420, 5437, 5454, 5475, 5485, 5498, 5515, 5530, + 5547, 5558, 5577, 5586, 5598, 5601, 5605, 5610, + 5614, 5624, 5630, 5640, 5641, 5690, 5692, 5704, + 5713, 5719, 5729, 5739, 5741, 5749, 5755, 5760, + 5766, 5770, 5775, 5781, 5787, 5797, 5809, 5813, + 5817, 5830, 5834, 5852, 5862, 5873, 5875, 5881, + 5886, 5896, 5901, 5906, 5908, 5938, 5945, 5951, + 5955, 5962, 5968, 5980, 5988, 5994, 6000, 6013, + 6017, 6026, 6033, 6042, 6050, 6067, 6078, 6085, + 6093, 6096, 6102, 6106, 6116, 6126, 6165, 6166, + 6169, 6175, 6191, 6197, 6222, 6228, 6234, 6240, + 6248, 6252, 6258, 6271, 6277, 6285, 6302, 6318, + 6322, 6331, 6337, 6343, 6350, 6354, 6358, 6370, + 6374, 6378, 6384, 6388, 6391, 6399, 6419, 6423, + 6429, 6431, 6435, 6439, 6444, 6451, 6457, 6458, + 6464, 6467, 6469, 6469, 6471, 6478, 6488, 6501, + 6508, 6512, 6516, 6525, 6557, 6564, 6568, 6570, + 6573, 6583, 6599, 6619, 6638, 6657, 6674, 6688, + 6705, 6722, 6743, 6753, 6766, 6783, 6798, 6815, + 6826, 6845, 6854, 6866, 6869, 6873, 6878, 6882, + 6892, 6898, 6908, 6909, 6958, 6960, 6972, 6981, + 6987, 6997, 7007, 7009, 7017, 7023, 7028, 7034, + 7038, 7043, 7049, 7055, 7065, 7077, 7081, 7085, + 7098, 7102, 7120, 7126, 7135, 7137, 7143, 7148, + 7158, 7168, 7175, 7176, 7178, 7180, 7182, 7185, + 7190, 7195, 7198, 7206, 7210, 7212, 7214, 7216, + 7246, 7254, 7256, 7258, 7261, 7266, 7271, 7281, + 7293, 7299, 7304, 7314, 7317, 7324, 7328, 7336, + 7346, 7350, 7358, 7360, 7368, 7371, 7373, 7378, + 7380, 7387, 7389, 7397, 7398, 7419, 7421, 7431, + 7436, 7438, 7442, 7446, 7448, 7452, 7454, 7455, + 7459, 7461, 7466, 7468, 7472, 7476, 7480, 7482, + 7484, 7493, 7497, 7503, 7509, 7518, 7520, 7522, + 7523, 7525, 7532, 7536, 7540, 7543, 7545, 7547, + 7549, 7564, 7568, 7570, 7572, 7577, 7581, 7585, + 7587, 7589, 7593, 7597, 7599, 7604, 7611, 7616, + 7620, 7628, 7629, 7635, 7637, 7638, 7640, 7642, + 7644, 7650, 7655, 7656, 7657, 7659, 7668, 7670, + 7689, 7693, 7695, 7701, 7705, 7706, 7710, 7714, + 7716, 7718, 7723, 7736, 7738, 7740, 7744, 7748, + 7750, 7752, 7754, 7758, 7760, 7762, 7764, 7766, + 7768, 7769, 7773, 7779, 7783, 7789, 7791, 7795, + 7799, 7804, 7805, 7807, 7808, 7814, 7817, 7819, + 7819, 7825, 7855, 7862, 7868, 7872, 7879, 7885, + 7897, 7905, 7911, 7917, 7930, 7934, 7943, 7950, + 7959, 7967, 7984, 7996, 8002, 8005, 8009, 8015, + 8025, 8035, 8074, 8075, 8078, 8084, 8100, 8106, + 8131, 8137, 8143, 8149, 8157, 8161, 8167, 8180, + 8186, 8194, 8211, 8227, 8231, 8240, 8246, 8252, + 8259, 8263, 8267, 8279, 8283, 8287, 8293, 8297, + 8301, 8309, 8329, 8333, 8339, 8341, 8345, 8349, + 8354, 8361, 8367, 8368, 8374, 8377, 8379, 8379, + 8381, 8385, 8387, 8397, 8400, 8408, 8418, 8427, + 8436, 8449, 8456, 8460, 8464, 8474, 8506, 8513, + 8517, 8519, 8522, 8530, 8546, 8564, 8583, 8600, + 8617, 8629, 8646, 8663, 8684, 8694, 8707, 8722, + 8737, 8754, 8765, 8782, 8791, 8803, 8806, 8810, + 8815, 8819, 8829, 8835, 8845, 8846, 8895, 8897, + 8909, 8915, 8921, 8931, 8941, 8943, 8949, 8955, + 8960, 8966, 8970, 8975, 8981, 8987, 8995, 9007, + 9011, 9015, 9028, 9032, 9050, 9059, 9071, 9073, + 9079, 9084, 9094, 9099, 9104, 9106, 9136, 9143, + 9149, 9153, 9160, 9166, 9176, 9184, 9190, 9196, + 9205, 9209, 9218, 9225, 9234, 9242, 9259, 9271, + 9279, 9288, 9291, 9298, 9302, 9312, 9322, 9361, + 9362, 9365, 9371, 9387, 9393, 9418, 9424, 9428, + 9434, 9442, 9446, 9452, 9463, 9469, 9477, 9494, + 9510, 9514, 9521, 9527, 9533, 9538, 9542, 9546, + 9558, 9562, 9566, 9572, 9576, 9579, 9587, 9607, + 9611, 9617, 9619, 9623, 9627, 9632, 9639, 9645, + 9646, 9652, 9655, 9657, 9657, 9659, 9664, 9670, + 9671, 9676, 9687, 9694, 9701, 9710, 9712, 9714, + 9719, 9751, 9753, 9755, 9757, 9762, 9773, 9788, + 9807, 9822, 9838, 9852, 9868, 9883, 9904, 9914, + 9926, 9939, 9953, 9968, 9978, 9992, 10001, 10013, + 10016, 10020, 10025, 10029, 10039, 10045, 10051, 10052, + 10101, 10103, 10115, 10124, 10128, 10134, 10142, 10144, + 10152, 10158, 10162, 10168, 10173, 10179, 10187, 10193, + 10195, 10197, 10203, 10207, 10225, 10235, 10246, 10248, + 10252, 10258, 10268, 10273, 10278, 10280, 10310, 10315, + 10317, 10328, 10334, 10338, 10350, 10352, 10358, 10365, + 10370, 10376, 10393, 10405, 10412, 10416, 10418, 10428, + 10438, 10477, 10478, 10482, 10486, 10499, 10503, 10528, + 10534, 10538, 10542, 10545, 10554, 10558, 10564, 10580, + 10594, 10601, 10605, 10609, 10617, 10621, 10633, 10637, + 10641, 10643, 10646, 10654, 10674, 10678, 10684, 10686, + 10690, 10694, 10699, 10706, 10710, 10711, 10717, 10720, + 10722, 10726, 10728, 10738, 10741, 10748, 10758, 10765, + 10775, 10788, 10795, 10799, 10803, 10812, 10844, 10851, + 10855, 10857, 10860, 10870, 10886, 10906, 10925, 10944, + 10961, 10975, 10992, 11009, 11030, 11040, 11053, 11070, + 11085, 11102, 11113, 11132, 11141, 11153, 11156, 11160, + 11165, 11169, 11179, 11185, 11195, 11196, 11245, 11247, + 11259, 11268, 11274, 11284, 11294, 11296, 11304, 11310, + 11315, 11321, 11323, 11325, 11329, 11334, 11340, 11346, + 11356, 11368, 11372, 11376, 11384, 11397, 11401, 11419, + 11425, 11434, 11436, 11442, 11447, 11457, 11467, 11474, + 11480, 11510, 11516, 11523, 11529, 11533, 11540, 11546, + 11558, 11566, 11572, 11578, 11591, 11595, 11604, 11611, + 11620, 11628, 11645, 11657, 11663, 11669, 11672, 11675, + 11681, 11691, 11701, 11740, 11741, 11744, 11750, 11756, + 11772, 11778, 11803, 11809, 11815, 11821, 11825, 11833, + 11837, 11843, 11856, 11862, 11870, 11887, 11903, 11907, + 11916, 11922, 11928, 11935, 11939, 11941, 11945, 11951, + 11963, 11967, 11971, 11975, 11983, 11989, 11993, 11997, + 12005, 12025, 12029, 12035, 12037, 12044, 12048, 12052, + 12057, 12064, 12070, 12071, 12077, 12080, 12082, 12082, + 12084, 12088, 12090, 12100, 12103, 12111, 12121, 12130, + 12139, 12152, 12159, 12163, 12167, 12177, 12209, 12216, + 12220, 12222, 12225, 12233, 12249, 12267, 12286, 12303, + 12320, 12332, 12349, 12366, 12387, 12397, 12410, 12425, + 12440, 12457, 12468, 12485, 12494, 12506, 12509, 12513, + 12518, 12522, 12532, 12538, 12548, 12549, 12598, 12600, + 12612, 12618, 12624, 12634, 12644, 12646, 12652, 12658, + 12663, 12669, 12673, 12678, 12684, 12690, 12698, 12710, + 12714, 12718, 12731, 12735, 12753, 12762, 12774, 12776, + 12782, 12787, 12797, 12802, 12807, 12809, 12839, 12846, + 12852, 12856, 12863, 12869, 12879, 12887, 12893, 12899, + 12908, 12912, 12921, 12928, 12937, 12945, 12962, 12974, + 12982, 12991, 12994, 13001, 13005, 13015, 13025, 13064, + 13065, 13068, 13074, 13090, 13096, 13121, 13127, 13131, + 13137, 13145, 13149, 13155, 13166, 13172, 13180, 13197, + 13213, 13217, 13224, 13230, 13236, 13241, 13245, 13249, + 13261, 13265, 13269, 13275, 13279, 13282, 13290, 13310, + 13314, 13320, 13322, 13326, 13330, 13335, 13342, 13348, + 13349, 13355, 13358, 13360, 13360, 13362, 13363, 13365, + 13367, 13369, 13372, 13377, 13382, 13388, 13398, 13402, + 13404, 13406, 13410, 13440, 13448, 13450, 13452, 13455, + 13464, 13469, 13483, 13497, 13507, 13512, 13524, 13527, + 13536, 13540, 13552, 13564, 13568, 13580, 13582, 13592, + 13595, 13599, 13604, 13608, 13617, 13619, 13627, 13628, + 13652, 13654, 13666, 13673, 13675, 13679, 13683, 13685, + 13693, 13697, 13698, 13702, 13704, 13709, 13715, 13719, + 13727, 13733, 13735, 13737, 13741, 13750, 13754, 13760, + 13764, 13768, 13770, 13772, 13773, 13775, 13777, 13779, + 13781, 13797, 13799, 13803, 13805, 13807, 13812, 13816, + 13824, 13828, 13830, 13834, 13846, 13848, 13855, 13862, + 13867, 13873, 13878, 13879, 13883, 13885, 13891, 13897, + 13898, 13899, 13901, 13910, 13912, 13934, 13938, 13944, + 13950, 13952, 13958, 13959, 13963, 13971, 13973, 13977, + 13982, 13995, 13997, 14003, 14007, 14011, 14017, 14019, + 14023, 14029, 14031, 14033, 14035, 14037, 14038, 14042, + 14049, 14053, 14059, 14061, 14063, 14067, 14071, 14076, + 14077, 14079, 14080, 14086, 14089, 14091, 14091, 14095, + 14097, 14107, 14110, 14118, 14128, 14137, 14148, 14161, + 14168, 14172, 14176, 14186, 14218, 14225, 14229, 14231, + 14234, 14244, 14260, 14280, 14299, 14318, 14335, 14349, + 14366, 14383, 14404, 14414, 14427, 14444, 14459, 14476, + 14487, 14506, 14515, 14527, 14530, 14534, 14539, 14543, + 14553, 14559, 14569, 14570, 14619, 14621, 14633, 14642, + 14648, 14658, 14668, 14670, 14678, 14684, 14689, 14695, + 14699, 14704, 14710, 14716, 14726, 14738, 14742, 14746, + 14759, 14763, 14781, 14790, 14802, 14804, 14810, 14815, + 14825, 14830, 14835, 14837, 14867, 14874, 14880, 14884, + 14891, 14897, 14909, 14917, 14923, 14929, 14942, 14946, + 14955, 14962, 14971, 14979, 14996, 15008, 15016, 15019, + 15023, 15033, 15043, 15082, 15083, 15086, 15092, 15108, + 15114, 15139, 15145, 15151, 15157, 15165, 15169, 15175, + 15188, 15194, 15202, 15219, 15235, 15239, 15248, 15254, + 15260, 15267, 15271, 15275, 15287, 15291, 15295, 15301, + 15305, 15308, 15316, 15336, 15340, 15346, 15348, 15352, + 15356, 15361, 15368, 15374, 15375, 15381, 15384, 15386, + 15386, 15388, 15393, 15395, 15405, 15408, 15415, 15426, + 15433, 15443, 15456, 15463, 15467, 15471, 15480, 15512, + 15519, 15523, 15525, 15528, 15538, 15554, 15574, 15593, + 15612, 15629, 15643, 15660, 15677, 15698, 15708, 15721, + 15738, 15753, 15770, 15781, 15800, 15809, 15821, 15824, + 15828, 15833, 15837, 15847, 15853, 15863, 15864, 15913, + 15915, 15927, 15936, 15942, 15952, 15962, 15964, 15972, + 15978, 15983, 15989, 15993, 15998, 16004, 16010, 16020, + 16032, 16036, 16040, 16053, 16057, 16075, 16085, 16096, + 16098, 16104, 16109, 16119, 16124, 16129, 16131, 16161, + 16168, 16174, 16178, 16185, 16191, 16203, 16211, 16217, + 16223, 16236, 16240, 16249, 16256, 16265, 16273, 16290, + 16302, 16309, 16312, 16316, 16326, 16336, 16375, 16376, + 16379, 16385, 16401, 16407, 16432, 16438, 16444, 16450, + 16458, 16462, 16468, 16481, 16487, 16495, 16512, 16528, + 16532, 16541, 16547, 16553, 16560, 16564, 16568, 16580, + 16584, 16588, 16594, 16598, 16601, 16609, 16629, 16633, + 16639, 16641, 16645, 16649, 16654, 16661, 16667, 16668, + 16674, 16677, 16679, 16679, 16681, 16685, 16687, 16697, + 16700, 16707, 16717, 16724, 16734, 16747, 16754, 16758, + 16762, 16771, 16803, 16810, 16814, 16816, 16819, 16829, + 16845, 16865, 16884, 16903, 16920, 16934, 16951, 16968, + 16989, 16999, 17012, 17029, 17044, 17061, 17072, 17091, + 17100, 17112, 17115, 17119, 17124, 17128, 17138, 17144, + 17154, 17155, 17204, 17206, 17218, 17227, 17233, 17243, + 17253, 17255, 17263, 17269, 17274, 17280, 17284, 17289, + 17295, 17301, 17311, 17323, 17327, 17331, 17344, 17348, + 17366, 17372, 17381, 17383, 17389, 17394, 17404, 17414, + 17421, 17427, 17457, 17464, 17470, 17474, 17481, 17487, + 17499, 17507, 17513, 17519, 17532, 17536, 17545, 17552, + 17561, 17569, 17586, 17598, 17604, 17610, 17613, 17616, + 17622, 17632, 17642, 17681, 17682, 17685, 17691, 17707, + 17713, 17738, 17744, 17750, 17756, 17764, 17768, 17774, + 17787, 17793, 17801, 17818, 17834, 17838, 17847, 17853, + 17859, 17866, 17870, 17874, 17886, 17890, 17894, 17900, + 17904, 17908, 17916, 17936, 17940, 17946, 17948, 17952, + 17956, 17961, 17968, 17974, 17975, 17981, 17984, 17986, + 17986, 17988, 17992, 17994, 18004, 18007, 18014, 18024, + 18031, 18041, 18054, 18061, 18065, 18069, 18078, 18110, + 18117, 18121, 18123, 18126, 18136, 18152, 18172, 18191, + 18210, 18227, 18241, 18258, 18275, 18296, 18306, 18319, + 18336, 18351, 18368, 18379, 18398, 18407, 18419, 18422, + 18426, 18431, 18435, 18445, 18451, 18461, 18462, 18511, + 18513, 18525, 18534, 18540, 18550, 18560, 18562, 18570, + 18576, 18581, 18587, 18591, 18596, 18602, 18608, 18618, + 18630, 18634, 18638, 18651, 18655, 18673, 18679, 18690, + 18692, 18698, 18703, 18713, 18723, 18730, 18736, 18766, + 18773, 18779, 18783, 18790, 18796, 18808, 18816, 18822, + 18828, 18841, 18845, 18854, 18861, 18870, 18878, 18895, + 18907, 18913, 18916, 18922, 18932, 18942, 18981, 18982, + 18985, 18991, 19007, 19013, 19038, 19044, 19050, 19056, + 19064, 19068, 19074, 19087, 19093, 19101, 19118, 19134, + 19138, 19147, 19153, 19159, 19166, 19170, 19174, 19186, + 19190, 19194, 19200, 19204, 19208, 19216, 19236, 19240, + 19246, 19248, 19252, 19256, 19261, 19268, 19274, 19275, + 19281, 19284, 19286, 19286, 19288, 19289, 19291, 19293, + 19295, 19298, 19303, 19308, 19311, 19319, 19323, 19325, + 19327, 19329, 19359, 19367, 19369, 19371, 19374, 19379, + 19384, 19394, 19406, 19412, 19417, 19427, 19430, 19437, + 19441, 19449, 19459, 19463, 19471, 19473, 19481, 19484, + 19486, 19491, 19493, 19500, 19502, 19510, 19511, 19532, + 19534, 19544, 19549, 19551, 19555, 19559, 19561, 19565, + 19567, 19568, 19572, 19574, 19579, 19581, 19585, 19589, + 19593, 19595, 19597, 19606, 19610, 19616, 19620, 19624, + 19626, 19628, 19629, 19631, 19633, 19635, 19637, 19652, + 19656, 19658, 19660, 19665, 19669, 19673, 19675, 19677, + 19681, 19685, 19687, 19692, 19699, 19704, 19708, 19713, + 19714, 19718, 19720, 19726, 19731, 19732, 19733, 19735, + 19744, 19746, 19765, 19769, 19771, 19777, 19781, 19782, + 19786, 19790, 19792, 19794, 19799, 19812, 19814, 19816, + 19820, 19824, 19826, 19828, 19830, 19834, 19836, 19838, + 19840, 19842, 19843, 19847, 19853, 19857, 19863, 19865, + 19869, 19873, 19878, 19879, 19881, 19882, 19888, 19891, + 19893, 19893, 19897, 19899, 19909, 19912, 19919, 19928, + 19935, 19942, 19955, 19962, 19966, 19970, 19977, 20009, + 20016, 20020, 20022, 20025, 20032, 20048, 20066, 20085, + 20102, 20119, 20129, 20146, 20161, 20182, 20190, 20203, + 20216, 20231, 20246, 20257, 20272, 20281, 20291, 20294, + 20296, 20301, 20303, 20311, 20317, 20327, 20328, 20375, + 20377, 20387, 20394, 20400, 20410, 20420, 20422, 20426, + 20430, 20435, 20441, 20445, 20450, 20452, 20458, 20464, + 20474, 20478, 20482, 20495, 20499, 20517, 20521, 20527, + 20529, 20535, 20540, 20550, 20555, 20560, 20562, 20592, + 20599, 20605, 20609, 20616, 20622, 20630, 20636, 20642, + 20648, 20653, 20657, 20664, 20671, 20680, 20686, 20703, + 20715, 20719, 20722, 20726, 20736, 20746, 20785, 20786, + 20789, 20795, 20811, 20817, 20841, 20847, 20849, 20855, + 20861, 20865, 20871, 20879, 20885, 20889, 20906, 20922, + 20926, 20931, 20937, 20943, 20946, 20950, 20952, 20964, + 20968, 20972, 20978, 20982, 20985, 20993, 21013, 21017, + 21023, 21025, 21029, 21033, 21038, 21045, 21051, 21052, + 21058, 21061, 21063, 21063, 21065, 21069, 21071, 21081, + 21084, 21092, 21102, 21111, 21122, 21135, 21142, 21146, + 21150, 21160, 21192, 21199, 21203, 21205, 21208, 21218, + 21234, 21254, 21273, 21292, 21309, 21323, 21340, 21357, + 21378, 21388, 21401, 21418, 21433, 21450, 21461, 21480, + 21489, 21501, 21504, 21508, 21513, 21517, 21527, 21533, + 21543, 21544, 21593, 21595, 21607, 21616, 21622, 21632, + 21642, 21644, 21652, 21658, 21663, 21669, 21673, 21678, + 21684, 21690, 21700, 21712, 21716, 21720, 21733, 21737, + 21755, 21764, 21776, 21778, 21784, 21789, 21799, 21804, + 21809, 21811, 21841, 21848, 21854, 21858, 21865, 21871, + 21883, 21891, 21897, 21903, 21916, 21920, 21929, 21936, + 21945, 21953, 21970, 21982, 21990, 21993, 21997, 22007, + 22017, 22056, 22057, 22060, 22066, 22082, 22088, 22113, + 22119, 22125, 22131, 22139, 22143, 22149, 22162, 22168, + 22176, 22193, 22209, 22213, 22222, 22228, 22234, 22241, + 22245, 22249, 22261, 22265, 22269, 22275, 22279, 22282, + 22290, 22310, 22314, 22320, 22322, 22326, 22330, 22335, + 22342, 22348, 22349, 22355, 22358, 22360, 22360, 22362, + 22366, 22368, 22378, 22381, 22388, 22398, 22405, 22415, + 22428, 22435, 22439, 22443, 22452, 22484, 22491, 22495, + 22497, 22500, 22510, 22526, 22546, 22565, 22584, 22601, + 22615, 22632, 22649, 22670, 22680, 22693, 22710, 22725, + 22742, 22753, 22772, 22781, 22793, 22796, 22800, 22805, + 22809, 22819, 22825, 22835, 22836, 22885, 22887, 22899, + 22908, 22914, 22924, 22934, 22936, 22944, 22950, 22955, + 22961, 22965, 22970, 22976, 22982, 22992, 23004, 23008, + 23012, 23025, 23029, 23047, 23053, 23064, 23066, 23072, + 23077, 23087, 23097, 23104, 23110, 23140, 23147, 23153, + 23157, 23164, 23170, 23182, 23190, 23196, 23202, 23215, + 23219, 23228, 23235, 23244, 23252, 23269, 23281, 23287, + 23290, 23296, 23306, 23316, 23355, 23356, 23359, 23365, + 23381, 23387, 23412, 23418, 23424, 23430, 23438, 23442, + 23448, 23461, 23467, 23475, 23492, 23508, 23512, 23521, + 23527, 23533, 23540, 23544, 23548, 23560, 23564, 23568, + 23574, 23578, 23582, 23590, 23610, 23614, 23620, 23622, + 23626, 23630, 23635, 23642, 23648, 23649, 23655, 23658, + 23660, 23660, 23662, 23663, 23665, 23667, 23669, 23672, + 23677, 23682, 23685, 23693, 23697, 23699, 23701, 23703, + 23733, 23754, 23760, 23762, 23777, 23782, 23788, 23789, + 23796, 23800, 23803, 23813, 23829, 23849, 23868, 23887, + 23904, 23918, 23935, 23952, 23973, 23983, 23996, 24013, + 24028, 24045, 24056, 24075, 24084, 24096, 24100, 24104, + 24114, 24120, 24130, 24142, 24151, 24153, 24158, 24160, + 24170, 24173, 24180, 24191, 24198, 24208, 24221, 24228, + 24232, 24236, 24245, 24277, 24284, 24288, 24290, 24293, + 24303, 24319, 24339, 24358, 24377, 24394, 24408, 24425, + 24442, 24463, 24473, 24486, 24503, 24518, 24535, 24546, + 24565, 24574, 24586, 24589, 24593, 24598, 24602, 24612, + 24618, 24628, 24629, 24682, 24684, 24696, 24705, 24705, + 24707, 24713, 24723, 24733, 24735, 24743, 24749, 24754, + 24760, 24764, 24769, 24775, 24781, 24791, 24803, 24807, + 24811, 24824, 24828, 24846, 24856, 24867, 24869, 24875, + 24880, 24890, 24897, 24902, 24904, 24908, 24914, 24916, + 24917, 24919, 24921, 24923, 24926, 24931, 24936, 24939, + 24947, 24951, 24953, 24955, 24957, 24987, 24995, 24997, + 24999, 25002, 25007, 25012, 25022, 25034, 25040, 25045, + 25055, 25058, 25065, 25069, 25077, 25087, 25091, 25099, + 25101, 25109, 25112, 25114, 25119, 25121, 25128, 25130, + 25138, 25139, 25164, 25166, 25176, 25181, 25181, 25183, + 25185, 25189, 25193, 25195, 25199, 25201, 25202, 25206, + 25208, 25213, 25215, 25219, 25223, 25227, 25229, 25231, + 25240, 25244, 25250, 25254, 25258, 25260, 25262, 25263, + 25265, 25272, 25274, 25276, 25278, 25280, 25282, 25300, + 25304, 25306, 25308, 25313, 25317, 25321, 25323, 25327, + 25331, 25335, 25337, 25342, 25349, 25354, 25358, 25358, + 25362, 25364, 25368, 25373, 25374, 25378, 25380, 25390, + 25396, 25401, 25402, 25403, 25405, 25414, 25416, 25435, + 25439, 25441, 25447, 25451, 25452, 25456, 25460, 25462, + 25464, 25469, 25482, 25484, 25486, 25490, 25494, 25496, + 25498, 25500, 25504, 25506, 25508, 25510, 25512, 25513, + 25517, 25523, 25527, 25533, 25535, 25539, 25543, 25548, + 25549, 25551, 25552, 25558, 25561, 25593, 25600, 25606, + 25610, 25617, 25623, 25635, 25643, 25651, 25657, 25670, + 25674, 25683, 25690, 25699, 25707, 25707, 25711, 25713, + 25717, 25734, 25746, 25753, 25756, 25758, 25768, 25778, + 25817, 25818, 25821, 25827, 25843, 25849, 25874, 25880, + 25886, 25892, 25900, 25904, 25910, 25923, 25929, 25937, + 25954, 25970, 25974, 25983, 25989, 25995, 26002, 26006, + 26010, 26022, 26026, 26030, 26036, 26040, 26043, 26051, + 26071, 26075, 26081, 26083, 26087, 26091, 26096, 26103, + 26109, 26110, 26116, 26119, 26121, 26123, 26129, 26139, + 26149, 26157, 26163, 26168, 26174, 26178, 26184, 26190, + 26200, 26212, 26216, 26220, 26233, 26241, 26252, 26258, + 26263, 26273, 26277, 26278, 26280, 26282, 26284, 26287, + 26292, 26297, 26300, 26308, 26312, 26314, 26316, 26318, + 26348, 26356, 26358, 26360, 26363, 26368, 26373, 26383, + 26395, 26401, 26406, 26416, 26419, 26426, 26430, 26438, + 26448, 26452, 26460, 26462, 26470, 26473, 26475, 26480, + 26482, 26489, 26491, 26499, 26500, 26521, 26523, 26533, + 26538, 26540, 26544, 26548, 26550, 26554, 26556, 26557, + 26561, 26563, 26568, 26570, 26574, 26578, 26582, 26584, + 26586, 26595, 26599, 26605, 26609, 26613, 26615, 26617, + 26618, 26620, 26622, 26624, 26626, 26641, 26645, 26647, + 26649, 26654, 26658, 26662, 26664, 26666, 26670, 26674, + 26676, 26681, 26688, 26693, 26697, 26702, 26703, 26707, + 26709, 26715, 26720, 26721, 26722, 26724, 26733, 26735, + 26754, 26758, 26760, 26766, 26770, 26771, 26775, 26779, + 26781, 26783, 26788, 26801, 26803, 26805, 26809, 26813, + 26815, 26817, 26819, 26823, 26825, 26827, 26829, 26831, + 26832, 26836, 26842, 26846, 26852, 26854, 26858, 26862, + 26867, 26868, 26870, 26871, 26877, 26880, 26882, 26882, + 26884, 26886, 26900, 26905, 26907, 26917, 26920, 26927, + 26938, 26945, 26955, 26968, 26975, 26979, 26983, 26992, + 27024, 27031, 27035, 27037, 27040, 27050, 27066, 27086, + 27105, 27124, 27141, 27155, 27172, 27189, 27210, 27220, + 27233, 27250, 27265, 27282, 27293, 27312, 27321, 27333, + 27336, 27340, 27345, 27349, 27359, 27365, 27375, 27376, + 27425, 27427, 27439, 27448, 27454, 27464, 27474, 27476, + 27484, 27490, 27495, 27501, 27505, 27510, 27516, 27522, + 27532, 27544, 27548, 27552, 27565, 27569, 27587, 27597, + 27608, 27610, 27616, 27621, 27631, 27636, 27641, 27643, + 27673, 27680, 27686, 27690, 27697, 27703, 27715, 27723, + 27729, 27735, 27748, 27752, 27761, 27768, 27777, 27785, + 27802, 27814, 27821, 27824, 27828, 27838, 27848, 27887, + 27888, 27891, 27897, 27913, 27919, 27944, 27950, 27956, + 27962, 27970, 27974, 27980, 27993, 27999, 28007, 28024, + 28040, 28044, 28053, 28059, 28065, 28072, 28076, 28080, + 28092, 28096, 28100, 28106, 28110, 28113, 28121, 28141, + 28145, 28151, 28153, 28157, 28161, 28166, 28173, 28179, + 28180, 28186, 28189, 28191, 28191, 28193, 28194, 28196, + 28198, 28200, 28203, 28208, 28213, 28216, 28224, 28228, + 28230, 28232, 28234, 28264, 28272, 28274, 28276, 28279, + 28284, 28289, 28299, 28311, 28317, 28322, 28332, 28335, + 28342, 28346, 28354, 28364, 28368, 28376, 28378, 28386, + 28389, 28391, 28396, 28398, 28405, 28407, 28415, 28416, + 28441, 28443, 28453, 28458, 28460, 28464, 28468, 28470, + 28474, 28476, 28477, 28481, 28483, 28488, 28490, 28494, + 28498, 28502, 28504, 28506, 28515, 28519, 28525, 28529, + 28533, 28535, 28537, 28538, 28540, 28547, 28549, 28551, + 28569, 28573, 28575, 28577, 28582, 28586, 28590, 28592, + 28596, 28600, 28604, 28606, 28611, 28618, 28623, 28627, + 28632, 28633, 28637, 28641, 28651, 28657, 28662, 28663, + 28664, 28666, 28675, 28677, 28696, 28700, 28702, 28708, + 28712, 28713, 28717, 28721, 28723, 28725, 28730, 28743, + 28745, 28747, 28751, 28755, 28757, 28759, 28761, 28765, + 28767, 28769, 28771, 28773, 28774, 28778, 28784, 28788, + 28794, 28796, 28800, 28804, 28809, 28810, 28812, 28813, + 28819, 28822, 28824, 28824, 28825, 28827, 28829, 28831, + 28834, 28839, 28844, 28847, 28855, 28859, 28861, 28863, + 28865, 28895, 28903, 28905, 28907, 28910, 28915, 28920, + 28930, 28942, 28948, 28953, 28963, 28966, 28973, 28977, + 28985, 28995, 28999, 29007, 29009, 29017, 29020, 29022, + 29027, 29029, 29036, 29038, 29046, 29047, 29068, 29070, + 29080, 29085, 29087, 29091, 29095, 29097, 29101, 29103, + 29104, 29108, 29110, 29115, 29117, 29121, 29125, 29129, + 29131, 29133, 29142, 29146, 29152, 29158, 29167, 29169, + 29171, 29172, 29174, 29181, 29185, 29189, 29192, 29194, + 29196, 29198, 29213, 29217, 29219, 29221, 29226, 29230, + 29234, 29236, 29238, 29242, 29246, 29248, 29253, 29260, + 29265, 29269, 29277, 29278, 29284, 29286, 29288, 29290, + 29296, 29301, 29302, 29303, 29305, 29314, 29316, 29335, + 29339, 29341, 29347, 29351, 29352, 29356, 29360, 29362, + 29364, 29369, 29382, 29384, 29386, 29390, 29394, 29396, + 29398, 29400, 29404, 29406, 29408, 29410, 29412, 29414, + 29415, 29419, 29425, 29429, 29435, 29437, 29441, 29445, + 29450, 29451, 29453, 29454, 29460, 29463, 29465, 29465, + 29467, 29468, 29470, 29472, 29474, 29477, 29482, 29487, + 29490, 29498, 29502, 29504, 29506, 29508, 29538, 29546, + 29548, 29550, 29553, 29558, 29563, 29573, 29585, 29591, + 29596, 29606, 29609, 29616, 29620, 29628, 29638, 29642, + 29650, 29652, 29660, 29663, 29665, 29670, 29672, 29679, + 29681, 29689, 29690, 29711, 29713, 29723, 29728, 29730, + 29734, 29738, 29740, 29744, 29746, 29747, 29751, 29753, + 29758, 29760, 29764, 29768, 29772, 29774, 29776, 29785, + 29789, 29795, 29799, 29803, 29805, 29807, 29808, 29810, + 29812, 29814, 29816, 29831, 29835, 29837, 29839, 29844, + 29848, 29852, 29854, 29856, 29860, 29864, 29866, 29871, + 29878, 29883, 29887, 29892, 29893, 29897, 29899, 29905, + 29910, 29911, 29912, 29914, 29923, 29925, 29944, 29948, + 29950, 29956, 29960, 29961, 29965, 29969, 29971, 29973, + 29978, 29991, 29993, 29995, 29999, 30003, 30005, 30007, + 30009, 30013, 30015, 30017, 30019, 30021, 30022, 30026, + 30032, 30036, 30042, 30044, 30048, 30052, 30057, 30058, + 30060, 30061, 30067, 30070, 30072, 30072, 30080, 30081, + 30082, 30084, 30086, 30088, 30091, 30096, 30101, 30104, + 30112, 30116, 30118, 30120, 30122, 30152, 30160, 30162, + 30164, 30167, 30172, 30177, 30187, 30199, 30205, 30210, + 30220, 30223, 30230, 30234, 30242, 30252, 30256, 30264, + 30266, 30274, 30277, 30279, 30284, 30286, 30293, 30295, + 30303, 30304, 30325, 30327, 30337, 30342, 30344, 30348, + 30352, 30354, 30358, 30360, 30361, 30365, 30367, 30372, + 30374, 30378, 30382, 30386, 30388, 30390, 30399, 30403, + 30409, 30413, 30417, 30419, 30421, 30422, 30424, 30426, + 30428, 30430, 30445, 30449, 30451, 30453, 30458, 30462, + 30466, 30468, 30470, 30474, 30478, 30480, 30485, 30492, + 30497, 30501, 30506, 30507, 30511, 30513, 30519, 30524, + 30525, 30526, 30528, 30537, 30539, 30558, 30562, 30564, + 30570, 30574, 30575, 30579, 30583, 30585, 30587, 30592, + 30605, 30607, 30609, 30613, 30617, 30619, 30621, 30623, + 30627, 30629, 30631, 30633, 30635, 30636, 30640, 30646, + 30650, 30656, 30658, 30662, 30666, 30671, 30672, 30674, + 30675, 30681, 30684, 30686, 30686, 30688, 30690, 30692, + 30695, 30700, 30705, 30708, 30716, 30720, 30722, 30724, + 30726, 30756, 30777, 30783, 30785, 30800, 30805, 30811, + 30812, 30814, 30821, 30827, 30831, 30838, 30844, 30856, + 30864, 30872, 30878, 30891, 30895, 30904, 30913, 30921, + 30922, 30927, 30929, 30939, 30942, 30949, 30960, 30967, + 30977, 30990, 30997, 31001, 31005, 31014, 31046, 31053, + 31057, 31059, 31062, 31072, 31088, 31108, 31127, 31146, + 31163, 31177, 31194, 31211, 31232, 31242, 31255, 31272, + 31287, 31304, 31315, 31334, 31343, 31355, 31358, 31362, + 31367, 31371, 31381, 31387, 31397, 31398, 31451, 31453, + 31465, 31474, 31480, 31490, 31500, 31502, 31510, 31516, + 31521, 31527, 31531, 31536, 31542, 31548, 31558, 31570, + 31574, 31578, 31591, 31595, 31613, 31623, 31634, 31636, + 31642, 31647, 31657, 31664, 31669, 31671, 31703, 31710, + 31716, 31720, 31727, 31733, 31745, 31753, 31761, 31767, + 31780, 31784, 31793, 31800, 31809, 31817, 31834, 31846, + 31853, 31856, 31860, 31870, 31880, 31919, 31920, 31923, + 31929, 31945, 31951, 31976, 31982, 31988, 31994, 32002, + 32006, 32012, 32025, 32031, 32039, 32056, 32072, 32076, + 32085, 32091, 32097, 32104, 32108, 32112, 32124, 32128, + 32132, 32138, 32142, 32145, 32153, 32173, 32177, 32183, + 32185, 32189, 32193, 32198, 32205, 32211, 32212, 32218, + 32221, 32223, 32223, 32225, 32227, 32229, 32231, 32234, + 32239, 32244, 32247, 32255, 32259, 32261, 32263, 32265, + 32295, 32316, 32322, 32324, 32339, 32344, 32350, 32351, + 32353, 32355, 32367, 32373, 32376, 32380, 32386, 32396, + 32435, 32438, 32444, 32460, 32466, 32491, 32497, 32503, + 32509, 32517, 32521, 32527, 32540, 32546, 32554, 32571, + 32587, 32591, 32600, 32606, 32612, 32619, 32623, 32627, + 32639, 32643, 32647, 32653, 32657, 32661, 32663, 32671, + 32691, 32698, 32704, 32709, 32711, 32712, 32714, 32716, + 32718, 32721, 32726, 32731, 32734, 32742, 32746, 32748, + 32750, 32752, 32782, 32790, 32792, 32794, 32797, 32802, + 32807, 32817, 32829, 32835, 32840, 32850, 32853, 32860, + 32864, 32872, 32882, 32886, 32894, 32896, 32904, 32907, + 32909, 32914, 32916, 32923, 32925, 32933, 32934, 32955, + 32957, 32967, 32972, 32974, 32978, 32982, 32984, 32988, + 32990, 32991, 32995, 32997, 33002, 33004, 33008, 33012, + 33016, 33018, 33020, 33029, 33033, 33039, 33043, 33047, + 33049, 33051, 33052, 33054, 33056, 33058, 33060, 33075, + 33079, 33081, 33083, 33088, 33092, 33096, 33098, 33100, + 33104, 33108, 33110, 33115, 33122, 33127, 33131, 33136, + 33137, 33141, 33143, 33150, 33155, 33156, 33157, 33159, + 33168, 33170, 33189, 33193, 33195, 33201, 33205, 33206, + 33210, 33214, 33216, 33218, 33223, 33236, 33238, 33240, + 33244, 33248, 33250, 33252, 33254, 33258, 33260, 33262, + 33264, 33266, 33267, 33271, 33277, 33281, 33287, 33289, + 33293, 33297, 33302, 33303, 33305, 33306, 33307, 33313, + 33316, 33318, 33318, 33319, 33322, 33322, 33324, 33326, + 33329, 33331, 33333, 33336, 33338, 33342, 33344, 33393, + 33414, 33415, 33460, 33505, 33549, 33594, 33635, 33680, + 33721, 33743, 33784, 33828, 33869, 33910, 33936, 33957, + 33984, 34029, 34081, 34107, 34128, 34178, 34216, 34261, + 34302, 34348, 34395, 34444, 34493, 34540, 34592, 34644, + 34667, 34690, 34742, 34788, 34834, 34908, 34973, 35023, + 35069, 35128, 35177, 35227, 35272, 35303, 35330, 35359, + 35381, 35403, 35425, 35450, 35476, 35508, 35536, 35564, + 35594, 35617, 35640, 35663, 35689, 35742, 35812, 35851, + 35877, 35928, 35980, 36026, 36076, 36097, 36143, 36197, + 36246, 36292, 36340, 36388, 36438, 36463, 36501, 36532, + 36554, 36606, 36652, 36697, 36745, 36791, 36840, 36886, + 36938, 36990, 37038, 37084, 37130, 37183, 37231, 37279, + 37327, 37373, 37419, 37464, 37510, 37556, 37602, 37650, + 37696, 37742, 37791, 37843, 37895, 37941, 37987, 38039, + 38092, 38138, 38187, 38238, 38287, 38335, 38380, 38428, + 38474, 38523, 38586, 38634, 38679, 38729, 38774, 38824, + 38871, 38924, 38977, 39035, 39095, 39149, 39198, 39252, + 39299, 39350, 39402, 39458, 39512, 39564, 39620, 39666, + 39718, 39765, 39811, 39860, 39906, 39957, 40003, 40055, + 40100, 40130, 40153, 40175, 40198, 40220, 40243, 40266, + 40290, 40316, 40342, 40366, 40395, 40420, 40443, 40466, + 40490, 40516, 40542, 40566, 40595, 40620, 40643, 40666, + 40689, 40740, 40782, 40809, 40832, 40868, 40894, 40921, + 40943, 40966, 40989, 41012, 41063, 41105, 41132, 41155, + 41191, 41217, 41244, 41266, 41297, 41326, 41350, 41378, + 41409, 41437, 41468, 41502, 41530, 41555, 41580, 41610, + 41663, 41737, 41781, 41805, 41850, 41871, 41908, 41952, + 41976, 41998, 42019, 42040, 42069, 42092, 42115, 42137, + 42160, 42182, 42205, 42228, 42251, 42275, 42301, 42327, + 42351, 42380, 42405, 42428, 42451, 42475, 42501, 42527, + 42551, 42580, 42605, 42628, 42651, 42674, 42725, 42767, + 42794, 42817, 42853, 42879, 42906, 42928, 42951, 42974, + 42997, 43048, 43090, 43117, 43140, 43176, 43202, 43229, + 43251, 43275, 43301, 43327, 43358, 43391, 43418, 43444, + 43475, 43499, 43527, 43552, 43581, 43612, 43637, 43666, + 43689, 43718, 43742, 43765, 43791, 43814, 43842, 43865, + 43894, 43916, 43939, 43970, 43996, 44019, 44044, 44069, + 44092, 44117, 44140, 44162, 44187, 44210, 44236, 44259, + 44284, 44309, 44334, 44357, 44380, 44410, 44435, 44460, + 44485, 44508, 44531, 44553, 44576, 44599, 44622, 44647, + 44670, 44693, 44719, 44744, 44769, 44792, 44815, 44840, + 44865, 44888, 44914, 44942, 44968, 44993, 45015, 45040, + 45063, 45089, 45129, 45154, 45176, 45203, 45225, 45252, + 45276, 45297, 45321, 45374, 45418, 45470, 45516, 45566, + 45592, 45615, 45660, 45712, 45743, 45767, 45795, 45827, + 45855, 45886, 45920, 45948, 45998, 46044, 46091, 46140, + 46189, 46236, 46288, 46340, 46365, 46390, 46420, 46473, + 46547, 46586, 46614, 46667, 46713, 46767, 46816, 46862, + 46910, 46958, 47008, 47029, 47077, 47125, 47171, 47217, + 47262, 47308, 47354, 47400, 47448, 47494, 47540, 47589, + 47641, 47666, 47704, 47735, 47757, 47809, 47855, 47901, + 47953, 48006, 48052, 48101, 48152, 48201, 48249, 48294, + 48342, 48388, 48437, 48500, 48548, 48593, 48643, 48688, + 48738, 48790, 48836, 48881, 48929, 48975, 49024, 49070, + 49122, 49174, 49222, 49268, 49314, 49367, 49415, 49467, + 49513, 49559, 49633, 49698, 49748, 49794, 49853, 49902, + 49952, 49997, 50044, 50097, 50150, 50208, 50268, 50322, + 50371, 50425, 50472, 50523, 50575, 50631, 50685, 50737, + 50793, 50839, 50891, 50938, 50984, 51033, 51079, 51130, + 51176, 51228, 51273, 51316, 51354, +} + +var _s_trans_keys []byte = []byte{ + 173, 0, 127, 176, 255, 131, 137, 191, + 145, 189, 135, 129, 130, 132, 133, 156, + 128, 133, 144, 154, 176, 139, 159, 150, + 157, 159, 164, 167, 168, 170, 173, 143, + 145, 176, 255, 139, 255, 166, 176, 171, + 179, 160, 161, 163, 164, 165, 167, 169, + 171, 173, 174, 175, 176, 177, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 166, 170, 172, 178, 150, + 153, 155, 163, 165, 167, 169, 173, 153, + 155, 163, 255, 189, 132, 185, 144, 152, + 161, 164, 255, 188, 129, 131, 190, 255, + 133, 134, 137, 138, 142, 150, 152, 161, + 164, 255, 131, 134, 137, 138, 142, 144, + 146, 175, 178, 180, 182, 255, 134, 138, + 142, 161, 164, 255, 188, 129, 131, 190, + 191, 128, 132, 135, 136, 139, 141, 150, + 151, 162, 163, 130, 190, 191, 151, 128, + 130, 134, 136, 138, 141, 128, 131, 190, + 255, 133, 137, 142, 148, 151, 161, 164, + 255, 128, 132, 134, 136, 138, 141, 149, + 150, 162, 163, 129, 131, 190, 255, 133, + 137, 142, 150, 152, 161, 164, 255, 130, + 131, 138, 150, 143, 148, 152, 159, 178, + 179, 177, 180, 186, 135, 142, 177, 180, + 185, 187, 188, 136, 141, 181, 183, 185, + 152, 153, 190, 191, 177, 191, 128, 132, + 134, 135, 141, 151, 153, 188, 134, 128, + 129, 130, 141, 156, 157, 158, 159, 160, + 162, 164, 168, 169, 170, 172, 173, 174, + 175, 176, 179, 183, 171, 190, 150, 153, + 158, 160, 162, 164, 167, 173, 177, 180, + 143, 130, 141, 154, 157, 157, 159, 146, + 148, 178, 180, 146, 147, 178, 179, 180, + 255, 148, 156, 158, 255, 139, 142, 169, + 160, 171, 176, 187, 151, 155, 191, 149, + 158, 160, 188, 176, 190, 128, 132, 180, + 255, 133, 170, 180, 255, 128, 130, 161, + 173, 166, 179, 164, 183, 173, 144, 146, + 148, 168, 178, 180, 184, 185, 128, 181, + 188, 191, 128, 129, 131, 179, 181, 183, + 140, 143, 170, 174, 160, 164, 166, 175, + 144, 176, 175, 177, 191, 160, 191, 128, + 130, 170, 175, 153, 154, 153, 154, 155, + 160, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 175, 175, 178, 180, 189, + 158, 159, 176, 177, 130, 134, 139, 163, + 167, 128, 129, 180, 255, 133, 159, 178, + 255, 166, 173, 135, 147, 128, 131, 179, + 255, 129, 164, 166, 255, 169, 182, 131, + 140, 141, 187, 189, 176, 178, 180, 183, + 184, 190, 191, 129, 171, 175, 181, 182, + 163, 170, 172, 173, 172, 184, 187, 190, + 191, 158, 128, 143, 160, 175, 185, 187, + 144, 145, 150, 155, 157, 158, 135, 139, + 141, 168, 171, 189, 160, 182, 186, 191, + 129, 131, 133, 134, 140, 143, 184, 186, + 165, 166, 128, 129, 130, 132, 133, 134, + 135, 136, 139, 140, 141, 146, 147, 150, + 151, 152, 153, 154, 156, 128, 130, 184, + 255, 135, 190, 131, 175, 187, 188, 190, + 255, 128, 130, 167, 180, 179, 128, 130, + 179, 255, 129, 137, 141, 255, 172, 183, + 159, 170, 188, 128, 131, 190, 191, 151, + 128, 132, 135, 136, 139, 141, 162, 163, + 166, 172, 176, 180, 176, 255, 132, 255, + 175, 181, 184, 255, 129, 155, 158, 255, + 129, 255, 171, 183, 157, 171, 171, 172, + 189, 190, 176, 180, 176, 182, 145, 190, + 143, 146, 178, 157, 158, 160, 163, 133, + 134, 137, 168, 169, 170, 165, 169, 173, + 255, 131, 132, 140, 169, 174, 255, 130, + 132, 128, 182, 187, 255, 173, 180, 182, + 255, 132, 155, 159, 161, 175, 163, 144, + 150, 160, 128, 129, 132, 135, 133, 134, + 129, 160, 255, 192, 255, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 48, 57, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 65, 90, 97, 122, 196, 218, + 235, 236, 170, 173, 181, 186, 128, 150, + 152, 182, 184, 255, 192, 255, 128, 255, + 173, 130, 133, 146, 159, 165, 171, 175, + 255, 0, 127, 181, 190, 176, 183, 184, + 185, 186, 191, 192, 255, 134, 140, 136, + 138, 142, 161, 163, 255, 182, 130, 131, + 137, 176, 151, 152, 154, 160, 190, 136, + 144, 145, 191, 192, 255, 135, 129, 130, + 132, 133, 144, 170, 176, 179, 156, 128, + 133, 144, 154, 160, 191, 176, 128, 138, + 139, 159, 174, 255, 148, 158, 169, 150, + 164, 167, 173, 176, 185, 189, 190, 192, + 255, 144, 143, 145, 146, 175, 176, 255, + 139, 140, 141, 255, 166, 176, 178, 255, + 186, 138, 170, 171, 179, 180, 181, 160, + 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 154, + 164, 168, 128, 149, 150, 173, 128, 152, + 153, 155, 160, 180, 163, 255, 189, 132, + 185, 144, 152, 161, 164, 176, 177, 255, + 132, 169, 177, 188, 129, 131, 141, 142, + 145, 146, 179, 181, 186, 187, 190, 255, + 142, 158, 133, 134, 137, 138, 143, 150, + 152, 155, 156, 161, 164, 175, 176, 177, + 178, 255, 188, 129, 131, 133, 138, 143, + 144, 147, 168, 170, 176, 178, 179, 181, + 182, 184, 185, 190, 255, 157, 131, 134, + 137, 138, 142, 144, 146, 152, 153, 158, + 159, 175, 178, 180, 182, 255, 189, 129, + 131, 133, 141, 143, 145, 147, 168, 170, + 176, 178, 179, 181, 185, 188, 255, 134, + 138, 144, 185, 142, 159, 160, 161, 164, + 255, 189, 129, 131, 133, 140, 143, 144, + 147, 168, 170, 176, 178, 179, 181, 185, + 188, 191, 177, 128, 132, 135, 136, 139, + 141, 150, 151, 156, 157, 159, 161, 162, + 163, 130, 131, 156, 133, 138, 142, 144, + 146, 149, 153, 154, 158, 159, 163, 164, + 168, 170, 174, 185, 190, 191, 144, 151, + 128, 130, 134, 136, 138, 141, 189, 128, + 131, 133, 140, 142, 144, 146, 168, 170, + 185, 190, 255, 133, 137, 151, 142, 148, + 152, 154, 155, 159, 160, 161, 164, 255, + 189, 129, 131, 133, 140, 142, 144, 146, + 168, 170, 179, 181, 185, 188, 191, 158, + 128, 132, 134, 136, 138, 141, 149, 150, + 160, 161, 162, 163, 177, 178, 189, 129, + 131, 133, 140, 142, 144, 146, 186, 190, + 255, 133, 137, 142, 143, 150, 152, 158, + 159, 161, 164, 185, 186, 191, 192, 255, + 189, 130, 131, 133, 150, 154, 177, 179, + 187, 138, 150, 128, 134, 143, 148, 152, + 159, 178, 179, 177, 180, 186, 135, 142, + 177, 180, 185, 187, 188, 136, 141, 128, + 181, 183, 185, 152, 153, 190, 191, 128, + 135, 137, 172, 177, 191, 128, 132, 134, + 135, 136, 140, 141, 151, 153, 188, 134, + 128, 129, 130, 131, 137, 138, 139, 140, + 141, 142, 143, 144, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, + 168, 169, 170, 172, 173, 174, 175, 176, + 177, 179, 181, 182, 183, 188, 189, 190, + 191, 132, 152, 180, 184, 185, 187, 171, + 190, 150, 153, 158, 160, 162, 164, 167, + 173, 177, 180, 143, 130, 141, 154, 157, + 160, 255, 134, 187, 136, 140, 142, 143, + 137, 151, 153, 142, 143, 158, 159, 137, + 177, 142, 143, 182, 183, 191, 255, 128, + 130, 133, 136, 150, 152, 255, 145, 150, + 151, 155, 156, 157, 159, 160, 255, 128, + 143, 160, 255, 182, 183, 190, 255, 129, + 255, 173, 174, 192, 255, 129, 154, 160, + 255, 171, 173, 185, 255, 128, 140, 142, + 145, 146, 148, 160, 177, 178, 180, 128, + 145, 146, 147, 160, 172, 174, 176, 178, + 179, 180, 255, 148, 156, 158, 255, 139, + 142, 160, 255, 184, 255, 169, 128, 170, + 176, 255, 182, 255, 128, 158, 160, 171, + 176, 187, 128, 150, 151, 155, 191, 149, + 158, 160, 188, 176, 190, 128, 132, 133, + 179, 180, 255, 133, 139, 140, 170, 180, + 255, 128, 130, 131, 160, 161, 173, 174, + 175, 186, 255, 166, 179, 180, 255, 128, + 163, 164, 183, 141, 143, 154, 189, 173, + 144, 146, 148, 168, 169, 177, 178, 180, + 181, 182, 184, 185, 128, 181, 188, 191, + 150, 151, 158, 159, 152, 154, 156, 158, + 134, 135, 142, 143, 190, 255, 190, 128, + 180, 182, 188, 130, 132, 134, 140, 144, + 147, 150, 155, 160, 172, 178, 180, 182, + 188, 128, 129, 130, 131, 132, 133, 134, + 146, 147, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 140, 143, 170, 174, 177, + 191, 160, 164, 166, 175, 144, 156, 144, + 176, 130, 135, 149, 164, 166, 168, 138, + 147, 153, 157, 170, 173, 175, 185, 188, + 191, 142, 133, 137, 160, 255, 137, 255, + 182, 255, 170, 255, 128, 174, 176, 255, + 159, 165, 170, 175, 177, 180, 255, 167, + 173, 128, 165, 176, 255, 191, 168, 174, + 176, 255, 128, 150, 160, 166, 168, 174, + 176, 182, 184, 190, 128, 134, 136, 142, + 144, 150, 152, 158, 160, 191, 175, 128, + 130, 132, 133, 134, 133, 170, 175, 187, + 188, 153, 154, 133, 173, 177, 255, 143, + 159, 187, 255, 128, 146, 147, 148, 152, + 153, 154, 155, 156, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 129, + 255, 141, 255, 144, 189, 141, 143, 160, + 169, 172, 255, 191, 128, 174, 175, 178, + 180, 189, 128, 157, 158, 159, 160, 255, + 176, 177, 178, 255, 151, 159, 162, 255, + 137, 138, 174, 175, 184, 255, 183, 255, + 130, 134, 139, 163, 167, 168, 255, 128, + 179, 128, 129, 130, 179, 180, 255, 187, + 189, 133, 159, 178, 183, 184, 255, 138, + 165, 166, 173, 176, 255, 135, 147, 148, + 159, 189, 255, 128, 131, 132, 178, 179, + 255, 143, 129, 164, 166, 255, 128, 168, + 169, 182, 131, 128, 139, 140, 141, 187, + 189, 176, 178, 180, 183, 184, 190, 191, + 129, 160, 170, 171, 175, 178, 180, 181, + 182, 129, 134, 137, 142, 145, 150, 160, + 166, 168, 174, 176, 255, 155, 166, 175, + 128, 162, 163, 170, 172, 173, 158, 159, + 160, 255, 164, 175, 135, 138, 188, 255, + 172, 173, 174, 175, 180, 181, 182, 183, + 184, 185, 187, 188, 189, 190, 191, 176, + 186, 158, 190, 128, 134, 147, 151, 157, + 168, 170, 182, 184, 188, 128, 129, 131, + 132, 134, 255, 178, 255, 147, 255, 190, + 255, 144, 255, 144, 145, 136, 175, 188, + 255, 128, 143, 160, 175, 176, 180, 182, + 255, 191, 189, 255, 161, 186, 129, 154, + 158, 159, 160, 190, 130, 135, 138, 143, + 146, 151, 154, 156, 185, 187, 144, 145, + 146, 147, 148, 150, 155, 157, 158, 159, + 128, 129, 130, 131, 133, 135, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 148, + 149, 152, 156, 157, 160, 161, 162, 163, + 164, 166, 168, 169, 170, 171, 172, 173, + 174, 176, 177, 153, 155, 178, 179, 128, + 139, 141, 166, 168, 186, 188, 189, 191, + 255, 142, 143, 158, 255, 187, 255, 128, + 180, 189, 128, 156, 160, 255, 160, 145, + 255, 128, 159, 176, 255, 139, 143, 182, + 186, 187, 255, 128, 157, 160, 255, 144, + 132, 135, 150, 255, 158, 255, 128, 167, + 176, 255, 164, 255, 183, 255, 128, 149, + 160, 167, 136, 188, 128, 133, 138, 181, + 183, 184, 191, 255, 150, 159, 183, 255, + 128, 158, 160, 178, 180, 181, 128, 149, + 160, 185, 128, 183, 190, 191, 128, 191, + 129, 131, 133, 134, 140, 143, 144, 147, + 149, 151, 153, 179, 184, 186, 160, 188, + 128, 156, 128, 135, 137, 164, 165, 166, + 128, 181, 128, 149, 160, 178, 128, 145, + 128, 178, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 138, 139, 140, 141, 146, + 147, 150, 151, 152, 153, 154, 156, 162, + 163, 171, 128, 130, 131, 183, 184, 255, + 135, 190, 131, 175, 187, 188, 190, 255, + 144, 168, 128, 130, 131, 166, 167, 180, + 179, 182, 144, 178, 128, 130, 131, 178, + 179, 255, 154, 156, 129, 132, 133, 137, + 141, 255, 128, 145, 147, 171, 172, 183, + 136, 128, 134, 138, 141, 143, 157, 159, + 168, 176, 255, 159, 170, 171, 255, 189, + 128, 131, 133, 140, 143, 144, 147, 168, + 170, 176, 178, 179, 181, 185, 188, 191, + 144, 151, 128, 132, 135, 136, 139, 141, + 157, 161, 162, 163, 166, 172, 176, 180, + 128, 175, 176, 255, 134, 132, 135, 136, + 255, 128, 174, 175, 181, 184, 255, 129, + 151, 152, 155, 158, 255, 132, 129, 255, + 128, 170, 171, 183, 157, 171, 160, 255, + 160, 190, 192, 255, 128, 184, 128, 142, + 145, 149, 129, 141, 144, 146, 147, 148, + 154, 255, 175, 255, 132, 255, 128, 144, + 129, 143, 144, 153, 145, 152, 135, 255, + 160, 168, 169, 171, 172, 173, 174, 188, + 189, 190, 161, 167, 185, 255, 144, 173, + 176, 180, 128, 175, 176, 182, 128, 131, + 163, 183, 189, 255, 144, 255, 133, 143, + 145, 190, 191, 255, 143, 146, 147, 159, + 176, 177, 178, 171, 175, 189, 255, 128, + 136, 144, 153, 157, 158, 160, 163, 133, + 134, 137, 144, 145, 146, 147, 148, 149, + 154, 155, 156, 157, 158, 159, 168, 169, + 170, 150, 153, 165, 169, 173, 255, 131, + 132, 140, 169, 174, 255, 130, 132, 149, + 157, 173, 186, 188, 160, 161, 163, 164, + 167, 168, 132, 134, 149, 157, 186, 139, + 140, 191, 255, 134, 128, 132, 138, 144, + 146, 255, 166, 167, 129, 155, 187, 149, + 181, 143, 175, 137, 169, 131, 140, 255, + 128, 182, 187, 255, 173, 180, 182, 255, + 132, 155, 159, 161, 175, 160, 163, 184, + 185, 186, 161, 162, 133, 143, 144, 150, + 151, 255, 164, 167, 185, 187, 128, 131, + 133, 159, 161, 162, 169, 178, 180, 183, + 130, 135, 137, 139, 148, 151, 153, 155, + 157, 159, 164, 190, 141, 143, 145, 146, + 161, 162, 167, 170, 172, 178, 180, 183, + 185, 188, 128, 137, 139, 155, 161, 163, + 165, 169, 171, 187, 132, 133, 134, 176, + 255, 138, 143, 170, 175, 138, 255, 160, + 128, 129, 132, 135, 133, 134, 129, 160, + 255, 192, 255, 176, 255, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 48, 57, 173, 128, 255, 176, + 255, 131, 137, 191, 145, 189, 135, 129, + 130, 132, 133, 156, 128, 133, 144, 154, + 171, 176, 139, 159, 160, 169, 150, 157, + 159, 164, 167, 168, 170, 173, 176, 185, + 143, 145, 176, 255, 139, 255, 166, 176, + 128, 137, 171, 179, 160, 161, 163, 164, + 165, 167, 169, 171, 173, 174, 175, 176, + 177, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 166, 170, + 172, 178, 150, 153, 155, 163, 165, 167, + 169, 173, 153, 155, 163, 255, 189, 132, + 185, 144, 152, 161, 164, 165, 166, 175, + 176, 255, 188, 129, 131, 190, 255, 133, + 134, 137, 138, 142, 150, 152, 161, 164, + 165, 166, 175, 176, 255, 131, 134, 137, + 138, 142, 144, 146, 165, 166, 175, 178, + 180, 182, 255, 134, 138, 142, 161, 164, + 165, 166, 175, 176, 255, 188, 129, 131, + 190, 191, 128, 132, 135, 136, 139, 141, + 150, 151, 162, 163, 166, 175, 130, 190, + 191, 151, 128, 130, 134, 136, 138, 141, + 166, 175, 128, 131, 190, 255, 133, 137, + 142, 148, 151, 161, 164, 165, 166, 175, + 176, 255, 128, 132, 134, 136, 138, 141, + 149, 150, 162, 163, 166, 175, 129, 131, + 190, 255, 133, 137, 142, 150, 152, 161, + 164, 165, 166, 175, 176, 255, 130, 131, + 138, 150, 143, 148, 152, 159, 166, 175, + 178, 179, 177, 180, 186, 135, 142, 144, + 153, 177, 180, 185, 187, 188, 136, 141, + 144, 153, 181, 183, 185, 152, 153, 160, + 169, 190, 191, 177, 191, 128, 132, 134, + 135, 141, 151, 153, 188, 134, 128, 129, + 130, 141, 156, 157, 158, 159, 160, 162, + 164, 165, 167, 168, 169, 170, 172, 173, + 174, 175, 176, 177, 179, 183, 171, 190, + 128, 137, 150, 153, 158, 160, 162, 164, + 167, 173, 177, 180, 143, 130, 141, 144, + 153, 154, 157, 157, 159, 146, 148, 178, + 180, 146, 147, 178, 179, 180, 255, 148, + 156, 158, 159, 160, 169, 170, 255, 139, + 142, 144, 153, 169, 160, 171, 176, 187, + 134, 143, 144, 153, 151, 155, 191, 149, + 158, 160, 188, 128, 137, 144, 153, 176, + 190, 128, 132, 180, 255, 133, 143, 144, + 153, 154, 170, 180, 255, 128, 130, 161, + 173, 176, 185, 166, 179, 164, 183, 128, + 137, 144, 153, 173, 144, 146, 148, 168, + 178, 180, 184, 185, 128, 181, 188, 191, + 128, 129, 131, 179, 181, 183, 140, 143, + 170, 174, 160, 164, 166, 175, 144, 176, + 175, 177, 191, 160, 191, 128, 130, 170, + 175, 153, 154, 152, 153, 154, 155, 160, + 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 175, 160, 169, 175, 178, 180, + 189, 158, 159, 176, 177, 130, 134, 139, + 163, 167, 128, 129, 180, 255, 133, 143, + 144, 153, 154, 159, 178, 255, 128, 137, + 166, 173, 135, 147, 128, 131, 179, 255, + 129, 143, 144, 153, 154, 164, 166, 175, + 176, 185, 186, 255, 169, 182, 131, 140, + 141, 144, 153, 187, 189, 176, 178, 180, + 183, 184, 190, 191, 129, 171, 175, 181, + 182, 163, 170, 172, 173, 176, 185, 172, + 184, 187, 190, 191, 158, 128, 143, 160, + 175, 185, 187, 144, 145, 150, 155, 157, + 158, 135, 139, 141, 146, 168, 171, 189, + 160, 182, 186, 191, 129, 131, 133, 134, + 140, 143, 184, 186, 165, 166, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 139, + 140, 141, 146, 147, 150, 151, 152, 153, + 154, 155, 156, 163, 128, 130, 184, 255, + 135, 165, 166, 175, 176, 190, 131, 175, + 187, 188, 190, 255, 176, 185, 128, 130, + 167, 180, 182, 191, 179, 128, 130, 179, + 255, 129, 137, 141, 143, 144, 153, 154, + 255, 172, 183, 159, 170, 176, 185, 188, + 128, 131, 190, 191, 151, 128, 132, 135, + 136, 139, 141, 162, 163, 166, 172, 176, + 180, 176, 255, 132, 143, 144, 153, 154, + 255, 175, 181, 184, 255, 129, 155, 158, + 255, 129, 143, 144, 153, 154, 255, 171, + 183, 128, 137, 157, 171, 176, 185, 169, + 171, 172, 173, 189, 190, 176, 180, 176, + 182, 145, 190, 143, 146, 178, 157, 158, + 160, 163, 133, 134, 137, 159, 168, 169, + 170, 165, 169, 173, 255, 131, 132, 140, + 169, 174, 255, 130, 132, 142, 191, 128, + 182, 187, 255, 173, 180, 182, 255, 132, + 155, 159, 161, 175, 163, 144, 150, 160, + 128, 129, 132, 135, 133, 134, 129, 160, + 255, 192, 255, 170, 173, 181, 186, 128, + 255, 181, 190, 176, 183, 184, 185, 186, + 191, 192, 255, 130, 131, 137, 190, 136, + 144, 145, 191, 192, 255, 135, 179, 129, + 130, 132, 133, 144, 170, 176, 178, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 173, 128, 255, 176, + 255, 131, 137, 191, 145, 189, 135, 129, + 130, 132, 133, 144, 170, 176, 178, 170, + 173, 181, 186, 0, 127, 181, 190, 176, + 183, 184, 185, 186, 191, 192, 255, 130, + 131, 137, 190, 136, 144, 145, 191, 192, + 255, 135, 179, 129, 130, 132, 133, 144, + 170, 176, 178, 156, 128, 133, 144, 154, + 160, 191, 171, 176, 128, 138, 139, 159, + 160, 169, 174, 255, 148, 158, 169, 150, + 164, 167, 173, 176, 185, 189, 190, 192, + 255, 144, 143, 145, 146, 175, 176, 255, + 139, 140, 141, 255, 166, 176, 178, 255, + 186, 128, 137, 138, 170, 171, 179, 180, + 181, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, + 191, 154, 164, 168, 128, 149, 150, 173, + 128, 152, 153, 155, 163, 255, 189, 132, + 185, 144, 176, 152, 161, 164, 165, 166, + 175, 177, 255, 132, 169, 177, 188, 129, + 131, 141, 142, 145, 146, 179, 181, 186, + 187, 190, 255, 142, 158, 133, 134, 137, + 138, 143, 150, 152, 155, 156, 161, 164, + 165, 166, 175, 176, 177, 178, 255, 188, + 129, 131, 133, 138, 143, 144, 147, 168, + 170, 176, 178, 179, 181, 182, 184, 185, + 190, 255, 157, 131, 134, 137, 138, 142, + 144, 146, 152, 153, 158, 159, 165, 166, + 175, 178, 180, 182, 255, 189, 129, 131, + 133, 141, 143, 145, 147, 168, 170, 176, + 178, 179, 181, 185, 188, 255, 134, 138, + 144, 185, 142, 159, 160, 161, 164, 165, + 166, 175, 176, 255, 189, 129, 131, 133, + 140, 143, 144, 147, 168, 170, 176, 178, + 179, 181, 185, 188, 191, 177, 128, 132, + 135, 136, 139, 141, 150, 151, 156, 157, + 159, 161, 162, 163, 166, 175, 130, 131, + 156, 133, 138, 142, 144, 146, 149, 153, + 154, 158, 159, 163, 164, 168, 170, 174, + 185, 190, 191, 144, 151, 128, 130, 134, + 136, 138, 141, 166, 175, 189, 128, 131, + 133, 140, 142, 144, 146, 168, 170, 185, + 190, 255, 133, 137, 151, 142, 148, 152, + 154, 155, 159, 160, 161, 164, 165, 166, + 175, 176, 255, 189, 129, 131, 133, 140, + 142, 144, 146, 168, 170, 179, 181, 185, + 188, 191, 158, 128, 132, 134, 136, 138, + 141, 149, 150, 160, 161, 162, 163, 166, + 175, 177, 178, 189, 129, 131, 133, 140, + 142, 144, 146, 186, 190, 255, 133, 137, + 142, 143, 150, 152, 158, 159, 161, 164, + 165, 166, 175, 176, 185, 186, 191, 192, + 255, 189, 130, 131, 133, 150, 154, 177, + 179, 187, 138, 150, 128, 134, 143, 148, + 152, 159, 166, 175, 178, 179, 177, 180, + 186, 135, 142, 144, 153, 177, 180, 185, + 187, 188, 136, 141, 144, 153, 128, 181, + 183, 185, 152, 153, 160, 169, 190, 191, + 128, 135, 137, 172, 177, 191, 128, 132, + 134, 135, 136, 140, 141, 151, 153, 188, + 134, 128, 129, 130, 131, 137, 138, 139, + 140, 141, 142, 143, 144, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 167, 168, 169, 170, 172, 173, + 174, 175, 176, 177, 179, 181, 182, 183, + 188, 189, 190, 191, 132, 152, 180, 184, + 185, 187, 171, 190, 128, 137, 150, 153, + 158, 160, 162, 164, 167, 173, 177, 180, + 143, 130, 141, 144, 153, 154, 157, 160, + 255, 155, 156, 157, 159, 160, 255, 128, + 140, 142, 145, 146, 148, 160, 177, 178, + 180, 128, 145, 146, 147, 160, 172, 174, + 176, 178, 179, 180, 255, 148, 156, 158, + 159, 160, 169, 170, 255, 139, 142, 144, + 153, 160, 255, 169, 128, 170, 176, 255, + 128, 158, 160, 171, 176, 187, 128, 150, + 151, 155, 191, 149, 158, 160, 188, 128, + 137, 144, 153, 176, 190, 128, 132, 133, + 179, 180, 255, 133, 139, 140, 143, 144, + 153, 154, 170, 180, 255, 128, 130, 131, + 160, 161, 173, 174, 175, 176, 185, 186, + 255, 166, 179, 180, 255, 128, 163, 164, + 183, 128, 137, 141, 143, 144, 153, 154, + 189, 173, 144, 146, 148, 168, 169, 177, + 178, 180, 181, 182, 184, 185, 128, 181, + 188, 191, 128, 129, 130, 131, 132, 133, + 134, 146, 147, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 140, 143, 170, 174, + 191, 255, 165, 177, 191, 129, 147, 149, + 159, 160, 175, 176, 255, 144, 176, 165, + 170, 175, 177, 180, 255, 191, 168, 174, + 176, 255, 128, 134, 136, 142, 144, 150, + 152, 158, 160, 191, 128, 130, 132, 133, + 134, 133, 170, 175, 187, 188, 153, 154, + 128, 146, 147, 148, 152, 153, 154, 155, + 156, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 129, 255, 141, 143, + 160, 169, 172, 255, 191, 128, 174, 175, + 178, 180, 189, 128, 157, 158, 159, 160, + 255, 176, 177, 178, 255, 130, 134, 139, + 163, 167, 168, 255, 128, 129, 130, 179, + 180, 255, 187, 189, 133, 143, 144, 153, + 154, 159, 178, 183, 184, 255, 128, 137, + 138, 165, 166, 173, 176, 255, 135, 147, + 148, 159, 189, 255, 128, 131, 132, 178, + 179, 255, 143, 129, 142, 144, 153, 154, + 164, 166, 175, 176, 185, 186, 255, 128, + 168, 169, 182, 131, 128, 139, 140, 141, + 144, 153, 187, 189, 176, 178, 180, 183, + 184, 190, 191, 129, 160, 170, 171, 175, + 178, 180, 181, 182, 128, 162, 163, 170, + 172, 173, 176, 185, 172, 173, 174, 175, + 180, 181, 182, 183, 184, 185, 187, 188, + 189, 190, 191, 176, 186, 158, 190, 128, + 134, 147, 151, 157, 168, 170, 182, 184, + 188, 128, 129, 131, 132, 134, 143, 144, + 255, 128, 143, 160, 175, 179, 180, 141, + 143, 176, 180, 182, 255, 191, 189, 255, + 191, 161, 186, 158, 159, 160, 190, 130, + 135, 138, 143, 146, 151, 154, 156, 185, + 187, 144, 145, 146, 147, 148, 150, 155, + 157, 158, 159, 128, 129, 130, 131, 133, + 135, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 148, 149, 152, 156, 157, 160, + 161, 162, 163, 164, 166, 168, 169, 170, + 171, 172, 173, 174, 176, 177, 153, 155, + 178, 179, 189, 160, 145, 255, 139, 143, + 182, 186, 187, 255, 158, 159, 160, 169, + 170, 255, 128, 191, 129, 131, 133, 134, + 140, 143, 144, 147, 149, 151, 153, 179, + 184, 186, 128, 135, 137, 164, 165, 166, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 138, 139, 140, 141, 146, 147, 150, + 151, 152, 153, 154, 155, 156, 162, 163, + 171, 128, 130, 131, 183, 184, 255, 135, + 165, 166, 175, 176, 190, 131, 175, 187, + 188, 190, 255, 144, 168, 176, 185, 128, + 130, 131, 166, 167, 180, 182, 191, 179, + 182, 144, 178, 128, 130, 131, 178, 179, + 255, 155, 129, 132, 133, 137, 141, 143, + 144, 153, 154, 156, 157, 255, 128, 145, + 147, 171, 172, 183, 159, 170, 171, 175, + 176, 185, 186, 255, 189, 128, 131, 133, + 140, 143, 144, 147, 168, 170, 176, 178, + 179, 181, 185, 188, 191, 144, 151, 128, + 132, 135, 136, 139, 141, 157, 161, 162, + 163, 166, 172, 176, 180, 128, 175, 176, + 255, 134, 132, 135, 136, 143, 144, 153, + 154, 255, 128, 174, 175, 181, 184, 255, + 129, 151, 152, 155, 158, 255, 132, 129, + 143, 144, 153, 154, 255, 128, 170, 171, + 183, 157, 171, 176, 185, 160, 169, 170, + 190, 192, 255, 160, 168, 169, 171, 172, + 173, 174, 188, 189, 190, 161, 167, 128, + 158, 160, 169, 144, 173, 176, 180, 128, + 175, 176, 182, 128, 131, 144, 153, 163, + 183, 189, 255, 133, 143, 145, 190, 191, + 255, 143, 146, 147, 159, 176, 177, 178, + 128, 136, 144, 153, 157, 158, 160, 163, + 133, 134, 137, 144, 145, 146, 147, 148, + 149, 154, 155, 156, 157, 158, 159, 168, + 169, 170, 150, 153, 165, 169, 173, 255, + 131, 132, 140, 169, 174, 255, 130, 132, + 131, 140, 141, 142, 191, 192, 255, 128, + 182, 187, 255, 173, 180, 182, 255, 132, + 155, 159, 161, 175, 160, 163, 184, 185, + 186, 161, 162, 133, 143, 144, 150, 151, + 255, 160, 128, 129, 132, 135, 133, 134, + 129, 160, 255, 192, 255, 176, 255, 156, + 128, 133, 144, 154, 176, 139, 159, 150, + 157, 159, 164, 167, 168, 170, 173, 143, + 145, 176, 255, 139, 255, 166, 176, 171, + 179, 160, 161, 163, 164, 165, 167, 169, + 171, 173, 174, 175, 176, 177, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 166, 170, 172, 178, 150, + 153, 155, 163, 165, 167, 169, 173, 153, + 155, 163, 255, 189, 132, 185, 144, 152, + 161, 164, 255, 188, 129, 131, 190, 255, + 133, 134, 137, 138, 142, 150, 152, 161, + 164, 255, 131, 134, 137, 138, 142, 144, + 146, 175, 178, 180, 182, 255, 134, 138, + 142, 161, 164, 255, 188, 129, 131, 190, + 191, 128, 132, 135, 136, 139, 141, 150, + 151, 162, 163, 130, 190, 191, 151, 128, + 130, 134, 136, 138, 141, 128, 131, 190, + 255, 133, 137, 142, 148, 151, 161, 164, + 255, 128, 132, 134, 136, 138, 141, 149, + 150, 162, 163, 129, 131, 190, 255, 133, + 137, 142, 150, 152, 161, 164, 255, 130, + 131, 138, 150, 143, 148, 152, 159, 178, + 179, 177, 180, 186, 135, 142, 177, 180, + 185, 187, 188, 136, 141, 181, 183, 185, + 152, 153, 190, 191, 177, 191, 128, 132, + 134, 135, 141, 151, 153, 188, 134, 128, + 129, 130, 141, 156, 157, 158, 159, 160, + 162, 164, 168, 169, 170, 172, 173, 174, + 175, 176, 179, 183, 171, 190, 150, 153, + 158, 160, 162, 164, 167, 173, 177, 180, + 143, 130, 141, 154, 157, 157, 159, 146, + 148, 178, 180, 146, 147, 178, 179, 180, + 255, 148, 156, 158, 255, 139, 142, 169, + 160, 171, 176, 187, 151, 155, 191, 149, + 158, 160, 188, 176, 190, 128, 132, 180, + 255, 133, 170, 180, 255, 128, 130, 161, + 173, 166, 179, 164, 183, 173, 144, 146, + 148, 168, 178, 180, 184, 185, 128, 181, + 188, 191, 128, 129, 131, 179, 181, 183, + 140, 143, 170, 174, 160, 164, 166, 175, + 144, 176, 175, 177, 191, 160, 191, 128, + 130, 170, 175, 153, 154, 153, 154, 155, + 160, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 175, 175, 178, 180, 189, + 158, 159, 176, 177, 130, 134, 139, 163, + 167, 128, 129, 180, 255, 133, 159, 178, + 255, 166, 173, 135, 147, 128, 131, 179, + 255, 129, 164, 166, 255, 169, 182, 131, + 140, 141, 187, 189, 176, 178, 180, 183, + 184, 190, 191, 129, 171, 175, 181, 182, + 163, 170, 172, 173, 172, 173, 184, 187, + 190, 191, 158, 190, 157, 168, 170, 182, + 184, 188, 128, 129, 131, 132, 134, 143, + 128, 143, 160, 175, 185, 187, 144, 145, + 150, 155, 157, 158, 135, 139, 141, 168, + 171, 189, 160, 182, 186, 191, 129, 131, + 133, 134, 140, 143, 184, 186, 165, 166, + 128, 129, 130, 132, 133, 134, 135, 136, + 139, 140, 141, 146, 147, 150, 151, 152, + 153, 154, 156, 128, 130, 184, 255, 135, + 190, 131, 175, 187, 188, 190, 255, 128, + 130, 167, 180, 179, 128, 130, 179, 255, + 129, 137, 141, 255, 172, 183, 159, 170, + 188, 128, 131, 190, 191, 151, 128, 132, + 135, 136, 139, 141, 162, 163, 166, 172, + 176, 180, 176, 255, 132, 255, 175, 181, + 184, 255, 129, 155, 158, 255, 129, 255, + 171, 183, 157, 171, 171, 172, 189, 190, + 176, 180, 176, 182, 145, 190, 143, 146, + 178, 157, 158, 160, 163, 133, 134, 137, + 168, 169, 170, 165, 169, 173, 255, 131, + 132, 140, 169, 174, 255, 130, 132, 128, + 182, 187, 255, 173, 180, 182, 255, 132, + 155, 159, 161, 175, 163, 144, 150, 160, + 128, 129, 132, 135, 133, 134, 129, 160, + 255, 192, 255, 170, 173, 181, 183, 186, + 151, 173, 130, 133, 146, 159, 165, 171, + 175, 255, 128, 255, 181, 190, 176, 183, + 184, 185, 186, 191, 192, 255, 135, 140, + 134, 138, 142, 161, 163, 255, 130, 131, + 137, 190, 136, 144, 145, 191, 192, 255, + 135, 179, 180, 129, 130, 132, 133, 144, + 170, 176, 178, 156, 128, 133, 144, 154, + 160, 191, 171, 176, 128, 138, 139, 159, + 160, 169, 174, 255, 148, 158, 169, 150, + 164, 167, 173, 176, 185, 189, 190, 192, + 255, 144, 143, 145, 146, 175, 176, 255, + 139, 140, 141, 255, 166, 176, 178, 255, + 186, 128, 137, 138, 170, 171, 179, 180, + 181, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, + 191, 154, 164, 168, 128, 149, 150, 173, + 128, 152, 153, 155, 163, 255, 189, 132, + 185, 144, 176, 152, 161, 164, 165, 166, + 175, 177, 255, 132, 169, 177, 188, 129, + 131, 141, 142, 145, 146, 179, 181, 186, + 187, 190, 255, 142, 158, 133, 134, 137, + 138, 143, 150, 152, 155, 156, 161, 164, + 165, 166, 175, 176, 177, 178, 255, 188, + 129, 131, 133, 138, 143, 144, 147, 168, + 170, 176, 178, 179, 181, 182, 184, 185, + 190, 255, 157, 131, 134, 137, 138, 142, + 144, 146, 152, 153, 158, 159, 165, 166, + 175, 178, 180, 182, 255, 189, 129, 131, + 133, 141, 143, 145, 147, 168, 170, 176, + 178, 179, 181, 185, 188, 255, 134, 138, + 144, 185, 142, 159, 160, 161, 164, 165, + 166, 175, 176, 255, 189, 129, 131, 133, + 140, 143, 144, 147, 168, 170, 176, 178, + 179, 181, 185, 188, 191, 177, 128, 132, + 135, 136, 139, 141, 150, 151, 156, 157, + 159, 161, 162, 163, 166, 175, 130, 131, + 156, 133, 138, 142, 144, 146, 149, 153, + 154, 158, 159, 163, 164, 168, 170, 174, + 185, 190, 191, 144, 151, 128, 130, 134, + 136, 138, 141, 166, 175, 189, 128, 131, + 133, 140, 142, 144, 146, 168, 170, 185, + 190, 255, 133, 137, 151, 142, 148, 152, + 154, 155, 159, 160, 161, 164, 165, 166, + 175, 176, 255, 189, 129, 131, 133, 140, + 142, 144, 146, 168, 170, 179, 181, 185, + 188, 191, 158, 128, 132, 134, 136, 138, + 141, 149, 150, 160, 161, 162, 163, 166, + 175, 177, 178, 189, 129, 131, 133, 140, + 142, 144, 146, 186, 190, 255, 133, 137, + 142, 143, 150, 152, 158, 159, 161, 164, + 165, 166, 175, 176, 185, 186, 191, 192, + 255, 189, 130, 131, 133, 150, 154, 177, + 179, 187, 138, 150, 128, 134, 143, 148, + 152, 159, 166, 175, 178, 179, 177, 180, + 186, 135, 142, 144, 153, 177, 180, 185, + 187, 188, 136, 141, 144, 153, 128, 181, + 183, 185, 152, 153, 160, 169, 190, 191, + 128, 135, 137, 172, 177, 191, 128, 132, + 134, 135, 136, 140, 141, 151, 153, 188, + 134, 128, 129, 130, 131, 137, 138, 139, + 140, 141, 142, 143, 144, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 167, 168, 169, 170, 172, 173, + 174, 175, 176, 177, 179, 181, 182, 183, + 188, 189, 190, 191, 132, 152, 180, 184, + 185, 187, 171, 190, 128, 137, 150, 153, + 158, 160, 162, 164, 167, 173, 177, 180, + 143, 130, 141, 144, 153, 154, 157, 160, + 255, 155, 156, 157, 159, 160, 255, 128, + 140, 142, 145, 146, 148, 160, 177, 178, + 180, 128, 145, 146, 147, 160, 172, 174, + 176, 178, 179, 180, 255, 148, 156, 158, + 159, 160, 169, 170, 255, 139, 142, 144, + 153, 160, 255, 169, 128, 170, 176, 255, + 128, 158, 160, 171, 176, 187, 128, 150, + 151, 155, 191, 149, 158, 160, 188, 128, + 137, 144, 153, 176, 190, 128, 132, 133, + 179, 180, 255, 133, 139, 140, 143, 144, + 153, 154, 170, 180, 255, 128, 130, 131, + 160, 161, 173, 174, 175, 176, 185, 186, + 255, 166, 179, 180, 255, 128, 163, 164, + 183, 173, 144, 146, 148, 168, 169, 177, + 178, 180, 181, 182, 184, 185, 128, 181, + 188, 191, 128, 129, 130, 131, 132, 133, + 134, 146, 147, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 164, 167, 140, 143, + 152, 153, 170, 174, 191, 255, 165, 177, + 191, 129, 147, 149, 159, 160, 175, 176, + 255, 144, 176, 165, 170, 175, 177, 180, + 255, 191, 168, 174, 176, 255, 128, 134, + 136, 142, 144, 150, 152, 158, 160, 191, + 128, 130, 132, 133, 134, 133, 170, 175, + 187, 188, 153, 154, 128, 146, 147, 148, + 152, 153, 154, 155, 156, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, + 129, 255, 191, 128, 174, 175, 178, 180, + 189, 128, 157, 158, 159, 160, 255, 176, + 177, 178, 255, 130, 134, 139, 163, 167, + 168, 255, 128, 129, 130, 179, 180, 255, + 187, 189, 133, 143, 144, 153, 154, 159, + 178, 183, 184, 255, 128, 137, 138, 165, + 166, 173, 176, 255, 135, 147, 148, 159, + 189, 255, 128, 131, 132, 178, 179, 255, + 143, 129, 142, 144, 153, 154, 164, 166, + 175, 176, 185, 186, 255, 128, 168, 169, + 182, 131, 128, 139, 140, 141, 144, 153, + 187, 189, 176, 178, 180, 183, 184, 190, + 191, 129, 160, 170, 171, 175, 178, 180, + 181, 182, 128, 162, 163, 170, 172, 173, + 176, 185, 172, 173, 174, 175, 180, 181, + 182, 183, 184, 185, 187, 188, 189, 190, + 191, 176, 186, 190, 128, 134, 147, 151, + 157, 168, 170, 182, 184, 188, 147, 128, + 143, 160, 175, 179, 180, 146, 149, 141, + 143, 176, 180, 182, 255, 191, 189, 255, + 135, 142, 154, 191, 161, 186, 158, 159, + 160, 190, 130, 135, 138, 143, 146, 151, + 154, 156, 185, 187, 144, 145, 146, 147, + 148, 150, 155, 157, 158, 159, 128, 129, + 130, 131, 133, 135, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 148, 149, 152, + 156, 157, 160, 161, 162, 163, 164, 166, + 168, 169, 170, 171, 172, 173, 174, 176, + 177, 153, 155, 178, 179, 189, 160, 145, + 255, 139, 143, 182, 186, 187, 255, 128, + 191, 129, 131, 133, 134, 140, 143, 144, + 147, 149, 151, 153, 179, 184, 186, 128, + 135, 137, 164, 165, 166, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 138, 139, + 140, 141, 146, 147, 150, 151, 152, 153, + 154, 155, 156, 162, 163, 171, 128, 130, + 131, 183, 184, 255, 135, 165, 166, 175, + 176, 190, 131, 175, 187, 188, 190, 255, + 128, 130, 131, 166, 167, 180, 182, 191, + 179, 182, 144, 178, 128, 130, 131, 178, + 179, 255, 155, 129, 132, 133, 137, 141, + 143, 144, 153, 154, 156, 157, 255, 128, + 145, 147, 171, 172, 183, 159, 170, 171, + 175, 176, 185, 186, 255, 189, 128, 131, + 133, 140, 143, 144, 147, 168, 170, 176, + 178, 179, 181, 185, 188, 191, 144, 151, + 128, 132, 135, 136, 139, 141, 157, 161, + 162, 163, 166, 172, 176, 180, 128, 175, + 176, 255, 134, 132, 135, 136, 143, 144, + 153, 154, 255, 128, 174, 175, 181, 184, + 255, 129, 151, 152, 155, 158, 255, 132, + 129, 143, 144, 153, 154, 255, 128, 170, + 171, 183, 157, 171, 176, 185, 160, 168, + 169, 171, 172, 173, 174, 188, 189, 190, + 161, 167, 144, 173, 176, 180, 128, 175, + 176, 182, 133, 143, 145, 190, 191, 255, + 143, 146, 147, 159, 176, 177, 178, 128, + 136, 144, 153, 157, 158, 160, 163, 133, + 134, 137, 144, 145, 146, 147, 148, 149, + 154, 155, 156, 157, 158, 159, 168, 169, + 170, 150, 153, 165, 169, 173, 255, 131, + 132, 140, 169, 174, 255, 130, 132, 128, + 182, 187, 255, 173, 180, 182, 255, 132, + 155, 159, 161, 175, 160, 163, 184, 185, + 186, 161, 162, 133, 143, 144, 150, 151, + 255, 160, 128, 129, 132, 135, 133, 134, + 129, 160, 255, 192, 255, 176, 255, 156, + 128, 133, 144, 154, 160, 191, 171, 176, + 128, 138, 139, 159, 160, 169, 174, 255, + 148, 158, 169, 150, 164, 167, 173, 176, + 185, 189, 190, 192, 255, 144, 143, 145, + 146, 175, 176, 255, 139, 140, 141, 255, + 166, 176, 178, 255, 186, 128, 137, 138, + 170, 171, 179, 180, 181, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 154, 164, 168, + 128, 149, 150, 173, 128, 152, 153, 155, + 163, 255, 189, 132, 185, 144, 176, 152, + 161, 164, 165, 166, 175, 177, 255, 132, + 169, 177, 188, 129, 131, 141, 142, 145, + 146, 179, 181, 186, 187, 190, 255, 142, + 158, 133, 134, 137, 138, 143, 150, 152, + 155, 156, 161, 164, 165, 166, 175, 176, + 177, 178, 255, 188, 129, 131, 133, 138, + 143, 144, 147, 168, 170, 176, 178, 179, + 181, 182, 184, 185, 190, 255, 157, 131, + 134, 137, 138, 142, 144, 146, 152, 153, + 158, 159, 165, 166, 175, 178, 180, 182, + 255, 189, 129, 131, 133, 141, 143, 145, + 147, 168, 170, 176, 178, 179, 181, 185, + 188, 255, 134, 138, 144, 185, 142, 159, + 160, 161, 164, 165, 166, 175, 176, 255, + 189, 129, 131, 133, 140, 143, 144, 147, + 168, 170, 176, 178, 179, 181, 185, 188, + 191, 177, 128, 132, 135, 136, 139, 141, + 150, 151, 156, 157, 159, 161, 162, 163, + 166, 175, 130, 131, 156, 133, 138, 142, + 144, 146, 149, 153, 154, 158, 159, 163, + 164, 168, 170, 174, 185, 190, 191, 144, + 151, 128, 130, 134, 136, 138, 141, 166, + 175, 189, 128, 131, 133, 140, 142, 144, + 146, 168, 170, 185, 190, 255, 133, 137, + 151, 142, 148, 152, 154, 155, 159, 160, + 161, 164, 165, 166, 175, 176, 255, 189, + 129, 131, 133, 140, 142, 144, 146, 168, + 170, 179, 181, 185, 188, 191, 158, 128, + 132, 134, 136, 138, 141, 149, 150, 160, + 161, 162, 163, 166, 175, 177, 178, 189, + 129, 131, 133, 140, 142, 144, 146, 186, + 190, 255, 133, 137, 142, 143, 150, 152, + 158, 159, 161, 164, 165, 166, 175, 176, + 185, 186, 191, 192, 255, 189, 130, 131, + 133, 150, 154, 177, 179, 187, 138, 150, + 128, 134, 143, 148, 152, 159, 166, 175, + 178, 179, 177, 180, 186, 135, 142, 144, + 153, 177, 180, 185, 187, 188, 136, 141, + 144, 153, 128, 181, 183, 185, 152, 153, + 160, 169, 190, 191, 128, 135, 137, 172, + 177, 191, 128, 132, 134, 135, 136, 140, + 141, 151, 153, 188, 134, 128, 129, 130, + 131, 137, 138, 139, 140, 141, 142, 143, + 144, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 167, 168, + 169, 170, 172, 173, 174, 175, 176, 177, + 179, 181, 182, 183, 188, 189, 190, 191, + 132, 152, 180, 184, 185, 187, 171, 190, + 128, 137, 150, 153, 158, 160, 162, 164, + 167, 173, 177, 180, 143, 130, 141, 144, + 153, 154, 157, 160, 255, 155, 156, 157, + 159, 160, 255, 128, 140, 142, 145, 146, + 148, 160, 177, 178, 180, 128, 145, 146, + 147, 160, 172, 174, 176, 178, 179, 180, + 255, 148, 156, 158, 159, 160, 169, 170, + 255, 139, 142, 144, 153, 160, 255, 169, + 128, 170, 176, 255, 128, 158, 160, 171, + 176, 187, 128, 150, 151, 155, 191, 149, + 158, 160, 188, 128, 137, 144, 153, 176, + 190, 128, 132, 133, 179, 180, 255, 133, + 139, 140, 143, 144, 153, 154, 170, 180, + 255, 128, 130, 131, 160, 161, 173, 174, + 175, 176, 185, 186, 255, 166, 179, 180, + 255, 128, 163, 164, 183, 173, 144, 146, + 148, 168, 169, 177, 178, 180, 181, 182, + 184, 185, 128, 181, 188, 191, 128, 129, + 130, 131, 132, 133, 134, 146, 147, 176, + 177, 178, 179, 180, 181, 182, 183, 184, + 140, 143, 170, 174, 191, 255, 165, 177, + 191, 129, 147, 149, 159, 176, 255, 144, + 176, 165, 170, 175, 177, 180, 255, 191, + 168, 174, 176, 255, 128, 134, 136, 142, + 144, 150, 152, 158, 160, 191, 128, 130, + 131, 132, 133, 134, 135, 139, 140, 141, + 133, 170, 175, 177, 181, 187, 188, 173, + 128, 255, 176, 255, 131, 137, 191, 145, + 189, 135, 129, 130, 132, 133, 156, 128, + 133, 144, 154, 176, 139, 159, 150, 157, + 159, 164, 167, 168, 170, 173, 143, 145, + 176, 255, 139, 255, 166, 176, 171, 179, + 160, 161, 163, 164, 165, 167, 169, 171, + 173, 174, 175, 176, 177, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 166, 170, 172, 178, 150, 153, + 155, 163, 165, 167, 169, 173, 153, 155, + 163, 255, 189, 132, 185, 144, 152, 161, + 164, 255, 188, 129, 131, 190, 255, 133, + 134, 137, 138, 142, 150, 152, 161, 164, + 255, 131, 134, 137, 138, 142, 144, 146, + 175, 178, 180, 182, 255, 134, 138, 142, + 161, 164, 255, 188, 129, 131, 190, 191, + 128, 132, 135, 136, 139, 141, 150, 151, + 162, 163, 130, 190, 191, 151, 128, 130, + 134, 136, 138, 141, 128, 131, 190, 255, + 133, 137, 142, 148, 151, 161, 164, 255, + 128, 132, 134, 136, 138, 141, 149, 150, + 162, 163, 129, 131, 190, 255, 133, 137, + 142, 150, 152, 161, 164, 255, 130, 131, + 138, 150, 143, 148, 152, 159, 178, 179, + 177, 180, 186, 135, 142, 177, 180, 185, + 187, 188, 136, 141, 181, 183, 185, 152, + 153, 190, 191, 177, 191, 128, 132, 134, + 135, 141, 151, 153, 188, 134, 128, 129, + 130, 141, 156, 157, 158, 159, 160, 162, + 164, 168, 169, 170, 172, 173, 174, 175, + 176, 179, 183, 171, 190, 150, 153, 158, + 160, 162, 164, 167, 173, 177, 180, 143, + 130, 141, 154, 157, 157, 159, 146, 148, + 178, 180, 146, 147, 178, 179, 180, 255, + 148, 156, 158, 255, 139, 142, 169, 160, + 171, 176, 187, 151, 155, 191, 149, 158, + 160, 188, 176, 190, 128, 132, 180, 255, + 133, 170, 180, 255, 128, 130, 161, 173, + 166, 179, 164, 183, 173, 144, 146, 148, + 168, 178, 180, 184, 185, 128, 181, 188, + 191, 128, 129, 131, 179, 181, 183, 140, + 143, 170, 174, 191, 255, 165, 129, 147, + 149, 159, 160, 175, 176, 255, 144, 176, + 175, 177, 191, 160, 191, 128, 130, 131, + 135, 139, 140, 141, 170, 175, 177, 181, + 153, 156, 160, 255, 187, 192, 255, 176, + 191, 144, 190, 152, 255, 153, 154, 155, + 160, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 175, 175, 178, 180, 189, + 158, 159, 176, 177, 130, 134, 139, 163, + 167, 128, 129, 180, 255, 133, 159, 178, + 255, 166, 173, 135, 147, 128, 131, 179, + 255, 129, 164, 166, 255, 169, 182, 131, + 140, 141, 187, 189, 176, 178, 180, 183, + 184, 190, 191, 129, 171, 175, 181, 182, + 163, 170, 172, 173, 172, 184, 185, 187, + 188, 189, 190, 191, 158, 128, 143, 160, + 175, 179, 180, 141, 143, 191, 166, 255, + 160, 255, 185, 187, 144, 145, 150, 155, + 157, 158, 135, 139, 141, 168, 171, 189, + 160, 182, 186, 191, 129, 131, 133, 134, + 140, 143, 184, 186, 165, 166, 128, 129, + 130, 132, 133, 134, 135, 136, 139, 140, + 141, 146, 147, 150, 151, 152, 153, 154, + 156, 128, 130, 184, 255, 135, 190, 131, + 175, 187, 188, 190, 255, 128, 130, 167, + 180, 179, 128, 130, 179, 255, 129, 137, + 141, 255, 172, 183, 159, 170, 188, 128, + 131, 190, 191, 151, 128, 132, 135, 136, + 139, 141, 162, 163, 166, 172, 176, 180, + 176, 255, 132, 255, 175, 181, 184, 255, + 129, 155, 158, 255, 129, 255, 171, 183, + 157, 171, 171, 172, 189, 190, 176, 180, + 176, 182, 145, 190, 143, 146, 128, 178, + 128, 157, 158, 160, 163, 133, 134, 137, + 168, 169, 170, 165, 169, 173, 255, 131, + 132, 140, 169, 174, 255, 130, 132, 128, + 182, 187, 255, 173, 180, 182, 255, 132, + 155, 159, 161, 175, 163, 144, 150, 160, + 128, 129, 132, 135, 133, 134, 129, 160, + 255, 192, 255, 153, 154, 155, 156, 160, + 255, 128, 146, 147, 148, 152, 153, 154, + 155, 156, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 129, 255, 191, + 128, 174, 175, 178, 180, 189, 128, 157, + 158, 159, 160, 255, 176, 177, 178, 255, + 130, 134, 139, 163, 167, 168, 255, 128, + 129, 130, 179, 180, 255, 187, 189, 133, + 143, 144, 153, 154, 159, 178, 183, 184, + 255, 128, 137, 138, 165, 166, 173, 176, + 255, 135, 147, 148, 159, 189, 255, 128, + 131, 132, 178, 179, 255, 143, 129, 142, + 144, 153, 154, 164, 166, 175, 176, 185, + 186, 255, 128, 168, 169, 182, 131, 128, + 139, 140, 141, 144, 153, 187, 189, 176, + 178, 180, 183, 184, 190, 191, 129, 160, + 170, 171, 175, 178, 180, 181, 182, 128, + 162, 163, 170, 172, 173, 176, 185, 172, + 173, 174, 175, 180, 181, 182, 183, 184, + 185, 187, 188, 189, 190, 191, 176, 186, + 158, 190, 128, 134, 147, 151, 157, 168, + 170, 182, 184, 188, 128, 143, 160, 175, + 179, 180, 191, 189, 255, 129, 154, 166, + 255, 158, 159, 160, 190, 191, 255, 130, + 135, 138, 143, 146, 151, 154, 156, 185, + 187, 144, 145, 146, 147, 148, 150, 155, + 157, 158, 159, 128, 129, 130, 131, 133, + 135, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 148, 149, 152, 156, 157, 160, + 161, 162, 163, 164, 166, 168, 169, 170, + 171, 172, 173, 174, 176, 177, 153, 155, + 178, 179, 189, 160, 145, 255, 139, 143, + 182, 186, 187, 255, 128, 191, 129, 131, + 133, 134, 140, 143, 144, 147, 149, 151, + 153, 179, 184, 186, 128, 135, 137, 164, + 165, 166, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 138, 139, 140, 141, 146, + 147, 150, 151, 152, 153, 154, 155, 156, + 162, 163, 171, 128, 130, 131, 183, 184, + 255, 135, 165, 166, 175, 176, 190, 131, + 175, 187, 188, 190, 255, 128, 130, 131, + 166, 167, 180, 182, 191, 179, 182, 144, + 178, 128, 130, 131, 178, 179, 255, 155, + 129, 132, 133, 137, 141, 143, 144, 153, + 154, 156, 157, 255, 128, 145, 147, 171, + 172, 183, 159, 170, 171, 175, 176, 185, + 186, 255, 189, 128, 131, 133, 140, 143, + 144, 147, 168, 170, 176, 178, 179, 181, + 185, 188, 191, 144, 151, 128, 132, 135, + 136, 139, 141, 157, 161, 162, 163, 166, + 172, 176, 180, 128, 175, 176, 255, 134, + 132, 135, 136, 143, 144, 153, 154, 255, + 128, 174, 175, 181, 184, 255, 129, 151, + 152, 155, 158, 255, 132, 129, 143, 144, + 153, 154, 255, 128, 170, 171, 183, 157, + 171, 176, 185, 160, 168, 169, 171, 172, + 173, 174, 188, 189, 190, 161, 167, 144, + 173, 176, 180, 128, 175, 176, 182, 133, + 143, 145, 190, 191, 255, 143, 146, 147, + 159, 128, 176, 177, 178, 128, 136, 144, + 153, 157, 158, 160, 163, 133, 134, 137, + 144, 145, 146, 147, 148, 149, 154, 155, + 156, 157, 158, 159, 168, 169, 170, 150, + 153, 165, 169, 173, 255, 131, 132, 140, + 169, 174, 255, 130, 132, 128, 182, 187, + 255, 173, 180, 182, 255, 132, 155, 159, + 161, 175, 160, 163, 184, 185, 186, 161, + 162, 133, 143, 144, 150, 151, 255, 160, + 128, 129, 132, 135, 133, 134, 129, 160, + 255, 192, 255, 176, 255, 170, 173, 181, + 186, 0, 127, 181, 190, 176, 183, 184, + 185, 186, 191, 192, 255, 130, 131, 137, + 137, 190, 136, 144, 145, 191, 192, 255, + 135, 179, 129, 130, 132, 133, 144, 170, + 176, 178, 156, 128, 133, 140, 141, 144, + 154, 160, 191, 171, 172, 176, 128, 138, + 139, 169, 174, 255, 148, 158, 169, 150, + 164, 167, 173, 176, 185, 189, 190, 192, + 255, 144, 143, 145, 146, 175, 176, 255, + 139, 140, 141, 255, 166, 176, 178, 255, + 184, 186, 128, 137, 138, 170, 171, 179, + 180, 181, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 154, 164, 168, 128, 149, 150, + 173, 128, 152, 153, 155, 163, 255, 189, + 132, 185, 144, 176, 152, 161, 164, 165, + 177, 255, 132, 169, 177, 188, 129, 131, + 141, 142, 145, 146, 179, 181, 186, 187, + 190, 255, 142, 158, 133, 134, 137, 138, + 143, 150, 152, 155, 156, 161, 164, 165, + 176, 177, 178, 255, 188, 129, 131, 133, + 138, 143, 144, 147, 168, 170, 176, 178, + 179, 181, 182, 184, 185, 190, 255, 157, + 131, 134, 137, 138, 142, 144, 146, 152, + 153, 158, 159, 165, 178, 180, 182, 255, + 189, 129, 131, 133, 141, 143, 145, 147, + 168, 170, 176, 178, 179, 181, 185, 188, + 255, 134, 138, 144, 185, 142, 159, 160, + 161, 164, 165, 176, 255, 189, 129, 131, + 133, 140, 143, 144, 147, 168, 170, 176, + 178, 179, 181, 185, 188, 191, 177, 128, + 132, 135, 136, 139, 141, 150, 151, 156, + 157, 159, 161, 162, 163, 166, 175, 130, + 131, 156, 133, 138, 142, 144, 146, 149, + 153, 154, 158, 159, 163, 164, 168, 170, + 174, 185, 190, 191, 144, 151, 128, 130, + 134, 136, 138, 141, 166, 175, 189, 128, + 131, 133, 140, 142, 144, 146, 168, 170, + 185, 190, 255, 133, 137, 151, 142, 148, + 152, 154, 155, 159, 160, 161, 164, 165, + 176, 255, 189, 129, 131, 133, 140, 142, + 144, 146, 168, 170, 179, 181, 185, 188, + 191, 158, 128, 132, 134, 136, 138, 141, + 149, 150, 160, 161, 162, 163, 166, 175, + 177, 178, 189, 129, 131, 133, 140, 142, + 144, 146, 186, 190, 255, 133, 137, 142, + 143, 150, 152, 158, 159, 161, 164, 165, + 176, 185, 186, 191, 192, 255, 189, 130, + 131, 133, 150, 154, 177, 179, 187, 138, + 150, 128, 134, 143, 148, 152, 159, 166, + 175, 178, 179, 177, 180, 186, 135, 142, + 144, 153, 177, 180, 185, 187, 188, 136, + 141, 144, 153, 128, 181, 183, 185, 152, + 153, 160, 169, 190, 191, 128, 135, 137, + 172, 177, 191, 128, 132, 134, 135, 136, + 140, 141, 151, 153, 188, 134, 128, 129, + 130, 131, 137, 138, 139, 140, 141, 142, + 143, 144, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 167, + 168, 169, 170, 172, 173, 174, 175, 176, + 177, 179, 181, 182, 183, 188, 189, 190, + 191, 132, 152, 180, 184, 185, 187, 171, + 190, 128, 137, 150, 153, 158, 160, 162, + 164, 167, 173, 177, 180, 130, 141, 143, + 157, 160, 255, 155, 156, 157, 159, 160, + 255, 128, 140, 142, 145, 146, 148, 160, + 177, 178, 180, 128, 145, 146, 147, 160, + 172, 174, 176, 178, 179, 180, 255, 148, + 156, 158, 159, 170, 255, 139, 142, 144, + 153, 160, 255, 169, 128, 170, 176, 255, + 128, 158, 160, 171, 176, 187, 128, 150, + 151, 155, 191, 149, 158, 160, 188, 128, + 137, 144, 153, 176, 190, 128, 132, 133, + 179, 180, 255, 133, 139, 140, 143, 154, + 170, 180, 255, 128, 130, 131, 160, 161, + 173, 174, 175, 176, 185, 186, 255, 166, + 179, 180, 255, 128, 163, 164, 183, 173, + 144, 146, 148, 168, 169, 177, 178, 180, + 181, 182, 184, 185, 128, 181, 188, 191, + 128, 129, 130, 131, 132, 133, 134, 146, + 147, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 164, 140, 143, 152, 153, 170, + 174, 191, 255, 132, 165, 177, 191, 129, + 147, 149, 159, 160, 175, 176, 255, 144, + 176, 165, 170, 175, 177, 180, 255, 191, + 168, 174, 176, 255, 128, 134, 136, 142, + 144, 150, 152, 158, 160, 191, 128, 130, + 132, 133, 134, 133, 170, 175, 187, 188, + 153, 154, 128, 146, 147, 148, 152, 153, + 154, 155, 156, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 129, 255, + 191, 128, 174, 175, 178, 180, 189, 128, + 157, 158, 159, 160, 255, 176, 177, 178, + 255, 130, 134, 139, 163, 167, 168, 255, + 128, 129, 130, 179, 180, 255, 187, 189, + 133, 143, 154, 159, 178, 183, 184, 255, + 128, 137, 138, 165, 166, 173, 176, 255, + 135, 147, 148, 159, 189, 255, 128, 131, + 132, 178, 179, 255, 143, 129, 142, 154, + 164, 166, 175, 186, 255, 128, 168, 169, + 182, 131, 128, 139, 140, 141, 144, 153, + 187, 189, 176, 178, 180, 183, 184, 190, + 191, 129, 160, 170, 171, 175, 178, 180, + 181, 182, 128, 162, 163, 170, 172, 173, + 176, 185, 172, 173, 174, 175, 180, 181, + 182, 183, 184, 185, 187, 188, 189, 190, + 191, 176, 186, 158, 190, 128, 134, 147, + 151, 157, 168, 170, 182, 184, 188, 144, + 148, 128, 143, 160, 175, 179, 180, 144, + 146, 148, 141, 143, 176, 180, 182, 255, + 191, 189, 255, 135, 140, 142, 155, 191, + 161, 186, 158, 159, 160, 190, 130, 135, + 138, 143, 146, 151, 154, 156, 185, 187, + 144, 145, 146, 147, 148, 150, 155, 157, + 158, 159, 128, 129, 130, 131, 133, 135, + 138, 139, 140, 141, 142, 143, 144, 145, + 146, 148, 149, 152, 156, 157, 160, 161, + 162, 163, 164, 166, 168, 169, 170, 171, + 172, 173, 174, 176, 177, 153, 155, 178, + 179, 189, 160, 145, 255, 139, 143, 182, + 186, 187, 255, 128, 191, 129, 131, 133, + 134, 140, 143, 144, 147, 149, 151, 153, + 179, 184, 186, 128, 135, 137, 164, 165, + 166, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 138, 139, 140, 141, 146, 147, + 150, 151, 152, 153, 154, 155, 156, 162, + 163, 171, 128, 130, 131, 183, 184, 255, + 135, 165, 176, 190, 131, 175, 187, 188, + 190, 255, 128, 130, 131, 166, 167, 180, + 182, 191, 179, 182, 144, 178, 128, 130, + 131, 178, 179, 255, 155, 129, 132, 133, + 137, 141, 143, 154, 156, 157, 255, 128, + 145, 147, 171, 172, 183, 159, 170, 171, + 175, 176, 185, 186, 255, 189, 128, 131, + 133, 140, 143, 144, 147, 168, 170, 176, + 178, 179, 181, 185, 188, 191, 144, 151, + 128, 132, 135, 136, 139, 141, 157, 161, + 162, 163, 166, 172, 176, 180, 128, 175, + 176, 255, 134, 132, 135, 136, 143, 154, + 255, 128, 174, 175, 181, 184, 255, 129, + 151, 152, 155, 158, 255, 132, 129, 143, + 154, 255, 128, 170, 171, 183, 157, 171, + 176, 185, 160, 168, 169, 171, 172, 173, + 174, 188, 189, 190, 161, 167, 144, 173, + 176, 180, 128, 175, 176, 182, 133, 143, + 145, 190, 191, 255, 143, 146, 147, 159, + 176, 177, 178, 128, 136, 144, 153, 157, + 158, 160, 163, 133, 134, 137, 144, 145, + 146, 147, 148, 149, 154, 155, 156, 157, + 158, 159, 168, 169, 170, 150, 153, 165, + 169, 173, 255, 131, 132, 140, 169, 174, + 255, 130, 132, 128, 182, 187, 255, 173, + 180, 182, 255, 132, 155, 159, 161, 175, + 160, 163, 184, 185, 186, 161, 162, 133, + 143, 144, 150, 151, 255, 160, 128, 129, + 132, 135, 133, 134, 129, 160, 255, 192, + 255, 176, 255, 170, 173, 181, 183, 186, + 181, 190, 184, 185, 192, 255, 130, 190, + 136, 144, 192, 255, 135, 179, 180, 129, + 130, 132, 133, 144, 170, 176, 178, 156, + 128, 133, 144, 154, 160, 191, 171, 128, + 159, 160, 169, 174, 255, 148, 158, 169, + 176, 185, 189, 190, 192, 255, 143, 255, + 139, 140, 186, 128, 137, 138, 181, 160, + 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 128, + 173, 128, 155, 163, 255, 176, 164, 165, + 166, 175, 132, 169, 177, 141, 142, 145, + 146, 179, 181, 186, 187, 158, 133, 134, + 137, 138, 143, 150, 152, 155, 164, 165, + 166, 175, 178, 255, 188, 129, 131, 133, + 138, 143, 144, 147, 168, 170, 176, 178, + 179, 181, 182, 184, 185, 190, 255, 157, + 131, 134, 137, 138, 142, 144, 146, 152, + 159, 165, 166, 175, 182, 255, 129, 131, + 133, 141, 143, 145, 147, 168, 170, 176, + 178, 179, 181, 185, 188, 255, 134, 138, + 142, 143, 145, 159, 164, 165, 166, 175, + 176, 184, 186, 255, 129, 131, 133, 140, + 143, 144, 147, 168, 170, 176, 178, 179, + 181, 185, 188, 191, 177, 128, 132, 135, + 136, 139, 141, 150, 151, 156, 157, 159, + 163, 166, 175, 156, 130, 131, 133, 138, + 142, 144, 146, 149, 153, 154, 158, 159, + 163, 164, 168, 170, 174, 185, 190, 191, + 144, 151, 128, 130, 134, 136, 138, 141, + 166, 175, 128, 131, 133, 140, 142, 144, + 146, 168, 170, 185, 189, 255, 133, 137, + 151, 142, 148, 155, 159, 164, 165, 166, + 175, 176, 255, 129, 131, 133, 140, 142, + 144, 146, 168, 170, 179, 181, 185, 188, + 191, 158, 128, 132, 134, 136, 138, 141, + 149, 150, 160, 163, 166, 175, 177, 178, + 129, 131, 133, 140, 142, 144, 146, 186, + 189, 255, 133, 137, 143, 150, 152, 158, + 164, 165, 166, 175, 176, 185, 192, 255, + 189, 130, 131, 133, 150, 154, 177, 179, + 187, 138, 150, 128, 134, 143, 148, 152, + 159, 166, 175, 178, 179, 177, 180, 186, + 135, 142, 144, 153, 177, 180, 185, 187, + 188, 136, 141, 144, 153, 128, 181, 183, + 185, 152, 153, 160, 169, 190, 191, 128, + 135, 137, 172, 177, 191, 128, 132, 134, + 151, 153, 188, 134, 128, 129, 130, 131, + 137, 138, 139, 140, 141, 142, 143, 144, + 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 167, 168, 169, + 170, 172, 173, 174, 175, 176, 177, 179, + 181, 182, 183, 188, 189, 190, 191, 132, + 152, 180, 184, 185, 187, 171, 190, 128, + 137, 150, 153, 158, 160, 162, 164, 167, + 173, 177, 180, 143, 130, 141, 144, 153, + 154, 157, 160, 255, 155, 156, 160, 255, + 128, 140, 142, 148, 160, 180, 128, 147, + 160, 172, 174, 176, 178, 179, 180, 255, + 148, 156, 158, 159, 160, 169, 170, 255, + 139, 142, 144, 153, 160, 255, 128, 170, + 176, 255, 128, 158, 160, 171, 176, 187, + 191, 149, 158, 160, 188, 128, 137, 144, + 153, 176, 190, 140, 143, 144, 153, 154, + 170, 180, 255, 128, 175, 176, 185, 186, + 255, 180, 255, 128, 183, 144, 146, 148, + 182, 184, 185, 128, 181, 188, 191, 128, + 129, 130, 131, 132, 133, 134, 146, 147, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 164, 167, 140, 143, 152, 153, 170, + 174, 191, 255, 165, 176, 191, 129, 147, + 149, 159, 160, 177, 178, 255, 144, 176, + 165, 170, 180, 255, 168, 174, 176, 190, + 192, 255, 128, 134, 136, 142, 144, 150, + 152, 158, 160, 191, 128, 130, 132, 133, + 134, 133, 170, 175, 187, 188, 153, 154, + 128, 146, 147, 148, 152, 153, 154, 155, + 156, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 129, 255, 191, 128, + 178, 180, 189, 168, 255, 188, 133, 143, + 144, 153, 154, 159, 184, 186, 190, 255, + 128, 137, 138, 173, 176, 255, 148, 159, + 189, 255, 129, 142, 144, 153, 154, 164, + 166, 175, 176, 185, 186, 255, 128, 182, + 128, 141, 144, 153, 187, 189, 176, 178, + 180, 183, 184, 190, 191, 129, 160, 175, + 178, 182, 128, 170, 172, 173, 176, 185, + 172, 173, 174, 175, 180, 181, 182, 183, + 184, 185, 187, 188, 189, 190, 191, 176, + 186, 158, 190, 128, 134, 147, 151, 157, + 168, 170, 182, 184, 188, 147, 128, 143, + 160, 175, 179, 180, 189, 190, 192, 255, + 158, 190, 130, 135, 138, 143, 146, 151, + 154, 156, 185, 187, 144, 145, 146, 147, + 148, 150, 155, 157, 158, 159, 128, 129, + 130, 131, 133, 135, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 148, 149, 152, + 156, 157, 160, 161, 162, 163, 164, 166, + 168, 169, 170, 171, 172, 173, 174, 176, + 177, 153, 155, 178, 179, 189, 145, 159, + 161, 255, 139, 143, 187, 255, 191, 128, + 131, 133, 134, 140, 147, 149, 151, 153, + 179, 184, 186, 128, 135, 137, 166, 129, + 130, 131, 132, 133, 135, 136, 138, 139, + 140, 141, 146, 147, 150, 151, 152, 153, + 154, 155, 156, 162, 163, 171, 128, 134, + 135, 165, 166, 175, 176, 190, 187, 188, + 190, 255, 128, 180, 182, 191, 182, 144, + 179, 155, 133, 137, 141, 143, 144, 153, + 157, 255, 128, 145, 147, 183, 171, 175, + 176, 185, 186, 255, 128, 131, 133, 140, + 143, 144, 147, 168, 170, 176, 178, 179, + 181, 185, 188, 191, 144, 151, 128, 132, + 135, 136, 139, 141, 157, 163, 166, 172, + 176, 180, 134, 136, 143, 144, 153, 154, + 255, 128, 181, 184, 255, 129, 151, 158, + 255, 129, 131, 133, 143, 144, 153, 154, + 255, 157, 171, 176, 185, 160, 168, 169, + 171, 172, 173, 174, 188, 189, 190, 161, + 167, 144, 173, 176, 180, 133, 143, 191, + 255, 143, 159, 176, 177, 178, 128, 136, + 144, 153, 157, 158, 160, 163, 133, 134, + 137, 144, 145, 146, 147, 148, 149, 154, + 155, 156, 157, 158, 159, 168, 169, 170, + 150, 153, 165, 169, 173, 255, 131, 132, + 140, 169, 174, 255, 130, 132, 128, 182, + 187, 255, 173, 180, 182, 255, 132, 155, + 159, 161, 175, 160, 163, 184, 185, 186, + 161, 162, 133, 143, 151, 255, 160, 128, + 129, 132, 135, 133, 134, 129, 160, 255, + 176, 255, 170, 173, 181, 186, 128, 255, + 181, 190, 176, 183, 184, 185, 186, 191, + 192, 255, 130, 131, 137, 190, 136, 144, + 145, 191, 192, 255, 135, 179, 129, 130, + 132, 133, 144, 170, 176, 178, 156, 128, + 133, 144, 154, 160, 191, 171, 176, 128, + 138, 139, 159, 160, 169, 174, 255, 148, + 158, 169, 150, 164, 167, 173, 176, 185, + 189, 190, 192, 255, 144, 143, 145, 146, + 175, 176, 255, 139, 140, 141, 255, 166, + 176, 178, 255, 186, 128, 137, 138, 170, + 171, 179, 180, 181, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 154, 164, 168, 128, + 149, 150, 173, 128, 152, 153, 155, 163, + 255, 189, 132, 185, 144, 176, 152, 161, + 164, 165, 166, 175, 177, 255, 132, 169, + 177, 188, 129, 131, 141, 142, 145, 146, + 179, 181, 186, 187, 190, 255, 142, 158, + 133, 134, 137, 138, 143, 150, 152, 155, + 156, 161, 164, 165, 166, 175, 176, 177, + 178, 255, 188, 129, 131, 133, 138, 143, + 144, 147, 168, 170, 176, 178, 179, 181, + 182, 184, 185, 190, 255, 157, 131, 134, + 137, 138, 142, 144, 146, 152, 153, 158, + 159, 165, 166, 175, 178, 180, 182, 255, + 189, 129, 131, 133, 141, 143, 145, 147, + 168, 170, 176, 178, 179, 181, 185, 188, + 255, 134, 138, 144, 185, 142, 159, 160, + 161, 164, 165, 166, 175, 176, 255, 189, + 129, 131, 133, 140, 143, 144, 147, 168, + 170, 176, 178, 179, 181, 185, 188, 191, + 177, 128, 132, 135, 136, 139, 141, 150, + 151, 156, 157, 159, 161, 162, 163, 166, + 175, 130, 131, 156, 133, 138, 142, 144, + 146, 149, 153, 154, 158, 159, 163, 164, + 168, 170, 174, 185, 190, 191, 144, 151, + 128, 130, 134, 136, 138, 141, 166, 175, + 189, 128, 131, 133, 140, 142, 144, 146, + 168, 170, 185, 190, 255, 133, 137, 151, + 142, 148, 152, 154, 155, 159, 160, 161, + 164, 165, 166, 175, 176, 255, 189, 129, + 131, 133, 140, 142, 144, 146, 168, 170, + 179, 181, 185, 188, 191, 158, 128, 132, + 134, 136, 138, 141, 149, 150, 160, 161, + 162, 163, 166, 175, 177, 178, 189, 129, + 131, 133, 140, 142, 144, 146, 186, 190, + 255, 133, 137, 142, 143, 150, 152, 158, + 159, 161, 164, 165, 166, 175, 176, 185, + 186, 191, 192, 255, 189, 130, 131, 133, + 150, 154, 177, 179, 187, 138, 150, 128, + 134, 143, 148, 152, 159, 166, 175, 178, + 179, 177, 180, 186, 135, 142, 144, 153, + 177, 180, 185, 187, 188, 136, 141, 144, + 153, 128, 181, 183, 185, 152, 153, 160, + 169, 190, 191, 128, 135, 137, 172, 177, + 191, 128, 132, 134, 135, 136, 140, 141, + 151, 153, 188, 134, 128, 129, 130, 131, + 137, 138, 139, 140, 141, 142, 143, 144, + 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 167, 168, 169, + 170, 172, 173, 174, 175, 176, 177, 179, + 181, 182, 183, 188, 189, 190, 191, 132, + 152, 180, 184, 185, 187, 171, 190, 128, + 137, 150, 153, 158, 160, 162, 164, 167, + 173, 177, 180, 143, 130, 141, 144, 153, + 154, 157, 160, 255, 155, 156, 157, 159, + 160, 255, 128, 140, 142, 145, 146, 148, + 160, 177, 178, 180, 128, 145, 146, 147, + 160, 172, 174, 176, 178, 179, 180, 255, + 148, 156, 158, 159, 160, 169, 170, 255, + 139, 142, 144, 153, 160, 255, 169, 128, + 170, 176, 255, 128, 158, 160, 171, 176, + 187, 134, 143, 144, 153, 128, 150, 151, + 155, 191, 149, 158, 160, 188, 128, 137, + 144, 153, 176, 190, 128, 132, 133, 179, + 180, 255, 133, 139, 140, 143, 144, 153, + 154, 170, 180, 255, 128, 130, 131, 160, + 161, 173, 174, 175, 176, 185, 186, 255, + 166, 179, 180, 255, 128, 163, 164, 183, + 128, 137, 141, 143, 144, 153, 154, 189, + 173, 144, 146, 148, 168, 169, 177, 178, + 180, 181, 182, 184, 185, 128, 181, 188, + 191, 128, 129, 130, 131, 132, 133, 134, + 146, 147, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 140, 143, 170, 174, 191, + 255, 165, 177, 191, 129, 147, 149, 159, + 176, 255, 144, 176, 165, 170, 175, 177, + 180, 255, 191, 168, 174, 176, 255, 128, + 134, 136, 142, 144, 150, 152, 158, 160, + 191, 128, 130, 131, 132, 133, 134, 135, + 139, 140, 141, 133, 170, 175, 177, 181, + 187, 188, 153, 154, 155, 156, 160, 255, + 128, 146, 147, 148, 152, 153, 154, 155, + 156, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 129, 255, 141, 143, + 160, 169, 172, 255, 191, 128, 174, 175, + 178, 180, 189, 128, 157, 158, 159, 160, + 255, 176, 177, 178, 255, 130, 134, 139, + 163, 167, 168, 255, 128, 129, 130, 179, + 180, 255, 187, 189, 133, 143, 144, 153, + 154, 159, 178, 183, 184, 255, 128, 137, + 138, 165, 166, 173, 176, 255, 135, 147, + 148, 159, 189, 255, 128, 131, 132, 178, + 179, 255, 143, 129, 142, 144, 153, 154, + 164, 166, 175, 176, 185, 186, 255, 128, + 168, 169, 182, 131, 128, 139, 140, 141, + 144, 153, 187, 189, 176, 178, 180, 183, + 184, 190, 191, 129, 160, 170, 171, 175, + 178, 180, 181, 182, 128, 162, 163, 170, + 172, 173, 176, 185, 172, 173, 174, 175, + 180, 181, 182, 183, 184, 185, 187, 188, + 189, 190, 191, 176, 186, 158, 190, 128, + 134, 147, 151, 157, 168, 170, 182, 184, + 188, 128, 143, 160, 175, 179, 180, 141, + 143, 176, 180, 182, 255, 191, 189, 255, + 191, 161, 186, 158, 159, 160, 190, 191, + 255, 130, 135, 138, 143, 146, 151, 154, + 156, 185, 187, 144, 145, 146, 147, 148, + 150, 155, 157, 158, 159, 128, 129, 130, + 131, 133, 135, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 148, 149, 152, 156, + 157, 160, 161, 162, 163, 164, 166, 168, + 169, 170, 171, 172, 173, 174, 176, 177, + 153, 155, 178, 179, 189, 160, 145, 255, + 139, 143, 182, 186, 187, 255, 158, 159, + 160, 169, 170, 255, 128, 191, 129, 131, + 133, 134, 140, 143, 144, 147, 149, 151, + 153, 179, 184, 186, 128, 135, 137, 164, + 165, 166, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 138, 139, 140, 141, 146, + 147, 150, 151, 152, 153, 154, 155, 156, + 162, 163, 171, 128, 130, 131, 183, 184, + 255, 135, 165, 166, 175, 176, 190, 131, + 175, 187, 188, 190, 255, 144, 168, 176, + 185, 128, 130, 131, 166, 167, 180, 182, + 191, 179, 182, 144, 178, 128, 130, 131, + 178, 179, 255, 155, 129, 132, 133, 137, + 141, 143, 144, 153, 154, 156, 157, 255, + 128, 145, 147, 171, 172, 183, 159, 170, + 171, 175, 176, 185, 186, 255, 189, 128, + 131, 133, 140, 143, 144, 147, 168, 170, + 176, 178, 179, 181, 185, 188, 191, 144, + 151, 128, 132, 135, 136, 139, 141, 157, + 161, 162, 163, 166, 172, 176, 180, 128, + 175, 176, 255, 134, 132, 135, 136, 143, + 144, 153, 154, 255, 128, 174, 175, 181, + 184, 255, 129, 151, 152, 155, 158, 255, + 132, 129, 143, 144, 153, 154, 255, 128, + 170, 171, 183, 128, 137, 157, 171, 176, + 185, 160, 169, 170, 190, 192, 255, 160, + 168, 169, 171, 172, 173, 174, 188, 189, + 190, 161, 167, 128, 158, 160, 169, 144, + 173, 176, 180, 128, 175, 176, 182, 128, + 131, 144, 153, 163, 183, 189, 255, 133, + 143, 145, 190, 191, 255, 143, 146, 147, + 159, 128, 176, 177, 178, 128, 136, 144, + 153, 157, 158, 160, 163, 133, 134, 137, + 144, 145, 146, 147, 148, 149, 154, 155, + 156, 157, 158, 159, 168, 169, 170, 150, + 153, 165, 169, 173, 255, 131, 132, 140, + 169, 174, 255, 130, 132, 131, 140, 141, + 142, 191, 192, 255, 128, 182, 187, 255, + 173, 180, 182, 255, 132, 155, 159, 161, + 175, 160, 163, 184, 185, 186, 161, 162, + 133, 143, 144, 150, 151, 255, 160, 128, + 129, 132, 135, 133, 134, 129, 160, 255, + 192, 255, 176, 255, 170, 173, 181, 186, + 128, 255, 181, 190, 176, 183, 184, 185, + 186, 191, 192, 255, 130, 131, 137, 137, + 190, 136, 144, 145, 191, 192, 255, 135, + 179, 129, 130, 132, 133, 144, 170, 176, + 178, 156, 128, 133, 140, 141, 144, 154, + 160, 191, 171, 172, 176, 128, 138, 139, + 169, 174, 255, 148, 158, 169, 150, 164, + 167, 173, 176, 185, 189, 190, 192, 255, + 144, 143, 145, 146, 175, 176, 255, 139, + 140, 141, 255, 166, 176, 178, 255, 184, + 186, 128, 137, 138, 170, 171, 179, 180, + 181, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, + 191, 154, 164, 168, 128, 149, 150, 173, + 128, 152, 153, 155, 163, 255, 189, 132, + 185, 144, 176, 152, 161, 164, 165, 177, + 255, 132, 169, 177, 188, 129, 131, 141, + 142, 145, 146, 179, 181, 186, 187, 190, + 255, 142, 158, 133, 134, 137, 138, 143, + 150, 152, 155, 156, 161, 164, 165, 176, + 177, 178, 255, 188, 129, 131, 133, 138, + 143, 144, 147, 168, 170, 176, 178, 179, + 181, 182, 184, 185, 190, 255, 157, 131, + 134, 137, 138, 142, 144, 146, 152, 153, + 158, 159, 165, 178, 180, 182, 255, 189, + 129, 131, 133, 141, 143, 145, 147, 168, + 170, 176, 178, 179, 181, 185, 188, 255, + 134, 138, 144, 185, 142, 159, 160, 161, + 164, 165, 176, 255, 189, 129, 131, 133, + 140, 143, 144, 147, 168, 170, 176, 178, + 179, 181, 185, 188, 191, 177, 128, 132, + 135, 136, 139, 141, 150, 151, 156, 157, + 159, 161, 162, 163, 166, 175, 130, 131, + 156, 133, 138, 142, 144, 146, 149, 153, + 154, 158, 159, 163, 164, 168, 170, 174, + 185, 190, 191, 144, 151, 128, 130, 134, + 136, 138, 141, 166, 175, 189, 128, 131, + 133, 140, 142, 144, 146, 168, 170, 185, + 190, 255, 133, 137, 151, 142, 148, 152, + 154, 155, 159, 160, 161, 164, 165, 176, + 255, 189, 129, 131, 133, 140, 142, 144, + 146, 168, 170, 179, 181, 185, 188, 191, + 158, 128, 132, 134, 136, 138, 141, 149, + 150, 160, 161, 162, 163, 166, 175, 177, + 178, 189, 129, 131, 133, 140, 142, 144, + 146, 186, 190, 255, 133, 137, 142, 143, + 150, 152, 158, 159, 161, 164, 165, 176, + 185, 186, 191, 192, 255, 189, 130, 131, + 133, 150, 154, 177, 179, 187, 138, 150, + 128, 134, 143, 148, 152, 159, 166, 175, + 178, 179, 177, 180, 186, 135, 142, 144, + 153, 177, 180, 185, 187, 188, 136, 141, + 144, 153, 128, 181, 183, 185, 152, 153, + 160, 169, 190, 191, 128, 135, 137, 172, + 177, 191, 128, 132, 134, 135, 136, 140, + 141, 151, 153, 188, 134, 128, 129, 130, + 131, 137, 138, 139, 140, 141, 142, 143, + 144, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 167, 168, + 169, 170, 172, 173, 174, 175, 176, 177, + 179, 181, 182, 183, 188, 189, 190, 191, + 132, 152, 180, 184, 185, 187, 171, 190, + 128, 137, 150, 153, 158, 160, 162, 164, + 167, 173, 177, 180, 130, 141, 143, 157, + 160, 255, 155, 156, 157, 159, 160, 255, + 128, 140, 142, 145, 146, 148, 160, 177, + 178, 180, 128, 145, 146, 147, 160, 172, + 174, 176, 178, 179, 180, 255, 148, 156, + 158, 159, 170, 255, 139, 142, 144, 153, + 160, 255, 169, 128, 170, 176, 255, 128, + 158, 160, 171, 176, 187, 128, 150, 151, + 155, 191, 149, 158, 160, 188, 128, 137, + 144, 153, 176, 190, 128, 132, 133, 179, + 180, 255, 133, 139, 140, 143, 154, 170, + 180, 255, 128, 130, 131, 160, 161, 173, + 174, 175, 176, 185, 186, 255, 166, 179, + 180, 255, 128, 163, 164, 183, 173, 144, + 146, 148, 168, 169, 177, 178, 180, 181, + 182, 184, 185, 128, 181, 188, 191, 128, + 129, 130, 131, 132, 133, 134, 146, 147, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 164, 140, 143, 152, 153, 170, 174, + 191, 255, 132, 165, 177, 191, 129, 147, + 149, 159, 160, 175, 176, 255, 144, 176, + 165, 170, 175, 177, 180, 255, 191, 168, + 174, 176, 255, 128, 134, 136, 142, 144, + 150, 152, 158, 160, 191, 128, 130, 132, + 133, 134, 133, 170, 175, 187, 188, 153, + 154, 128, 146, 147, 148, 152, 153, 154, + 155, 156, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 129, 255, 191, + 128, 174, 175, 178, 180, 189, 128, 157, + 158, 159, 160, 255, 176, 177, 178, 255, + 130, 134, 139, 163, 167, 168, 255, 128, + 129, 130, 179, 180, 255, 187, 189, 133, + 143, 154, 159, 178, 183, 184, 255, 128, + 137, 138, 165, 166, 173, 176, 255, 135, + 147, 148, 159, 189, 255, 128, 131, 132, + 178, 179, 255, 143, 129, 142, 154, 164, + 166, 175, 186, 255, 128, 168, 169, 182, + 131, 128, 139, 140, 141, 144, 153, 187, + 189, 176, 178, 180, 183, 184, 190, 191, + 129, 160, 170, 171, 175, 178, 180, 181, + 182, 128, 162, 163, 170, 172, 173, 176, + 185, 172, 173, 174, 175, 180, 181, 182, + 183, 184, 185, 187, 188, 189, 190, 191, + 176, 186, 158, 190, 128, 134, 147, 151, + 157, 168, 170, 182, 184, 188, 144, 148, + 128, 143, 160, 175, 179, 180, 144, 146, + 148, 141, 143, 176, 180, 182, 255, 191, + 189, 255, 135, 140, 142, 155, 191, 161, + 186, 158, 159, 160, 190, 130, 135, 138, + 143, 146, 151, 154, 156, 185, 187, 144, + 145, 146, 147, 148, 150, 155, 157, 158, + 159, 128, 129, 130, 131, 133, 135, 138, + 139, 140, 141, 142, 143, 144, 145, 146, + 148, 149, 152, 156, 157, 160, 161, 162, + 163, 164, 166, 168, 169, 170, 171, 172, + 173, 174, 176, 177, 153, 155, 178, 179, + 189, 160, 145, 255, 139, 143, 182, 186, + 187, 255, 128, 191, 129, 131, 133, 134, + 140, 143, 144, 147, 149, 151, 153, 179, + 184, 186, 128, 135, 137, 164, 165, 166, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 138, 139, 140, 141, 146, 147, 150, + 151, 152, 153, 154, 155, 156, 162, 163, + 171, 128, 130, 131, 183, 184, 255, 135, + 165, 176, 190, 131, 175, 187, 188, 190, + 255, 128, 130, 131, 166, 167, 180, 182, + 191, 179, 182, 144, 178, 128, 130, 131, + 178, 179, 255, 155, 129, 132, 133, 137, + 141, 143, 154, 156, 157, 255, 128, 145, + 147, 171, 172, 183, 159, 170, 171, 175, + 176, 185, 186, 255, 189, 128, 131, 133, + 140, 143, 144, 147, 168, 170, 176, 178, + 179, 181, 185, 188, 191, 144, 151, 128, + 132, 135, 136, 139, 141, 157, 161, 162, + 163, 166, 172, 176, 180, 128, 175, 176, + 255, 134, 132, 135, 136, 143, 154, 255, + 128, 174, 175, 181, 184, 255, 129, 151, + 152, 155, 158, 255, 132, 129, 143, 154, + 255, 128, 170, 171, 183, 157, 171, 176, + 185, 160, 168, 169, 171, 172, 173, 174, + 188, 189, 190, 161, 167, 144, 173, 176, + 180, 128, 175, 176, 182, 133, 143, 145, + 190, 191, 255, 143, 146, 147, 159, 176, + 177, 178, 128, 136, 144, 153, 157, 158, + 160, 163, 133, 134, 137, 144, 145, 146, + 147, 148, 149, 154, 155, 156, 157, 158, + 159, 168, 169, 170, 150, 153, 165, 169, + 173, 255, 131, 132, 140, 169, 174, 255, + 130, 132, 128, 182, 187, 255, 173, 180, + 182, 255, 132, 155, 159, 161, 175, 160, + 163, 184, 185, 186, 161, 162, 133, 143, + 144, 150, 151, 255, 160, 128, 129, 132, + 135, 133, 134, 129, 160, 255, 192, 255, + 176, 255, 173, 128, 255, 176, 255, 131, + 137, 191, 145, 189, 135, 129, 130, 132, + 133, 156, 128, 133, 144, 154, 171, 176, + 139, 159, 160, 169, 150, 157, 159, 164, + 167, 168, 170, 173, 176, 185, 143, 145, + 176, 255, 139, 255, 166, 176, 128, 137, + 171, 179, 160, 161, 163, 164, 165, 167, + 169, 171, 173, 174, 175, 176, 177, 179, + 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 166, 170, 172, 178, + 150, 153, 155, 163, 165, 167, 169, 173, + 153, 155, 163, 255, 189, 132, 185, 144, + 152, 161, 164, 165, 166, 175, 176, 255, + 188, 129, 131, 190, 255, 133, 134, 137, + 138, 142, 150, 152, 161, 164, 165, 166, + 175, 176, 255, 131, 134, 137, 138, 142, + 144, 146, 165, 166, 175, 178, 180, 182, + 255, 134, 138, 142, 161, 164, 165, 166, + 175, 176, 255, 188, 129, 131, 190, 191, + 128, 132, 135, 136, 139, 141, 150, 151, + 162, 163, 166, 175, 130, 190, 191, 151, + 128, 130, 134, 136, 138, 141, 166, 175, + 128, 131, 190, 255, 133, 137, 142, 148, + 151, 161, 164, 165, 166, 175, 176, 255, + 128, 132, 134, 136, 138, 141, 149, 150, + 162, 163, 166, 175, 129, 131, 190, 255, + 133, 137, 142, 150, 152, 161, 164, 165, + 166, 175, 176, 255, 130, 131, 138, 150, + 143, 148, 152, 159, 166, 175, 178, 179, + 177, 180, 186, 135, 142, 144, 153, 177, + 180, 185, 187, 188, 136, 141, 144, 153, + 181, 183, 185, 152, 153, 160, 169, 190, + 191, 177, 191, 128, 132, 134, 135, 141, + 151, 153, 188, 134, 128, 129, 130, 141, + 156, 157, 158, 159, 160, 162, 164, 165, + 167, 168, 169, 170, 172, 173, 174, 175, + 176, 177, 179, 183, 171, 190, 128, 137, + 150, 153, 158, 160, 162, 164, 167, 173, + 177, 180, 143, 130, 141, 144, 153, 154, + 157, 157, 159, 146, 148, 178, 180, 146, + 147, 178, 179, 180, 255, 148, 156, 158, + 159, 160, 169, 170, 255, 139, 142, 144, + 153, 169, 160, 171, 176, 187, 151, 155, + 191, 149, 158, 160, 188, 128, 137, 144, + 153, 176, 190, 128, 132, 180, 255, 133, + 143, 144, 153, 154, 170, 180, 255, 128, + 130, 161, 173, 176, 185, 166, 179, 164, + 183, 128, 137, 144, 153, 173, 144, 146, + 148, 168, 178, 180, 184, 185, 128, 181, + 188, 191, 128, 129, 131, 179, 181, 183, + 140, 143, 170, 174, 160, 164, 166, 175, + 144, 176, 175, 177, 191, 160, 191, 128, + 130, 170, 175, 153, 154, 152, 153, 154, + 155, 160, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 175, 160, 169, 175, + 178, 180, 189, 158, 159, 176, 177, 130, + 134, 139, 163, 167, 128, 129, 180, 255, + 133, 143, 144, 153, 154, 159, 178, 255, + 128, 137, 166, 173, 135, 147, 128, 131, + 179, 255, 129, 143, 144, 153, 154, 164, + 166, 175, 176, 185, 186, 255, 169, 182, + 131, 140, 141, 144, 153, 187, 189, 176, + 178, 180, 183, 184, 190, 191, 129, 171, + 175, 181, 182, 163, 170, 172, 173, 176, + 185, 172, 184, 187, 190, 191, 158, 128, + 143, 160, 175, 185, 187, 144, 145, 150, + 155, 157, 158, 135, 139, 141, 146, 168, + 171, 189, 160, 182, 186, 191, 129, 131, + 133, 134, 140, 143, 184, 186, 165, 166, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 139, 140, 141, 146, 147, 150, 151, + 152, 153, 154, 155, 156, 163, 128, 130, + 184, 255, 135, 165, 166, 175, 176, 190, + 131, 175, 187, 188, 190, 255, 176, 185, + 128, 130, 167, 180, 182, 191, 179, 128, + 130, 179, 255, 129, 137, 141, 143, 144, + 153, 154, 255, 172, 183, 159, 170, 176, + 185, 188, 128, 131, 190, 191, 151, 128, + 132, 135, 136, 139, 141, 162, 163, 166, + 172, 176, 180, 176, 255, 132, 143, 144, + 153, 154, 255, 175, 181, 184, 255, 129, + 155, 158, 255, 129, 143, 144, 153, 154, + 255, 171, 183, 157, 171, 176, 185, 169, + 171, 172, 173, 189, 190, 176, 180, 176, + 182, 145, 190, 143, 146, 178, 157, 158, + 160, 163, 133, 134, 137, 159, 168, 169, + 170, 165, 169, 173, 255, 131, 132, 140, + 169, 174, 255, 130, 132, 142, 191, 128, + 182, 187, 255, 173, 180, 182, 255, 132, + 155, 159, 161, 175, 163, 144, 150, 160, + 128, 129, 132, 135, 133, 134, 129, 160, + 255, 192, 255, 170, 173, 181, 186, 128, + 255, 181, 190, 176, 183, 184, 185, 186, + 191, 192, 255, 130, 131, 137, 137, 190, + 136, 144, 145, 191, 192, 255, 135, 179, + 129, 130, 132, 133, 144, 170, 176, 178, + 156, 128, 133, 140, 141, 144, 154, 160, + 191, 171, 172, 176, 128, 138, 139, 159, + 160, 169, 174, 255, 148, 158, 169, 150, + 164, 167, 173, 176, 185, 189, 190, 192, + 255, 144, 143, 145, 146, 175, 176, 255, + 139, 140, 141, 255, 166, 176, 178, 255, + 184, 186, 128, 137, 138, 170, 171, 179, + 180, 181, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 154, 164, 168, 128, 149, 150, + 173, 128, 152, 153, 155, 163, 255, 189, + 132, 185, 144, 176, 152, 161, 164, 165, + 166, 175, 177, 255, 132, 169, 177, 188, + 129, 131, 141, 142, 145, 146, 179, 181, + 186, 187, 190, 255, 142, 158, 133, 134, + 137, 138, 143, 150, 152, 155, 156, 161, + 164, 165, 166, 175, 176, 177, 178, 255, + 188, 129, 131, 133, 138, 143, 144, 147, + 168, 170, 176, 178, 179, 181, 182, 184, + 185, 190, 255, 157, 131, 134, 137, 138, + 142, 144, 146, 152, 153, 158, 159, 165, + 166, 175, 178, 180, 182, 255, 189, 129, + 131, 133, 141, 143, 145, 147, 168, 170, + 176, 178, 179, 181, 185, 188, 255, 134, + 138, 144, 185, 142, 159, 160, 161, 164, + 165, 166, 175, 176, 255, 189, 129, 131, + 133, 140, 143, 144, 147, 168, 170, 176, + 178, 179, 181, 185, 188, 191, 177, 128, + 132, 135, 136, 139, 141, 150, 151, 156, + 157, 159, 161, 162, 163, 166, 175, 130, + 131, 156, 133, 138, 142, 144, 146, 149, + 153, 154, 158, 159, 163, 164, 168, 170, + 174, 185, 190, 191, 144, 151, 128, 130, + 134, 136, 138, 141, 166, 175, 189, 128, + 131, 133, 140, 142, 144, 146, 168, 170, + 185, 190, 255, 133, 137, 151, 142, 148, + 152, 154, 155, 159, 160, 161, 164, 165, + 166, 175, 176, 255, 189, 129, 131, 133, + 140, 142, 144, 146, 168, 170, 179, 181, + 185, 188, 191, 158, 128, 132, 134, 136, + 138, 141, 149, 150, 160, 161, 162, 163, + 166, 175, 177, 178, 189, 129, 131, 133, + 140, 142, 144, 146, 186, 190, 255, 133, + 137, 142, 143, 150, 152, 158, 159, 161, + 164, 165, 166, 175, 176, 185, 186, 191, + 192, 255, 189, 130, 131, 133, 150, 154, + 177, 179, 187, 138, 150, 128, 134, 143, + 148, 152, 159, 166, 175, 178, 179, 177, + 180, 186, 135, 142, 144, 153, 177, 180, + 185, 187, 188, 136, 141, 144, 153, 128, + 181, 183, 185, 152, 153, 160, 169, 190, + 191, 128, 135, 137, 172, 177, 191, 128, + 132, 134, 135, 136, 140, 141, 151, 153, + 188, 134, 128, 129, 130, 131, 137, 138, + 139, 140, 141, 142, 143, 144, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 167, 168, 169, 170, 172, + 173, 174, 175, 176, 177, 179, 181, 182, + 183, 188, 189, 190, 191, 132, 152, 180, + 184, 185, 187, 171, 190, 128, 137, 150, + 153, 158, 160, 162, 164, 167, 173, 177, + 180, 143, 130, 141, 144, 153, 154, 157, + 160, 255, 155, 156, 157, 159, 160, 255, + 128, 140, 142, 145, 146, 148, 160, 177, + 178, 180, 128, 145, 146, 147, 160, 172, + 174, 176, 178, 179, 180, 255, 148, 156, + 158, 159, 160, 169, 170, 255, 139, 142, + 144, 153, 160, 255, 169, 128, 170, 176, + 255, 128, 158, 160, 171, 176, 187, 128, + 150, 151, 155, 191, 149, 158, 160, 188, + 128, 137, 144, 153, 176, 190, 128, 132, + 133, 179, 180, 255, 133, 139, 140, 143, + 144, 153, 154, 170, 180, 255, 128, 130, + 131, 160, 161, 173, 174, 175, 176, 185, + 186, 255, 166, 179, 180, 255, 128, 163, + 164, 183, 173, 144, 146, 148, 168, 169, + 177, 178, 180, 181, 182, 184, 185, 128, + 181, 188, 191, 128, 129, 130, 131, 132, + 133, 134, 146, 147, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 164, 140, 143, + 152, 153, 170, 174, 191, 255, 132, 165, + 177, 191, 129, 147, 149, 159, 160, 175, + 176, 255, 144, 176, 165, 170, 175, 177, + 180, 255, 191, 168, 174, 176, 255, 128, + 134, 136, 142, 144, 150, 152, 158, 160, + 191, 128, 130, 132, 133, 134, 133, 170, + 175, 187, 188, 153, 154, 128, 146, 147, + 148, 152, 153, 154, 155, 156, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 129, 255, 191, 128, 174, 175, 178, + 180, 189, 128, 157, 158, 159, 160, 255, + 176, 177, 178, 255, 130, 134, 139, 163, + 167, 168, 255, 128, 129, 130, 179, 180, + 255, 187, 189, 133, 143, 144, 153, 154, + 159, 178, 183, 184, 255, 128, 137, 138, + 165, 166, 173, 176, 255, 135, 147, 148, + 159, 189, 255, 128, 131, 132, 178, 179, + 255, 143, 129, 142, 144, 153, 154, 164, + 166, 175, 176, 185, 186, 255, 128, 168, + 169, 182, 131, 128, 139, 140, 141, 144, + 153, 187, 189, 176, 178, 180, 183, 184, + 190, 191, 129, 160, 170, 171, 175, 178, + 180, 181, 182, 128, 162, 163, 170, 172, + 173, 176, 185, 172, 173, 174, 175, 180, + 181, 182, 183, 184, 185, 187, 188, 189, + 190, 191, 176, 186, 158, 190, 128, 134, + 147, 151, 157, 168, 170, 182, 184, 188, + 144, 148, 128, 143, 160, 175, 179, 180, + 191, 189, 255, 158, 159, 160, 190, 130, + 135, 138, 143, 146, 151, 154, 156, 185, + 187, 144, 145, 146, 147, 148, 150, 155, + 157, 158, 159, 128, 129, 130, 131, 133, + 135, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 148, 149, 152, 156, 157, 160, + 161, 162, 163, 164, 166, 168, 169, 170, + 171, 172, 173, 174, 176, 177, 153, 155, + 178, 179, 189, 160, 145, 255, 139, 143, + 182, 186, 187, 255, 128, 191, 129, 131, + 133, 134, 140, 143, 144, 147, 149, 151, + 153, 179, 184, 186, 128, 135, 137, 164, + 165, 166, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 138, 139, 140, 141, 146, + 147, 150, 151, 152, 153, 154, 155, 156, + 162, 163, 171, 128, 130, 131, 183, 184, + 255, 135, 165, 166, 175, 176, 190, 131, + 175, 187, 188, 190, 255, 128, 130, 131, + 166, 167, 180, 182, 191, 179, 182, 144, + 178, 128, 130, 131, 178, 179, 255, 155, + 129, 132, 133, 137, 141, 143, 144, 153, + 154, 156, 157, 255, 128, 145, 147, 171, + 172, 183, 159, 170, 171, 175, 176, 185, + 186, 255, 189, 128, 131, 133, 140, 143, + 144, 147, 168, 170, 176, 178, 179, 181, + 185, 188, 191, 144, 151, 128, 132, 135, + 136, 139, 141, 157, 161, 162, 163, 166, + 172, 176, 180, 128, 175, 176, 255, 134, + 132, 135, 136, 143, 144, 153, 154, 255, + 128, 174, 175, 181, 184, 255, 129, 151, + 152, 155, 158, 255, 132, 129, 143, 144, + 153, 154, 255, 128, 170, 171, 183, 157, + 171, 176, 185, 160, 168, 169, 171, 172, + 173, 174, 188, 189, 190, 161, 167, 144, + 173, 176, 180, 128, 175, 176, 182, 133, + 143, 145, 190, 191, 255, 143, 146, 147, + 159, 176, 177, 178, 128, 136, 144, 153, + 157, 158, 160, 163, 133, 134, 137, 144, + 145, 146, 147, 148, 149, 154, 155, 156, + 157, 158, 159, 168, 169, 170, 150, 153, + 165, 169, 173, 255, 131, 132, 140, 169, + 174, 255, 130, 132, 128, 182, 187, 255, + 173, 180, 182, 255, 132, 155, 159, 161, + 175, 160, 163, 184, 185, 186, 161, 162, + 133, 143, 144, 150, 151, 255, 160, 128, + 129, 132, 135, 133, 134, 129, 160, 255, + 192, 255, 176, 255, 170, 173, 181, 183, + 186, 128, 255, 181, 190, 176, 183, 184, + 185, 186, 191, 192, 255, 130, 131, 137, + 190, 136, 144, 145, 191, 192, 255, 135, + 179, 180, 129, 130, 132, 133, 144, 170, + 176, 178, 156, 128, 133, 144, 154, 160, + 191, 171, 176, 128, 138, 139, 159, 160, + 169, 174, 255, 148, 158, 169, 150, 164, + 167, 173, 176, 185, 189, 190, 192, 255, + 144, 143, 145, 146, 175, 176, 255, 139, + 140, 141, 255, 166, 176, 178, 255, 186, + 128, 137, 138, 170, 171, 179, 180, 181, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 154, 164, 168, 128, 149, 150, 173, 128, + 152, 153, 155, 163, 255, 189, 132, 185, + 144, 176, 152, 161, 164, 165, 166, 175, + 177, 255, 132, 169, 177, 188, 129, 131, + 141, 142, 145, 146, 179, 181, 186, 187, + 190, 255, 142, 158, 133, 134, 137, 138, + 143, 150, 152, 155, 156, 161, 164, 165, + 166, 175, 176, 177, 178, 255, 188, 129, + 131, 133, 138, 143, 144, 147, 168, 170, + 176, 178, 179, 181, 182, 184, 185, 190, + 255, 157, 131, 134, 137, 138, 142, 144, + 146, 152, 153, 158, 159, 165, 166, 175, + 178, 180, 182, 255, 189, 129, 131, 133, + 141, 143, 145, 147, 168, 170, 176, 178, + 179, 181, 185, 188, 255, 134, 138, 144, + 185, 142, 159, 160, 161, 164, 165, 166, + 175, 176, 255, 189, 129, 131, 133, 140, + 143, 144, 147, 168, 170, 176, 178, 179, + 181, 185, 188, 191, 177, 128, 132, 135, + 136, 139, 141, 150, 151, 156, 157, 159, + 161, 162, 163, 166, 175, 130, 131, 156, + 133, 138, 142, 144, 146, 149, 153, 154, + 158, 159, 163, 164, 168, 170, 174, 185, + 190, 191, 144, 151, 128, 130, 134, 136, + 138, 141, 166, 175, 189, 128, 131, 133, + 140, 142, 144, 146, 168, 170, 185, 190, + 255, 133, 137, 151, 142, 148, 152, 154, + 155, 159, 160, 161, 164, 165, 166, 175, + 176, 255, 189, 129, 131, 133, 140, 142, + 144, 146, 168, 170, 179, 181, 185, 188, + 191, 158, 128, 132, 134, 136, 138, 141, + 149, 150, 160, 161, 162, 163, 166, 175, + 177, 178, 189, 129, 131, 133, 140, 142, + 144, 146, 186, 190, 255, 133, 137, 142, + 143, 150, 152, 158, 159, 161, 164, 165, + 166, 175, 176, 185, 186, 191, 192, 255, + 189, 130, 131, 133, 150, 154, 177, 179, + 187, 138, 150, 128, 134, 143, 148, 152, + 159, 166, 175, 178, 179, 177, 180, 186, + 135, 142, 144, 153, 177, 180, 185, 187, + 188, 136, 141, 144, 153, 128, 181, 183, + 185, 152, 153, 160, 169, 190, 191, 128, + 135, 137, 172, 177, 191, 128, 132, 134, + 135, 136, 140, 141, 151, 153, 188, 134, + 128, 129, 130, 131, 137, 138, 139, 140, + 141, 142, 143, 144, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, + 165, 167, 168, 169, 170, 172, 173, 174, + 175, 176, 177, 179, 181, 182, 183, 188, + 189, 190, 191, 132, 152, 180, 184, 185, + 187, 171, 190, 128, 137, 150, 153, 158, + 160, 162, 164, 167, 173, 177, 180, 143, + 130, 141, 144, 153, 154, 157, 160, 255, + 155, 156, 157, 159, 160, 255, 128, 140, + 142, 145, 146, 148, 160, 177, 178, 180, + 128, 145, 146, 147, 160, 172, 174, 176, + 178, 179, 180, 255, 148, 156, 158, 159, + 160, 169, 170, 255, 139, 142, 144, 153, + 160, 255, 169, 128, 170, 176, 255, 128, + 158, 160, 171, 176, 187, 128, 150, 151, + 155, 191, 149, 158, 160, 188, 128, 137, + 144, 153, 176, 190, 128, 132, 133, 179, + 180, 255, 133, 139, 140, 143, 144, 153, + 154, 170, 180, 255, 128, 130, 131, 160, + 161, 173, 174, 175, 176, 185, 186, 255, + 166, 179, 180, 255, 128, 163, 164, 183, + 173, 144, 146, 148, 168, 169, 177, 178, + 180, 181, 182, 184, 185, 128, 181, 188, + 191, 128, 129, 130, 131, 132, 133, 134, + 146, 147, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 164, 167, 140, 143, 152, + 153, 170, 174, 191, 255, 165, 177, 191, + 129, 147, 149, 159, 160, 175, 176, 255, + 144, 176, 165, 170, 175, 177, 180, 255, + 191, 168, 174, 176, 255, 128, 134, 136, + 142, 144, 150, 152, 158, 160, 191, 128, + 130, 132, 133, 134, 133, 170, 175, 187, + 188, 153, 154, 128, 146, 147, 148, 152, + 153, 154, 155, 156, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 129, + 255, 191, 128, 174, 175, 178, 180, 189, + 128, 157, 158, 159, 160, 255, 176, 177, + 178, 255, 130, 134, 139, 163, 167, 168, + 255, 128, 129, 130, 179, 180, 255, 187, + 189, 133, 143, 144, 153, 154, 159, 178, + 183, 184, 255, 128, 137, 138, 165, 166, + 173, 176, 255, 135, 147, 148, 159, 189, + 255, 128, 131, 132, 178, 179, 255, 143, + 129, 142, 144, 153, 154, 164, 166, 175, + 176, 185, 186, 255, 128, 168, 169, 182, + 131, 128, 139, 140, 141, 144, 153, 187, + 189, 176, 178, 180, 183, 184, 190, 191, + 129, 160, 170, 171, 175, 178, 180, 181, + 182, 128, 162, 163, 170, 172, 173, 176, + 185, 172, 173, 174, 175, 180, 181, 182, + 183, 184, 185, 187, 188, 189, 190, 191, + 176, 186, 158, 190, 128, 134, 147, 151, + 157, 168, 170, 182, 184, 188, 147, 128, + 143, 160, 175, 179, 180, 191, 189, 255, + 158, 159, 160, 190, 130, 135, 138, 143, + 146, 151, 154, 156, 185, 187, 144, 145, + 146, 147, 148, 150, 155, 157, 158, 159, + 128, 129, 130, 131, 133, 135, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 148, + 149, 152, 156, 157, 160, 161, 162, 163, + 164, 166, 168, 169, 170, 171, 172, 173, + 174, 176, 177, 153, 155, 178, 179, 189, + 160, 145, 255, 139, 143, 182, 186, 187, + 255, 128, 191, 129, 131, 133, 134, 140, + 143, 144, 147, 149, 151, 153, 179, 184, + 186, 128, 135, 137, 164, 165, 166, 128, + 129, 130, 131, 132, 133, 134, 135, 136, + 138, 139, 140, 141, 146, 147, 150, 151, + 152, 153, 154, 155, 156, 162, 163, 171, + 128, 130, 131, 183, 184, 255, 135, 165, + 166, 175, 176, 190, 131, 175, 187, 188, + 190, 255, 128, 130, 131, 166, 167, 180, + 182, 191, 179, 182, 144, 178, 128, 130, + 131, 178, 179, 255, 155, 129, 132, 133, + 137, 141, 143, 144, 153, 154, 156, 157, + 255, 128, 145, 147, 171, 172, 183, 159, + 170, 171, 175, 176, 185, 186, 255, 189, + 128, 131, 133, 140, 143, 144, 147, 168, + 170, 176, 178, 179, 181, 185, 188, 191, + 144, 151, 128, 132, 135, 136, 139, 141, + 157, 161, 162, 163, 166, 172, 176, 180, + 128, 175, 176, 255, 134, 132, 135, 136, + 143, 144, 153, 154, 255, 128, 174, 175, + 181, 184, 255, 129, 151, 152, 155, 158, + 255, 132, 129, 143, 144, 153, 154, 255, + 128, 170, 171, 183, 157, 171, 176, 185, + 160, 168, 169, 171, 172, 173, 174, 188, + 189, 190, 161, 167, 144, 173, 176, 180, + 128, 175, 176, 182, 133, 143, 145, 190, + 191, 255, 143, 146, 147, 159, 176, 177, + 178, 128, 136, 144, 153, 157, 158, 160, + 163, 133, 134, 137, 144, 145, 146, 147, + 148, 149, 154, 155, 156, 157, 158, 159, + 168, 169, 170, 150, 153, 165, 169, 173, + 255, 131, 132, 140, 169, 174, 255, 130, + 132, 128, 182, 187, 255, 173, 180, 182, + 255, 132, 155, 159, 161, 175, 160, 163, + 184, 185, 186, 161, 162, 133, 143, 144, + 150, 151, 255, 160, 128, 129, 132, 135, + 133, 134, 129, 160, 255, 192, 255, 176, + 255, 170, 173, 181, 186, 128, 255, 181, + 190, 176, 183, 184, 185, 186, 191, 192, + 255, 130, 131, 137, 190, 136, 144, 145, + 191, 192, 255, 135, 179, 129, 130, 132, + 133, 144, 170, 176, 178, 156, 128, 133, + 144, 154, 160, 191, 171, 176, 128, 138, + 139, 159, 160, 169, 174, 255, 148, 158, + 169, 150, 164, 167, 173, 176, 185, 189, + 190, 192, 255, 144, 143, 145, 146, 175, + 176, 255, 139, 140, 141, 255, 166, 176, + 178, 255, 186, 128, 137, 138, 170, 171, + 179, 180, 181, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 154, 164, 168, 128, 149, + 150, 173, 128, 152, 153, 155, 163, 255, + 189, 132, 185, 144, 176, 152, 161, 164, + 165, 166, 175, 177, 255, 132, 169, 177, + 188, 129, 131, 141, 142, 145, 146, 179, + 181, 186, 187, 190, 255, 142, 158, 133, + 134, 137, 138, 143, 150, 152, 155, 156, + 161, 164, 165, 166, 175, 176, 177, 178, + 255, 188, 129, 131, 133, 138, 143, 144, + 147, 168, 170, 176, 178, 179, 181, 182, + 184, 185, 190, 255, 157, 131, 134, 137, + 138, 142, 144, 146, 152, 153, 158, 159, + 165, 166, 175, 178, 180, 182, 255, 189, + 129, 131, 133, 141, 143, 145, 147, 168, + 170, 176, 178, 179, 181, 185, 188, 255, + 134, 138, 144, 185, 142, 159, 160, 161, + 164, 165, 166, 175, 176, 255, 189, 129, + 131, 133, 140, 143, 144, 147, 168, 170, + 176, 178, 179, 181, 185, 188, 191, 177, + 128, 132, 135, 136, 139, 141, 150, 151, + 156, 157, 159, 161, 162, 163, 166, 175, + 130, 131, 156, 133, 138, 142, 144, 146, + 149, 153, 154, 158, 159, 163, 164, 168, + 170, 174, 185, 190, 191, 144, 151, 128, + 130, 134, 136, 138, 141, 166, 175, 189, + 128, 131, 133, 140, 142, 144, 146, 168, + 170, 185, 190, 255, 133, 137, 151, 142, + 148, 152, 154, 155, 159, 160, 161, 164, + 165, 166, 175, 176, 255, 189, 129, 131, + 133, 140, 142, 144, 146, 168, 170, 179, + 181, 185, 188, 191, 158, 128, 132, 134, + 136, 138, 141, 149, 150, 160, 161, 162, + 163, 166, 175, 177, 178, 189, 129, 131, + 133, 140, 142, 144, 146, 186, 190, 255, + 133, 137, 142, 143, 150, 152, 158, 159, + 161, 164, 165, 166, 175, 176, 185, 186, + 191, 192, 255, 189, 130, 131, 133, 150, + 154, 177, 179, 187, 138, 150, 128, 134, + 143, 148, 152, 159, 166, 175, 178, 179, + 177, 180, 186, 135, 142, 144, 153, 177, + 180, 185, 187, 188, 136, 141, 144, 153, + 128, 181, 183, 185, 152, 153, 160, 169, + 190, 191, 128, 135, 137, 172, 177, 191, + 128, 132, 134, 135, 136, 140, 141, 151, + 153, 188, 134, 128, 129, 130, 131, 137, + 138, 139, 140, 141, 142, 143, 144, 153, + 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 167, 168, 169, 170, + 172, 173, 174, 175, 176, 177, 179, 181, + 182, 183, 188, 189, 190, 191, 132, 152, + 180, 184, 185, 187, 171, 190, 128, 137, + 150, 153, 158, 160, 162, 164, 167, 173, + 177, 180, 143, 130, 141, 144, 153, 154, + 157, 160, 255, 155, 156, 157, 159, 160, + 255, 128, 140, 142, 145, 146, 148, 160, + 177, 178, 180, 128, 145, 146, 147, 160, + 172, 174, 176, 178, 179, 180, 255, 148, + 156, 158, 159, 160, 169, 170, 255, 139, + 142, 144, 153, 160, 255, 169, 128, 170, + 176, 255, 128, 158, 160, 171, 176, 187, + 128, 150, 151, 155, 191, 149, 158, 160, + 188, 128, 137, 144, 153, 176, 190, 128, + 132, 133, 179, 180, 255, 133, 139, 140, + 143, 144, 153, 154, 170, 180, 255, 128, + 130, 131, 160, 161, 173, 174, 175, 176, + 185, 186, 255, 166, 179, 180, 255, 128, + 163, 164, 183, 173, 144, 146, 148, 168, + 169, 177, 178, 180, 181, 182, 184, 185, + 128, 181, 188, 191, 128, 129, 130, 131, + 132, 133, 134, 146, 147, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 140, 143, + 170, 174, 191, 255, 165, 177, 191, 129, + 147, 149, 159, 176, 255, 144, 176, 165, + 170, 175, 177, 180, 255, 191, 168, 174, + 176, 255, 128, 134, 136, 142, 144, 150, + 152, 158, 160, 191, 128, 130, 131, 132, + 133, 134, 135, 139, 140, 141, 133, 170, + 175, 177, 181, 187, 188, 153, 154, 155, + 156, 160, 255, 128, 146, 147, 148, 152, + 153, 154, 155, 156, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 129, + 255, 191, 128, 174, 175, 178, 180, 189, + 128, 157, 158, 159, 160, 255, 176, 177, + 178, 255, 130, 134, 139, 163, 167, 168, + 255, 128, 129, 130, 179, 180, 255, 187, + 189, 133, 143, 144, 153, 154, 159, 178, + 183, 184, 255, 128, 137, 138, 165, 166, + 173, 176, 255, 135, 147, 148, 159, 189, + 255, 128, 131, 132, 178, 179, 255, 143, + 129, 142, 144, 153, 154, 164, 166, 175, + 176, 185, 186, 255, 128, 168, 169, 182, + 131, 128, 139, 140, 141, 144, 153, 187, + 189, 176, 178, 180, 183, 184, 190, 191, + 129, 160, 170, 171, 175, 178, 180, 181, + 182, 128, 162, 163, 170, 172, 173, 176, + 185, 172, 173, 174, 175, 180, 181, 182, + 183, 184, 185, 187, 188, 189, 190, 191, + 176, 186, 158, 190, 128, 134, 147, 151, + 157, 168, 170, 182, 184, 188, 128, 143, + 160, 175, 179, 180, 141, 143, 176, 180, + 182, 255, 191, 189, 255, 191, 161, 186, + 158, 159, 160, 190, 191, 255, 130, 135, + 138, 143, 146, 151, 154, 156, 185, 187, + 144, 145, 146, 147, 148, 150, 155, 157, + 158, 159, 128, 129, 130, 131, 133, 135, + 138, 139, 140, 141, 142, 143, 144, 145, + 146, 148, 149, 152, 156, 157, 160, 161, + 162, 163, 164, 166, 168, 169, 170, 171, + 172, 173, 174, 176, 177, 153, 155, 178, + 179, 189, 160, 145, 255, 139, 143, 182, + 186, 187, 255, 128, 191, 129, 131, 133, + 134, 140, 143, 144, 147, 149, 151, 153, + 179, 184, 186, 128, 135, 137, 164, 165, + 166, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 138, 139, 140, 141, 146, 147, + 150, 151, 152, 153, 154, 155, 156, 162, + 163, 171, 128, 130, 131, 183, 184, 255, + 135, 165, 166, 175, 176, 190, 131, 175, + 187, 188, 190, 255, 128, 130, 131, 166, + 167, 180, 182, 191, 179, 182, 144, 178, + 128, 130, 131, 178, 179, 255, 155, 129, + 132, 133, 137, 141, 143, 144, 153, 154, + 156, 157, 255, 128, 145, 147, 171, 172, + 183, 159, 170, 171, 175, 176, 185, 186, + 255, 189, 128, 131, 133, 140, 143, 144, + 147, 168, 170, 176, 178, 179, 181, 185, + 188, 191, 144, 151, 128, 132, 135, 136, + 139, 141, 157, 161, 162, 163, 166, 172, + 176, 180, 128, 175, 176, 255, 134, 132, + 135, 136, 143, 144, 153, 154, 255, 128, + 174, 175, 181, 184, 255, 129, 151, 152, + 155, 158, 255, 132, 129, 143, 144, 153, + 154, 255, 128, 170, 171, 183, 157, 171, + 176, 185, 160, 168, 169, 171, 172, 173, + 174, 188, 189, 190, 161, 167, 144, 173, + 176, 180, 128, 175, 176, 182, 133, 143, + 145, 190, 191, 255, 143, 146, 147, 159, + 128, 176, 177, 178, 128, 136, 144, 153, + 157, 158, 160, 163, 133, 134, 137, 144, + 145, 146, 147, 148, 149, 154, 155, 156, + 157, 158, 159, 168, 169, 170, 150, 153, + 165, 169, 173, 255, 131, 132, 140, 169, + 174, 255, 130, 132, 128, 182, 187, 255, + 173, 180, 182, 255, 132, 155, 159, 161, + 175, 160, 163, 184, 185, 186, 161, 162, + 133, 143, 144, 150, 151, 255, 160, 128, + 129, 132, 135, 133, 134, 129, 160, 255, + 192, 255, 176, 255, 170, 173, 181, 186, + 0, 127, 181, 190, 176, 183, 184, 185, + 186, 191, 192, 255, 130, 131, 137, 190, + 136, 144, 145, 191, 192, 255, 135, 179, + 129, 130, 132, 133, 144, 170, 176, 178, + 156, 128, 133, 144, 154, 160, 191, 171, + 176, 128, 138, 139, 159, 160, 169, 174, + 255, 148, 158, 169, 150, 164, 167, 173, + 176, 185, 189, 190, 192, 255, 144, 143, + 145, 146, 175, 176, 255, 139, 140, 141, + 255, 166, 176, 178, 255, 186, 128, 137, + 138, 170, 171, 179, 180, 181, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 154, 164, + 168, 128, 149, 150, 173, 128, 152, 153, + 155, 163, 255, 189, 132, 185, 144, 176, + 152, 161, 164, 165, 166, 175, 177, 255, + 132, 169, 177, 188, 129, 131, 141, 142, + 145, 146, 179, 181, 186, 187, 190, 255, + 142, 158, 133, 134, 137, 138, 143, 150, + 152, 155, 156, 161, 164, 165, 166, 175, + 176, 177, 178, 255, 188, 129, 131, 133, + 138, 143, 144, 147, 168, 170, 176, 178, + 179, 181, 182, 184, 185, 190, 255, 157, + 131, 134, 137, 138, 142, 144, 146, 152, + 153, 158, 159, 165, 166, 175, 178, 180, + 182, 255, 189, 129, 131, 133, 141, 143, + 145, 147, 168, 170, 176, 178, 179, 181, + 185, 188, 255, 134, 138, 144, 185, 142, + 159, 160, 161, 164, 165, 166, 175, 176, + 255, 189, 129, 131, 133, 140, 143, 144, + 147, 168, 170, 176, 178, 179, 181, 185, + 188, 191, 177, 128, 132, 135, 136, 139, + 141, 150, 151, 156, 157, 159, 161, 162, + 163, 166, 175, 130, 131, 156, 133, 138, + 142, 144, 146, 149, 153, 154, 158, 159, + 163, 164, 168, 170, 174, 185, 190, 191, + 144, 151, 128, 130, 134, 136, 138, 141, + 166, 175, 189, 128, 131, 133, 140, 142, + 144, 146, 168, 170, 185, 190, 255, 133, + 137, 151, 142, 148, 152, 154, 155, 159, + 160, 161, 164, 165, 166, 175, 176, 255, + 189, 129, 131, 133, 140, 142, 144, 146, + 168, 170, 179, 181, 185, 188, 191, 158, + 128, 132, 134, 136, 138, 141, 149, 150, + 160, 161, 162, 163, 166, 175, 177, 178, + 189, 129, 131, 133, 140, 142, 144, 146, + 186, 190, 255, 133, 137, 142, 143, 150, + 152, 158, 159, 161, 164, 165, 166, 175, + 176, 185, 186, 191, 192, 255, 189, 130, + 131, 133, 150, 154, 177, 179, 187, 138, + 150, 128, 134, 143, 148, 152, 159, 166, + 175, 178, 179, 177, 180, 186, 135, 142, + 144, 153, 177, 180, 185, 187, 188, 136, + 141, 144, 153, 128, 181, 183, 185, 152, + 153, 160, 169, 190, 191, 128, 135, 137, + 172, 177, 191, 128, 132, 134, 135, 136, + 140, 141, 151, 153, 188, 134, 128, 129, + 130, 131, 137, 138, 139, 140, 141, 142, + 143, 144, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 167, + 168, 169, 170, 172, 173, 174, 175, 176, + 177, 179, 181, 182, 183, 188, 189, 190, + 191, 132, 152, 180, 184, 185, 187, 171, + 190, 128, 137, 150, 153, 158, 160, 162, + 164, 167, 173, 177, 180, 143, 130, 141, + 144, 153, 154, 157, 160, 255, 155, 156, + 157, 159, 160, 255, 128, 140, 142, 145, + 146, 148, 160, 177, 178, 180, 128, 145, + 146, 147, 160, 172, 174, 176, 178, 179, + 180, 255, 148, 156, 158, 159, 160, 169, + 170, 255, 139, 142, 144, 153, 160, 255, + 169, 128, 170, 176, 255, 128, 158, 160, + 171, 176, 187, 128, 150, 151, 155, 191, + 149, 158, 160, 188, 128, 137, 144, 153, + 176, 190, 128, 132, 133, 179, 180, 255, + 133, 139, 140, 143, 144, 153, 154, 170, + 180, 255, 128, 130, 131, 160, 161, 173, + 174, 175, 176, 185, 186, 255, 166, 179, + 180, 255, 128, 163, 164, 183, 173, 144, + 146, 148, 168, 169, 177, 178, 180, 181, + 182, 184, 185, 128, 181, 188, 191, 128, + 129, 130, 131, 132, 133, 134, 146, 147, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 140, 143, 170, 174, 191, 255, 165, + 177, 191, 129, 147, 149, 159, 160, 175, + 176, 255, 144, 176, 165, 170, 175, 177, + 180, 255, 191, 168, 174, 176, 255, 128, + 134, 136, 142, 144, 150, 152, 158, 160, + 191, 128, 130, 131, 132, 133, 134, 135, + 139, 140, 141, 133, 170, 175, 177, 181, + 187, 188, 153, 154, 155, 156, 160, 255, + 128, 146, 147, 148, 152, 153, 154, 155, + 156, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 129, 255, 191, 128, + 174, 175, 178, 180, 189, 128, 157, 158, + 159, 160, 255, 176, 177, 178, 255, 130, + 134, 139, 163, 167, 168, 255, 128, 129, + 130, 179, 180, 255, 187, 189, 133, 143, + 144, 153, 154, 159, 178, 183, 184, 255, + 128, 137, 138, 165, 166, 173, 176, 255, + 135, 147, 148, 159, 189, 255, 128, 131, + 132, 178, 179, 255, 143, 129, 142, 144, + 153, 154, 164, 166, 175, 176, 185, 186, + 255, 128, 168, 169, 182, 131, 128, 139, + 140, 141, 144, 153, 187, 189, 176, 178, + 180, 183, 184, 190, 191, 129, 160, 170, + 171, 175, 178, 180, 181, 182, 128, 162, + 163, 170, 172, 173, 176, 185, 172, 173, + 174, 175, 180, 181, 182, 183, 184, 185, + 187, 188, 189, 190, 191, 176, 186, 158, + 190, 128, 134, 147, 151, 157, 168, 170, + 182, 184, 188, 128, 143, 160, 175, 179, + 180, 191, 189, 255, 158, 159, 160, 190, + 191, 255, 130, 135, 138, 143, 146, 151, + 154, 156, 185, 187, 144, 145, 146, 147, + 148, 150, 155, 157, 158, 159, 128, 129, + 130, 131, 133, 135, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 148, 149, 152, + 156, 157, 160, 161, 162, 163, 164, 166, + 168, 169, 170, 171, 172, 173, 174, 176, + 177, 153, 155, 178, 179, 189, 160, 145, + 255, 139, 143, 182, 186, 187, 255, 128, + 191, 129, 131, 133, 134, 140, 143, 144, + 147, 149, 151, 153, 179, 184, 186, 128, + 135, 137, 164, 165, 166, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 138, 139, + 140, 141, 146, 147, 150, 151, 152, 153, + 154, 155, 156, 162, 163, 171, 128, 130, + 131, 183, 184, 255, 135, 165, 166, 175, + 176, 190, 131, 175, 187, 188, 190, 255, + 128, 130, 131, 166, 167, 180, 182, 191, + 179, 182, 144, 178, 128, 130, 131, 178, + 179, 255, 155, 129, 132, 133, 137, 141, + 143, 144, 153, 154, 156, 157, 255, 128, + 145, 147, 171, 172, 183, 159, 170, 171, + 175, 176, 185, 186, 255, 189, 128, 131, + 133, 140, 143, 144, 147, 168, 170, 176, + 178, 179, 181, 185, 188, 191, 144, 151, + 128, 132, 135, 136, 139, 141, 157, 161, + 162, 163, 166, 172, 176, 180, 128, 175, + 176, 255, 134, 132, 135, 136, 143, 144, + 153, 154, 255, 128, 174, 175, 181, 184, + 255, 129, 151, 152, 155, 158, 255, 132, + 129, 143, 144, 153, 154, 255, 128, 170, + 171, 183, 157, 171, 176, 185, 160, 168, + 169, 171, 172, 173, 174, 188, 189, 190, + 161, 167, 144, 173, 176, 180, 128, 175, + 176, 182, 133, 143, 145, 190, 191, 255, + 143, 146, 147, 159, 128, 176, 177, 178, + 128, 136, 144, 153, 157, 158, 160, 163, + 133, 134, 137, 144, 145, 146, 147, 148, + 149, 154, 155, 156, 157, 158, 159, 168, + 169, 170, 150, 153, 165, 169, 173, 255, + 131, 132, 140, 169, 174, 255, 130, 132, + 128, 182, 187, 255, 173, 180, 182, 255, + 132, 155, 159, 161, 175, 160, 163, 184, + 185, 186, 161, 162, 133, 143, 144, 150, + 151, 255, 160, 128, 129, 132, 135, 133, + 134, 129, 160, 255, 192, 255, 176, 255, + 173, 0, 127, 176, 255, 131, 137, 191, + 145, 189, 135, 129, 130, 132, 133, 156, + 128, 133, 144, 154, 176, 139, 159, 150, + 157, 159, 164, 167, 168, 170, 173, 143, + 145, 176, 255, 139, 255, 166, 176, 171, + 179, 160, 161, 163, 164, 165, 167, 169, + 171, 173, 174, 175, 176, 177, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 166, 170, 172, 178, 150, + 153, 155, 163, 165, 167, 169, 173, 153, + 155, 163, 255, 189, 132, 185, 144, 152, + 161, 164, 255, 188, 129, 131, 190, 255, + 133, 134, 137, 138, 142, 150, 152, 161, + 164, 255, 131, 134, 137, 138, 142, 144, + 146, 175, 178, 180, 182, 255, 134, 138, + 142, 161, 164, 255, 188, 129, 131, 190, + 191, 128, 132, 135, 136, 139, 141, 150, + 151, 162, 163, 130, 190, 191, 151, 128, + 130, 134, 136, 138, 141, 128, 131, 190, + 255, 133, 137, 142, 148, 151, 161, 164, + 255, 128, 132, 134, 136, 138, 141, 149, + 150, 162, 163, 129, 131, 190, 255, 133, + 137, 142, 150, 152, 161, 164, 255, 130, + 131, 138, 150, 143, 148, 152, 159, 178, + 179, 177, 180, 186, 135, 142, 177, 180, + 185, 187, 188, 136, 141, 181, 183, 185, + 152, 153, 190, 191, 177, 191, 128, 132, + 134, 135, 141, 151, 153, 188, 134, 128, + 129, 130, 141, 156, 157, 158, 159, 160, + 162, 164, 168, 169, 170, 172, 173, 174, + 175, 176, 179, 183, 171, 190, 150, 153, + 158, 160, 162, 164, 167, 173, 177, 180, + 143, 130, 141, 154, 157, 157, 159, 146, + 148, 178, 180, 146, 147, 178, 179, 180, + 255, 148, 156, 158, 255, 139, 142, 169, + 160, 171, 176, 187, 151, 155, 191, 149, + 158, 160, 188, 176, 190, 128, 132, 180, + 255, 133, 170, 180, 255, 128, 130, 161, + 173, 166, 179, 164, 183, 173, 144, 146, + 148, 168, 178, 180, 184, 185, 128, 181, + 188, 191, 128, 129, 131, 179, 181, 183, + 140, 143, 170, 174, 160, 164, 166, 175, + 144, 176, 175, 177, 191, 160, 191, 128, + 130, 170, 175, 153, 154, 153, 154, 155, + 160, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 175, 175, 178, 180, 189, + 158, 159, 176, 177, 130, 134, 139, 163, + 167, 128, 129, 180, 255, 133, 159, 178, + 255, 166, 173, 135, 147, 128, 131, 179, + 255, 129, 164, 166, 255, 169, 182, 131, + 140, 141, 187, 189, 176, 178, 180, 183, + 184, 190, 191, 129, 171, 175, 181, 182, + 163, 170, 172, 173, 172, 184, 187, 190, + 191, 158, 128, 143, 160, 175, 185, 187, + 144, 145, 150, 155, 157, 158, 135, 139, + 141, 168, 171, 189, 160, 182, 186, 191, + 129, 131, 133, 134, 140, 143, 184, 186, + 165, 166, 128, 129, 130, 132, 133, 134, + 135, 136, 139, 140, 141, 146, 147, 150, + 151, 152, 153, 154, 156, 128, 130, 184, + 255, 135, 190, 131, 175, 187, 188, 190, + 255, 128, 130, 167, 180, 179, 128, 130, + 179, 255, 129, 137, 141, 255, 172, 183, + 159, 170, 188, 128, 131, 190, 191, 151, + 128, 132, 135, 136, 139, 141, 162, 163, + 166, 172, 176, 180, 176, 255, 132, 255, + 175, 181, 184, 255, 129, 155, 158, 255, + 129, 255, 171, 183, 157, 171, 171, 172, + 189, 190, 176, 180, 176, 182, 145, 190, + 143, 146, 178, 157, 158, 160, 163, 133, + 134, 137, 168, 169, 170, 165, 169, 173, + 255, 131, 132, 140, 169, 174, 255, 130, + 132, 128, 182, 187, 255, 173, 180, 182, + 255, 132, 155, 159, 161, 175, 163, 144, + 150, 160, 128, 129, 132, 135, 133, 134, + 129, 160, 255, 192, 255, 170, 173, 181, + 186, 0, 127, 181, 190, 176, 183, 184, + 185, 186, 191, 192, 255, 130, 131, 137, + 190, 136, 144, 145, 191, 192, 255, 135, + 129, 130, 132, 133, 144, 170, 176, 179, + 156, 128, 133, 144, 154, 160, 191, 176, + 128, 138, 139, 159, 174, 255, 148, 158, + 169, 150, 164, 167, 173, 176, 185, 189, + 190, 192, 255, 144, 143, 145, 146, 175, + 176, 255, 139, 140, 141, 255, 166, 176, + 178, 255, 186, 138, 170, 171, 179, 180, + 181, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, + 191, 154, 164, 168, 128, 149, 150, 173, + 128, 152, 153, 155, 163, 255, 189, 132, + 185, 144, 152, 161, 164, 176, 177, 255, + 132, 169, 177, 188, 129, 131, 141, 142, + 145, 146, 179, 181, 186, 187, 190, 255, + 142, 158, 133, 134, 137, 138, 143, 150, + 152, 155, 156, 161, 164, 175, 176, 177, + 178, 255, 188, 129, 131, 133, 138, 143, + 144, 147, 168, 170, 176, 178, 179, 181, + 182, 184, 185, 190, 255, 157, 131, 134, + 137, 138, 142, 144, 146, 152, 153, 158, + 159, 175, 178, 180, 182, 255, 189, 129, + 131, 133, 141, 143, 145, 147, 168, 170, + 176, 178, 179, 181, 185, 188, 255, 134, + 138, 144, 185, 142, 159, 160, 161, 164, + 255, 189, 129, 131, 133, 140, 143, 144, + 147, 168, 170, 176, 178, 179, 181, 185, + 188, 191, 177, 128, 132, 135, 136, 139, + 141, 150, 151, 156, 157, 159, 161, 162, + 163, 130, 131, 156, 133, 138, 142, 144, + 146, 149, 153, 154, 158, 159, 163, 164, + 168, 170, 174, 185, 190, 191, 144, 151, + 128, 130, 134, 136, 138, 141, 189, 128, + 131, 133, 140, 142, 144, 146, 168, 170, + 185, 190, 255, 133, 137, 151, 142, 148, + 152, 154, 155, 159, 160, 161, 164, 255, + 189, 129, 131, 133, 140, 142, 144, 146, + 168, 170, 179, 181, 185, 188, 191, 158, + 128, 132, 134, 136, 138, 141, 149, 150, + 160, 161, 162, 163, 177, 178, 189, 129, + 131, 133, 140, 142, 144, 146, 186, 190, + 255, 133, 137, 142, 143, 150, 152, 158, + 159, 161, 164, 185, 186, 191, 192, 255, + 189, 130, 131, 133, 150, 154, 177, 179, + 187, 138, 150, 128, 134, 143, 148, 152, + 159, 178, 179, 177, 180, 186, 135, 142, + 177, 180, 185, 187, 188, 136, 141, 128, + 181, 183, 185, 152, 153, 190, 191, 128, + 135, 137, 172, 177, 191, 128, 132, 134, + 135, 136, 140, 141, 151, 153, 188, 134, + 128, 129, 130, 131, 137, 138, 139, 140, + 141, 142, 143, 144, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, + 168, 169, 170, 172, 173, 174, 175, 176, + 177, 179, 181, 182, 183, 188, 189, 190, + 191, 132, 152, 180, 184, 185, 187, 171, + 190, 150, 153, 158, 160, 162, 164, 167, + 173, 177, 180, 143, 130, 141, 154, 157, + 160, 255, 155, 156, 157, 159, 160, 255, + 128, 140, 142, 145, 146, 148, 160, 177, + 178, 180, 128, 145, 146, 147, 160, 172, + 174, 176, 178, 179, 180, 255, 148, 156, + 158, 255, 139, 142, 160, 255, 169, 128, + 170, 176, 255, 128, 158, 160, 171, 176, + 187, 128, 150, 151, 155, 191, 149, 158, + 160, 188, 176, 190, 128, 132, 133, 179, + 180, 255, 133, 139, 140, 170, 180, 255, + 128, 130, 131, 160, 161, 173, 174, 175, + 186, 255, 166, 179, 180, 255, 128, 163, + 164, 183, 173, 144, 146, 148, 168, 169, + 177, 178, 180, 181, 182, 184, 185, 128, + 181, 188, 191, 128, 129, 130, 131, 132, + 133, 134, 146, 147, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 140, 143, 170, + 174, 177, 191, 160, 164, 166, 175, 144, + 176, 165, 170, 175, 177, 180, 255, 191, + 168, 174, 176, 255, 128, 134, 136, 142, + 144, 150, 152, 158, 160, 191, 128, 130, + 132, 133, 134, 133, 170, 175, 187, 188, + 153, 154, 128, 146, 147, 148, 152, 153, + 154, 155, 156, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 129, 255, + 191, 128, 174, 175, 178, 180, 189, 128, + 157, 158, 159, 160, 255, 176, 177, 178, + 255, 130, 134, 139, 163, 167, 168, 255, + 128, 129, 130, 179, 180, 255, 187, 189, + 133, 159, 178, 183, 184, 255, 138, 165, + 166, 173, 176, 255, 135, 147, 148, 159, + 189, 255, 128, 131, 132, 178, 179, 255, + 143, 129, 164, 166, 255, 128, 168, 169, + 182, 131, 128, 139, 140, 141, 187, 189, + 176, 178, 180, 183, 184, 190, 191, 129, + 160, 170, 171, 175, 178, 180, 181, 182, + 128, 162, 163, 170, 172, 173, 172, 173, + 174, 175, 180, 181, 182, 183, 184, 185, + 187, 188, 189, 190, 191, 176, 186, 158, + 190, 128, 134, 147, 151, 157, 168, 170, + 182, 184, 188, 128, 143, 160, 175, 191, + 189, 255, 158, 159, 160, 190, 130, 135, + 138, 143, 146, 151, 154, 156, 185, 187, + 144, 145, 146, 147, 148, 150, 155, 157, + 158, 159, 128, 129, 130, 131, 133, 135, + 138, 139, 140, 141, 142, 143, 144, 145, + 146, 148, 149, 152, 156, 157, 160, 161, + 162, 163, 164, 166, 168, 169, 170, 171, + 172, 173, 174, 176, 177, 153, 155, 178, + 179, 189, 160, 145, 255, 139, 143, 182, + 186, 187, 255, 128, 191, 129, 131, 133, + 134, 140, 143, 144, 147, 149, 151, 153, + 179, 184, 186, 128, 135, 137, 164, 165, + 166, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 138, 139, 140, 141, 146, 147, + 150, 151, 152, 153, 154, 156, 162, 163, + 171, 128, 130, 131, 183, 184, 255, 135, + 190, 131, 175, 187, 188, 190, 255, 128, + 130, 131, 166, 167, 180, 179, 182, 144, + 178, 128, 130, 131, 178, 179, 255, 154, + 156, 129, 132, 133, 137, 141, 255, 128, + 145, 147, 171, 172, 183, 159, 170, 171, + 255, 189, 128, 131, 133, 140, 143, 144, + 147, 168, 170, 176, 178, 179, 181, 185, + 188, 191, 144, 151, 128, 132, 135, 136, + 139, 141, 157, 161, 162, 163, 166, 172, + 176, 180, 128, 175, 176, 255, 134, 132, + 135, 136, 255, 128, 174, 175, 181, 184, + 255, 129, 151, 152, 155, 158, 255, 132, + 129, 255, 128, 170, 171, 183, 157, 171, + 160, 168, 169, 171, 172, 173, 174, 188, + 189, 190, 161, 167, 144, 173, 176, 180, + 128, 175, 176, 182, 133, 143, 145, 190, + 191, 255, 143, 146, 147, 159, 176, 177, + 178, 128, 136, 144, 153, 157, 158, 160, + 163, 133, 134, 137, 144, 145, 146, 147, + 148, 149, 154, 155, 156, 157, 158, 159, + 168, 169, 170, 150, 153, 165, 169, 173, + 255, 131, 132, 140, 169, 174, 255, 130, + 132, 128, 182, 187, 255, 173, 180, 182, + 255, 132, 155, 159, 161, 175, 160, 163, + 184, 185, 186, 161, 162, 133, 143, 144, + 150, 151, 255, 160, 128, 129, 132, 135, + 133, 134, 129, 160, 255, 192, 255, 176, + 255, 170, 173, 181, 186, 0, 127, 181, + 190, 176, 183, 184, 185, 186, 191, 192, + 255, 130, 131, 137, 137, 190, 136, 144, + 145, 191, 192, 255, 135, 179, 129, 130, + 132, 133, 144, 170, 176, 178, 156, 128, + 133, 140, 141, 144, 154, 160, 191, 171, + 172, 176, 128, 138, 139, 159, 160, 169, + 174, 255, 148, 158, 169, 150, 164, 167, + 173, 176, 185, 189, 190, 192, 255, 144, + 143, 145, 146, 175, 176, 255, 139, 140, + 141, 255, 166, 176, 178, 255, 184, 186, + 128, 137, 138, 170, 171, 179, 180, 181, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 154, 164, 168, 128, 149, 150, 173, 128, + 152, 153, 155, 163, 255, 189, 132, 185, + 144, 176, 152, 161, 164, 165, 166, 175, + 177, 255, 132, 169, 177, 188, 129, 131, + 141, 142, 145, 146, 179, 181, 186, 187, + 190, 255, 142, 158, 133, 134, 137, 138, + 143, 150, 152, 155, 156, 161, 164, 165, + 166, 175, 176, 177, 178, 255, 188, 129, + 131, 133, 138, 143, 144, 147, 168, 170, + 176, 178, 179, 181, 182, 184, 185, 190, + 255, 157, 131, 134, 137, 138, 142, 144, + 146, 152, 153, 158, 159, 165, 166, 175, + 178, 180, 182, 255, 189, 129, 131, 133, + 141, 143, 145, 147, 168, 170, 176, 178, + 179, 181, 185, 188, 255, 134, 138, 144, + 185, 142, 159, 160, 161, 164, 165, 166, + 175, 176, 255, 189, 129, 131, 133, 140, + 143, 144, 147, 168, 170, 176, 178, 179, + 181, 185, 188, 191, 177, 128, 132, 135, + 136, 139, 141, 150, 151, 156, 157, 159, + 161, 162, 163, 166, 175, 130, 131, 156, + 133, 138, 142, 144, 146, 149, 153, 154, + 158, 159, 163, 164, 168, 170, 174, 185, + 190, 191, 144, 151, 128, 130, 134, 136, + 138, 141, 166, 175, 189, 128, 131, 133, + 140, 142, 144, 146, 168, 170, 185, 190, + 255, 133, 137, 151, 142, 148, 152, 154, + 155, 159, 160, 161, 164, 165, 166, 175, + 176, 255, 189, 129, 131, 133, 140, 142, + 144, 146, 168, 170, 179, 181, 185, 188, + 191, 158, 128, 132, 134, 136, 138, 141, + 149, 150, 160, 161, 162, 163, 166, 175, + 177, 178, 189, 129, 131, 133, 140, 142, + 144, 146, 186, 190, 255, 133, 137, 142, + 143, 150, 152, 158, 159, 161, 164, 165, + 166, 175, 176, 185, 186, 191, 192, 255, + 189, 130, 131, 133, 150, 154, 177, 179, + 187, 138, 150, 128, 134, 143, 148, 152, + 159, 166, 175, 178, 179, 177, 180, 186, + 135, 142, 144, 153, 177, 180, 185, 187, + 188, 136, 141, 144, 153, 128, 181, 183, + 185, 152, 153, 160, 169, 190, 191, 128, + 135, 137, 172, 177, 191, 128, 132, 134, + 135, 136, 140, 141, 151, 153, 188, 134, + 128, 129, 130, 131, 137, 138, 139, 140, + 141, 142, 143, 144, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, + 165, 167, 168, 169, 170, 172, 173, 174, + 175, 176, 177, 179, 181, 182, 183, 188, + 189, 190, 191, 132, 152, 180, 184, 185, + 187, 171, 190, 128, 137, 150, 153, 158, + 160, 162, 164, 167, 173, 177, 180, 143, + 130, 141, 144, 153, 154, 157, 160, 255, + 155, 156, 157, 159, 160, 255, 128, 140, + 142, 145, 146, 148, 160, 177, 178, 180, + 128, 145, 146, 147, 160, 172, 174, 176, + 178, 179, 180, 255, 148, 156, 158, 159, + 160, 169, 170, 255, 139, 142, 144, 153, + 160, 255, 169, 128, 170, 176, 255, 128, + 158, 160, 171, 176, 187, 128, 150, 151, + 155, 191, 149, 158, 160, 188, 128, 137, + 144, 153, 176, 190, 128, 132, 133, 179, + 180, 255, 133, 139, 140, 143, 144, 153, + 154, 170, 180, 255, 128, 130, 131, 160, + 161, 173, 174, 175, 176, 185, 186, 255, + 166, 179, 180, 255, 128, 163, 164, 183, + 173, 144, 146, 148, 168, 169, 177, 178, + 180, 181, 182, 184, 185, 128, 181, 188, + 191, 128, 129, 130, 131, 132, 133, 134, + 146, 147, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 164, 140, 143, 152, 153, + 170, 174, 191, 255, 132, 165, 177, 191, + 129, 147, 149, 159, 160, 175, 176, 255, + 144, 176, 165, 170, 175, 177, 180, 255, + 191, 168, 174, 176, 255, 128, 134, 136, + 142, 144, 150, 152, 158, 160, 191, 128, + 130, 132, 133, 134, 133, 170, 175, 187, + 188, 153, 154, 128, 146, 147, 148, 152, + 153, 154, 155, 156, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 129, + 255, 191, 128, 174, 175, 178, 180, 189, + 128, 157, 158, 159, 160, 255, 176, 177, + 178, 255, 130, 134, 139, 163, 167, 168, + 255, 128, 129, 130, 179, 180, 255, 187, + 189, 133, 143, 144, 153, 154, 159, 178, + 183, 184, 255, 128, 137, 138, 165, 166, + 173, 176, 255, 135, 147, 148, 159, 189, + 255, 128, 131, 132, 178, 179, 255, 143, + 129, 142, 144, 153, 154, 164, 166, 175, + 176, 185, 186, 255, 128, 168, 169, 182, + 131, 128, 139, 140, 141, 144, 153, 187, + 189, 176, 178, 180, 183, 184, 190, 191, + 129, 160, 170, 171, 175, 178, 180, 181, + 182, 128, 162, 163, 170, 172, 173, 176, + 185, 172, 173, 174, 175, 180, 181, 182, + 183, 184, 185, 187, 188, 189, 190, 191, + 176, 186, 158, 190, 128, 134, 147, 151, + 157, 168, 170, 182, 184, 188, 144, 148, + 128, 143, 160, 175, 179, 180, 191, 189, + 255, 158, 159, 160, 190, 130, 135, 138, + 143, 146, 151, 154, 156, 185, 187, 144, + 145, 146, 147, 148, 150, 155, 157, 158, + 159, 128, 129, 130, 131, 133, 135, 138, + 139, 140, 141, 142, 143, 144, 145, 146, + 148, 149, 152, 156, 157, 160, 161, 162, + 163, 164, 166, 168, 169, 170, 171, 172, + 173, 174, 176, 177, 153, 155, 178, 179, + 189, 160, 145, 255, 139, 143, 182, 186, + 187, 255, 128, 191, 129, 131, 133, 134, + 140, 143, 144, 147, 149, 151, 153, 179, + 184, 186, 128, 135, 137, 164, 165, 166, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 138, 139, 140, 141, 146, 147, 150, + 151, 152, 153, 154, 155, 156, 162, 163, + 171, 128, 130, 131, 183, 184, 255, 135, + 165, 166, 175, 176, 190, 131, 175, 187, + 188, 190, 255, 128, 130, 131, 166, 167, + 180, 182, 191, 179, 182, 144, 178, 128, + 130, 131, 178, 179, 255, 155, 129, 132, + 133, 137, 141, 143, 144, 153, 154, 156, + 157, 255, 128, 145, 147, 171, 172, 183, + 159, 170, 171, 175, 176, 185, 186, 255, + 189, 128, 131, 133, 140, 143, 144, 147, + 168, 170, 176, 178, 179, 181, 185, 188, + 191, 144, 151, 128, 132, 135, 136, 139, + 141, 157, 161, 162, 163, 166, 172, 176, + 180, 128, 175, 176, 255, 134, 132, 135, + 136, 143, 144, 153, 154, 255, 128, 174, + 175, 181, 184, 255, 129, 151, 152, 155, + 158, 255, 132, 129, 143, 144, 153, 154, + 255, 128, 170, 171, 183, 157, 171, 176, + 185, 160, 168, 169, 171, 172, 173, 174, + 188, 189, 190, 161, 167, 144, 173, 176, + 180, 128, 175, 176, 182, 133, 143, 145, + 190, 191, 255, 143, 146, 147, 159, 176, + 177, 178, 128, 136, 144, 153, 157, 158, + 160, 163, 133, 134, 137, 144, 145, 146, + 147, 148, 149, 154, 155, 156, 157, 158, + 159, 168, 169, 170, 150, 153, 165, 169, + 173, 255, 131, 132, 140, 169, 174, 255, + 130, 132, 128, 182, 187, 255, 173, 180, + 182, 255, 132, 155, 159, 161, 175, 160, + 163, 184, 185, 186, 161, 162, 133, 143, + 144, 150, 151, 255, 160, 128, 129, 132, + 135, 133, 134, 129, 160, 255, 192, 255, + 176, 255, 170, 173, 181, 186, 0, 127, + 181, 190, 176, 183, 184, 185, 186, 191, + 192, 255, 130, 131, 137, 190, 136, 144, + 145, 191, 192, 255, 135, 179, 129, 130, + 132, 133, 144, 170, 176, 178, 156, 128, + 133, 144, 154, 160, 191, 171, 176, 128, + 138, 139, 159, 160, 169, 174, 255, 148, + 158, 169, 150, 164, 167, 173, 176, 185, + 189, 190, 192, 255, 144, 143, 145, 146, + 175, 176, 255, 139, 140, 141, 255, 166, + 176, 178, 255, 186, 128, 137, 138, 170, + 171, 179, 180, 181, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 154, 164, 168, 128, + 149, 150, 173, 128, 152, 153, 155, 163, + 255, 189, 132, 185, 144, 176, 152, 161, + 164, 165, 166, 175, 177, 255, 132, 169, + 177, 188, 129, 131, 141, 142, 145, 146, + 179, 181, 186, 187, 190, 255, 142, 158, + 133, 134, 137, 138, 143, 150, 152, 155, + 156, 161, 164, 165, 166, 175, 176, 177, + 178, 255, 188, 129, 131, 133, 138, 143, + 144, 147, 168, 170, 176, 178, 179, 181, + 182, 184, 185, 190, 255, 157, 131, 134, + 137, 138, 142, 144, 146, 152, 153, 158, + 159, 165, 166, 175, 178, 180, 182, 255, + 189, 129, 131, 133, 141, 143, 145, 147, + 168, 170, 176, 178, 179, 181, 185, 188, + 255, 134, 138, 144, 185, 142, 159, 160, + 161, 164, 165, 166, 175, 176, 255, 189, + 129, 131, 133, 140, 143, 144, 147, 168, + 170, 176, 178, 179, 181, 185, 188, 191, + 177, 128, 132, 135, 136, 139, 141, 150, + 151, 156, 157, 159, 161, 162, 163, 166, + 175, 130, 131, 156, 133, 138, 142, 144, + 146, 149, 153, 154, 158, 159, 163, 164, + 168, 170, 174, 185, 190, 191, 144, 151, + 128, 130, 134, 136, 138, 141, 166, 175, + 189, 128, 131, 133, 140, 142, 144, 146, + 168, 170, 185, 190, 255, 133, 137, 151, + 142, 148, 152, 154, 155, 159, 160, 161, + 164, 165, 166, 175, 176, 255, 189, 129, + 131, 133, 140, 142, 144, 146, 168, 170, + 179, 181, 185, 188, 191, 158, 128, 132, + 134, 136, 138, 141, 149, 150, 160, 161, + 162, 163, 166, 175, 177, 178, 189, 129, + 131, 133, 140, 142, 144, 146, 186, 190, + 255, 133, 137, 142, 143, 150, 152, 158, + 159, 161, 164, 165, 166, 175, 176, 185, + 186, 191, 192, 255, 189, 130, 131, 133, + 150, 154, 177, 179, 187, 138, 150, 128, + 134, 143, 148, 152, 159, 166, 175, 178, + 179, 177, 180, 186, 135, 142, 144, 153, + 177, 180, 185, 187, 188, 136, 141, 144, + 153, 128, 181, 183, 185, 152, 153, 160, + 169, 190, 191, 128, 135, 137, 172, 177, + 191, 128, 132, 134, 135, 136, 140, 141, + 151, 153, 188, 134, 128, 129, 130, 131, + 137, 138, 139, 140, 141, 142, 143, 144, + 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 167, 168, 169, + 170, 172, 173, 174, 175, 176, 177, 179, + 181, 182, 183, 188, 189, 190, 191, 132, + 152, 180, 184, 185, 187, 171, 190, 128, + 137, 150, 153, 158, 160, 162, 164, 167, + 173, 177, 180, 143, 130, 141, 144, 153, + 154, 157, 160, 255, 155, 156, 157, 159, + 160, 255, 128, 140, 142, 145, 146, 148, + 160, 177, 178, 180, 128, 145, 146, 147, + 160, 172, 174, 176, 178, 179, 180, 255, + 148, 156, 158, 159, 160, 169, 170, 255, + 139, 142, 144, 153, 160, 255, 169, 128, + 170, 176, 255, 128, 158, 160, 171, 176, + 187, 128, 150, 151, 155, 191, 149, 158, + 160, 188, 128, 137, 144, 153, 176, 190, + 128, 132, 133, 179, 180, 255, 133, 139, + 140, 143, 144, 153, 154, 170, 180, 255, + 128, 130, 131, 160, 161, 173, 174, 175, + 176, 185, 186, 255, 166, 179, 180, 255, + 128, 163, 164, 183, 173, 144, 146, 148, + 168, 169, 177, 178, 180, 181, 182, 184, + 185, 128, 181, 188, 191, 128, 129, 130, + 131, 132, 133, 134, 146, 147, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 140, + 143, 170, 174, 191, 255, 165, 177, 191, + 129, 147, 149, 159, 160, 175, 176, 255, + 144, 176, 165, 170, 175, 177, 180, 255, + 191, 168, 174, 176, 255, 128, 134, 136, + 142, 144, 150, 152, 158, 160, 191, 128, + 130, 131, 132, 133, 134, 135, 139, 140, + 141, 133, 170, 175, 177, 181, 187, 188, + 153, 154, 155, 156, 160, 255, 128, 146, + 147, 148, 152, 153, 154, 155, 156, 158, + 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 129, 255, 191, 128, 174, 175, + 178, 180, 189, 128, 157, 158, 159, 160, + 255, 176, 177, 178, 255, 130, 134, 139, + 163, 167, 168, 255, 128, 129, 130, 179, + 180, 255, 187, 189, 133, 143, 144, 153, + 154, 159, 178, 183, 184, 255, 128, 137, + 138, 165, 166, 173, 176, 255, 135, 147, + 148, 159, 189, 255, 128, 131, 132, 178, + 179, 255, 143, 129, 142, 144, 153, 154, + 164, 166, 175, 176, 185, 186, 255, 128, + 168, 169, 182, 131, 128, 139, 140, 141, + 144, 153, 187, 189, 176, 178, 180, 183, + 184, 190, 191, 129, 160, 170, 171, 175, + 178, 180, 181, 182, 128, 162, 163, 170, + 172, 173, 176, 185, 172, 173, 174, 175, + 180, 181, 182, 183, 184, 185, 187, 188, + 189, 190, 191, 176, 186, 158, 190, 128, + 134, 147, 151, 157, 168, 170, 182, 184, + 188, 128, 143, 160, 175, 179, 180, 191, + 189, 255, 158, 159, 160, 190, 191, 255, + 130, 135, 138, 143, 146, 151, 154, 156, + 185, 187, 144, 145, 146, 147, 148, 150, + 155, 157, 158, 159, 128, 129, 130, 131, + 133, 135, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 148, 149, 152, 156, 157, + 160, 161, 162, 163, 164, 166, 168, 169, + 170, 171, 172, 173, 174, 176, 177, 153, + 155, 178, 179, 189, 160, 145, 255, 139, + 143, 182, 186, 187, 255, 128, 191, 129, + 131, 133, 134, 140, 143, 144, 147, 149, + 151, 153, 179, 184, 186, 128, 135, 137, + 164, 165, 166, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 138, 139, 140, 141, + 146, 147, 150, 151, 152, 153, 154, 155, + 156, 162, 163, 171, 128, 130, 131, 183, + 184, 255, 135, 165, 166, 175, 176, 190, + 131, 175, 187, 188, 190, 255, 128, 130, + 131, 166, 167, 180, 182, 191, 179, 182, + 144, 178, 128, 130, 131, 178, 179, 255, + 155, 129, 132, 133, 137, 141, 143, 144, + 153, 154, 156, 157, 255, 128, 145, 147, + 171, 172, 183, 159, 170, 171, 175, 176, + 185, 186, 255, 189, 128, 131, 133, 140, + 143, 144, 147, 168, 170, 176, 178, 179, + 181, 185, 188, 191, 144, 151, 128, 132, + 135, 136, 139, 141, 157, 161, 162, 163, + 166, 172, 176, 180, 128, 175, 176, 255, + 134, 132, 135, 136, 143, 144, 153, 154, + 255, 128, 174, 175, 181, 184, 255, 129, + 151, 152, 155, 158, 255, 132, 129, 143, + 144, 153, 154, 255, 128, 170, 171, 183, + 157, 171, 176, 185, 160, 168, 169, 171, + 172, 173, 174, 188, 189, 190, 161, 167, + 144, 173, 176, 180, 128, 175, 176, 182, + 133, 143, 145, 190, 191, 255, 143, 146, + 147, 159, 128, 176, 177, 178, 128, 136, + 144, 153, 157, 158, 160, 163, 133, 134, + 137, 144, 145, 146, 147, 148, 149, 154, + 155, 156, 157, 158, 159, 168, 169, 170, + 150, 153, 165, 169, 173, 255, 131, 132, + 140, 169, 174, 255, 130, 132, 128, 182, + 187, 255, 173, 180, 182, 255, 132, 155, + 159, 161, 175, 160, 163, 184, 185, 186, + 161, 162, 133, 143, 144, 150, 151, 255, + 160, 128, 129, 132, 135, 133, 134, 129, + 160, 255, 192, 255, 176, 255, 173, 0, + 127, 176, 255, 131, 137, 191, 145, 189, + 135, 129, 130, 132, 133, 156, 128, 133, + 144, 154, 176, 139, 159, 150, 157, 159, + 164, 167, 168, 170, 173, 143, 145, 176, + 255, 139, 255, 166, 176, 171, 179, 160, + 161, 163, 164, 165, 167, 169, 171, 173, + 174, 175, 176, 177, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, + 191, 166, 170, 172, 178, 128, 129, 130, + 141, 156, 157, 158, 159, 160, 162, 164, + 168, 169, 170, 172, 173, 174, 175, 176, + 179, 183, 128, 129, 131, 179, 181, 183, + 128, 130, 153, 154, 155, 160, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, + 175, 172, 184, 187, 190, 191, 144, 145, + 150, 155, 157, 158, 160, 154, 164, 168, + 128, 149, 150, 173, 128, 152, 153, 155, + 189, 132, 185, 144, 176, 152, 161, 164, + 165, 166, 175, 177, 255, 132, 169, 177, + 188, 129, 131, 141, 142, 145, 146, 179, + 181, 186, 187, 190, 255, 142, 158, 133, + 134, 137, 138, 143, 150, 152, 155, 156, + 161, 164, 165, 166, 175, 176, 177, 178, + 255, 188, 129, 131, 133, 138, 143, 144, + 147, 168, 170, 176, 178, 179, 181, 182, + 184, 185, 190, 255, 157, 131, 134, 137, + 138, 142, 144, 146, 152, 153, 158, 159, + 165, 166, 175, 178, 180, 182, 255, 189, + 129, 131, 133, 141, 143, 145, 147, 168, + 170, 176, 178, 179, 181, 185, 188, 255, + 134, 138, 144, 185, 142, 159, 160, 161, + 164, 165, 166, 175, 176, 255, 189, 129, + 131, 133, 140, 143, 144, 147, 168, 170, + 176, 178, 179, 181, 185, 188, 191, 177, + 128, 132, 135, 136, 139, 141, 150, 151, + 156, 157, 159, 161, 162, 163, 166, 175, + 130, 131, 156, 133, 138, 142, 144, 146, + 149, 153, 154, 158, 159, 163, 164, 168, + 170, 174, 185, 190, 191, 144, 151, 128, + 130, 134, 136, 138, 141, 166, 175, 189, + 128, 131, 133, 140, 142, 144, 146, 168, + 170, 185, 190, 255, 133, 137, 151, 142, + 148, 152, 154, 155, 159, 160, 161, 164, + 165, 166, 175, 176, 255, 189, 129, 131, + 133, 140, 142, 144, 146, 168, 170, 179, + 181, 185, 188, 191, 158, 128, 132, 134, + 136, 138, 141, 149, 150, 160, 161, 162, + 163, 166, 175, 177, 178, 189, 129, 131, + 133, 140, 142, 144, 146, 186, 190, 255, + 133, 137, 142, 143, 150, 152, 158, 159, + 161, 164, 165, 166, 175, 176, 185, 186, + 191, 192, 255, 189, 130, 131, 133, 150, + 154, 177, 179, 187, 138, 150, 128, 134, + 143, 148, 152, 159, 166, 175, 178, 179, + 135, 142, 144, 153, 136, 141, 144, 153, + 128, 181, 183, 185, 152, 153, 160, 169, + 190, 191, 128, 135, 137, 172, 177, 191, + 128, 132, 134, 135, 136, 140, 141, 151, + 153, 188, 128, 137, 150, 153, 158, 160, + 162, 164, 167, 173, 177, 180, 143, 130, + 141, 144, 153, 154, 157, 160, 255, 0, + 127, 170, 173, 181, 183, 186, 0, 127, + 181, 190, 176, 183, 184, 185, 186, 191, + 192, 255, 130, 131, 137, 190, 136, 144, + 145, 191, 192, 255, 135, 179, 180, 129, + 130, 132, 133, 144, 170, 176, 178, 156, + 128, 133, 144, 154, 160, 191, 171, 176, + 128, 138, 139, 159, 160, 169, 174, 255, + 148, 158, 169, 150, 164, 167, 173, 176, + 185, 189, 190, 192, 255, 144, 143, 145, + 146, 175, 176, 255, 139, 140, 141, 255, + 166, 176, 178, 255, 186, 128, 137, 138, + 170, 171, 179, 180, 181, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 154, 164, 168, + 128, 149, 150, 173, 128, 152, 153, 155, + 163, 255, 189, 132, 185, 144, 176, 152, + 161, 164, 165, 166, 175, 177, 255, 132, + 169, 177, 188, 129, 131, 141, 142, 145, + 146, 179, 181, 186, 187, 190, 255, 142, + 158, 133, 134, 137, 138, 143, 150, 152, + 155, 156, 161, 164, 165, 166, 175, 176, + 177, 178, 255, 188, 129, 131, 133, 138, + 143, 144, 147, 168, 170, 176, 178, 179, + 181, 182, 184, 185, 190, 255, 157, 131, + 134, 137, 138, 142, 144, 146, 152, 153, + 158, 159, 165, 166, 175, 178, 180, 182, + 255, 189, 129, 131, 133, 141, 143, 145, + 147, 168, 170, 176, 178, 179, 181, 185, + 188, 255, 134, 138, 144, 185, 142, 159, + 160, 161, 164, 165, 166, 175, 176, 255, + 189, 129, 131, 133, 140, 143, 144, 147, + 168, 170, 176, 178, 179, 181, 185, 188, + 191, 177, 128, 132, 135, 136, 139, 141, + 150, 151, 156, 157, 159, 161, 162, 163, + 166, 175, 130, 131, 156, 133, 138, 142, + 144, 146, 149, 153, 154, 158, 159, 163, + 164, 168, 170, 174, 185, 190, 191, 144, + 151, 128, 130, 134, 136, 138, 141, 166, + 175, 189, 128, 131, 133, 140, 142, 144, + 146, 168, 170, 185, 190, 255, 133, 137, + 151, 142, 148, 152, 154, 155, 159, 160, + 161, 164, 165, 166, 175, 176, 255, 189, + 129, 131, 133, 140, 142, 144, 146, 168, + 170, 179, 181, 185, 188, 191, 158, 128, + 132, 134, 136, 138, 141, 149, 150, 160, + 161, 162, 163, 166, 175, 177, 178, 189, + 129, 131, 133, 140, 142, 144, 146, 186, + 190, 255, 133, 137, 142, 143, 150, 152, + 158, 159, 161, 164, 165, 166, 175, 176, + 185, 186, 191, 192, 255, 189, 130, 131, + 133, 150, 154, 177, 179, 187, 138, 150, + 128, 134, 143, 148, 152, 159, 166, 175, + 178, 179, 177, 180, 186, 135, 142, 144, + 153, 177, 180, 185, 187, 188, 136, 141, + 144, 153, 128, 181, 183, 185, 152, 153, + 160, 169, 190, 191, 128, 135, 137, 172, + 177, 191, 128, 132, 134, 135, 136, 140, + 141, 151, 153, 188, 134, 128, 129, 130, + 131, 132, 135, 137, 138, 139, 140, 141, + 142, 143, 144, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, + 167, 168, 169, 170, 172, 173, 174, 175, + 176, 177, 179, 181, 182, 183, 188, 189, + 190, 191, 133, 134, 136, 152, 180, 184, + 185, 187, 171, 190, 128, 137, 150, 153, + 158, 160, 162, 164, 167, 173, 177, 180, + 143, 130, 141, 144, 153, 154, 157, 160, + 255, 192, 255, 155, 156, 157, 159, 160, + 255, 128, 140, 142, 145, 146, 148, 160, + 177, 178, 180, 128, 145, 146, 147, 160, + 172, 174, 176, 178, 179, 180, 255, 148, + 156, 158, 159, 160, 169, 170, 255, 139, + 142, 144, 153, 160, 255, 169, 128, 170, + 176, 255, 128, 158, 160, 171, 176, 187, + 128, 150, 151, 155, 191, 149, 158, 160, + 188, 128, 137, 144, 153, 176, 190, 128, + 132, 133, 179, 180, 255, 133, 139, 140, + 143, 144, 153, 154, 170, 180, 255, 128, + 130, 131, 160, 161, 173, 174, 175, 176, + 185, 186, 255, 166, 179, 180, 255, 128, + 163, 164, 183, 173, 144, 146, 148, 168, + 169, 177, 178, 180, 181, 182, 184, 185, + 128, 181, 188, 191, 128, 129, 130, 131, + 132, 133, 134, 146, 147, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 164, 167, + 140, 143, 152, 153, 170, 174, 191, 255, + 165, 177, 191, 129, 147, 149, 159, 160, + 175, 176, 255, 144, 176, 165, 170, 175, + 177, 180, 255, 191, 168, 174, 176, 255, + 128, 134, 136, 142, 144, 150, 152, 158, + 160, 191, 128, 130, 132, 133, 134, 136, + 137, 133, 170, 175, 187, 188, 153, 154, + 133, 173, 177, 255, 143, 159, 160, 186, + 187, 255, 128, 158, 173, 0, 127, 176, + 255, 131, 137, 191, 145, 189, 135, 129, + 130, 132, 133, 156, 128, 133, 144, 154, + 176, 139, 159, 150, 157, 159, 164, 167, + 168, 170, 173, 143, 145, 176, 255, 139, + 255, 166, 176, 171, 179, 160, 161, 163, + 164, 165, 167, 169, 171, 173, 174, 175, + 176, 177, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 166, + 170, 172, 178, 150, 153, 155, 163, 165, + 167, 169, 173, 153, 155, 163, 255, 189, + 132, 185, 144, 152, 161, 164, 255, 188, + 129, 131, 190, 255, 133, 134, 137, 138, + 142, 150, 152, 161, 164, 255, 131, 134, + 137, 138, 142, 144, 146, 175, 178, 180, + 182, 255, 134, 138, 142, 161, 164, 255, + 188, 129, 131, 190, 191, 128, 132, 135, + 136, 139, 141, 150, 151, 162, 163, 130, + 190, 191, 151, 128, 130, 134, 136, 138, + 141, 128, 131, 190, 255, 133, 137, 142, + 148, 151, 161, 164, 255, 128, 132, 134, + 136, 138, 141, 149, 150, 162, 163, 129, + 131, 190, 255, 133, 137, 142, 150, 152, + 161, 164, 255, 130, 131, 138, 150, 143, + 148, 152, 159, 178, 179, 177, 180, 186, + 135, 142, 177, 180, 185, 187, 188, 136, + 141, 181, 183, 185, 152, 153, 190, 191, + 177, 191, 128, 132, 134, 135, 141, 151, + 153, 188, 134, 128, 129, 130, 132, 135, + 141, 156, 157, 158, 159, 160, 162, 164, + 168, 169, 170, 172, 173, 174, 175, 176, + 179, 183, 133, 134, 171, 190, 150, 153, + 158, 160, 162, 164, 167, 173, 177, 180, + 143, 130, 141, 154, 157, 192, 255, 157, + 159, 146, 148, 178, 180, 146, 147, 178, + 179, 180, 255, 148, 156, 158, 255, 139, + 142, 169, 160, 171, 176, 187, 151, 155, + 191, 149, 158, 160, 188, 176, 190, 128, + 132, 180, 255, 133, 170, 180, 255, 128, + 130, 161, 173, 166, 179, 164, 183, 173, + 144, 146, 148, 168, 178, 180, 184, 185, + 128, 181, 188, 191, 128, 129, 131, 179, + 181, 183, 140, 143, 170, 174, 160, 164, + 166, 175, 144, 176, 175, 177, 191, 160, + 191, 128, 130, 132, 133, 134, 136, 137, + 170, 175, 153, 154, 177, 255, 143, 255, + 160, 190, 153, 154, 155, 160, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, + 175, 176, 177, 255, 175, 178, 180, 189, + 158, 159, 176, 177, 130, 134, 139, 163, + 167, 128, 129, 180, 255, 133, 159, 178, + 255, 166, 173, 135, 147, 160, 188, 128, + 131, 179, 255, 129, 164, 166, 255, 169, + 182, 131, 140, 141, 187, 189, 176, 178, + 180, 183, 184, 190, 191, 129, 171, 175, + 181, 182, 163, 170, 172, 173, 158, 159, + 160, 255, 164, 175, 135, 138, 188, 255, + 172, 184, 187, 190, 191, 158, 128, 143, + 160, 175, 158, 190, 130, 135, 138, 143, + 146, 151, 154, 156, 185, 187, 144, 145, + 150, 155, 157, 158, 135, 139, 141, 168, + 171, 189, 160, 182, 186, 191, 129, 131, + 133, 134, 140, 143, 184, 186, 165, 166, + 128, 129, 130, 132, 133, 134, 135, 136, + 139, 140, 141, 146, 147, 150, 151, 152, + 153, 154, 156, 128, 130, 184, 255, 135, + 190, 131, 175, 187, 188, 190, 255, 128, + 130, 167, 180, 179, 128, 130, 179, 255, + 129, 137, 141, 255, 172, 183, 159, 170, + 188, 128, 131, 190, 191, 151, 128, 132, + 135, 136, 139, 141, 162, 163, 166, 172, + 176, 180, 176, 255, 132, 255, 175, 181, + 184, 255, 129, 155, 158, 255, 129, 255, + 171, 183, 157, 171, 171, 172, 189, 190, + 176, 180, 176, 182, 145, 190, 143, 146, + 178, 157, 158, 160, 163, 133, 134, 137, + 168, 169, 170, 165, 169, 173, 255, 131, + 132, 140, 169, 174, 255, 130, 132, 128, + 182, 187, 255, 173, 180, 182, 255, 132, + 155, 159, 161, 175, 163, 144, 150, 160, + 128, 129, 132, 135, 133, 134, 129, 160, + 255, 128, 146, 147, 148, 152, 153, 154, + 155, 156, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 129, 157, 177, + 255, 191, 128, 174, 175, 178, 180, 189, + 128, 157, 158, 159, 160, 255, 176, 177, + 178, 255, 130, 134, 139, 163, 167, 168, + 255, 128, 129, 130, 179, 180, 255, 187, + 189, 133, 143, 144, 153, 154, 159, 178, + 183, 184, 255, 128, 137, 138, 165, 166, + 173, 176, 255, 135, 147, 148, 159, 160, + 188, 189, 255, 128, 131, 132, 178, 179, + 255, 143, 129, 142, 144, 153, 154, 164, + 166, 175, 176, 185, 186, 255, 128, 168, + 169, 182, 131, 128, 139, 140, 141, 144, + 153, 187, 189, 176, 178, 180, 183, 184, + 190, 191, 129, 160, 170, 171, 175, 178, + 180, 181, 182, 128, 162, 163, 170, 172, + 173, 176, 185, 158, 159, 160, 255, 164, + 175, 135, 138, 188, 255, 172, 173, 174, + 175, 180, 181, 182, 183, 184, 185, 187, + 188, 189, 190, 191, 176, 186, 158, 190, + 128, 134, 147, 151, 157, 168, 170, 182, + 184, 188, 147, 128, 143, 160, 175, 179, + 180, 191, 189, 255, 158, 190, 130, 135, + 138, 143, 146, 151, 154, 156, 185, 187, + 144, 145, 146, 147, 148, 150, 155, 157, + 158, 159, 128, 129, 130, 131, 133, 135, + 138, 139, 140, 141, 142, 143, 144, 145, + 146, 148, 149, 152, 156, 157, 160, 161, + 162, 163, 164, 166, 168, 169, 170, 171, + 172, 173, 174, 176, 177, 153, 155, 178, + 179, 189, 160, 145, 255, 139, 143, 182, + 186, 187, 255, 128, 191, 129, 131, 133, + 134, 140, 143, 144, 147, 149, 151, 153, + 179, 184, 186, 128, 135, 137, 164, 165, + 166, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 138, 139, 140, 141, 146, 147, + 150, 151, 152, 153, 154, 155, 156, 162, + 163, 171, 128, 130, 131, 183, 184, 255, + 135, 165, 166, 175, 176, 190, 131, 175, + 187, 188, 190, 255, 128, 130, 131, 166, + 167, 180, 182, 191, 179, 182, 144, 178, + 128, 130, 131, 178, 179, 255, 155, 129, + 132, 133, 137, 141, 143, 144, 153, 154, + 156, 157, 255, 128, 145, 147, 171, 172, + 183, 159, 170, 171, 175, 176, 185, 186, + 255, 189, 128, 131, 133, 140, 143, 144, + 147, 168, 170, 176, 178, 179, 181, 185, + 188, 191, 144, 151, 128, 132, 135, 136, + 139, 141, 157, 161, 162, 163, 166, 172, + 176, 180, 128, 175, 176, 255, 134, 132, + 135, 136, 143, 144, 153, 154, 255, 128, + 174, 175, 181, 184, 255, 129, 151, 152, + 155, 158, 255, 132, 129, 143, 144, 153, + 154, 255, 128, 170, 171, 183, 157, 171, + 176, 185, 160, 168, 169, 171, 172, 173, + 174, 188, 189, 190, 161, 167, 144, 173, + 176, 180, 128, 175, 176, 182, 133, 143, + 145, 190, 191, 255, 143, 146, 147, 159, + 176, 177, 178, 128, 136, 144, 153, 157, + 158, 160, 163, 133, 134, 137, 144, 145, + 146, 147, 148, 149, 154, 155, 156, 157, + 158, 159, 168, 169, 170, 150, 153, 165, + 169, 173, 255, 131, 132, 140, 169, 174, + 255, 130, 132, 128, 182, 187, 255, 173, + 180, 182, 255, 132, 155, 159, 161, 175, + 160, 163, 184, 185, 186, 161, 162, 133, + 143, 144, 150, 151, 255, 160, 128, 129, + 132, 135, 133, 134, 129, 160, 255, 192, + 255, 176, 255, 155, 156, 157, 159, 160, + 255, 128, 140, 142, 145, 146, 148, 160, + 177, 178, 180, 128, 145, 146, 147, 160, + 172, 174, 176, 178, 179, 148, 156, 158, + 159, 160, 169, 170, 255, 139, 142, 144, + 153, 160, 255, 169, 128, 170, 176, 255, + 128, 158, 160, 171, 176, 187, 128, 150, + 151, 155, 128, 137, 144, 153, 176, 190, + 128, 132, 133, 179, 180, 255, 133, 139, + 140, 143, 144, 153, 154, 170, 180, 255, + 128, 130, 131, 160, 161, 173, 174, 175, + 176, 185, 186, 255, 166, 179, 180, 255, + 128, 163, 164, 183, 173, 144, 146, 148, + 168, 169, 177, 178, 180, 181, 182, 184, + 185, 140, 143, 168, 169, 170, 174, 191, + 255, 165, 177, 191, 129, 147, 149, 159, + 160, 175, 176, 255, 165, 170, 175, 177, + 180, 255, 191, 168, 174, 176, 255, 128, + 134, 136, 142, 144, 150, 152, 158, 160, + 191, 128, 153, 155, 255, 173, 0, 127, + 176, 255, 131, 137, 191, 145, 189, 135, + 129, 130, 132, 133, 156, 128, 133, 144, + 154, 176, 139, 159, 150, 157, 159, 164, + 167, 168, 170, 173, 143, 145, 176, 255, + 139, 255, 166, 176, 171, 179, 160, 161, + 163, 164, 165, 167, 169, 171, 173, 174, + 175, 176, 177, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 166, 170, 172, 178, 150, 153, 155, 163, + 165, 167, 169, 173, 153, 155, 163, 255, + 189, 132, 185, 144, 152, 161, 164, 255, + 188, 129, 131, 190, 255, 133, 134, 137, + 138, 142, 150, 152, 161, 164, 255, 131, + 134, 137, 138, 142, 144, 146, 175, 178, + 180, 182, 255, 134, 138, 142, 161, 164, + 255, 188, 129, 131, 190, 191, 128, 132, + 135, 136, 139, 141, 150, 151, 162, 163, + 130, 190, 191, 151, 128, 130, 134, 136, + 138, 141, 128, 131, 190, 255, 133, 137, + 142, 148, 151, 161, 164, 255, 128, 132, + 134, 136, 138, 141, 149, 150, 162, 163, + 129, 131, 190, 255, 133, 137, 142, 150, + 152, 161, 164, 255, 130, 131, 138, 150, + 143, 148, 152, 159, 178, 179, 177, 180, + 186, 135, 142, 177, 180, 185, 187, 188, + 136, 141, 181, 183, 185, 152, 153, 190, + 191, 177, 191, 128, 132, 134, 135, 141, + 151, 153, 188, 134, 128, 129, 130, 141, + 156, 157, 158, 159, 160, 162, 164, 168, + 169, 170, 172, 173, 174, 175, 176, 179, + 183, 171, 190, 150, 153, 158, 160, 162, + 164, 167, 173, 177, 180, 143, 130, 141, + 154, 157, 157, 159, 146, 148, 178, 180, + 146, 147, 178, 179, 180, 255, 148, 156, + 158, 255, 139, 142, 169, 160, 171, 176, + 187, 151, 155, 191, 149, 158, 160, 188, + 176, 190, 128, 132, 180, 255, 133, 170, + 180, 255, 128, 130, 161, 173, 166, 179, + 164, 183, 173, 144, 146, 148, 168, 178, + 180, 184, 185, 128, 181, 188, 191, 128, + 129, 131, 179, 181, 183, 140, 143, 170, + 174, 160, 164, 166, 175, 144, 176, 175, + 177, 191, 160, 191, 128, 130, 170, 175, + 153, 154, 153, 154, 155, 160, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, + 175, 175, 178, 180, 189, 158, 159, 176, + 177, 130, 134, 139, 163, 167, 128, 129, + 180, 255, 133, 159, 178, 255, 166, 173, + 135, 147, 128, 131, 179, 255, 129, 164, + 166, 255, 169, 182, 131, 140, 141, 187, + 189, 176, 178, 180, 183, 184, 190, 191, + 129, 171, 175, 181, 182, 163, 170, 172, + 173, 172, 184, 187, 190, 191, 158, 128, + 143, 160, 175, 185, 187, 144, 145, 150, + 155, 157, 158, 135, 139, 141, 168, 171, + 189, 160, 182, 186, 191, 129, 131, 133, + 134, 140, 143, 184, 186, 165, 166, 128, + 129, 130, 132, 133, 134, 135, 136, 139, + 140, 141, 146, 147, 150, 151, 152, 153, + 154, 156, 128, 130, 184, 255, 135, 190, + 131, 175, 187, 188, 190, 255, 128, 130, + 167, 180, 179, 128, 130, 179, 255, 129, + 137, 141, 255, 172, 183, 159, 170, 188, + 128, 131, 190, 191, 151, 128, 132, 135, + 136, 139, 141, 162, 163, 166, 172, 176, + 180, 176, 255, 132, 255, 175, 181, 184, + 255, 129, 155, 158, 255, 129, 255, 171, + 183, 157, 171, 171, 172, 189, 190, 176, + 180, 176, 182, 145, 190, 143, 146, 178, + 157, 158, 160, 163, 133, 134, 137, 168, + 169, 170, 165, 169, 173, 255, 131, 132, + 140, 169, 174, 255, 130, 132, 128, 182, + 187, 255, 173, 180, 182, 255, 132, 155, + 159, 161, 175, 163, 144, 150, 160, 128, + 129, 132, 135, 133, 134, 129, 160, 255, + 192, 255, 180, 255, 150, 255, 133, 135, + 187, 188, 161, 169, 170, 173, 174, 175, + 177, 181, 184, 186, 170, 173, 181, 183, + 186, 0, 127, 181, 190, 176, 183, 184, + 185, 186, 191, 192, 255, 130, 131, 137, + 190, 136, 144, 145, 191, 192, 255, 135, + 179, 180, 129, 130, 132, 133, 144, 170, + 176, 178, 156, 128, 133, 144, 154, 160, + 191, 171, 176, 128, 138, 139, 159, 160, + 169, 174, 255, 148, 158, 169, 150, 164, + 167, 173, 176, 185, 189, 190, 192, 255, + 144, 143, 145, 146, 175, 176, 255, 139, + 140, 141, 255, 166, 176, 178, 255, 186, + 128, 137, 138, 170, 171, 179, 180, 181, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 154, 164, 168, 128, 149, 150, 173, 128, + 152, 153, 155, 163, 255, 189, 132, 185, + 144, 176, 152, 161, 164, 165, 166, 175, + 177, 255, 132, 169, 177, 188, 129, 131, + 141, 142, 145, 146, 179, 181, 186, 187, + 190, 255, 142, 158, 133, 134, 137, 138, + 143, 150, 152, 155, 156, 161, 164, 165, + 166, 175, 176, 177, 178, 255, 188, 129, + 131, 133, 138, 143, 144, 147, 168, 170, + 176, 178, 179, 181, 182, 184, 185, 190, + 255, 157, 131, 134, 137, 138, 142, 144, + 146, 152, 153, 158, 159, 165, 166, 175, + 178, 180, 182, 255, 189, 129, 131, 133, + 141, 143, 145, 147, 168, 170, 176, 178, + 179, 181, 185, 188, 255, 134, 138, 144, + 185, 142, 159, 160, 161, 164, 165, 166, + 175, 176, 255, 189, 129, 131, 133, 140, + 143, 144, 147, 168, 170, 176, 178, 179, + 181, 185, 188, 191, 177, 128, 132, 135, + 136, 139, 141, 150, 151, 156, 157, 159, + 161, 162, 163, 166, 175, 130, 131, 156, + 133, 138, 142, 144, 146, 149, 153, 154, + 158, 159, 163, 164, 168, 170, 174, 185, + 190, 191, 144, 151, 128, 130, 134, 136, + 138, 141, 166, 175, 189, 128, 131, 133, + 140, 142, 144, 146, 168, 170, 185, 190, + 255, 133, 137, 151, 142, 148, 152, 154, + 155, 159, 160, 161, 164, 165, 166, 175, + 176, 255, 189, 129, 131, 133, 140, 142, + 144, 146, 168, 170, 179, 181, 185, 188, + 191, 158, 128, 132, 134, 136, 138, 141, + 149, 150, 160, 161, 162, 163, 166, 175, + 177, 178, 189, 129, 131, 133, 140, 142, + 144, 146, 186, 190, 255, 133, 137, 142, + 143, 150, 152, 158, 159, 161, 164, 165, + 166, 175, 176, 185, 186, 191, 192, 255, + 189, 130, 131, 133, 150, 154, 177, 179, + 187, 138, 150, 128, 134, 143, 148, 152, + 159, 166, 175, 178, 179, 177, 180, 186, + 135, 142, 144, 153, 177, 180, 185, 187, + 188, 136, 141, 144, 153, 128, 181, 183, + 185, 152, 153, 160, 169, 190, 191, 128, + 135, 137, 172, 177, 191, 128, 132, 134, + 135, 136, 140, 141, 151, 153, 188, 134, + 128, 129, 130, 131, 137, 138, 139, 140, + 141, 142, 143, 144, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, + 165, 167, 168, 169, 170, 172, 173, 174, + 175, 176, 177, 179, 181, 182, 183, 188, + 189, 190, 191, 132, 152, 180, 184, 185, + 187, 171, 190, 128, 137, 150, 153, 158, + 160, 162, 164, 167, 173, 177, 180, 143, + 130, 141, 144, 153, 154, 157, 160, 255, + 155, 156, 157, 159, 160, 255, 128, 140, + 142, 145, 146, 148, 160, 177, 178, 180, + 128, 145, 146, 147, 160, 172, 174, 176, + 178, 179, 180, 255, 148, 156, 158, 159, + 160, 169, 170, 255, 139, 142, 144, 153, + 160, 255, 169, 128, 170, 176, 255, 128, + 158, 160, 171, 176, 187, 128, 150, 151, + 155, 191, 149, 158, 160, 188, 128, 137, + 144, 153, 176, 190, 128, 132, 133, 179, + 180, 255, 133, 139, 140, 143, 144, 153, + 154, 170, 180, 255, 128, 130, 131, 160, + 161, 173, 174, 175, 176, 185, 186, 255, + 166, 179, 180, 255, 128, 163, 164, 183, + 173, 144, 146, 148, 168, 169, 177, 178, + 180, 181, 182, 184, 185, 128, 181, 188, + 191, 128, 129, 130, 131, 132, 133, 134, + 146, 147, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 164, 167, 140, 143, 152, + 153, 170, 174, 191, 255, 165, 177, 191, + 129, 147, 149, 159, 160, 175, 176, 255, + 144, 176, 165, 170, 175, 177, 180, 255, + 191, 168, 174, 176, 255, 128, 134, 136, + 142, 144, 150, 152, 158, 160, 191, 128, + 130, 132, 133, 134, 133, 170, 175, 187, + 188, 153, 154, 128, 146, 147, 148, 152, + 153, 154, 155, 156, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 129, + 255, 191, 128, 174, 175, 178, 180, 189, + 128, 157, 158, 159, 160, 255, 176, 177, + 178, 255, 130, 134, 139, 163, 167, 168, + 255, 128, 129, 130, 179, 180, 255, 187, + 189, 133, 143, 144, 153, 154, 159, 178, + 183, 184, 255, 128, 137, 138, 165, 166, + 173, 176, 255, 135, 147, 148, 159, 189, + 255, 128, 131, 132, 178, 179, 255, 143, + 129, 142, 144, 153, 154, 164, 166, 175, + 176, 185, 186, 255, 128, 168, 169, 182, + 131, 128, 139, 140, 141, 144, 153, 187, + 189, 176, 178, 180, 183, 184, 190, 191, + 129, 160, 170, 171, 175, 178, 180, 181, + 182, 128, 162, 163, 170, 172, 173, 176, + 185, 172, 173, 174, 175, 180, 181, 182, + 183, 184, 185, 187, 188, 189, 190, 191, + 176, 186, 158, 190, 128, 134, 147, 151, + 157, 168, 170, 182, 184, 188, 147, 128, + 143, 160, 175, 179, 180, 191, 189, 255, + 158, 159, 160, 190, 130, 135, 138, 143, + 146, 151, 154, 156, 185, 187, 144, 145, + 146, 147, 148, 150, 155, 157, 158, 159, + 128, 129, 130, 131, 133, 135, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 148, + 149, 152, 156, 157, 160, 161, 162, 163, + 164, 166, 168, 169, 170, 171, 172, 173, + 174, 176, 177, 153, 155, 178, 179, 189, + 160, 145, 255, 139, 143, 182, 186, 187, + 255, 128, 191, 129, 131, 133, 134, 140, + 143, 144, 147, 149, 151, 153, 179, 184, + 186, 128, 135, 137, 164, 165, 166, 128, + 129, 130, 131, 132, 133, 134, 135, 136, + 138, 139, 140, 141, 146, 147, 150, 151, + 152, 153, 154, 155, 156, 162, 163, 171, + 128, 130, 131, 183, 184, 255, 135, 165, + 166, 175, 176, 190, 131, 175, 187, 188, + 190, 255, 128, 130, 131, 166, 167, 180, + 182, 191, 179, 182, 144, 178, 128, 130, + 131, 178, 179, 255, 155, 129, 132, 133, + 137, 141, 143, 144, 153, 154, 156, 157, + 255, 128, 145, 147, 171, 172, 183, 159, + 170, 171, 175, 176, 185, 186, 255, 189, + 128, 131, 133, 140, 143, 144, 147, 168, + 170, 176, 178, 179, 181, 185, 188, 191, + 144, 151, 128, 132, 135, 136, 139, 141, + 157, 161, 162, 163, 166, 172, 176, 180, + 128, 175, 176, 255, 134, 132, 135, 136, + 143, 144, 153, 154, 255, 128, 174, 175, + 181, 184, 255, 129, 151, 152, 155, 158, + 255, 132, 129, 143, 144, 153, 154, 255, + 128, 170, 171, 183, 157, 171, 176, 185, + 160, 168, 169, 171, 172, 173, 174, 188, + 189, 190, 161, 167, 144, 173, 176, 180, + 128, 175, 176, 182, 133, 143, 145, 190, + 191, 255, 143, 146, 147, 159, 176, 177, + 178, 128, 136, 144, 153, 157, 158, 160, + 163, 133, 134, 137, 144, 145, 146, 147, + 148, 149, 154, 155, 156, 157, 158, 159, + 168, 169, 170, 150, 153, 165, 169, 173, + 255, 131, 132, 140, 169, 174, 255, 130, + 132, 128, 182, 187, 255, 173, 180, 182, + 255, 132, 155, 159, 161, 175, 160, 163, + 184, 185, 186, 161, 162, 133, 143, 144, + 150, 151, 255, 160, 128, 129, 132, 135, + 133, 134, 129, 160, 255, 192, 255, 176, + 255, 173, 0, 127, 176, 255, 131, 137, + 191, 145, 189, 135, 129, 130, 132, 133, + 156, 128, 133, 144, 154, 176, 139, 159, + 150, 157, 159, 164, 167, 168, 170, 173, + 143, 145, 176, 255, 139, 255, 166, 176, + 171, 179, 160, 161, 163, 164, 165, 167, + 169, 171, 173, 174, 175, 176, 177, 179, + 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 166, 170, 172, 178, + 150, 153, 155, 163, 165, 167, 169, 173, + 153, 155, 163, 255, 189, 132, 185, 144, + 152, 161, 164, 255, 188, 129, 131, 190, + 255, 133, 134, 137, 138, 142, 150, 152, + 161, 164, 255, 131, 134, 137, 138, 142, + 144, 146, 175, 178, 180, 182, 255, 134, + 138, 142, 161, 164, 255, 188, 129, 131, + 190, 191, 128, 132, 135, 136, 139, 141, + 150, 151, 162, 163, 130, 190, 191, 151, + 128, 130, 134, 136, 138, 141, 128, 131, + 190, 255, 133, 137, 142, 148, 151, 161, + 164, 255, 128, 132, 134, 136, 138, 141, + 149, 150, 162, 163, 129, 131, 190, 255, + 133, 137, 142, 150, 152, 161, 164, 255, + 130, 131, 138, 150, 143, 148, 152, 159, + 178, 179, 177, 180, 186, 135, 142, 177, + 180, 185, 187, 188, 136, 141, 181, 183, + 185, 152, 153, 190, 191, 177, 191, 128, + 132, 134, 135, 141, 151, 153, 188, 134, + 128, 129, 130, 132, 135, 141, 156, 157, + 158, 159, 160, 162, 164, 168, 169, 170, + 172, 173, 174, 175, 176, 179, 183, 133, + 134, 171, 190, 150, 153, 158, 160, 162, + 164, 167, 173, 177, 180, 143, 130, 141, + 154, 157, 157, 159, 146, 148, 178, 180, + 146, 147, 178, 179, 180, 255, 148, 156, + 158, 255, 139, 142, 169, 160, 171, 176, + 187, 151, 155, 191, 149, 158, 160, 188, + 176, 190, 128, 132, 180, 255, 133, 170, + 180, 255, 128, 130, 161, 173, 166, 179, + 164, 183, 173, 144, 146, 148, 168, 178, + 180, 184, 185, 128, 181, 188, 191, 128, + 129, 131, 179, 181, 183, 140, 143, 170, + 174, 160, 164, 166, 175, 144, 176, 175, + 177, 191, 160, 191, 128, 130, 132, 133, + 134, 136, 137, 170, 175, 153, 154, 153, + 154, 155, 160, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 175, 176, 177, + 255, 175, 178, 180, 189, 158, 159, 176, + 177, 130, 134, 139, 163, 167, 128, 129, + 180, 255, 133, 159, 178, 255, 166, 173, + 135, 147, 160, 188, 128, 131, 179, 255, + 129, 164, 166, 255, 169, 182, 131, 140, + 141, 187, 189, 176, 178, 180, 183, 184, + 190, 191, 129, 171, 175, 181, 182, 163, + 170, 172, 173, 172, 184, 187, 190, 191, + 158, 128, 143, 160, 175, 158, 159, 160, + 190, 130, 135, 138, 143, 146, 151, 154, + 156, 185, 187, 144, 145, 150, 155, 157, + 158, 135, 139, 141, 168, 171, 189, 160, + 182, 186, 191, 129, 131, 133, 134, 140, + 143, 184, 186, 165, 166, 128, 129, 130, + 132, 133, 134, 135, 136, 139, 140, 141, + 146, 147, 150, 151, 152, 153, 154, 156, + 128, 130, 184, 255, 135, 190, 131, 175, + 187, 188, 190, 255, 128, 130, 167, 180, + 179, 128, 130, 179, 255, 129, 137, 141, + 255, 172, 183, 159, 170, 188, 128, 131, + 190, 191, 151, 128, 132, 135, 136, 139, + 141, 162, 163, 166, 172, 176, 180, 176, + 255, 132, 255, 175, 181, 184, 255, 129, + 155, 158, 255, 129, 255, 171, 183, 157, + 171, 171, 172, 189, 190, 176, 180, 176, + 182, 145, 190, 143, 146, 178, 157, 158, + 160, 163, 133, 134, 137, 168, 169, 170, + 165, 169, 173, 255, 131, 132, 140, 169, + 174, 255, 130, 132, 128, 182, 187, 255, + 173, 180, 182, 255, 132, 155, 159, 161, + 175, 163, 144, 150, 160, 128, 129, 132, + 135, 133, 134, 129, 160, 255, 192, 255, + 173, 0, 127, 176, 255, 131, 137, 191, + 145, 189, 135, 129, 130, 132, 133, 156, + 128, 133, 144, 154, 176, 139, 159, 150, + 157, 159, 164, 167, 168, 170, 173, 143, + 145, 176, 255, 139, 255, 166, 176, 171, + 179, 160, 161, 163, 164, 165, 167, 169, + 171, 173, 174, 175, 176, 177, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 166, 170, 172, 178, 150, + 153, 155, 163, 165, 167, 169, 173, 153, + 155, 163, 255, 189, 132, 185, 144, 152, + 161, 164, 255, 188, 129, 131, 190, 255, + 133, 134, 137, 138, 142, 150, 152, 161, + 164, 255, 131, 134, 137, 138, 142, 144, + 146, 175, 178, 180, 182, 255, 134, 138, + 142, 161, 164, 255, 188, 129, 131, 190, + 191, 128, 132, 135, 136, 139, 141, 150, + 151, 162, 163, 130, 190, 191, 151, 128, + 130, 134, 136, 138, 141, 128, 131, 190, + 255, 133, 137, 142, 148, 151, 161, 164, + 255, 128, 132, 134, 136, 138, 141, 149, + 150, 162, 163, 129, 131, 190, 255, 133, + 137, 142, 150, 152, 161, 164, 255, 130, + 131, 138, 150, 143, 148, 152, 159, 178, + 179, 177, 180, 186, 135, 142, 177, 180, + 185, 187, 188, 136, 141, 181, 183, 185, + 152, 153, 190, 191, 177, 191, 128, 132, + 134, 135, 141, 151, 153, 188, 134, 128, + 129, 130, 141, 156, 157, 158, 159, 160, + 162, 164, 168, 169, 170, 172, 173, 174, + 175, 176, 179, 183, 171, 190, 150, 153, + 158, 160, 162, 164, 167, 173, 177, 180, + 143, 130, 141, 154, 157, 157, 159, 146, + 148, 178, 180, 146, 147, 178, 179, 180, + 255, 148, 156, 158, 255, 139, 142, 169, + 160, 171, 176, 187, 151, 155, 191, 149, + 158, 160, 188, 176, 190, 128, 132, 180, + 255, 133, 170, 180, 255, 128, 130, 161, + 173, 166, 179, 164, 183, 173, 144, 146, + 148, 168, 178, 180, 184, 185, 128, 181, + 188, 191, 128, 129, 131, 179, 181, 183, + 140, 143, 170, 174, 191, 255, 165, 129, + 147, 149, 159, 160, 175, 176, 255, 144, + 176, 175, 177, 191, 160, 191, 128, 130, + 131, 135, 139, 140, 141, 170, 175, 177, + 181, 153, 156, 160, 255, 187, 192, 255, + 176, 191, 144, 190, 152, 255, 153, 154, + 155, 160, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 175, 175, 178, 180, + 189, 158, 159, 176, 177, 130, 134, 139, + 163, 167, 128, 129, 180, 255, 133, 159, + 178, 255, 166, 173, 135, 147, 128, 131, + 179, 255, 129, 164, 166, 255, 169, 182, + 131, 140, 141, 187, 189, 176, 178, 180, + 183, 184, 190, 191, 129, 171, 175, 181, + 182, 163, 170, 172, 173, 172, 184, 185, + 187, 188, 189, 190, 191, 158, 128, 143, + 160, 175, 179, 180, 166, 255, 160, 255, + 185, 187, 144, 145, 150, 155, 157, 158, + 135, 139, 141, 168, 171, 189, 160, 182, + 186, 191, 129, 131, 133, 134, 140, 143, + 184, 186, 165, 166, 128, 129, 130, 132, + 133, 134, 135, 136, 139, 140, 141, 146, + 147, 150, 151, 152, 153, 154, 156, 128, + 130, 184, 255, 135, 190, 131, 175, 187, + 188, 190, 255, 128, 130, 167, 180, 179, + 128, 130, 179, 255, 129, 137, 141, 255, + 172, 183, 159, 170, 188, 128, 131, 190, + 191, 151, 128, 132, 135, 136, 139, 141, + 162, 163, 166, 172, 176, 180, 176, 255, + 132, 255, 175, 181, 184, 255, 129, 155, + 158, 255, 129, 255, 171, 183, 157, 171, + 171, 172, 189, 190, 176, 180, 176, 182, + 145, 190, 143, 146, 128, 178, 128, 157, + 158, 160, 163, 133, 134, 137, 168, 169, + 170, 165, 169, 173, 255, 131, 132, 140, + 169, 174, 255, 130, 132, 128, 182, 187, + 255, 173, 180, 182, 255, 132, 155, 159, + 161, 175, 163, 144, 150, 160, 128, 129, + 132, 135, 133, 134, 129, 160, 255, 192, + 255, 129, 255, 173, 128, 255, 176, 255, + 131, 137, 191, 145, 189, 135, 129, 130, + 132, 133, 156, 128, 133, 144, 154, 176, + 139, 159, 150, 157, 159, 164, 167, 168, + 170, 173, 143, 145, 176, 255, 139, 255, + 166, 176, 171, 179, 160, 161, 163, 164, + 165, 167, 169, 171, 173, 174, 175, 176, + 177, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 166, 170, + 172, 178, 150, 153, 155, 163, 165, 167, + 169, 173, 153, 155, 163, 255, 189, 132, + 185, 144, 152, 161, 164, 255, 188, 129, + 131, 190, 255, 133, 134, 137, 138, 142, + 150, 152, 161, 164, 255, 131, 134, 137, + 138, 142, 144, 146, 175, 178, 180, 182, + 255, 134, 138, 142, 161, 164, 255, 188, + 129, 131, 190, 191, 128, 132, 135, 136, + 139, 141, 150, 151, 162, 163, 130, 190, + 191, 151, 128, 130, 134, 136, 138, 141, + 128, 131, 190, 255, 133, 137, 142, 148, + 151, 161, 164, 255, 128, 132, 134, 136, + 138, 141, 149, 150, 162, 163, 129, 131, + 190, 255, 133, 137, 142, 150, 152, 161, + 164, 255, 130, 131, 138, 150, 143, 148, + 152, 159, 178, 179, 177, 180, 186, 135, + 142, 177, 180, 185, 187, 188, 136, 141, + 181, 183, 185, 152, 153, 190, 191, 177, + 191, 128, 132, 134, 135, 141, 151, 153, + 188, 134, 128, 129, 130, 141, 156, 157, + 158, 159, 160, 162, 164, 168, 169, 170, + 172, 173, 174, 175, 176, 179, 183, 171, + 190, 150, 153, 158, 160, 162, 164, 167, + 173, 177, 180, 143, 130, 141, 154, 157, + 157, 159, 146, 148, 178, 180, 146, 147, + 178, 179, 180, 255, 148, 156, 158, 255, + 139, 142, 169, 160, 171, 176, 187, 151, + 155, 191, 149, 158, 160, 188, 176, 190, + 128, 132, 180, 255, 133, 170, 180, 255, + 128, 130, 161, 173, 166, 179, 164, 183, + 173, 144, 146, 148, 168, 178, 180, 184, + 185, 128, 181, 188, 191, 128, 129, 131, + 179, 181, 183, 140, 143, 170, 174, 160, + 164, 166, 175, 144, 176, 175, 177, 191, + 160, 191, 128, 130, 170, 175, 153, 154, + 153, 154, 155, 160, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 175, 175, + 178, 180, 189, 158, 159, 176, 177, 130, + 134, 139, 163, 167, 128, 129, 180, 255, + 133, 159, 178, 255, 166, 173, 135, 147, + 128, 131, 179, 255, 129, 164, 166, 255, + 169, 182, 131, 140, 141, 187, 189, 176, + 178, 180, 183, 184, 190, 191, 129, 171, + 175, 181, 182, 163, 170, 172, 173, 172, + 184, 187, 190, 191, 158, 128, 143, 160, + 175, 185, 187, 144, 145, 150, 155, 157, + 158, 135, 139, 141, 168, 171, 189, 160, + 182, 186, 191, 129, 131, 133, 134, 140, + 143, 184, 186, 165, 166, 128, 129, 130, + 132, 133, 134, 135, 136, 139, 140, 141, + 146, 147, 150, 151, 152, 153, 154, 156, + 128, 130, 184, 255, 135, 190, 131, 175, + 187, 188, 190, 255, 128, 130, 167, 180, + 179, 128, 130, 179, 255, 129, 137, 141, + 255, 172, 183, 159, 170, 188, 128, 131, + 190, 191, 151, 128, 132, 135, 136, 139, + 141, 162, 163, 166, 172, 176, 180, 176, + 255, 132, 255, 175, 181, 184, 255, 129, + 155, 158, 255, 129, 255, 171, 183, 157, + 171, 171, 172, 189, 190, 176, 180, 176, + 182, 145, 190, 143, 146, 178, 157, 158, + 160, 163, 133, 134, 137, 168, 169, 170, + 165, 169, 173, 255, 131, 132, 140, 169, + 174, 255, 130, 132, 128, 182, 187, 255, + 173, 180, 182, 255, 132, 155, 159, 161, + 175, 163, 144, 150, 160, 128, 129, 132, + 135, 133, 134, 129, 160, 255, 192, 255, + 151, 152, 153, 154, 155, 156, 160, 255, + 173, 173, 128, 255, 176, 255, 131, 137, + 191, 145, 189, 135, 129, 130, 132, 133, + 156, 128, 133, 144, 154, 176, 139, 159, + 150, 157, 159, 164, 167, 168, 170, 173, + 143, 145, 176, 255, 139, 255, 166, 176, + 171, 179, 160, 161, 163, 164, 165, 167, + 169, 171, 173, 174, 175, 176, 177, 179, + 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 166, 170, 172, 178, + 150, 153, 155, 163, 165, 167, 169, 173, + 153, 155, 163, 255, 189, 132, 185, 144, + 152, 161, 164, 255, 188, 129, 131, 190, + 255, 133, 134, 137, 138, 142, 150, 152, + 161, 164, 255, 131, 134, 137, 138, 142, + 144, 146, 175, 178, 180, 182, 255, 134, + 138, 142, 161, 164, 255, 188, 129, 131, + 190, 191, 128, 132, 135, 136, 139, 141, + 150, 151, 162, 163, 130, 190, 191, 151, + 128, 130, 134, 136, 138, 141, 128, 131, + 190, 255, 133, 137, 142, 148, 151, 161, + 164, 255, 128, 132, 134, 136, 138, 141, + 149, 150, 162, 163, 129, 131, 190, 255, + 133, 137, 142, 150, 152, 161, 164, 255, + 130, 131, 138, 150, 143, 148, 152, 159, + 178, 179, 177, 180, 186, 135, 142, 177, + 180, 185, 187, 188, 136, 141, 181, 183, + 185, 152, 153, 190, 191, 177, 191, 128, + 132, 134, 135, 141, 151, 153, 188, 134, + 128, 129, 130, 141, 156, 157, 158, 159, + 160, 162, 164, 168, 169, 170, 172, 173, + 174, 175, 176, 179, 183, 171, 190, 150, + 153, 158, 160, 162, 164, 167, 173, 177, + 180, 143, 130, 141, 154, 157, 157, 159, + 146, 148, 178, 180, 146, 147, 178, 179, + 180, 255, 148, 156, 158, 255, 139, 142, + 169, 160, 171, 176, 187, 151, 155, 191, + 149, 158, 160, 188, 176, 190, 128, 132, + 180, 255, 133, 170, 180, 255, 128, 130, + 161, 173, 166, 179, 164, 183, 173, 144, + 146, 148, 168, 178, 180, 184, 185, 128, + 181, 188, 191, 128, 129, 131, 179, 181, + 183, 140, 143, 170, 174, 160, 164, 166, + 175, 144, 176, 175, 177, 191, 160, 191, + 128, 130, 170, 175, 153, 154, 153, 154, + 155, 160, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 175, 175, 178, 180, + 189, 158, 159, 176, 177, 130, 134, 139, + 163, 167, 128, 129, 180, 255, 133, 159, + 178, 255, 166, 173, 135, 147, 128, 131, + 179, 255, 129, 164, 166, 255, 169, 182, + 131, 140, 141, 187, 189, 176, 178, 180, + 183, 184, 190, 191, 129, 171, 175, 181, + 182, 163, 170, 172, 173, 172, 184, 187, + 190, 191, 158, 128, 143, 160, 175, 185, + 187, 144, 145, 150, 155, 157, 158, 135, + 139, 141, 168, 171, 189, 160, 182, 186, + 191, 129, 131, 133, 134, 140, 143, 184, + 186, 165, 166, 128, 129, 130, 132, 133, + 134, 135, 136, 139, 140, 141, 146, 147, + 150, 151, 152, 153, 154, 156, 128, 130, + 184, 255, 135, 190, 131, 175, 187, 188, + 190, 255, 128, 130, 167, 180, 179, 128, + 130, 179, 255, 129, 137, 141, 255, 172, + 183, 159, 170, 188, 128, 131, 190, 191, + 151, 128, 132, 135, 136, 139, 141, 162, + 163, 166, 172, 176, 180, 176, 255, 132, + 255, 175, 181, 184, 255, 129, 155, 158, + 255, 129, 255, 171, 183, 157, 171, 171, + 172, 189, 190, 176, 180, 176, 182, 145, + 190, 143, 146, 178, 157, 158, 160, 163, + 133, 134, 137, 168, 169, 170, 165, 169, + 173, 255, 131, 132, 140, 169, 174, 255, + 130, 132, 128, 182, 187, 255, 173, 180, + 182, 255, 132, 155, 159, 161, 175, 163, + 144, 150, 160, 128, 129, 132, 135, 133, + 134, 129, 160, 255, 192, 255, 128, 255, + 176, 255, 131, 137, 191, 145, 189, 135, + 129, 130, 132, 133, 156, 128, 133, 144, + 154, 176, 139, 159, 150, 157, 159, 164, + 167, 168, 170, 173, 143, 145, 176, 255, + 139, 255, 166, 176, 171, 179, 160, 161, + 163, 164, 165, 167, 169, 171, 173, 174, + 175, 176, 177, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 166, 170, 172, 178, 128, 129, 130, 141, + 156, 157, 158, 159, 160, 162, 164, 168, + 169, 170, 172, 173, 174, 175, 176, 179, + 183, 128, 129, 131, 179, 181, 183, 128, + 130, 153, 154, 155, 160, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 175, + 172, 184, 187, 190, 191, 144, 145, 150, + 155, 157, 158, 160, 182, 255, 191, 128, + 174, 175, 178, 180, 189, 128, 157, 158, + 159, 160, 255, 176, 177, 178, 255, 130, + 134, 139, 163, 167, 168, 255, 128, 129, + 130, 179, 180, 255, 187, 189, 133, 143, + 144, 153, 154, 159, 178, 183, 184, 255, + 128, 137, 138, 165, 166, 173, 176, 255, + 135, 147, 148, 159, 160, 188, 189, 255, + 128, 131, 132, 178, 179, 255, 143, 129, + 142, 144, 153, 154, 164, 166, 175, 176, + 185, 186, 255, 128, 168, 169, 182, 131, + 128, 139, 140, 141, 144, 153, 187, 189, + 129, 160, 170, 171, 175, 178, 180, 181, + 182, 128, 162, 163, 170, 172, 173, 176, + 185, 173, 170, 173, 181, 183, 186, 128, + 255, 181, 190, 176, 183, 184, 185, 186, + 191, 192, 255, 130, 131, 137, 190, 136, + 144, 145, 191, 192, 255, 135, 179, 180, + 129, 130, 132, 133, 144, 170, 176, 178, + 156, 128, 133, 144, 154, 160, 191, 171, + 176, 128, 138, 139, 159, 160, 169, 174, + 255, 148, 158, 169, 150, 164, 167, 173, + 176, 185, 189, 190, 192, 255, 144, 143, + 145, 146, 175, 176, 255, 139, 140, 141, + 255, 166, 176, 178, 255, 186, 128, 137, + 138, 170, 171, 179, 180, 181, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 154, 164, + 168, 128, 149, 150, 173, 128, 152, 153, + 155, 163, 255, 189, 132, 185, 144, 176, + 152, 161, 164, 165, 166, 175, 177, 255, + 132, 169, 177, 188, 129, 131, 141, 142, + 145, 146, 179, 181, 186, 187, 190, 255, + 142, 158, 133, 134, 137, 138, 143, 150, + 152, 155, 156, 161, 164, 165, 166, 175, + 176, 177, 178, 255, 188, 129, 131, 133, + 138, 143, 144, 147, 168, 170, 176, 178, + 179, 181, 182, 184, 185, 190, 255, 157, + 131, 134, 137, 138, 142, 144, 146, 152, + 153, 158, 159, 165, 166, 175, 178, 180, + 182, 255, 189, 129, 131, 133, 141, 143, + 145, 147, 168, 170, 176, 178, 179, 181, + 185, 188, 255, 134, 138, 144, 185, 142, + 159, 160, 161, 164, 165, 166, 175, 176, + 255, 189, 129, 131, 133, 140, 143, 144, + 147, 168, 170, 176, 178, 179, 181, 185, + 188, 191, 177, 128, 132, 135, 136, 139, + 141, 150, 151, 156, 157, 159, 161, 162, + 163, 166, 175, 130, 131, 156, 133, 138, + 142, 144, 146, 149, 153, 154, 158, 159, + 163, 164, 168, 170, 174, 185, 190, 191, + 144, 151, 128, 130, 134, 136, 138, 141, + 166, 175, 189, 128, 131, 133, 140, 142, + 144, 146, 168, 170, 185, 190, 255, 133, + 137, 151, 142, 148, 152, 154, 155, 159, + 160, 161, 164, 165, 166, 175, 176, 255, + 189, 129, 131, 133, 140, 142, 144, 146, + 168, 170, 179, 181, 185, 188, 191, 158, + 128, 132, 134, 136, 138, 141, 149, 150, + 160, 161, 162, 163, 166, 175, 177, 178, + 189, 129, 131, 133, 140, 142, 144, 146, + 186, 190, 255, 133, 137, 142, 143, 150, + 152, 158, 159, 161, 164, 165, 166, 175, + 176, 185, 186, 191, 192, 255, 189, 130, + 131, 133, 150, 154, 177, 179, 187, 138, + 150, 128, 134, 143, 148, 152, 159, 166, + 175, 178, 179, 177, 180, 186, 135, 142, + 144, 153, 177, 180, 185, 187, 188, 136, + 141, 144, 153, 128, 181, 183, 185, 152, + 153, 160, 169, 190, 191, 128, 135, 137, + 172, 177, 191, 128, 132, 134, 135, 136, + 140, 141, 151, 153, 188, 134, 128, 129, + 130, 131, 132, 135, 137, 138, 139, 140, + 141, 142, 143, 144, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, + 165, 167, 168, 169, 170, 172, 173, 174, + 175, 176, 177, 179, 181, 182, 183, 188, + 189, 190, 191, 133, 134, 136, 152, 180, + 184, 185, 187, 171, 190, 128, 137, 150, + 153, 158, 160, 162, 164, 167, 173, 177, + 180, 143, 130, 141, 144, 153, 154, 157, + 160, 255, 155, 156, 157, 159, 160, 255, + 128, 140, 142, 145, 146, 148, 160, 177, + 178, 180, 128, 145, 146, 147, 160, 172, + 174, 176, 178, 179, 180, 255, 148, 156, + 158, 159, 160, 169, 170, 255, 139, 142, + 144, 153, 160, 255, 169, 128, 170, 176, + 255, 128, 158, 160, 171, 176, 187, 128, + 150, 151, 155, 191, 149, 158, 160, 188, + 128, 137, 144, 153, 176, 190, 128, 132, + 133, 179, 180, 255, 133, 139, 140, 143, + 144, 153, 154, 170, 180, 255, 128, 130, + 131, 160, 161, 173, 174, 175, 176, 185, + 186, 255, 166, 179, 180, 255, 128, 163, + 164, 183, 173, 144, 146, 148, 168, 169, + 177, 178, 180, 181, 182, 184, 185, 128, + 181, 188, 191, 128, 129, 130, 131, 132, + 133, 134, 146, 147, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 164, 167, 140, + 143, 152, 153, 170, 174, 191, 255, 165, + 177, 191, 129, 147, 149, 159, 160, 175, + 176, 255, 144, 176, 165, 170, 175, 177, + 180, 255, 191, 168, 174, 176, 255, 128, + 134, 136, 142, 144, 150, 152, 158, 160, + 191, 128, 130, 132, 133, 134, 136, 137, + 133, 170, 175, 187, 188, 153, 154, 128, + 146, 147, 148, 152, 153, 154, 155, 156, + 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 129, 157, 177, 255, 191, + 128, 174, 175, 178, 180, 189, 128, 157, + 158, 159, 160, 255, 176, 177, 178, 255, + 130, 134, 139, 163, 167, 168, 255, 128, + 129, 130, 179, 180, 255, 187, 189, 133, + 143, 144, 153, 154, 159, 178, 183, 184, + 255, 128, 137, 138, 165, 166, 173, 176, + 255, 135, 147, 148, 159, 160, 188, 189, + 255, 128, 131, 132, 178, 179, 255, 143, + 129, 142, 144, 153, 154, 164, 166, 175, + 176, 185, 186, 255, 128, 168, 169, 182, + 131, 128, 139, 140, 141, 144, 153, 187, + 189, 176, 178, 180, 183, 184, 190, 191, + 129, 160, 170, 171, 175, 178, 180, 181, + 182, 128, 162, 163, 170, 172, 173, 176, + 185, 172, 173, 174, 175, 180, 181, 182, + 183, 184, 185, 187, 188, 189, 190, 191, + 176, 186, 158, 190, 128, 134, 147, 151, + 157, 168, 170, 182, 184, 188, 147, 128, + 143, 160, 175, 179, 180, 191, 189, 255, + 158, 159, 160, 190, 130, 135, 138, 143, + 146, 151, 154, 156, 185, 187, 144, 145, + 146, 147, 148, 150, 155, 157, 158, 159, + 128, 129, 130, 131, 133, 135, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 148, + 149, 152, 156, 157, 160, 161, 162, 163, + 164, 166, 168, 169, 170, 171, 172, 173, + 174, 176, 177, 153, 155, 178, 179, 189, + 160, 145, 255, 139, 143, 182, 186, 187, + 255, 128, 191, 129, 131, 133, 134, 140, + 143, 144, 147, 149, 151, 153, 179, 184, + 186, 128, 135, 137, 164, 165, 166, 128, + 129, 130, 131, 132, 133, 134, 135, 136, + 138, 139, 140, 141, 146, 147, 150, 151, + 152, 153, 154, 155, 156, 162, 163, 171, + 128, 130, 131, 183, 184, 255, 135, 165, + 166, 175, 176, 190, 131, 175, 187, 188, + 190, 255, 128, 130, 131, 166, 167, 180, + 182, 191, 179, 182, 144, 178, 128, 130, + 131, 178, 179, 255, 155, 129, 132, 133, + 137, 141, 143, 144, 153, 154, 156, 157, + 255, 128, 145, 147, 171, 172, 183, 159, + 170, 171, 175, 176, 185, 186, 255, 189, + 128, 131, 133, 140, 143, 144, 147, 168, + 170, 176, 178, 179, 181, 185, 188, 191, + 144, 151, 128, 132, 135, 136, 139, 141, + 157, 161, 162, 163, 166, 172, 176, 180, + 128, 175, 176, 255, 134, 132, 135, 136, + 143, 144, 153, 154, 255, 128, 174, 175, + 181, 184, 255, 129, 151, 152, 155, 158, + 255, 132, 129, 143, 144, 153, 154, 255, + 128, 170, 171, 183, 157, 171, 176, 185, + 160, 168, 169, 171, 172, 173, 174, 188, + 189, 190, 161, 167, 144, 173, 176, 180, + 128, 175, 176, 182, 133, 143, 145, 190, + 191, 255, 143, 146, 147, 159, 176, 177, + 178, 128, 136, 144, 153, 157, 158, 160, + 163, 133, 134, 137, 144, 145, 146, 147, + 148, 149, 154, 155, 156, 157, 158, 159, + 168, 169, 170, 150, 153, 165, 169, 173, + 255, 131, 132, 140, 169, 174, 255, 130, + 132, 128, 182, 187, 255, 173, 180, 182, + 255, 132, 155, 159, 161, 175, 160, 163, + 184, 185, 186, 161, 162, 133, 143, 144, + 150, 151, 255, 160, 128, 129, 132, 135, + 133, 134, 129, 160, 255, 192, 255, 176, + 255, 128, 255, 176, 255, 131, 137, 191, + 145, 189, 135, 129, 130, 132, 133, 156, + 128, 133, 144, 154, 176, 139, 159, 150, + 157, 159, 164, 167, 168, 170, 173, 143, + 145, 176, 255, 139, 255, 166, 176, 171, + 179, 160, 161, 163, 164, 165, 167, 169, + 171, 173, 174, 175, 176, 177, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 166, 170, 172, 178, 128, + 129, 130, 141, 156, 157, 158, 159, 160, + 162, 164, 168, 169, 170, 172, 173, 174, + 175, 176, 179, 183, 128, 129, 131, 179, + 181, 183, 128, 130, 153, 154, 155, 160, + 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 175, 172, 184, 187, 190, 191, + 144, 145, 150, 155, 157, 158, 160, 174, + 175, 154, 255, 158, 190, 128, 134, 147, + 151, 157, 168, 170, 182, 184, 188, 128, + 143, 160, 175, 179, 180, 191, 189, 255, + 129, 154, 166, 255, 158, 159, 160, 190, + 191, 255, 130, 135, 138, 143, 146, 151, + 154, 156, 185, 187, 128, 129, 130, 131, + 133, 135, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 148, 149, 152, 156, 157, + 160, 161, 162, 163, 164, 166, 168, 169, + 170, 171, 172, 173, 174, 176, 177, 153, + 155, 178, 179, 160, 145, 255, 139, 143, + 182, 186, 187, 255, 128, 191, 129, 131, + 133, 134, 140, 143, 144, 147, 149, 151, + 153, 179, 184, 186, 128, 135, 137, 164, + 165, 166, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 138, 139, 140, 141, 146, + 147, 150, 151, 152, 153, 154, 155, 156, + 162, 163, 171, 128, 130, 131, 183, 184, + 255, 135, 165, 166, 175, 176, 190, 131, + 175, 187, 188, 190, 255, 128, 130, 131, + 166, 167, 180, 182, 191, 179, 182, 144, + 178, 128, 130, 131, 178, 179, 255, 155, + 129, 132, 133, 137, 141, 143, 144, 153, + 154, 156, 157, 255, 128, 145, 147, 171, + 172, 183, 159, 170, 171, 175, 176, 185, + 186, 255, 189, 128, 131, 133, 140, 143, + 144, 147, 168, 170, 176, 178, 179, 181, + 185, 188, 191, 144, 151, 128, 132, 135, + 136, 139, 141, 157, 161, 162, 163, 166, + 172, 176, 180, 128, 175, 176, 255, 134, + 132, 135, 136, 143, 144, 153, 154, 255, + 128, 174, 175, 181, 184, 255, 129, 151, + 152, 155, 158, 255, 132, 129, 143, 144, + 153, 154, 255, 128, 170, 171, 183, 157, + 171, 176, 185, 160, 168, 169, 171, 172, + 173, 174, 188, 189, 190, 161, 167, 144, + 173, 176, 180, 128, 175, 176, 182, 133, + 143, 145, 190, 191, 255, 143, 146, 147, + 159, 128, 176, 177, 178, 128, 129, 128, + 136, 144, 153, 157, 158, 160, 163, 133, + 134, 137, 144, 145, 146, 147, 148, 149, + 154, 155, 156, 157, 158, 159, 168, 169, + 170, 150, 153, 160, 163, 184, 185, 186, + 161, 162, 133, 143, 144, 150, 151, 255, + 132, 133, 134, 135, 136, 166, 191, 173, + 0, 127, 176, 255, 131, 137, 191, 145, + 189, 135, 129, 130, 132, 133, 156, 128, + 133, 144, 154, 176, 139, 159, 150, 157, + 159, 164, 167, 168, 170, 173, 143, 145, + 176, 255, 139, 255, 166, 176, 171, 179, + 160, 161, 163, 164, 165, 167, 169, 171, + 173, 174, 175, 176, 177, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 166, 170, 172, 178, 150, 153, + 155, 163, 165, 167, 169, 173, 153, 155, + 163, 255, 189, 132, 185, 144, 152, 161, + 164, 255, 188, 129, 131, 190, 255, 133, + 134, 137, 138, 142, 150, 152, 161, 164, + 255, 131, 134, 137, 138, 142, 144, 146, + 175, 178, 180, 182, 255, 134, 138, 142, + 161, 164, 255, 188, 129, 131, 190, 191, + 128, 132, 135, 136, 139, 141, 150, 151, + 162, 163, 130, 190, 191, 151, 128, 130, + 134, 136, 138, 141, 128, 131, 190, 255, + 133, 137, 142, 148, 151, 161, 164, 255, + 128, 132, 134, 136, 138, 141, 149, 150, + 162, 163, 129, 131, 190, 255, 133, 137, + 142, 150, 152, 161, 164, 255, 130, 131, + 138, 150, 143, 148, 152, 159, 178, 179, + 177, 180, 186, 135, 142, 177, 180, 185, + 187, 188, 136, 141, 181, 183, 185, 152, + 153, 190, 191, 177, 191, 128, 132, 134, + 135, 141, 151, 153, 188, 134, 128, 129, + 130, 141, 156, 157, 158, 159, 160, 162, + 164, 168, 169, 170, 172, 173, 174, 175, + 176, 179, 183, 171, 190, 150, 153, 158, + 160, 162, 164, 167, 173, 177, 180, 143, + 130, 141, 154, 157, 157, 159, 146, 148, + 178, 180, 146, 147, 178, 179, 180, 255, + 148, 156, 158, 255, 139, 142, 169, 160, + 171, 176, 187, 151, 155, 191, 149, 158, + 160, 188, 176, 190, 128, 132, 180, 255, + 133, 170, 180, 255, 128, 130, 161, 173, + 166, 179, 164, 183, 173, 144, 146, 148, + 168, 178, 180, 184, 185, 128, 181, 188, + 191, 128, 129, 131, 179, 181, 183, 140, + 143, 170, 174, 160, 164, 166, 175, 144, + 176, 175, 177, 191, 160, 191, 128, 130, + 170, 175, 153, 154, 153, 154, 155, 160, + 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 175, 175, 178, 180, 189, 158, + 159, 176, 177, 130, 134, 139, 163, 167, + 128, 129, 180, 255, 133, 159, 178, 255, + 166, 173, 135, 147, 128, 131, 179, 255, + 129, 164, 166, 255, 169, 182, 131, 140, + 141, 187, 189, 176, 178, 180, 183, 184, + 190, 191, 129, 171, 175, 181, 182, 163, + 170, 172, 173, 172, 184, 187, 190, 191, + 158, 128, 143, 160, 175, 185, 187, 144, + 145, 150, 155, 157, 158, 159, 135, 139, + 141, 168, 171, 189, 160, 182, 186, 191, + 129, 131, 133, 134, 140, 143, 184, 186, + 165, 166, 128, 129, 130, 132, 133, 134, + 135, 136, 139, 140, 141, 146, 147, 150, + 151, 152, 153, 154, 156, 128, 130, 184, + 255, 135, 190, 131, 175, 187, 188, 190, + 255, 128, 130, 167, 180, 179, 128, 130, + 179, 255, 129, 137, 141, 255, 172, 183, + 159, 170, 188, 128, 131, 190, 191, 151, + 128, 132, 135, 136, 139, 141, 162, 163, + 166, 172, 176, 180, 176, 255, 132, 255, + 175, 181, 184, 255, 129, 155, 158, 255, + 129, 255, 171, 183, 157, 171, 171, 172, + 189, 190, 176, 180, 176, 182, 145, 190, + 143, 146, 178, 157, 158, 160, 163, 133, + 134, 137, 168, 169, 170, 165, 169, 173, + 255, 131, 132, 140, 169, 174, 255, 130, + 132, 128, 182, 187, 255, 173, 180, 182, + 255, 132, 155, 159, 161, 175, 163, 144, + 150, 135, 160, 128, 129, 132, 135, 133, + 134, 129, 160, 255, 192, 255, 128, 128, + 129, 255, 155, 156, 151, 255, 156, 157, + 160, 181, 255, 158, 159, 186, 187, 255, + 162, 255, 160, 168, 161, 167, 158, 255, + 10, 13, 95, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 233, 234, 237, + 239, 240, 243, 11, 12, 48, 57, 65, + 90, 97, 122, 196, 218, 229, 232, 235, + 236, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 10, 39, + 44, 46, 59, 95, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 196, 218, 235, 236, 39, 44, 46, 59, + 95, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 196, 218, 235, + 236, 39, 46, 58, 95, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 196, 218, 235, 236, 39, 44, 46, + 59, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 196, 218, + 235, 236, 95, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 48, 57, 65, 90, 97, 122, 196, + 218, 235, 236, 34, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 196, 218, 235, 236, + 95, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 196, 218, 235, + 236, 95, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 196, 218, 235, 236, + 39, 46, 58, 95, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 196, 218, 235, 236, 95, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 196, 218, 235, 236, 95, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 196, 218, 235, 236, 133, 170, + 173, 181, 186, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 128, 150, 152, 182, 184, 255, + 39, 46, 58, 95, 173, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 196, 218, 235, 236, 39, 46, 58, + 95, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 0, + 47, 48, 57, 59, 64, 65, 90, 91, + 96, 97, 122, 123, 127, 196, 218, 235, + 236, 170, 173, 181, 183, 186, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 39, 46, 58, 95, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 176, 193, 196, 218, 228, 233, 235, 236, + 238, 255, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 65, 90, 97, 122, 196, 218, 235, 236, + 39, 44, 46, 59, 95, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 196, 218, 235, 236, 95, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 131, 137, + 196, 218, 235, 236, 39, 46, 58, 95, + 191, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 145, 189, 196, + 218, 235, 236, 39, 46, 58, 95, 135, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 129, 130, 132, 133, + 196, 218, 235, 236, 39, 46, 58, 95, + 156, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 128, 133, 144, + 154, 196, 218, 235, 236, 39, 46, 58, + 95, 176, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 139, 159, + 196, 218, 235, 236, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 150, 157, 159, 164, + 167, 168, 170, 173, 196, 218, 235, 236, + 39, 46, 58, 95, 143, 145, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 176, 193, 196, 218, 228, 233, + 235, 236, 238, 255, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 192, 255, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 128, 255, 39, 46, 58, 95, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 0, 47, 48, 57, + 59, 64, 65, 90, 91, 96, 97, 122, + 123, 138, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 166, 176, + 196, 218, 235, 236, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 171, 179, 196, 218, + 235, 236, 39, 46, 58, 95, 160, 161, + 163, 164, 165, 167, 169, 171, 173, 174, + 175, 176, 177, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 166, 170, 172, 178, + 196, 218, 235, 236, 39, 46, 58, 95, + 128, 129, 130, 141, 156, 157, 158, 159, + 160, 162, 164, 168, 169, 170, 172, 173, + 174, 175, 176, 179, 183, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 196, 218, 235, 236, 39, 46, 58, + 95, 128, 129, 131, 179, 181, 183, 194, + 195, 198, 199, 203, 204, 205, 206, 207, + 210, 212, 213, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 237, 239, 240, 243, 48, 57, 65, + 90, 97, 122, 196, 218, 235, 236, 39, + 46, 58, 95, 128, 130, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 196, 218, 235, 236, 39, 46, 58, + 95, 153, 154, 155, 160, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 175, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 196, 218, 235, 236, + 39, 46, 58, 95, 172, 184, 187, 190, + 191, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 196, 218, 235, + 236, 39, 46, 58, 95, 144, 145, 150, + 155, 157, 158, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 48, 57, 65, 90, 97, 122, 196, + 218, 235, 236, 39, 46, 58, 95, 160, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 196, 218, 235, 236, + 151, 173, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 130, + 133, 146, 159, 165, 171, 175, 255, 181, + 190, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 184, 185, + 192, 255, 135, 140, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 134, 138, 142, 161, 163, 255, 182, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 130, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 176, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 151, 152, + 154, 160, 190, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 136, 144, 192, 255, 135, 179, 180, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 129, 130, 132, 133, + 144, 170, 176, 178, 156, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 128, 133, 144, 154, 160, 191, + 171, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 128, 159, + 160, 169, 174, 255, 148, 158, 169, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 176, 185, 189, 190, + 192, 255, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 143, + 255, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 139, 140, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 178, 255, 186, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 128, 137, 138, + 181, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, + 191, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 128, 129, + 130, 131, 137, 138, 139, 140, 141, 142, + 143, 144, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 167, + 168, 169, 170, 172, 173, 174, 175, 176, + 177, 179, 181, 182, 183, 188, 189, 190, + 191, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 132, 152, + 180, 184, 185, 187, 128, 129, 130, 131, + 132, 133, 134, 146, 147, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 128, 130, 132, 133, 134, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 128, 146, 147, + 148, 152, 153, 154, 155, 156, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 129, 255, + 39, 46, 58, 95, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 150, 153, 155, 163, 165, 167, 169, 173, + 196, 218, 235, 236, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 153, 155, 196, 218, + 235, 236, 39, 46, 58, 95, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 163, 193, 196, 218, 228, 233, + 235, 236, 238, 255, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 39, 46, 58, 95, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 171, 190, 196, 218, 235, 236, 39, + 46, 58, 95, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 48, 57, 65, 90, 97, 122, 150, + 153, 158, 160, 162, 164, 167, 173, 177, + 180, 196, 218, 235, 236, 39, 46, 58, + 95, 143, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 130, 141, + 154, 157, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 157, 159, + 196, 218, 235, 236, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 146, 148, 178, 180, + 196, 218, 235, 236, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 146, 147, 178, 179, + 196, 218, 235, 236, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 180, 193, 196, 218, + 228, 233, 235, 236, 238, 255, 158, 159, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 160, 255, 172, + 173, 174, 175, 180, 181, 182, 183, 184, + 185, 187, 188, 189, 190, 191, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 176, 186, 144, 145, 146, + 147, 148, 150, 155, 157, 158, 159, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 160, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 39, 46, 58, 95, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 148, 156, 158, 193, 196, 218, + 228, 233, 235, 236, 238, 255, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 139, 142, + 196, 218, 235, 236, 39, 46, 58, 95, + 169, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 196, 218, 235, + 236, 39, 46, 58, 95, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 160, 171, 176, 187, 196, 218, 235, + 236, 39, 46, 58, 95, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 151, 155, 196, 218, 235, 236, 39, + 46, 58, 95, 191, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 149, 158, 160, 188, 196, 218, 235, 236, + 39, 46, 58, 95, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 176, 190, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 128, 132, + 180, 193, 196, 218, 228, 233, 235, 236, + 238, 255, 39, 46, 58, 95, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 133, 170, 180, 193, 196, 218, + 228, 233, 235, 236, 238, 255, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 128, 130, + 161, 173, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 166, 179, + 196, 218, 235, 236, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 164, 183, 196, 218, + 235, 236, 39, 46, 58, 95, 173, 194, + 195, 198, 199, 203, 204, 205, 206, 207, + 210, 212, 213, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 237, 239, 240, 243, 48, 57, 65, + 90, 97, 122, 144, 146, 148, 168, 178, + 180, 184, 185, 196, 218, 235, 236, 39, + 46, 58, 95, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 48, 57, 65, 90, 97, 122, 128, + 181, 188, 191, 196, 218, 235, 236, 39, + 46, 58, 95, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 48, 57, 65, 90, 97, 122, 140, + 143, 170, 174, 196, 218, 235, 236, 39, + 46, 58, 95, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 48, 57, 65, 90, 97, 122, 160, + 164, 166, 175, 196, 218, 235, 236, 39, + 46, 58, 95, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 48, 57, 65, 90, 97, 122, 144, + 176, 196, 218, 235, 236, 39, 46, 58, + 95, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 175, 177, 196, + 218, 235, 236, 39, 46, 58, 95, 191, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 196, 218, 235, 236, + 39, 46, 58, 95, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 160, 191, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 170, 175, + 196, 218, 235, 236, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 153, 154, 196, 218, + 235, 236, 39, 46, 58, 95, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 175, 178, 180, 189, 196, 218, + 235, 236, 39, 46, 58, 95, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 158, 159, 196, 218, 235, 236, + 39, 46, 58, 95, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 176, 177, 196, 218, 235, 236, 39, 46, + 58, 95, 130, 134, 139, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 163, 167, 196, 218, 235, 236, 39, + 46, 58, 95, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 48, 57, 65, 90, 97, 122, 128, + 129, 180, 193, 196, 218, 228, 233, 235, + 236, 238, 255, 39, 46, 58, 95, 194, + 195, 198, 199, 203, 204, 205, 206, 207, + 210, 212, 213, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 237, 239, 240, 243, 48, 57, 65, + 90, 97, 122, 133, 159, 178, 193, 196, + 218, 228, 233, 235, 236, 238, 255, 39, + 46, 58, 95, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 48, 57, 65, 90, 97, 122, 166, + 173, 196, 218, 235, 236, 39, 46, 58, + 95, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 135, 147, 196, + 218, 235, 236, 39, 46, 58, 95, 194, + 195, 198, 199, 203, 204, 205, 206, 207, + 210, 212, 213, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 237, 239, 240, 243, 48, 57, 65, + 90, 97, 122, 128, 131, 179, 193, 196, + 218, 228, 233, 235, 236, 238, 255, 39, + 46, 58, 95, 165, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 0, 47, 48, 57, 59, 64, + 65, 90, 91, 96, 97, 122, 123, 128, + 196, 218, 235, 236, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 169, 182, 196, 218, + 235, 236, 39, 46, 58, 95, 131, 194, + 195, 198, 199, 203, 204, 205, 206, 207, + 210, 212, 213, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 237, 239, 240, 243, 48, 57, 65, + 90, 97, 122, 140, 141, 187, 189, 196, + 218, 235, 236, 39, 46, 58, 95, 176, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 178, 180, 183, 184, + 190, 191, 196, 218, 235, 236, 39, 46, + 58, 95, 129, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 48, 57, 65, 90, 97, 122, 171, + 175, 181, 182, 196, 218, 235, 236, 39, + 46, 58, 95, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 48, 57, 65, 90, 97, 122, 163, + 170, 172, 173, 196, 218, 235, 236, 39, + 46, 58, 95, 158, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 196, 218, 235, 236, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 128, 143, 160, 175, + 196, 218, 235, 236, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 185, 187, 196, 218, + 235, 236, 39, 46, 58, 95, 135, 139, + 141, 168, 171, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 48, 57, 65, 90, 97, 122, 196, + 218, 235, 236, 39, 46, 58, 95, 128, + 129, 130, 132, 133, 134, 135, 136, 139, + 140, 141, 146, 147, 150, 151, 152, 153, + 154, 156, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 196, 218, + 235, 236, 39, 46, 58, 95, 171, 172, + 189, 190, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 196, 218, + 235, 236, 39, 46, 58, 95, 178, 194, + 195, 198, 199, 203, 204, 205, 206, 207, + 210, 212, 213, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 237, 239, 240, 243, 48, 57, 65, + 90, 97, 122, 196, 218, 235, 236, 39, + 46, 58, 95, 133, 134, 137, 168, 169, + 170, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 196, 218, 235, + 236, 39, 46, 58, 95, 163, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 196, 218, 235, 236, 39, 46, + 58, 95, 128, 129, 132, 135, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 133, 134, 196, 218, 235, 236, + 39, 46, 58, 95, 189, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 132, 185, 196, 218, 235, 236, 39, + 46, 58, 95, 144, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 152, 161, 164, 193, 196, 218, 228, 233, + 235, 236, 238, 255, 39, 46, 58, 95, + 188, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 129, 131, 190, + 193, 196, 218, 228, 233, 235, 236, 238, + 255, 39, 46, 58, 95, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 133, 134, 137, 138, 142, 150, 152, + 161, 164, 193, 196, 218, 228, 233, 235, + 236, 238, 255, 39, 46, 58, 95, 145, + 181, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 0, + 47, 48, 57, 59, 64, 65, 90, 91, + 96, 97, 122, 123, 130, 135, 136, 139, + 141, 176, 177, 196, 218, 235, 236, 39, + 46, 58, 95, 134, 138, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 142, 161, 164, 193, 196, 218, 228, + 233, 235, 236, 238, 255, 39, 46, 58, + 95, 188, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 129, 131, + 190, 191, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 128, 132, + 135, 136, 139, 141, 150, 151, 162, 163, + 196, 218, 235, 236, 39, 46, 58, 95, + 130, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 190, 191, 196, + 218, 235, 236, 39, 46, 58, 95, 151, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 128, 130, 134, 136, + 138, 141, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 128, 131, + 190, 193, 196, 218, 228, 233, 235, 236, + 238, 255, 39, 46, 58, 95, 133, 137, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 142, 148, 151, 161, + 164, 193, 196, 218, 228, 233, 235, 236, + 238, 255, 39, 46, 58, 95, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 128, 132, 134, 136, 138, 141, + 149, 150, 162, 163, 196, 218, 235, 236, + 39, 46, 58, 95, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 129, 131, 190, 193, 196, 218, 228, 233, + 235, 236, 238, 255, 39, 46, 58, 95, + 133, 137, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 142, 150, + 152, 161, 164, 193, 196, 218, 228, 233, + 235, 236, 238, 255, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 130, 131, 196, 218, + 235, 236, 39, 46, 58, 95, 138, 150, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 143, 148, 152, 159, + 178, 179, 196, 218, 235, 236, 39, 46, + 58, 95, 177, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 48, 57, 65, 90, 97, 122, 180, + 186, 196, 218, 235, 236, 39, 46, 58, + 95, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 135, 142, 196, + 218, 235, 236, 39, 46, 58, 95, 177, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 180, 185, 187, 188, + 196, 218, 235, 236, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 136, 141, 196, 218, + 235, 236, 39, 46, 58, 95, 181, 183, + 185, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 152, 153, 190, + 191, 196, 218, 235, 236, 39, 46, 58, + 95, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 177, 191, 196, + 218, 235, 236, 39, 46, 58, 95, 194, + 195, 198, 199, 203, 204, 205, 206, 207, + 210, 212, 213, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 237, 239, 240, 243, 48, 57, 65, + 90, 97, 122, 128, 132, 134, 135, 141, + 151, 153, 188, 196, 218, 235, 236, 39, + 46, 58, 95, 134, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 196, 218, 235, 236, 173, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 130, 133, 146, 159, 165, 171, + 175, 255, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 128, + 255, 173, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 128, 255, 173, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 176, 255, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 131, 137, 191, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 145, 189, 135, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 129, 130, 132, 133, 156, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 128, 133, 144, 154, 176, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 139, 159, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 150, 157, 159, 164, 167, + 168, 170, 173, 143, 145, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 176, 255, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 176, 255, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 131, 137, 191, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 145, 189, 135, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 129, 130, 132, 133, 156, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 128, 133, 144, 154, 176, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 139, 159, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 150, 157, 159, 164, 167, + 168, 170, 173, 143, 145, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 176, 255, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 139, 255, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 166, 176, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 171, + 179, 160, 161, 163, 164, 165, 167, 169, + 171, 173, 174, 175, 176, 177, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 166, 170, 172, 178, 128, 129, 130, 141, + 156, 157, 158, 159, 160, 162, 164, 168, + 169, 170, 172, 173, 174, 175, 176, 179, + 183, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 128, 129, + 131, 179, 181, 183, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 128, 130, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 153, 154, 155, 160, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 175, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 172, 184, 187, 190, + 191, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 144, 145, + 150, 155, 157, 158, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 160, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 139, 255, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 166, 176, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 171, 179, 160, 161, 163, 164, + 165, 167, 169, 171, 173, 174, 175, 176, + 177, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 166, 170, 172, 178, 128, + 129, 130, 141, 156, 157, 158, 159, 160, + 162, 164, 168, 169, 170, 172, 173, 174, + 175, 176, 179, 183, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 128, 129, 131, 179, 181, 183, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 128, 130, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 153, 154, 155, 160, 162, + 163, 164, 165, 166, 167, 168, 169, 170, + 171, 175, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 172, + 184, 187, 190, 191, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 144, 145, 150, 155, 157, 158, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 160, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 181, 190, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 176, 183, 184, 185, 186, 191, 192, + 255, 134, 140, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 136, 138, 142, 161, 163, 255, 130, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 131, 137, 190, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 136, 144, 145, 191, + 192, 255, 135, 179, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 129, 130, 132, 133, 144, 170, 176, + 178, 156, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 128, + 133, 144, 154, 160, 191, 171, 176, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 128, 138, 139, 159, + 160, 169, 174, 255, 148, 158, 169, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 150, 164, 167, 173, + 176, 185, 189, 190, 192, 255, 144, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 143, 145, 146, 175, + 176, 255, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 139, + 140, 141, 255, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 166, 176, 178, 255, 186, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 128, 137, 138, 170, 171, 179, + 180, 181, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 128, + 129, 130, 131, 132, 135, 137, 138, 139, + 140, 141, 142, 143, 144, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 167, 168, 169, 170, 172, 173, + 174, 175, 176, 177, 179, 181, 182, 183, + 188, 189, 190, 191, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 133, 134, 136, 152, 180, 184, 185, + 187, 39, 46, 58, 95, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 196, 218, 235, 236, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 235, 236, 128, 129, 130, + 131, 132, 133, 134, 146, 147, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 186, + 187, 188, 191, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 189, 190, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 128, + 129, 130, 131, 132, 133, 134, 135, 136, + 137, 139, 140, 141, 144, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 145, 255, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 196, 218, 235, 236, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 235, 236, + 95, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 150, 153, 155, + 163, 165, 167, 169, 173, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 153, 155, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 163, 255, 173, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 128, 255, + 173, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 128, 255, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 176, 255, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 131, 137, 191, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 145, 189, 135, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 129, 130, 132, 133, 156, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 128, 133, 144, 154, 176, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 139, 159, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 150, 157, 159, 164, + 167, 168, 170, 173, 143, 145, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 176, 255, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 176, 255, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 131, 137, 191, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 145, 189, 135, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 129, 130, 132, 133, 156, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 128, 133, 144, 154, 176, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 139, 159, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 150, 157, 159, 164, + 167, 168, 170, 173, 143, 145, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 176, 255, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 139, 255, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 166, 176, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 171, 179, 160, 161, 163, 164, 165, 167, + 169, 171, 173, 174, 175, 176, 177, 179, + 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 166, 170, 172, 178, 128, 129, 130, + 141, 156, 157, 158, 159, 160, 162, 164, + 168, 169, 170, 172, 173, 174, 175, 176, + 179, 183, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 128, + 129, 131, 179, 181, 183, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 128, 130, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 153, 154, 155, 160, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 175, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 172, 184, 187, + 190, 191, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 144, + 145, 150, 155, 157, 158, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 160, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 139, 255, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 166, 176, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 171, 179, 160, 161, 163, + 164, 165, 167, 169, 171, 173, 174, 175, + 176, 177, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 166, 170, 172, 178, + 128, 129, 130, 141, 156, 157, 158, 159, + 160, 162, 164, 168, 169, 170, 172, 173, + 174, 175, 176, 179, 183, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 128, 129, 131, 179, 181, 183, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 128, 130, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 153, 154, 155, 160, + 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 175, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 172, 184, 187, 190, 191, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 144, 145, 150, 155, 157, 158, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 160, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 189, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 132, 185, 144, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 152, 161, 164, 255, 188, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 129, 131, 190, 255, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 133, 134, 137, 138, + 142, 150, 152, 161, 164, 255, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 131, 134, 137, 138, 142, + 144, 146, 175, 178, 180, 182, 255, 134, + 138, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 142, 161, + 164, 255, 188, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 129, 131, 190, 191, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 128, 132, 135, 136, 139, 141, 150, + 151, 162, 163, 130, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 190, 191, 151, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 128, 130, 134, 136, 138, 141, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 128, 131, 190, 255, + 133, 137, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 142, + 148, 151, 161, 164, 255, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 128, 132, 134, 136, 138, 141, + 149, 150, 162, 163, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 129, 131, 190, 255, 133, 137, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 142, 150, 152, 161, + 164, 255, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 130, + 131, 138, 150, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 143, 148, 152, 159, 178, 179, 177, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 180, 186, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 135, 142, 177, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 180, 185, 187, 188, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 136, 141, 181, 183, + 185, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 152, 153, + 190, 191, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 177, + 191, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 128, 132, + 134, 135, 141, 151, 153, 188, 134, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 171, 190, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 150, 153, 158, 160, 162, 164, 167, 173, + 177, 180, 143, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 130, 141, 154, 157, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 157, 159, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 146, 148, 178, 180, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 146, 147, 178, 179, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 180, 255, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 148, 156, 158, 255, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 139, 142, 169, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 160, + 171, 176, 187, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 151, 155, 191, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 149, 158, 160, 188, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 176, 190, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 128, 132, 180, 255, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 133, 170, 180, 255, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 128, 130, 161, 173, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 166, 179, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 164, 183, 173, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 144, 146, 148, 168, 178, 180, + 184, 185, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 128, + 181, 188, 191, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 140, 143, 170, 174, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 160, 164, 166, 175, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 144, 176, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 175, 177, 191, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 160, 191, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 170, 175, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 153, 154, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 175, 178, 180, 189, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 158, 159, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 176, 177, 130, 134, 139, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 163, 167, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 128, 129, 180, 255, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 133, 159, 178, + 255, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 166, 173, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 135, 147, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 128, 131, 179, 255, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 129, 164, 166, + 255, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 169, 182, + 131, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 140, 141, + 187, 189, 176, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 178, 180, 183, 184, 190, 191, 129, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 171, 175, 181, 182, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 163, 170, 172, + 173, 158, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 128, 143, 160, 175, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 185, 187, 135, + 139, 141, 168, 171, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 128, 129, 130, 132, 133, 134, 135, + 136, 139, 140, 141, 146, 147, 150, 151, + 152, 153, 154, 156, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 171, 172, 189, 190, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 178, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 133, 134, 137, 168, 169, 170, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 163, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 128, 129, 132, 135, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 133, 134, 182, 183, 184, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 191, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 192, + 255, 128, 146, 147, 148, 152, 153, 154, + 155, 156, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 129, 157, 177, 255, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 196, 218, + 235, 236, 39, 46, 58, 95, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 150, 153, 155, 163, 165, 167, + 169, 173, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 153, 155, + 196, 218, 235, 236, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 163, 193, 196, 218, + 228, 233, 235, 236, 238, 255, 170, 173, + 181, 183, 186, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 128, 255, 39, + 46, 58, 95, 173, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 196, 218, 235, 236, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 0, 47, + 48, 57, 59, 64, 65, 90, 91, 96, + 97, 122, 123, 127, 196, 218, 235, 236, + 181, 190, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 176, + 183, 184, 185, 186, 191, 192, 255, 130, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 131, 137, 190, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 136, 144, 145, + 191, 192, 255, 135, 179, 180, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 129, 130, 132, 133, 144, + 170, 176, 178, 156, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 128, 133, 144, 154, 160, 191, 171, + 176, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 128, 138, + 139, 159, 160, 169, 174, 255, 148, 158, + 169, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 150, 164, + 167, 173, 176, 185, 189, 190, 192, 255, + 144, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 143, 145, + 146, 175, 176, 255, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 176, 193, 196, 218, + 228, 233, 235, 236, 238, 255, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 131, 137, + 196, 218, 235, 236, 39, 46, 58, 95, + 191, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 145, 189, 196, + 218, 235, 236, 39, 46, 58, 95, 135, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 129, 130, 132, 133, + 196, 218, 235, 236, 39, 46, 58, 95, + 156, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 128, 133, 144, + 154, 196, 218, 235, 236, 39, 46, 58, + 95, 176, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 139, 159, + 196, 218, 235, 236, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 150, 157, 159, 164, + 167, 168, 170, 173, 196, 218, 235, 236, + 39, 46, 58, 95, 143, 145, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 176, 193, 196, 218, 228, 233, + 235, 236, 238, 255, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 139, 140, 141, 255, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 166, 176, 178, 255, 186, 194, + 204, 205, 210, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 239, 240, 243, 128, 137, 138, 170, + 171, 179, 180, 181, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 194, 204, 205, 210, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 239, 240, + 243, 128, 129, 130, 131, 132, 135, 137, + 138, 139, 140, 141, 142, 143, 144, 153, + 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 167, 168, 169, 170, + 172, 173, 174, 175, 176, 177, 179, 181, + 182, 183, 188, 189, 190, 191, 194, 204, + 205, 210, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 239, 240, 243, 133, 134, 136, 152, 180, + 184, 185, 187, 128, 129, 130, 131, 132, + 133, 134, 146, 147, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 194, 204, 205, + 210, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 239, + 240, 243, 128, 130, 132, 133, 134, 136, + 137, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 128, 146, + 147, 148, 152, 153, 154, 155, 156, 158, + 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 129, + 157, 177, 255, 39, 46, 58, 95, 194, + 195, 198, 199, 203, 204, 205, 206, 207, + 210, 212, 213, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 237, 239, 240, 243, 48, 57, 65, + 90, 97, 122, 171, 190, 196, 218, 235, + 236, 39, 46, 58, 95, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 150, 153, 158, 160, 162, 164, 167, + 173, 177, 180, 196, 218, 235, 236, 39, + 46, 58, 95, 143, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 130, 141, 154, 157, 196, 218, 235, 236, + 39, 46, 58, 95, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 157, 159, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 146, 148, + 178, 180, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 146, 147, + 178, 179, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 180, 193, + 196, 218, 228, 233, 235, 236, 238, 255, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 39, 46, 58, + 95, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 140, 143, 170, + 174, 196, 218, 235, 236, 39, 46, 58, + 95, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 160, 164, 166, + 175, 196, 218, 235, 236, 39, 46, 58, + 95, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 144, 176, 196, + 218, 235, 236, 39, 46, 58, 95, 194, + 195, 198, 199, 203, 204, 205, 206, 207, + 210, 212, 213, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 237, 239, 240, 243, 48, 57, 65, + 90, 97, 122, 175, 177, 196, 218, 235, + 236, 39, 46, 58, 95, 191, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 160, 191, + 196, 218, 235, 236, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 170, 175, 196, 218, + 235, 236, 39, 46, 58, 95, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 153, 154, 196, 218, 235, 236, + 39, 46, 58, 95, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 175, 178, 180, 189, 196, 218, 235, 236, + 39, 46, 58, 95, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 158, 159, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 176, 177, + 196, 218, 235, 236, 39, 46, 58, 95, + 130, 134, 139, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 48, 57, 65, 90, 97, 122, 163, + 167, 196, 218, 235, 236, 39, 46, 58, + 95, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 128, 129, 180, + 193, 196, 218, 228, 233, 235, 236, 238, + 255, 158, 159, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 160, 255, 172, 173, 174, 175, 180, 181, + 182, 183, 184, 185, 187, 188, 189, 190, + 191, 194, 204, 205, 210, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 239, 240, 243, 176, 186, + 144, 145, 146, 147, 148, 150, 155, 157, + 158, 159, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, 160, + 194, 204, 205, 210, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 239, 240, 243, 39, 46, 58, + 95, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 133, 159, 178, + 193, 196, 218, 228, 233, 235, 236, 238, + 255, 39, 46, 58, 95, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 166, 173, 196, 218, 235, 236, 39, + 46, 58, 95, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 48, 57, 65, 90, 97, 122, 135, + 147, 196, 218, 235, 236, 39, 46, 58, + 95, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 128, 131, 179, + 193, 196, 218, 228, 233, 235, 236, 238, + 255, 39, 46, 58, 95, 165, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 0, 47, 48, 57, + 59, 64, 65, 90, 91, 96, 97, 122, + 123, 128, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 169, 182, + 196, 218, 235, 236, 39, 46, 58, 95, + 131, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 140, 141, 187, + 189, 196, 218, 235, 236, 39, 46, 58, + 95, 176, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 178, 180, + 183, 184, 190, 191, 196, 218, 235, 236, + 39, 46, 58, 95, 129, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 171, 175, 181, 182, 196, 218, 235, + 236, 39, 46, 58, 95, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 163, 170, 172, 173, 196, 218, 235, + 236, 39, 46, 58, 95, 158, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 128, 143, + 160, 175, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 185, 187, + 196, 218, 235, 236, 39, 46, 58, 95, + 135, 139, 141, 168, 171, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 196, 218, 235, 236, 39, 46, 58, + 95, 128, 129, 130, 132, 133, 134, 135, + 136, 139, 140, 141, 146, 147, 150, 151, + 152, 153, 154, 156, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 196, 218, 235, 236, 39, 46, 58, 95, + 171, 172, 189, 190, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 196, 218, 235, 236, 39, 46, 58, 95, + 178, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 196, 218, 235, + 236, 39, 46, 58, 95, 133, 134, 137, + 168, 169, 170, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 48, 57, 65, 90, 97, 122, 196, + 218, 235, 236, 39, 46, 58, 95, 163, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 196, 218, 235, 236, + 39, 46, 58, 95, 128, 129, 132, 135, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 133, 134, 196, 218, + 235, 236, 39, 46, 58, 95, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 148, 156, 158, 193, 196, 218, + 228, 233, 235, 236, 238, 255, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 139, 142, + 196, 218, 235, 236, 39, 46, 58, 95, + 169, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 196, 218, 235, + 236, 39, 46, 58, 95, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 160, 171, 176, 187, 196, 218, 235, + 236, 39, 46, 58, 95, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 151, 155, 196, 218, 235, 236, 39, + 46, 58, 95, 191, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 149, 158, 160, 188, 196, 218, 235, 236, + 39, 46, 58, 95, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 176, 190, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 128, 132, + 180, 193, 196, 218, 228, 233, 235, 236, + 238, 255, 39, 46, 58, 95, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 133, 170, 180, 193, 196, 218, + 228, 233, 235, 236, 238, 255, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 128, 130, + 161, 173, 196, 218, 235, 236, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 166, 179, + 196, 218, 235, 236, 39, 46, 58, 95, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 164, 183, 196, 218, + 235, 236, 39, 46, 58, 95, 173, 194, + 195, 198, 199, 203, 204, 205, 206, 207, + 210, 212, 213, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 237, 239, 240, 243, 48, 57, 65, + 90, 97, 122, 144, 146, 148, 168, 178, + 180, 184, 185, 196, 218, 235, 236, 39, + 46, 58, 95, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 48, 57, 65, 90, 97, 122, 128, + 181, 188, 191, 196, 218, 235, 236, 39, + 46, 58, 95, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 0, 47, 48, 57, 59, 64, 65, + 90, 91, 96, 97, 122, 123, 138, 196, + 218, 235, 236, 39, 46, 58, 95, 194, + 195, 198, 199, 203, 204, 205, 206, 207, + 210, 212, 213, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 237, 239, 240, 243, 48, 57, 65, + 90, 97, 122, 166, 176, 196, 218, 235, + 236, 39, 46, 58, 95, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 171, 179, 196, 218, 235, 236, 39, + 46, 58, 95, 160, 161, 163, 164, 165, + 167, 169, 171, 173, 174, 175, 176, 177, + 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 166, 170, 172, 178, 196, 218, 235, + 236, 39, 46, 58, 95, 128, 129, 130, + 141, 156, 157, 158, 159, 160, 162, 164, + 168, 169, 170, 172, 173, 174, 175, 176, + 179, 183, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 196, 218, + 235, 236, 39, 46, 58, 95, 128, 129, + 131, 179, 181, 183, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 196, 218, 235, 236, 39, 46, 58, 95, + 128, 130, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 196, 218, + 235, 236, 39, 46, 58, 95, 153, 154, + 155, 160, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 175, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 196, 218, 235, 236, 39, 46, 58, + 95, 172, 184, 187, 190, 191, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 196, 218, 235, 236, 39, 46, + 58, 95, 144, 145, 150, 155, 157, 158, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 196, 218, 235, 236, + 39, 46, 58, 95, 160, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 196, 218, 235, 236, 39, 46, 58, + 95, 189, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 132, 185, + 196, 218, 235, 236, 39, 46, 58, 95, + 144, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 152, 161, 164, + 193, 196, 218, 228, 233, 235, 236, 238, + 255, 39, 46, 58, 95, 188, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 129, 131, 190, 193, 196, 218, + 228, 233, 235, 236, 238, 255, 39, 46, + 58, 95, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 133, 134, + 137, 138, 142, 150, 152, 161, 164, 193, + 196, 218, 228, 233, 235, 236, 238, 255, + 39, 46, 58, 95, 145, 181, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 0, 47, 48, 57, + 59, 64, 65, 90, 91, 96, 97, 122, + 123, 130, 135, 136, 139, 141, 176, 177, + 196, 218, 235, 236, 39, 46, 58, 95, + 134, 138, 194, 195, 198, 199, 203, 204, + 205, 206, 207, 210, 212, 213, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 237, 239, 240, 243, + 48, 57, 65, 90, 97, 122, 142, 161, + 164, 193, 196, 218, 228, 233, 235, 236, + 238, 255, 39, 46, 58, 95, 188, 194, + 195, 198, 199, 203, 204, 205, 206, 207, + 210, 212, 213, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 237, 239, 240, 243, 48, 57, 65, + 90, 97, 122, 129, 131, 190, 191, 196, + 218, 235, 236, 39, 46, 58, 95, 194, + 195, 198, 199, 203, 204, 205, 206, 207, + 210, 212, 213, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 237, 239, 240, 243, 48, 57, 65, + 90, 97, 122, 128, 132, 135, 136, 139, + 141, 150, 151, 162, 163, 196, 218, 235, + 236, 39, 46, 58, 95, 130, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 190, 191, 196, 218, 235, 236, + 39, 46, 58, 95, 151, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 128, 130, 134, 136, 138, 141, 196, + 218, 235, 236, 39, 46, 58, 95, 194, + 195, 198, 199, 203, 204, 205, 206, 207, + 210, 212, 213, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 237, 239, 240, 243, 48, 57, 65, + 90, 97, 122, 128, 131, 190, 193, 196, + 218, 228, 233, 235, 236, 238, 255, 39, + 46, 58, 95, 133, 137, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 142, 148, 151, 161, 164, 193, 196, + 218, 228, 233, 235, 236, 238, 255, 39, + 46, 58, 95, 194, 195, 198, 199, 203, + 204, 205, 206, 207, 210, 212, 213, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 237, 239, 240, + 243, 48, 57, 65, 90, 97, 122, 128, + 132, 134, 136, 138, 141, 149, 150, 162, + 163, 196, 218, 235, 236, 39, 46, 58, + 95, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 129, 131, 190, + 193, 196, 218, 228, 233, 235, 236, 238, + 255, 39, 46, 58, 95, 133, 137, 194, + 195, 198, 199, 203, 204, 205, 206, 207, + 210, 212, 213, 214, 215, 216, 217, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 234, 237, 239, 240, 243, 48, 57, 65, + 90, 97, 122, 142, 150, 152, 161, 164, + 193, 196, 218, 228, 233, 235, 236, 238, + 255, 39, 46, 58, 95, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 130, 131, 196, 218, 235, 236, 39, + 46, 58, 95, 138, 150, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 143, 148, 152, 159, 178, 179, 196, + 218, 235, 236, 39, 46, 58, 95, 177, + 194, 195, 198, 199, 203, 204, 205, 206, + 207, 210, 212, 213, 214, 215, 216, 217, + 219, 220, 221, 222, 223, 224, 225, 226, + 227, 234, 237, 239, 240, 243, 48, 57, + 65, 90, 97, 122, 180, 186, 196, 218, + 235, 236, 39, 46, 58, 95, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 135, 142, 196, 218, 235, 236, + 39, 46, 58, 95, 177, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 180, 185, 187, 188, 196, 218, 235, + 236, 39, 46, 58, 95, 194, 195, 198, + 199, 203, 204, 205, 206, 207, 210, 212, + 213, 214, 215, 216, 217, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 234, 237, + 239, 240, 243, 48, 57, 65, 90, 97, + 122, 136, 141, 196, 218, 235, 236, 39, + 46, 58, 95, 181, 183, 185, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 152, 153, 190, 191, 196, 218, + 235, 236, 39, 46, 58, 95, 194, 195, + 198, 199, 203, 204, 205, 206, 207, 210, + 212, 213, 214, 215, 216, 217, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 234, + 237, 239, 240, 243, 48, 57, 65, 90, + 97, 122, 177, 191, 196, 218, 235, 236, + 39, 46, 58, 95, 194, 195, 198, 199, + 203, 204, 205, 206, 207, 210, 212, 213, + 214, 215, 216, 217, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 234, 237, 239, + 240, 243, 48, 57, 65, 90, 97, 122, + 128, 132, 134, 135, 141, 151, 153, 188, + 196, 218, 235, 236, 39, 46, 58, 95, + 134, 194, 195, 198, 199, 203, 204, 205, + 206, 207, 210, 212, 213, 214, 215, 216, + 217, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 234, 237, 239, 240, 243, 48, + 57, 65, 90, 97, 122, 196, 218, 235, + 236, 164, 169, 171, 172, 173, 174, 175, + 180, 181, 182, 183, 184, 185, 187, 188, + 189, 190, 191, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 165, 170, 176, 186, 144, 145, 146, 147, + 148, 150, 155, 157, 158, 159, 160, 170, + 171, 172, 175, 194, 204, 205, 210, 214, + 215, 216, 217, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 234, 239, 240, 243, + 161, 169, 194, 204, 205, 210, 214, 215, + 216, 217, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 234, 239, 240, 243, +} + +var _s_single_lengths []byte = []byte{ + 1, 0, 0, 0, 1, 1, 1, 1, + 0, 2, 0, 0, 0, 26, 0, 0, + 0, 1, 1, 1, 0, 0, 2, 1, + 0, 1, 1, 0, 2, 0, 0, 2, + 0, 2, 1, 0, 1, 0, 3, 0, + 0, 1, 21, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 1, 0, + 6, 0, 0, 0, 0, 1, 0, 2, + 0, 0, 15, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 1, 1, + 1, 0, 5, 1, 0, 0, 6, 5, + 1, 1, 0, 1, 0, 19, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 1, 0, 6, + 0, 0, 0, 0, 0, 1, 1, 0, + 1, 4, 1, 0, 0, 21, 30, 4, + 0, 0, 0, 0, 1, 0, 2, 2, + 1, 1, 1, 0, 1, 1, 1, 1, + 3, 1, 0, 0, 1, 32, 3, 0, + 0, 0, 1, 1, 4, 2, 1, 1, + 1, 4, 1, 1, 3, 2, 1, 3, + 1, 1, 1, 3, 1, 2, 1, 0, + 1, 0, 4, 0, 0, 1, 41, 0, + 0, 1, 2, 3, 2, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 4, 1, 0, 18, 0, + 2, 0, 0, 6, 1, 0, 0, 0, + 0, 1, 0, 2, 1, 0, 0, 1, + 5, 1, 0, 0, 0, 28, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 3, + 0, 0, 2, 0, 0, 0, 1, 0, + 1, 1, 1, 0, 1, 0, 0, 2, + 0, 0, 15, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 10, 35, 0, 0, 0, 0, + 1, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 24, 0, 0, 0, 0, 0, + 2, 0, 2, 0, 1, 0, 1, 2, + 0, 1, 0, 0, 1, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 2, 2, + 0, 10, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 18, 0, 0, 0, + 1, 4, 1, 4, 1, 0, 3, 2, + 2, 2, 1, 0, 0, 1, 5, 0, + 4, 12, 0, 3, 0, 0, 0, 1, + 4, 1, 0, 0, 0, 21, 1, 0, + 0, 0, 1, 1, 1, 2, 0, 2, + 0, 0, 0, 26, 0, 0, 0, 1, + 1, 1, 0, 0, 2, 1, 0, 1, + 1, 0, 2, 0, 0, 2, 0, 2, + 1, 0, 1, 0, 3, 0, 0, 1, + 24, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 1, + 0, 6, 0, 0, 0, 0, 1, 0, + 2, 0, 0, 16, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 0, 5, 1, 0, 0, + 6, 6, 1, 1, 0, 1, 0, 22, + 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 0, 0, + 0, 1, 0, 7, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 1, 4, 1, + 0, 0, 4, 0, 2, 1, 1, 2, + 21, 1, 0, 0, 0, 1, 1, 4, + 0, 2, 1, 1, 2, 1, 2, 3, + 1, 0, 0, 1, 32, 3, 0, 0, + 1, 2, 4, 2, 1, 1, 1, 4, + 1, 1, 3, 2, 1, 3, 1, 1, + 1, 3, 1, 2, 1, 0, 1, 0, + 4, 0, 0, 1, 43, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 1, 0, + 0, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 18, 0, 3, 0, 0, + 1, 0, 5, 1, 0, 28, 0, 1, + 0, 0, 3, 0, 2, 0, 0, 0, + 1, 0, 1, 1, 1, 0, 15, 2, + 0, 0, 0, 1, 1, 0, 0, 10, + 35, 1, 1, 0, 0, 2, 0, 25, + 0, 0, 0, 0, 0, 2, 0, 1, + 0, 0, 1, 2, 0, 1, 0, 0, + 1, 0, 0, 0, 10, 0, 0, 0, + 0, 0, 0, 3, 0, 18, 0, 0, + 0, 1, 0, 0, 1, 5, 0, 1, + 4, 1, 0, 0, 0, 1, 1, 0, + 2, 0, 0, 0, 26, 0, 0, 0, + 1, 1, 1, 0, 0, 2, 1, 0, + 1, 1, 0, 2, 0, 0, 2, 0, + 2, 1, 0, 1, 0, 3, 0, 0, + 1, 21, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 1, 0, 6, + 0, 0, 0, 0, 1, 0, 2, 0, + 0, 15, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, + 0, 6, 2, 0, 0, 0, 6, 5, + 1, 1, 0, 1, 0, 19, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 1, 0, 6, + 0, 0, 0, 0, 0, 1, 1, 0, + 1, 4, 1, 0, 0, 5, 2, 0, + 2, 2, 1, 1, 3, 1, 2, 3, + 1, 0, 0, 1, 32, 3, 0, 0, + 1, 2, 4, 2, 1, 1, 1, 4, + 1, 1, 3, 2, 1, 3, 1, 1, + 1, 3, 1, 2, 1, 0, 1, 0, + 4, 0, 0, 1, 43, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 1, 0, + 0, 1, 0, 0, 0, 0, 0, 0, + 1, 0, 18, 2, 3, 0, 0, 1, + 0, 5, 1, 0, 28, 1, 0, 0, + 3, 0, 2, 0, 0, 0, 1, 0, + 1, 1, 1, 0, 15, 1, 1, 2, + 1, 4, 0, 0, 10, 35, 1, 1, + 0, 2, 0, 25, 0, 0, 0, 0, + 2, 0, 1, 0, 0, 1, 2, 0, + 1, 0, 0, 1, 0, 0, 10, 0, + 0, 0, 0, 3, 0, 18, 0, 0, + 0, 0, 0, 1, 5, 0, 1, 4, + 1, 0, 0, 0, 1, 2, 3, 1, + 0, 0, 1, 32, 3, 0, 0, 1, + 2, 4, 2, 1, 1, 1, 4, 1, + 1, 3, 2, 1, 3, 1, 1, 1, + 3, 1, 2, 1, 0, 1, 0, 4, + 0, 0, 1, 43, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 1, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 1, + 0, 18, 0, 3, 0, 0, 1, 0, + 10, 1, 1, 0, 0, 0, 1, 1, + 1, 1, 0, 2, 0, 0, 0, 26, + 0, 0, 0, 1, 1, 1, 0, 0, + 2, 1, 0, 1, 1, 0, 2, 0, + 0, 2, 0, 2, 1, 0, 1, 0, + 3, 0, 0, 1, 21, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 1, 0, + 0, 1, 0, 0, 0, 0, 0, 0, + 1, 0, 6, 0, 1, 0, 0, 1, + 0, 7, 0, 0, 1, 0, 0, 0, + 15, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 0, + 8, 1, 0, 0, 1, 0, 0, 0, + 6, 5, 1, 1, 0, 1, 0, 19, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 2, + 1, 0, 6, 0, 0, 0, 0, 0, + 1, 1, 0, 1, 4, 1, 0, 0, + 0, 28, 1, 0, 0, 3, 0, 2, + 0, 0, 0, 1, 0, 1, 1, 1, + 0, 15, 2, 0, 1, 0, 0, 0, + 10, 35, 1, 1, 0, 2, 0, 25, + 0, 0, 0, 0, 2, 0, 1, 0, + 0, 1, 2, 0, 1, 0, 0, 1, + 0, 0, 10, 0, 0, 0, 0, 4, + 0, 18, 0, 0, 0, 0, 0, 1, + 5, 0, 1, 4, 1, 0, 0, 0, + 4, 0, 2, 1, 2, 2, 1, 3, + 3, 1, 0, 0, 2, 32, 3, 0, + 0, 1, 2, 4, 2, 1, 1, 1, + 4, 1, 1, 3, 2, 1, 3, 1, + 1, 1, 3, 1, 2, 1, 0, 1, + 0, 4, 0, 0, 1, 43, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 1, 0, 18, 1, 4, 0, 0, + 1, 0, 5, 1, 0, 28, 1, 0, + 0, 3, 0, 2, 0, 0, 0, 1, + 0, 1, 1, 1, 0, 15, 2, 2, + 3, 1, 5, 0, 0, 10, 35, 1, + 1, 0, 2, 0, 25, 0, 0, 0, + 0, 2, 0, 1, 0, 0, 1, 2, + 0, 1, 0, 0, 1, 0, 0, 10, + 0, 0, 0, 0, 3, 0, 18, 0, + 0, 0, 0, 0, 1, 5, 0, 1, + 4, 1, 0, 0, 0, 5, 2, 1, + 1, 3, 1, 1, 3, 0, 0, 1, + 32, 0, 0, 0, 1, 3, 1, 1, + 1, 0, 2, 0, 1, 1, 2, 0, + 3, 0, 1, 0, 2, 1, 2, 1, + 0, 1, 0, 4, 0, 0, 1, 43, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 18, 2, 3, 0, 0, + 0, 0, 5, 1, 0, 28, 1, 0, + 1, 0, 0, 0, 0, 0, 1, 1, + 0, 15, 2, 1, 0, 0, 0, 10, + 35, 1, 0, 0, 1, 0, 23, 0, + 0, 0, 1, 1, 0, 0, 0, 2, + 1, 0, 0, 0, 0, 10, 0, 0, + 0, 3, 0, 18, 0, 0, 0, 0, + 0, 1, 5, 0, 1, 4, 1, 0, + 4, 0, 2, 1, 1, 2, 1, 2, + 3, 1, 0, 0, 1, 32, 3, 0, + 0, 1, 2, 4, 2, 1, 1, 1, + 4, 1, 1, 3, 2, 1, 3, 1, + 1, 1, 3, 1, 2, 1, 0, 1, + 0, 4, 0, 0, 1, 43, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 18, 0, + 3, 0, 0, 1, 0, 10, 1, 0, + 28, 0, 1, 0, 0, 3, 0, 2, + 0, 0, 0, 1, 0, 1, 1, 1, + 0, 15, 2, 0, 0, 1, 1, 0, + 0, 10, 35, 1, 1, 0, 0, 2, + 0, 25, 0, 0, 0, 0, 0, 2, + 0, 1, 0, 0, 1, 2, 0, 1, + 0, 0, 1, 0, 0, 0, 0, 10, + 0, 0, 0, 0, 0, 0, 4, 0, + 18, 0, 0, 0, 1, 0, 0, 1, + 5, 0, 1, 4, 1, 0, 0, 0, + 4, 0, 2, 1, 2, 2, 1, 3, + 3, 1, 0, 0, 2, 32, 3, 0, + 0, 1, 2, 4, 2, 1, 1, 1, + 4, 1, 1, 3, 2, 1, 3, 1, + 1, 1, 3, 1, 2, 1, 0, 1, + 0, 4, 0, 0, 1, 43, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 1, 0, 18, 1, 4, 0, 0, + 1, 0, 5, 1, 0, 28, 1, 0, + 0, 3, 0, 2, 0, 0, 0, 1, + 0, 1, 1, 1, 0, 15, 2, 2, + 3, 1, 5, 0, 0, 10, 35, 1, + 1, 0, 2, 0, 25, 0, 0, 0, + 0, 2, 0, 1, 0, 0, 1, 2, + 0, 1, 0, 0, 1, 0, 0, 10, + 0, 0, 0, 0, 3, 0, 18, 0, + 0, 0, 0, 0, 1, 5, 0, 1, + 4, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 1, 1, 2, 0, 2, 0, + 0, 0, 26, 0, 0, 0, 1, 1, + 1, 0, 0, 2, 1, 0, 1, 1, + 0, 2, 0, 0, 2, 0, 2, 1, + 0, 1, 0, 3, 0, 0, 1, 24, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 6, 0, + 0, 0, 0, 1, 0, 2, 0, 0, + 16, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, + 0, 5, 1, 0, 0, 6, 6, 1, + 1, 0, 1, 0, 22, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 1, 0, 7, + 0, 0, 0, 0, 0, 0, 1, 1, + 0, 1, 4, 1, 0, 0, 4, 0, + 2, 1, 2, 2, 1, 3, 3, 1, + 0, 0, 2, 32, 3, 0, 0, 1, + 2, 4, 2, 1, 1, 1, 4, 1, + 1, 3, 2, 1, 3, 1, 1, 1, + 3, 1, 2, 1, 0, 1, 0, 4, + 0, 0, 1, 43, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 1, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 1, + 0, 18, 1, 4, 0, 0, 1, 0, + 5, 1, 0, 28, 1, 0, 0, 3, + 0, 2, 0, 0, 0, 1, 0, 1, + 1, 1, 0, 15, 2, 2, 1, 0, + 0, 10, 35, 1, 1, 0, 2, 0, + 25, 0, 0, 0, 0, 2, 0, 1, + 0, 0, 1, 2, 0, 1, 0, 0, + 1, 0, 0, 10, 0, 0, 0, 0, + 3, 0, 18, 0, 0, 0, 0, 0, + 1, 5, 0, 1, 4, 1, 0, 0, + 0, 5, 0, 2, 1, 1, 3, 1, + 2, 3, 1, 0, 0, 1, 32, 3, + 0, 0, 1, 2, 4, 2, 1, 1, + 1, 4, 1, 1, 3, 2, 1, 3, + 1, 1, 1, 3, 1, 2, 1, 0, + 1, 0, 4, 0, 0, 1, 43, 0, + 0, 1, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 1, 0, 18, 2, 3, 0, + 0, 1, 0, 5, 1, 0, 28, 1, + 0, 0, 3, 0, 2, 0, 0, 0, + 1, 0, 1, 1, 1, 0, 15, 2, + 1, 1, 0, 0, 10, 35, 1, 1, + 0, 2, 0, 25, 0, 0, 0, 0, + 2, 0, 1, 0, 0, 1, 2, 0, + 1, 0, 0, 1, 0, 0, 10, 0, + 0, 0, 0, 3, 0, 18, 0, 0, + 0, 0, 0, 1, 5, 0, 1, 4, + 1, 0, 0, 0, 4, 0, 2, 1, + 1, 2, 1, 2, 3, 1, 0, 0, + 1, 32, 3, 0, 0, 1, 2, 4, + 2, 1, 1, 1, 4, 1, 1, 3, + 2, 1, 3, 1, 1, 1, 3, 1, + 2, 1, 0, 1, 0, 4, 0, 0, + 1, 43, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 1, 0, 18, + 0, 3, 0, 0, 1, 0, 10, 1, + 0, 28, 1, 0, 0, 3, 0, 2, + 0, 0, 0, 1, 0, 1, 1, 1, + 0, 15, 2, 0, 0, 1, 1, 0, + 0, 10, 35, 1, 1, 0, 2, 0, + 25, 0, 0, 0, 0, 2, 0, 1, + 0, 0, 1, 2, 0, 1, 0, 0, + 1, 0, 0, 10, 0, 0, 0, 0, + 4, 0, 18, 0, 0, 0, 0, 0, + 1, 5, 0, 1, 4, 1, 0, 0, + 0, 4, 0, 2, 1, 1, 2, 1, + 2, 3, 1, 0, 0, 1, 32, 3, + 0, 0, 1, 2, 4, 2, 1, 1, + 1, 4, 1, 1, 3, 2, 1, 3, + 1, 1, 1, 3, 1, 2, 1, 0, + 1, 0, 4, 0, 0, 1, 43, 0, + 0, 1, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 1, 0, 18, 0, 3, 0, + 0, 1, 0, 10, 1, 0, 28, 1, + 0, 0, 3, 0, 2, 0, 0, 0, + 1, 0, 1, 1, 1, 0, 15, 2, + 0, 1, 0, 0, 10, 35, 1, 1, + 0, 2, 0, 25, 0, 0, 0, 0, + 2, 0, 1, 0, 0, 1, 2, 0, + 1, 0, 0, 1, 0, 0, 10, 0, + 0, 0, 0, 4, 0, 18, 0, 0, + 0, 0, 0, 1, 5, 0, 1, 4, + 1, 0, 0, 0, 1, 0, 0, 0, + 1, 1, 1, 1, 0, 2, 0, 0, + 0, 26, 0, 0, 0, 1, 1, 1, + 0, 0, 2, 1, 0, 1, 1, 0, + 2, 0, 0, 2, 0, 2, 1, 0, + 1, 0, 3, 0, 0, 1, 21, 0, + 0, 1, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 1, 0, 6, 0, 0, 0, + 0, 1, 0, 2, 0, 0, 15, 0, + 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 5, 1, + 0, 0, 6, 5, 1, 1, 0, 1, + 0, 19, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, + 0, 1, 0, 6, 0, 0, 0, 0, + 0, 1, 1, 0, 1, 4, 1, 0, + 0, 4, 0, 2, 1, 1, 1, 1, + 1, 3, 1, 0, 0, 1, 32, 3, + 0, 0, 1, 1, 4, 2, 1, 1, + 1, 4, 1, 1, 3, 2, 1, 3, + 1, 1, 1, 3, 1, 2, 1, 0, + 1, 0, 4, 0, 0, 1, 41, 0, + 0, 1, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 1, 0, 18, 0, 2, 0, + 0, 1, 0, 5, 1, 0, 28, 1, + 0, 0, 3, 0, 2, 0, 0, 0, + 1, 0, 1, 1, 1, 0, 15, 2, + 0, 1, 0, 0, 10, 35, 1, 1, + 0, 2, 0, 24, 0, 0, 0, 0, + 2, 0, 2, 0, 0, 1, 2, 0, + 1, 0, 0, 1, 0, 0, 10, 0, + 0, 0, 0, 3, 0, 18, 0, 0, + 0, 0, 0, 1, 5, 0, 1, 4, + 1, 0, 0, 0, 4, 0, 2, 1, + 2, 2, 1, 3, 3, 1, 0, 0, + 2, 32, 3, 0, 0, 1, 2, 4, + 2, 1, 1, 1, 4, 1, 1, 3, + 2, 1, 3, 1, 1, 1, 3, 1, + 2, 1, 0, 1, 0, 4, 0, 0, + 1, 43, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 1, 0, 18, + 1, 4, 0, 0, 1, 0, 5, 1, + 0, 28, 1, 0, 0, 3, 0, 2, + 0, 0, 0, 1, 0, 1, 1, 1, + 0, 15, 2, 2, 1, 0, 0, 10, + 35, 1, 1, 0, 2, 0, 25, 0, + 0, 0, 0, 2, 0, 1, 0, 0, + 1, 2, 0, 1, 0, 0, 1, 0, + 0, 10, 0, 0, 0, 0, 3, 0, + 18, 0, 0, 0, 0, 0, 1, 5, + 0, 1, 4, 1, 0, 0, 0, 4, + 0, 2, 1, 1, 2, 1, 2, 3, + 1, 0, 0, 1, 32, 3, 0, 0, + 1, 2, 4, 2, 1, 1, 1, 4, + 1, 1, 3, 2, 1, 3, 1, 1, + 1, 3, 1, 2, 1, 0, 1, 0, + 4, 0, 0, 1, 43, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 1, 0, + 0, 1, 0, 0, 0, 0, 0, 0, + 1, 0, 18, 0, 3, 0, 0, 1, + 0, 10, 1, 0, 28, 1, 0, 0, + 3, 0, 2, 0, 0, 0, 1, 0, + 1, 1, 1, 0, 15, 2, 0, 1, + 0, 0, 10, 35, 1, 1, 0, 2, + 0, 25, 0, 0, 0, 0, 2, 0, + 1, 0, 0, 1, 2, 0, 1, 0, + 0, 1, 0, 0, 10, 0, 0, 0, + 0, 4, 0, 18, 0, 0, 0, 0, + 0, 1, 5, 0, 1, 4, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 1, + 1, 1, 0, 2, 0, 0, 0, 26, + 21, 6, 2, 15, 5, 6, 1, 3, + 0, 1, 2, 4, 2, 1, 1, 1, + 4, 1, 1, 3, 2, 1, 3, 1, + 1, 1, 3, 1, 2, 0, 0, 4, + 0, 0, 0, 1, 0, 5, 0, 2, + 1, 1, 3, 1, 2, 3, 1, 0, + 0, 1, 32, 3, 0, 0, 1, 2, + 4, 2, 1, 1, 1, 4, 1, 1, + 3, 2, 1, 3, 1, 1, 1, 3, + 1, 2, 1, 0, 1, 0, 4, 0, + 0, 1, 45, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 0, 1, 0, 0, 0, 0, 0, 0, + 1, 0, 18, 2, 3, 0, 0, 1, + 0, 7, 1, 0, 0, 0, 0, 1, + 0, 0, 0, 1, 1, 1, 1, 0, + 2, 0, 0, 0, 26, 0, 0, 0, + 1, 1, 1, 0, 0, 2, 1, 0, + 1, 1, 0, 2, 0, 0, 2, 0, + 2, 1, 0, 1, 0, 3, 0, 0, + 1, 23, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 1, + 0, 6, 0, 0, 0, 0, 1, 0, + 7, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 2, + 0, 0, 5, 1, 0, 0, 0, 6, + 5, 1, 1, 0, 1, 0, 19, 0, + 0, 0, 0, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 0, 1, 0, + 6, 0, 0, 0, 0, 0, 1, 1, + 0, 1, 4, 1, 28, 1, 0, 0, + 3, 0, 2, 0, 0, 0, 1, 0, + 1, 1, 1, 0, 0, 2, 0, 0, + 15, 2, 1, 1, 0, 0, 10, 35, + 1, 1, 0, 2, 0, 25, 0, 0, + 0, 0, 2, 0, 1, 0, 0, 1, + 2, 0, 1, 0, 0, 1, 0, 0, + 10, 0, 0, 0, 0, 3, 0, 18, + 0, 0, 0, 0, 0, 1, 5, 0, + 1, 4, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 3, 0, 1, + 0, 0, 1, 0, 0, 0, 1, 1, + 1, 1, 0, 2, 0, 0, 0, 26, + 0, 0, 0, 1, 1, 1, 0, 0, + 2, 1, 0, 1, 1, 0, 2, 0, + 0, 2, 0, 2, 1, 0, 1, 0, + 3, 0, 0, 1, 21, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 1, 0, + 0, 1, 0, 0, 0, 0, 0, 0, + 1, 0, 6, 0, 0, 0, 0, 1, + 0, 2, 0, 0, 15, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 0, 5, 1, 0, 0, + 6, 5, 1, 1, 0, 1, 0, 19, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 1, + 0, 6, 0, 0, 0, 0, 0, 1, + 1, 0, 1, 4, 1, 0, 0, 0, + 0, 4, 5, 0, 2, 1, 1, 3, + 1, 2, 3, 1, 0, 0, 1, 32, + 3, 0, 0, 1, 2, 4, 2, 1, + 1, 1, 4, 1, 1, 3, 2, 1, + 3, 1, 1, 1, 3, 1, 2, 1, + 0, 1, 0, 4, 0, 0, 1, 43, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 18, 2, 3, + 0, 0, 1, 0, 5, 1, 0, 28, + 1, 0, 0, 3, 0, 2, 0, 0, + 0, 1, 0, 1, 1, 1, 0, 15, + 2, 1, 1, 0, 0, 10, 35, 1, + 1, 0, 2, 0, 25, 0, 0, 0, + 0, 2, 0, 1, 0, 0, 1, 2, + 0, 1, 0, 0, 1, 0, 0, 10, + 0, 0, 0, 0, 3, 0, 18, 0, + 0, 0, 0, 0, 1, 5, 0, 1, + 4, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 1, 1, 1, 0, 2, 0, + 0, 0, 26, 0, 0, 0, 1, 1, + 1, 0, 0, 2, 1, 0, 1, 1, + 0, 2, 0, 0, 2, 0, 2, 1, + 0, 1, 0, 3, 0, 0, 1, 23, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 6, 0, 0, + 0, 0, 1, 0, 7, 0, 0, 16, + 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 5, + 1, 0, 0, 0, 6, 5, 1, 1, + 0, 1, 0, 19, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 0, 1, 0, 6, 0, 0, + 0, 0, 0, 1, 1, 0, 1, 4, + 1, 0, 0, 1, 0, 0, 0, 1, + 1, 1, 1, 0, 2, 0, 0, 0, + 26, 0, 0, 0, 1, 1, 1, 0, + 0, 2, 1, 0, 1, 1, 0, 2, + 0, 0, 2, 0, 2, 1, 0, 1, + 0, 3, 0, 0, 1, 21, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 1, 0, 6, 0, 1, 0, 0, + 1, 0, 7, 0, 0, 1, 0, 0, + 0, 15, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, + 0, 8, 1, 0, 0, 0, 0, 6, + 5, 1, 1, 0, 1, 0, 19, 0, + 0, 0, 0, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 0, 2, 1, + 0, 6, 0, 0, 0, 0, 0, 1, + 1, 0, 1, 4, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 1, 1, 1, + 0, 2, 0, 0, 0, 26, 0, 0, + 0, 1, 1, 1, 0, 0, 2, 1, + 0, 1, 1, 0, 2, 0, 0, 2, + 0, 2, 1, 0, 1, 0, 3, 0, + 0, 1, 21, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 1, 0, + 6, 0, 0, 0, 0, 1, 0, 2, + 0, 0, 15, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 1, 1, + 1, 0, 5, 1, 0, 0, 6, 5, + 1, 1, 0, 1, 0, 19, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 1, 0, 6, + 0, 0, 0, 0, 0, 1, 1, 0, + 1, 4, 1, 0, 0, 0, 1, 1, + 0, 0, 0, 1, 1, 1, 1, 0, + 2, 0, 0, 0, 26, 0, 0, 0, + 1, 1, 1, 0, 0, 2, 1, 0, + 1, 1, 0, 2, 0, 0, 2, 0, + 2, 1, 0, 1, 0, 3, 0, 0, + 1, 21, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 1, 0, 6, + 0, 0, 0, 0, 1, 0, 2, 0, + 0, 15, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, + 0, 5, 1, 0, 0, 6, 5, 1, + 1, 0, 1, 0, 19, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 0, 1, 0, 6, 0, + 0, 0, 0, 0, 1, 1, 0, 1, + 4, 1, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 0, 2, 0, 0, 0, + 26, 21, 6, 2, 15, 5, 6, 1, + 0, 1, 0, 0, 3, 0, 2, 0, + 0, 0, 1, 0, 1, 1, 0, 1, + 5, 0, 2, 1, 1, 3, 1, 2, + 3, 1, 0, 0, 1, 32, 3, 0, + 0, 1, 2, 4, 2, 1, 1, 1, + 4, 1, 1, 3, 2, 1, 3, 1, + 1, 1, 3, 1, 2, 1, 0, 1, + 0, 4, 0, 0, 1, 45, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 1, 0, 18, 2, 3, 0, 0, + 1, 0, 7, 1, 0, 28, 1, 0, + 0, 3, 0, 2, 0, 0, 0, 1, + 0, 1, 1, 1, 0, 15, 2, 1, + 1, 0, 0, 10, 35, 1, 1, 0, + 2, 0, 25, 0, 0, 0, 0, 2, + 0, 1, 0, 0, 1, 2, 0, 1, + 0, 0, 1, 0, 0, 10, 0, 0, + 0, 0, 3, 0, 18, 0, 0, 0, + 0, 0, 1, 5, 0, 1, 4, 1, + 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 0, 2, 0, 0, 0, 26, + 21, 6, 2, 15, 5, 6, 1, 0, + 0, 2, 0, 1, 0, 0, 0, 35, + 1, 0, 2, 0, 25, 0, 0, 0, + 0, 2, 0, 1, 0, 0, 1, 2, + 0, 1, 0, 0, 1, 0, 0, 10, + 0, 0, 0, 0, 4, 2, 0, 18, + 5, 0, 5, 0, 1, 0, 0, 0, + 1, 1, 1, 1, 0, 2, 0, 0, + 0, 26, 0, 0, 0, 1, 1, 1, + 0, 0, 2, 1, 0, 1, 1, 0, + 2, 0, 0, 2, 0, 2, 1, 0, + 1, 0, 3, 0, 0, 1, 21, 0, + 0, 1, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 1, 0, 6, 0, 0, 0, + 0, 1, 0, 2, 0, 0, 15, 0, + 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 5, 1, + 0, 0, 7, 5, 1, 1, 0, 1, + 0, 19, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, + 0, 1, 0, 6, 0, 0, 0, 0, + 0, 1, 1, 0, 1, 1, 4, 1, + 0, 0, 1, 1, 0, 2, 0, 3, + 0, 0, 1, 0, 2, 0, 35, 21, + 1, 35, 35, 34, 35, 31, 35, 31, + 22, 31, 34, 31, 31, 26, 21, 21, + 35, 34, 26, 21, 34, 30, 35, 31, + 34, 35, 35, 35, 35, 34, 36, 21, + 21, 34, 34, 34, 60, 55, 40, 36, + 49, 39, 40, 35, 23, 23, 23, 22, + 22, 22, 21, 22, 24, 22, 22, 24, + 21, 21, 21, 22, 53, 64, 39, 26, + 49, 34, 34, 34, 21, 34, 34, 35, + 34, 34, 34, 34, 23, 36, 31, 22, + 34, 34, 35, 34, 34, 35, 34, 34, + 34, 34, 34, 34, 35, 34, 34, 34, + 34, 34, 35, 34, 34, 34, 34, 34, + 34, 37, 34, 34, 34, 34, 34, 35, + 34, 35, 35, 35, 34, 35, 34, 34, + 39, 53, 38, 35, 40, 35, 38, 35, + 35, 35, 34, 36, 36, 35, 34, 35, + 35, 34, 36, 34, 34, 36, 34, 36, + 35, 34, 35, 34, 37, 34, 34, 35, + 22, 21, 22, 21, 22, 21, 21, 22, + 22, 22, 22, 21, 23, 21, 21, 22, + 22, 22, 22, 21, 23, 21, 21, 21, + 47, 42, 27, 23, 36, 26, 27, 22, + 21, 21, 21, 47, 42, 27, 23, 36, + 26, 27, 22, 23, 23, 22, 22, 23, + 22, 23, 24, 22, 21, 21, 22, 53, + 66, 34, 22, 43, 21, 35, 34, 22, + 22, 21, 21, 21, 21, 21, 22, 21, + 22, 21, 21, 21, 22, 22, 22, 22, + 21, 23, 21, 21, 22, 22, 22, 22, + 21, 23, 21, 21, 21, 47, 42, 27, + 23, 36, 26, 27, 22, 21, 21, 21, + 47, 42, 27, 23, 36, 26, 27, 22, + 22, 22, 22, 21, 21, 23, 22, 21, + 22, 22, 21, 23, 21, 21, 23, 21, + 23, 22, 21, 22, 21, 24, 21, 21, + 22, 21, 21, 22, 21, 21, 21, 21, + 21, 21, 22, 21, 21, 22, 21, 21, + 21, 21, 21, 21, 22, 21, 21, 21, + 21, 21, 22, 21, 21, 21, 21, 21, + 21, 24, 21, 21, 21, 21, 21, 21, + 21, 22, 22, 22, 21, 22, 21, 21, + 26, 40, 25, 22, 27, 22, 25, 24, + 21, 22, 49, 34, 34, 34, 34, 26, + 21, 35, 34, 23, 22, 22, 24, 22, + 23, 24, 22, 34, 34, 35, 35, 35, + 35, 34, 36, 21, 21, 22, 53, 66, + 39, 28, 49, 34, 34, 35, 34, 34, + 34, 34, 21, 34, 34, 34, 34, 35, + 34, 34, 34, 34, 34, 34, 37, 34, + 23, 36, 31, 22, 34, 34, 34, 34, + 35, 34, 35, 35, 35, 34, 35, 34, + 34, 39, 53, 38, 35, 40, 35, 38, + 34, 34, 35, 34, 34, 35, 34, 34, + 34, 34, 34, 34, 35, 34, 34, 34, + 34, 60, 55, 40, 36, 49, 39, 40, + 35, 35, 35, 35, 34, 36, 36, 35, + 34, 35, 35, 34, 36, 34, 34, 36, + 34, 36, 35, 34, 35, 34, 37, 34, + 34, 35, 39, 36, 21, +} + +var _s_range_lengths []byte = []byte{ + 0, 1, 1, 1, 1, 2, 2, 1, + 4, 1, 1, 1, 1, 2, 4, 1, + 1, 1, 2, 2, 5, 6, 2, 2, + 5, 1, 3, 2, 3, 5, 2, 3, + 1, 3, 1, 1, 2, 1, 2, 1, + 4, 0, 0, 1, 5, 2, 1, 2, + 2, 1, 2, 1, 0, 2, 1, 2, + 1, 2, 2, 2, 1, 1, 4, 2, + 0, 2, 2, 1, 1, 0, 1, 0, + 1, 1, 0, 2, 1, 1, 1, 2, + 2, 1, 1, 2, 2, 1, 2, 3, + 2, 2, 0, 0, 2, 1, 0, 0, + 0, 0, 1, 4, 1, 0, 2, 1, + 3, 2, 0, 2, 2, 1, 1, 2, + 6, 1, 1, 2, 2, 1, 1, 1, + 0, 1, 1, 1, 1, 0, 2, 0, + 2, 3, 1, 2, 2, 2, 0, 1, + 0, 1, 1, 1, 0, 1, 4, 0, + 3, 0, 1, 1, 4, 1, 4, 3, + 0, 1, 0, 2, 3, 4, 3, 3, + 5, 3, 2, 2, 3, 0, 2, 2, + 1, 1, 1, 3, 6, 8, 9, 8, + 8, 3, 8, 7, 9, 3, 6, 5, + 7, 7, 5, 6, 4, 4, 1, 1, + 2, 1, 2, 3, 5, 0, 3, 1, + 5, 3, 2, 2, 3, 3, 1, 3, + 2, 2, 1, 2, 2, 2, 5, 5, + 1, 2, 2, 1, 2, 1, 3, 2, + 2, 1, 3, 3, 5, 2, 2, 2, + 6, 2, 2, 3, 2, 7, 0, 2, + 2, 1, 1, 5, 2, 1, 1, 1, + 2, 0, 3, 2, 2, 5, 5, 0, + 0, 2, 1, 2, 2, 1, 1, 1, + 3, 3, 3, 2, 2, 3, 1, 2, + 1, 3, 3, 3, 3, 3, 2, 2, + 3, 3, 4, 6, 1, 3, 0, 1, + 1, 2, 1, 5, 3, 1, 1, 1, + 1, 1, 2, 2, 2, 1, 1, 1, + 2, 5, 0, 2, 5, 2, 1, 1, + 0, 2, 1, 2, 3, 2, 2, 1, + 2, 1, 1, 2, 4, 2, 1, 2, + 2, 2, 7, 1, 1, 3, 1, 2, + 1, 1, 0, 3, 1, 3, 1, 3, + 1, 3, 3, 3, 5, 2, 8, 7, + 2, 2, 3, 3, 1, 2, 1, 1, + 2, 1, 3, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 3, 1, 3, + 2, 0, 2, 4, 1, 2, 3, 1, + 0, 3, 0, 2, 3, 1, 0, 0, + 0, 0, 1, 2, 2, 2, 1, 3, + 5, 7, 5, 0, 1, 2, 1, 0, + 1, 1, 1, 0, 1, 1, 0, 1, + 1, 1, 1, 2, 2, 2, 5, 1, + 1, 1, 2, 2, 4, 1, 1, 1, + 4, 2, 7, 7, 4, 2, 6, 1, + 4, 2, 5, 6, 2, 5, 1, 4, + 1, 2, 2, 2, 3, 1, 4, 0, + 0, 1, 6, 3, 1, 2, 2, 1, + 4, 2, 0, 2, 1, 1, 1, 2, + 3, 2, 4, 3, 1, 1, 2, 4, + 2, 0, 2, 2, 1, 1, 0, 1, + 0, 1, 1, 0, 1, 2, 1, 1, + 1, 2, 4, 2, 1, 2, 6, 1, + 3, 3, 2, 3, 0, 0, 2, 1, + 0, 0, 0, 0, 1, 4, 1, 0, + 2, 3, 3, 1, 3, 0, 2, 4, + 1, 2, 2, 6, 1, 3, 2, 2, + 3, 1, 1, 2, 0, 1, 1, 1, + 1, 0, 2, 0, 2, 3, 1, 1, + 2, 2, 2, 0, 1, 0, 1, 1, + 1, 0, 0, 1, 4, 1, 3, 4, + 0, 0, 1, 1, 1, 1, 4, 0, + 1, 4, 1, 3, 4, 3, 4, 5, + 3, 2, 2, 4, 0, 2, 2, 1, + 1, 4, 6, 9, 9, 9, 8, 5, + 8, 8, 9, 4, 6, 7, 7, 8, + 5, 8, 4, 5, 1, 2, 2, 2, + 3, 3, 5, 0, 3, 1, 6, 4, + 3, 5, 5, 1, 4, 3, 2, 3, + 2, 2, 3, 3, 5, 6, 2, 2, + 4, 6, 2, 0, 3, 4, 1, 3, + 2, 5, 0, 2, 1, 1, 3, 3, + 3, 2, 2, 3, 5, 4, 3, 3, + 6, 2, 4, 3, 4, 4, 1, 5, + 4, 3, 3, 1, 1, 2, 5, 0, + 2, 0, 1, 3, 3, 7, 3, 0, + 3, 3, 3, 2, 4, 1, 3, 6, + 3, 4, 8, 7, 2, 4, 3, 3, + 3, 2, 2, 3, 1, 2, 2, 2, + 4, 3, 2, 0, 4, 1, 2, 3, + 1, 3, 2, 2, 2, 1, 3, 0, + 1, 1, 1, 0, 1, 2, 1, 4, + 1, 1, 1, 1, 2, 4, 1, 1, + 1, 2, 2, 5, 6, 2, 2, 5, + 1, 3, 2, 3, 5, 2, 3, 1, + 3, 1, 1, 2, 1, 2, 1, 4, + 0, 0, 1, 5, 2, 1, 2, 2, + 1, 2, 1, 0, 2, 1, 2, 1, + 2, 2, 2, 1, 1, 4, 2, 0, + 2, 2, 1, 1, 0, 1, 0, 1, + 1, 0, 2, 1, 1, 1, 2, 2, + 1, 1, 2, 2, 1, 2, 3, 2, + 2, 0, 3, 3, 2, 1, 0, 0, + 0, 0, 1, 4, 1, 0, 2, 1, + 3, 2, 0, 2, 2, 1, 1, 2, + 6, 1, 1, 2, 2, 1, 1, 1, + 0, 1, 1, 1, 1, 0, 2, 0, + 2, 3, 1, 2, 2, 2, 0, 1, + 0, 1, 1, 1, 0, 0, 4, 1, + 4, 3, 1, 3, 4, 3, 4, 5, + 3, 2, 2, 4, 0, 2, 2, 1, + 1, 4, 6, 9, 9, 9, 8, 5, + 8, 8, 9, 4, 6, 7, 7, 8, + 5, 8, 4, 5, 1, 2, 2, 2, + 3, 3, 5, 0, 3, 1, 6, 4, + 3, 5, 5, 1, 4, 3, 2, 3, + 2, 2, 3, 3, 5, 6, 2, 2, + 6, 2, 0, 4, 4, 1, 3, 2, + 5, 0, 2, 1, 1, 3, 3, 2, + 2, 3, 5, 4, 3, 3, 6, 2, + 4, 3, 4, 4, 1, 5, 3, 3, + 1, 1, 2, 5, 0, 2, 0, 1, + 3, 7, 3, 0, 3, 3, 3, 4, + 1, 3, 6, 3, 4, 8, 7, 2, + 4, 3, 3, 3, 2, 2, 1, 2, + 2, 3, 2, 0, 4, 1, 2, 3, + 1, 2, 2, 2, 1, 3, 0, 1, + 1, 1, 0, 1, 3, 4, 5, 3, + 2, 2, 4, 0, 2, 2, 1, 1, + 4, 6, 9, 9, 9, 8, 5, 8, + 8, 9, 4, 6, 7, 7, 8, 5, + 8, 4, 5, 1, 2, 2, 2, 3, + 3, 5, 0, 3, 1, 6, 4, 3, + 5, 5, 1, 4, 3, 2, 3, 2, + 2, 3, 3, 5, 6, 2, 2, 6, + 2, 0, 3, 3, 1, 3, 2, 5, + 0, 3, 0, 1, 1, 1, 1, 2, + 2, 1, 4, 1, 1, 1, 1, 2, + 4, 1, 1, 1, 2, 2, 5, 6, + 2, 2, 5, 1, 3, 2, 3, 5, + 2, 3, 1, 3, 1, 1, 2, 1, + 2, 1, 4, 0, 0, 1, 5, 2, + 1, 2, 2, 1, 2, 1, 0, 2, + 1, 2, 1, 2, 2, 2, 1, 1, + 4, 2, 0, 3, 4, 1, 1, 0, + 1, 0, 2, 2, 1, 1, 1, 1, + 0, 2, 1, 1, 1, 2, 2, 1, + 1, 2, 2, 1, 2, 3, 2, 2, + 0, 0, 3, 1, 0, 1, 1, 1, + 0, 0, 0, 0, 1, 4, 1, 0, + 2, 1, 3, 2, 0, 2, 2, 1, + 1, 2, 6, 1, 1, 2, 2, 1, + 1, 1, 0, 1, 1, 1, 1, 0, + 0, 2, 0, 2, 3, 1, 2, 2, + 2, 0, 1, 0, 1, 1, 1, 0, + 3, 1, 3, 3, 2, 2, 3, 5, + 4, 3, 3, 6, 2, 4, 3, 4, + 4, 1, 5, 3, 1, 2, 3, 5, + 0, 2, 0, 1, 3, 7, 3, 0, + 3, 3, 3, 4, 1, 3, 6, 3, + 4, 8, 7, 2, 4, 3, 3, 3, + 2, 2, 1, 2, 2, 3, 2, 0, + 4, 1, 2, 3, 1, 2, 2, 2, + 1, 3, 0, 1, 1, 1, 0, 1, + 0, 1, 4, 1, 3, 4, 4, 3, + 5, 3, 2, 2, 4, 0, 2, 2, + 1, 1, 3, 6, 8, 9, 8, 8, + 4, 8, 8, 9, 4, 6, 6, 7, + 8, 5, 7, 4, 5, 1, 2, 2, + 2, 3, 3, 5, 0, 3, 1, 6, + 3, 3, 5, 5, 1, 3, 3, 2, + 3, 2, 2, 3, 3, 4, 6, 2, + 2, 6, 2, 0, 4, 4, 1, 3, + 2, 5, 0, 2, 1, 1, 3, 3, + 2, 2, 3, 4, 4, 3, 3, 4, + 2, 4, 3, 4, 4, 1, 5, 3, + 3, 1, 1, 2, 5, 0, 2, 0, + 1, 3, 7, 3, 0, 3, 2, 3, + 4, 1, 3, 5, 3, 4, 8, 7, + 2, 3, 3, 3, 2, 2, 2, 1, + 2, 2, 3, 2, 0, 4, 1, 2, + 3, 1, 2, 2, 2, 1, 3, 0, + 1, 1, 1, 0, 1, 0, 2, 0, + 2, 4, 3, 3, 3, 1, 1, 2, + 0, 1, 1, 1, 2, 4, 7, 9, + 7, 8, 6, 8, 7, 10, 4, 6, + 5, 7, 7, 5, 6, 4, 5, 1, + 2, 2, 2, 3, 3, 3, 0, 3, + 1, 6, 4, 2, 3, 4, 1, 4, + 3, 2, 3, 2, 3, 4, 3, 1, + 1, 3, 2, 0, 4, 4, 1, 2, + 3, 5, 0, 2, 1, 1, 2, 1, + 5, 3, 2, 6, 1, 3, 3, 2, + 3, 1, 5, 3, 2, 1, 5, 0, + 2, 0, 2, 2, 6, 2, 1, 3, + 2, 2, 1, 4, 2, 3, 8, 6, + 3, 2, 2, 4, 2, 1, 2, 2, + 1, 0, 4, 1, 2, 3, 1, 2, + 2, 2, 1, 2, 0, 1, 1, 1, + 0, 1, 4, 1, 3, 4, 3, 4, + 5, 3, 2, 2, 4, 0, 2, 2, + 1, 1, 4, 6, 9, 9, 9, 8, + 5, 8, 8, 9, 4, 6, 7, 7, + 8, 5, 8, 4, 5, 1, 2, 2, + 2, 3, 3, 5, 0, 3, 1, 6, + 4, 3, 5, 5, 1, 4, 3, 2, + 3, 1, 1, 2, 2, 3, 3, 5, + 6, 2, 2, 4, 6, 2, 0, 3, + 3, 1, 3, 2, 5, 0, 3, 3, + 1, 3, 3, 3, 2, 2, 3, 5, + 4, 3, 3, 6, 2, 4, 3, 4, + 4, 1, 5, 3, 3, 1, 1, 3, + 5, 0, 2, 0, 1, 3, 3, 7, + 3, 0, 3, 3, 3, 2, 4, 1, + 3, 6, 3, 4, 8, 7, 2, 4, + 3, 3, 3, 2, 1, 2, 3, 1, + 2, 2, 2, 4, 3, 2, 0, 4, + 1, 2, 3, 1, 3, 2, 2, 2, + 1, 3, 0, 1, 1, 1, 0, 1, + 0, 1, 4, 1, 3, 4, 4, 3, + 5, 3, 2, 2, 4, 0, 2, 2, + 1, 1, 3, 6, 8, 9, 8, 8, + 4, 8, 8, 9, 4, 6, 6, 7, + 8, 5, 7, 4, 5, 1, 2, 2, + 2, 3, 3, 5, 0, 3, 1, 6, + 3, 3, 5, 5, 1, 3, 3, 2, + 3, 2, 2, 3, 3, 4, 6, 2, + 2, 6, 2, 0, 4, 4, 1, 3, + 2, 5, 0, 2, 1, 1, 3, 3, + 2, 2, 3, 4, 4, 3, 3, 4, + 2, 4, 3, 4, 4, 1, 5, 3, + 3, 1, 1, 2, 5, 0, 2, 0, + 1, 3, 7, 3, 0, 3, 2, 3, + 4, 1, 3, 5, 3, 4, 8, 7, + 2, 3, 3, 3, 2, 2, 2, 1, + 2, 2, 3, 2, 0, 4, 1, 2, + 3, 1, 2, 2, 2, 1, 3, 0, + 1, 1, 1, 0, 1, 0, 1, 1, + 1, 1, 2, 2, 2, 5, 1, 1, + 1, 2, 2, 4, 1, 1, 1, 4, + 2, 7, 7, 4, 2, 6, 1, 4, + 2, 5, 6, 2, 5, 1, 4, 1, + 2, 2, 2, 3, 1, 4, 0, 0, + 1, 6, 3, 1, 2, 2, 1, 4, + 2, 0, 2, 1, 2, 3, 2, 4, + 3, 1, 1, 2, 4, 2, 0, 2, + 2, 1, 1, 0, 1, 0, 1, 1, + 0, 1, 2, 1, 1, 1, 2, 4, + 2, 1, 2, 6, 1, 3, 3, 2, + 3, 0, 0, 2, 1, 0, 0, 0, + 0, 1, 4, 1, 0, 2, 3, 3, + 1, 3, 0, 2, 4, 1, 2, 2, + 6, 1, 3, 2, 2, 3, 1, 2, + 0, 1, 1, 1, 1, 0, 2, 0, + 2, 3, 1, 1, 2, 2, 2, 0, + 1, 0, 1, 1, 1, 0, 0, 1, + 4, 1, 3, 4, 4, 4, 5, 3, + 2, 2, 4, 0, 2, 2, 1, 1, + 4, 6, 9, 9, 9, 8, 5, 8, + 8, 9, 4, 6, 7, 7, 8, 5, + 8, 4, 5, 1, 2, 2, 2, 3, + 3, 5, 0, 3, 1, 6, 4, 3, + 5, 5, 1, 4, 3, 2, 3, 2, + 2, 3, 3, 5, 6, 2, 2, 6, + 2, 0, 4, 4, 1, 3, 2, 5, + 0, 2, 1, 1, 3, 3, 2, 2, + 3, 5, 4, 3, 3, 6, 2, 4, + 3, 4, 4, 1, 5, 3, 1, 2, + 5, 0, 2, 0, 1, 3, 7, 3, + 0, 3, 3, 3, 4, 1, 3, 6, + 3, 4, 8, 7, 2, 4, 3, 3, + 3, 2, 2, 1, 2, 2, 3, 2, + 0, 4, 1, 2, 3, 1, 2, 2, + 2, 1, 3, 0, 1, 1, 1, 0, + 1, 0, 1, 4, 1, 3, 4, 3, + 4, 5, 3, 2, 2, 4, 0, 2, + 2, 1, 1, 4, 6, 9, 9, 9, + 8, 5, 8, 8, 9, 4, 6, 7, + 7, 8, 5, 8, 4, 5, 1, 2, + 2, 2, 3, 3, 5, 0, 3, 1, + 6, 4, 3, 5, 5, 1, 4, 3, + 2, 3, 2, 2, 3, 3, 5, 6, + 2, 2, 6, 2, 0, 4, 4, 1, + 3, 2, 5, 0, 2, 1, 1, 3, + 3, 2, 2, 3, 5, 4, 3, 3, + 6, 2, 4, 3, 4, 4, 1, 5, + 3, 1, 2, 5, 0, 2, 0, 1, + 3, 7, 3, 0, 3, 3, 3, 4, + 1, 3, 6, 3, 4, 8, 7, 2, + 4, 3, 3, 3, 2, 2, 1, 2, + 2, 3, 2, 0, 4, 1, 2, 3, + 1, 2, 2, 2, 1, 3, 0, 1, + 1, 1, 0, 1, 0, 1, 4, 1, + 3, 4, 3, 4, 5, 3, 2, 2, + 4, 0, 2, 2, 1, 1, 4, 6, + 9, 9, 9, 8, 5, 8, 8, 9, + 4, 6, 7, 7, 8, 5, 8, 4, + 5, 1, 2, 2, 2, 3, 3, 5, + 0, 3, 1, 6, 4, 3, 5, 5, + 1, 4, 3, 2, 3, 2, 2, 3, + 3, 5, 6, 2, 2, 6, 2, 0, + 3, 3, 1, 3, 2, 5, 0, 3, + 3, 1, 3, 3, 2, 2, 3, 5, + 4, 3, 3, 6, 2, 4, 3, 4, + 4, 1, 5, 3, 3, 1, 1, 3, + 5, 0, 2, 0, 1, 3, 7, 3, + 0, 3, 3, 3, 4, 1, 3, 6, + 3, 4, 8, 7, 2, 4, 3, 3, + 3, 2, 2, 1, 2, 2, 3, 2, + 0, 4, 1, 2, 3, 1, 2, 2, + 2, 1, 3, 0, 1, 1, 1, 0, + 1, 0, 1, 4, 1, 3, 4, 3, + 4, 5, 3, 2, 2, 4, 0, 2, + 2, 1, 1, 4, 6, 9, 9, 9, + 8, 5, 8, 8, 9, 4, 6, 7, + 7, 8, 5, 8, 4, 5, 1, 2, + 2, 2, 3, 3, 5, 0, 3, 1, + 6, 4, 3, 5, 5, 1, 4, 3, + 2, 3, 2, 2, 3, 3, 5, 6, + 2, 2, 6, 2, 0, 3, 4, 1, + 3, 2, 5, 0, 3, 3, 1, 3, + 3, 2, 2, 3, 5, 4, 3, 3, + 6, 2, 4, 3, 4, 4, 1, 5, + 3, 1, 3, 5, 0, 2, 0, 1, + 3, 7, 3, 0, 3, 3, 3, 4, + 1, 3, 6, 3, 4, 8, 7, 2, + 4, 3, 3, 3, 2, 2, 1, 2, + 2, 3, 2, 0, 4, 1, 2, 3, + 1, 2, 2, 2, 1, 3, 0, 1, + 1, 1, 0, 1, 0, 1, 1, 1, + 1, 2, 2, 1, 4, 1, 1, 1, + 1, 2, 4, 1, 1, 1, 2, 2, + 5, 6, 2, 2, 5, 1, 3, 2, + 3, 5, 2, 3, 1, 3, 1, 1, + 2, 1, 2, 1, 4, 0, 0, 1, + 5, 2, 1, 2, 2, 1, 2, 1, + 0, 2, 1, 2, 1, 2, 2, 2, + 1, 1, 4, 2, 0, 2, 2, 1, + 1, 0, 1, 0, 1, 1, 0, 2, + 1, 1, 1, 2, 2, 1, 1, 2, + 2, 1, 2, 3, 2, 2, 0, 0, + 2, 1, 0, 0, 0, 0, 1, 4, + 1, 0, 2, 1, 3, 2, 0, 2, + 2, 1, 1, 2, 6, 1, 1, 2, + 2, 1, 1, 1, 0, 1, 1, 1, + 1, 0, 2, 0, 2, 3, 1, 2, + 2, 2, 0, 1, 0, 1, 1, 1, + 0, 0, 1, 4, 1, 3, 4, 3, + 3, 5, 3, 2, 2, 3, 0, 2, + 2, 1, 1, 3, 6, 8, 9, 8, + 8, 3, 8, 7, 9, 3, 6, 5, + 7, 7, 5, 6, 4, 4, 1, 1, + 2, 1, 2, 3, 5, 0, 3, 1, + 5, 3, 3, 5, 5, 1, 2, 2, + 2, 3, 2, 2, 1, 3, 3, 5, + 2, 2, 6, 2, 0, 2, 2, 1, + 3, 2, 5, 0, 2, 1, 1, 3, + 3, 2, 2, 3, 3, 3, 3, 3, + 2, 2, 3, 3, 4, 3, 1, 5, + 2, 1, 2, 5, 0, 2, 0, 1, + 3, 7, 3, 0, 3, 1, 3, 3, + 1, 3, 3, 3, 2, 8, 7, 2, + 2, 3, 3, 1, 2, 1, 1, 2, + 2, 3, 2, 0, 4, 1, 2, 3, + 1, 2, 2, 2, 1, 3, 0, 1, + 1, 1, 0, 1, 0, 1, 4, 1, + 3, 4, 4, 4, 5, 3, 2, 2, + 4, 0, 2, 2, 1, 1, 4, 6, + 9, 9, 9, 8, 5, 8, 8, 9, + 4, 6, 7, 7, 8, 5, 8, 4, + 5, 1, 2, 2, 2, 3, 3, 5, + 0, 3, 1, 6, 4, 3, 5, 5, + 1, 4, 3, 2, 3, 2, 2, 3, + 3, 5, 6, 2, 2, 6, 2, 0, + 4, 4, 1, 3, 2, 5, 0, 2, + 1, 1, 3, 3, 2, 2, 3, 5, + 4, 3, 3, 6, 2, 4, 3, 4, + 4, 1, 5, 3, 1, 2, 5, 0, + 2, 0, 1, 3, 7, 3, 0, 3, + 3, 3, 4, 1, 3, 6, 3, 4, + 8, 7, 2, 4, 3, 3, 3, 2, + 2, 1, 2, 2, 3, 2, 0, 4, + 1, 2, 3, 1, 2, 2, 2, 1, + 3, 0, 1, 1, 1, 0, 1, 0, + 1, 4, 1, 3, 4, 3, 4, 5, + 3, 2, 2, 4, 0, 2, 2, 1, + 1, 4, 6, 9, 9, 9, 8, 5, + 8, 8, 9, 4, 6, 7, 7, 8, + 5, 8, 4, 5, 1, 2, 2, 2, + 3, 3, 5, 0, 3, 1, 6, 4, + 3, 5, 5, 1, 4, 3, 2, 3, + 2, 2, 3, 3, 5, 6, 2, 2, + 6, 2, 0, 3, 4, 1, 3, 2, + 5, 0, 3, 3, 1, 3, 3, 2, + 2, 3, 5, 4, 3, 3, 6, 2, + 4, 3, 4, 4, 1, 5, 3, 1, + 3, 5, 0, 2, 0, 1, 3, 7, + 3, 0, 3, 3, 3, 4, 1, 3, + 6, 3, 4, 8, 7, 2, 4, 3, + 3, 3, 2, 2, 1, 2, 2, 3, + 2, 0, 4, 1, 2, 3, 1, 2, + 2, 2, 1, 3, 0, 1, 1, 1, + 0, 1, 0, 1, 1, 1, 1, 2, + 2, 1, 4, 1, 1, 1, 1, 2, + 0, 0, 0, 0, 0, 0, 0, 2, + 2, 1, 4, 6, 9, 9, 9, 8, + 5, 8, 8, 9, 4, 6, 7, 7, + 8, 5, 8, 4, 5, 2, 2, 3, + 3, 5, 6, 4, 1, 0, 1, 4, + 1, 3, 4, 3, 4, 5, 3, 2, + 2, 4, 0, 2, 2, 1, 1, 4, + 6, 9, 9, 9, 8, 5, 8, 8, + 9, 4, 6, 7, 7, 8, 5, 8, + 4, 5, 1, 2, 2, 2, 3, 3, + 5, 0, 4, 1, 6, 4, 0, 1, + 3, 5, 5, 1, 4, 3, 2, 3, + 2, 2, 3, 3, 5, 6, 2, 2, + 6, 2, 0, 4, 4, 1, 3, 2, + 5, 0, 2, 1, 2, 3, 1, 0, + 1, 1, 1, 1, 2, 2, 1, 4, + 1, 1, 1, 1, 2, 4, 1, 1, + 1, 2, 2, 5, 6, 2, 2, 5, + 1, 3, 2, 3, 5, 2, 3, 1, + 3, 1, 1, 2, 1, 2, 1, 4, + 0, 1, 1, 5, 2, 0, 1, 1, + 2, 2, 1, 2, 1, 0, 2, 1, + 2, 1, 2, 2, 2, 1, 1, 4, + 2, 0, 2, 2, 1, 1, 0, 1, + 0, 1, 1, 1, 1, 1, 1, 2, + 1, 1, 1, 2, 2, 1, 2, 2, + 2, 1, 2, 3, 2, 2, 0, 1, + 1, 2, 0, 0, 2, 1, 5, 0, + 0, 0, 0, 1, 4, 1, 0, 2, + 1, 3, 2, 0, 2, 2, 1, 1, + 2, 6, 1, 1, 2, 2, 1, 1, + 1, 0, 1, 1, 1, 1, 0, 2, + 0, 2, 3, 1, 2, 2, 2, 0, + 1, 0, 1, 1, 2, 3, 3, 2, + 2, 3, 5, 4, 4, 3, 6, 2, + 4, 3, 4, 4, 0, 1, 1, 2, + 1, 5, 3, 1, 1, 5, 0, 2, + 0, 1, 3, 7, 3, 0, 3, 3, + 3, 4, 1, 3, 6, 3, 4, 8, + 7, 2, 4, 3, 3, 3, 2, 2, + 1, 2, 2, 3, 2, 0, 4, 1, + 2, 3, 1, 2, 2, 2, 1, 3, + 0, 1, 1, 1, 1, 3, 5, 5, + 4, 3, 2, 3, 2, 3, 3, 5, + 6, 2, 2, 6, 4, 4, 3, 2, + 5, 2, 0, 1, 1, 1, 1, 2, + 2, 1, 4, 1, 1, 1, 1, 2, + 4, 1, 1, 1, 2, 2, 5, 6, + 2, 2, 5, 1, 3, 2, 3, 5, + 2, 3, 1, 3, 1, 1, 2, 1, + 2, 1, 4, 0, 0, 1, 5, 2, + 1, 2, 2, 1, 2, 1, 0, 2, + 1, 2, 1, 2, 2, 2, 1, 1, + 4, 2, 0, 2, 2, 1, 1, 0, + 1, 0, 1, 1, 0, 2, 1, 1, + 1, 2, 2, 1, 1, 2, 2, 1, + 2, 3, 2, 2, 0, 0, 2, 1, + 0, 0, 0, 0, 1, 4, 1, 0, + 2, 1, 3, 2, 0, 2, 2, 1, + 1, 2, 6, 1, 1, 2, 2, 1, + 1, 1, 0, 1, 1, 1, 1, 0, + 2, 0, 2, 3, 1, 2, 2, 2, + 0, 1, 0, 1, 1, 1, 0, 1, + 1, 5, 0, 1, 4, 1, 3, 4, + 3, 4, 5, 3, 2, 2, 4, 0, + 2, 2, 1, 1, 4, 6, 9, 9, + 9, 8, 5, 8, 8, 9, 4, 6, + 7, 7, 8, 5, 8, 4, 5, 1, + 2, 2, 2, 3, 3, 5, 0, 3, + 1, 6, 4, 3, 5, 5, 1, 4, + 3, 2, 3, 2, 2, 3, 3, 5, + 6, 2, 2, 6, 2, 0, 4, 4, + 1, 3, 2, 5, 0, 2, 1, 1, + 3, 3, 2, 2, 3, 5, 4, 3, + 3, 6, 2, 4, 3, 4, 4, 1, + 5, 3, 1, 2, 5, 0, 2, 0, + 1, 3, 7, 3, 0, 3, 3, 3, + 4, 1, 3, 6, 3, 4, 8, 7, + 2, 4, 3, 3, 3, 2, 2, 1, + 2, 2, 3, 2, 0, 4, 1, 2, + 3, 1, 2, 2, 2, 1, 3, 0, + 1, 1, 1, 0, 1, 0, 1, 1, + 1, 1, 2, 2, 1, 4, 1, 1, + 1, 1, 2, 4, 1, 1, 1, 2, + 2, 5, 6, 2, 2, 5, 1, 3, + 2, 3, 5, 2, 3, 1, 3, 1, + 1, 2, 1, 2, 1, 4, 0, 1, + 1, 5, 2, 1, 2, 2, 1, 2, + 1, 0, 2, 1, 2, 1, 2, 2, + 2, 1, 1, 4, 2, 0, 2, 2, + 1, 1, 0, 1, 0, 1, 1, 1, + 2, 1, 1, 1, 2, 2, 1, 2, + 2, 2, 1, 2, 3, 2, 2, 0, + 0, 2, 2, 5, 0, 0, 0, 0, + 1, 4, 1, 0, 2, 1, 3, 2, + 0, 2, 2, 1, 1, 2, 6, 1, + 1, 2, 2, 1, 1, 1, 0, 1, + 1, 1, 1, 0, 2, 0, 2, 3, + 1, 2, 2, 2, 0, 1, 0, 1, + 1, 1, 0, 0, 1, 1, 1, 1, + 2, 2, 1, 4, 1, 1, 1, 1, + 2, 4, 1, 1, 1, 2, 2, 5, + 6, 2, 2, 5, 1, 3, 2, 3, + 5, 2, 3, 1, 3, 1, 1, 2, + 1, 2, 1, 4, 0, 0, 1, 5, + 2, 1, 2, 2, 1, 2, 1, 0, + 2, 1, 2, 1, 2, 2, 2, 1, + 1, 4, 2, 0, 3, 4, 1, 1, + 0, 1, 0, 2, 2, 1, 1, 1, + 1, 0, 2, 1, 1, 1, 2, 2, + 1, 1, 2, 2, 1, 2, 3, 2, + 2, 0, 0, 3, 1, 1, 1, 0, + 0, 0, 0, 1, 4, 1, 0, 2, + 1, 3, 2, 0, 2, 2, 1, 1, + 2, 6, 1, 1, 2, 2, 1, 1, + 1, 0, 1, 1, 1, 1, 0, 0, + 2, 0, 2, 3, 1, 2, 2, 2, + 0, 1, 0, 1, 1, 1, 0, 1, + 0, 1, 1, 1, 1, 2, 2, 1, + 4, 1, 1, 1, 1, 2, 4, 1, + 1, 1, 2, 2, 5, 6, 2, 2, + 5, 1, 3, 2, 3, 5, 2, 3, + 1, 3, 1, 1, 2, 1, 2, 1, + 4, 0, 0, 1, 5, 2, 1, 2, + 2, 1, 2, 1, 0, 2, 1, 2, + 1, 2, 2, 2, 1, 1, 4, 2, + 0, 2, 2, 1, 1, 0, 1, 0, + 1, 1, 0, 2, 1, 1, 1, 2, + 2, 1, 1, 2, 2, 1, 2, 3, + 2, 2, 0, 0, 2, 1, 0, 0, + 0, 0, 1, 4, 1, 0, 2, 1, + 3, 2, 0, 2, 2, 1, 1, 2, + 6, 1, 1, 2, 2, 1, 1, 1, + 0, 1, 1, 1, 1, 0, 2, 0, + 2, 3, 1, 2, 2, 2, 0, 1, + 0, 1, 1, 1, 0, 4, 0, 0, + 1, 1, 1, 1, 2, 2, 1, 4, + 1, 1, 1, 1, 2, 4, 1, 1, + 1, 2, 2, 5, 6, 2, 2, 5, + 1, 3, 2, 3, 5, 2, 3, 1, + 3, 1, 1, 2, 1, 2, 1, 4, + 0, 0, 1, 5, 2, 1, 2, 2, + 1, 2, 1, 0, 2, 1, 2, 1, + 2, 2, 2, 1, 1, 4, 2, 0, + 2, 2, 1, 1, 0, 1, 0, 1, + 1, 0, 2, 1, 1, 1, 2, 2, + 1, 1, 2, 2, 1, 2, 3, 2, + 2, 0, 0, 2, 1, 0, 0, 0, + 0, 1, 4, 1, 0, 2, 1, 3, + 2, 0, 2, 2, 1, 1, 2, 6, + 1, 1, 2, 2, 1, 1, 1, 0, + 1, 1, 1, 1, 0, 2, 0, 2, + 3, 1, 2, 2, 2, 0, 1, 0, + 1, 1, 1, 0, 1, 1, 1, 1, + 2, 2, 1, 4, 1, 1, 1, 1, + 2, 0, 0, 0, 0, 0, 0, 0, + 1, 3, 3, 2, 2, 3, 5, 4, + 4, 3, 6, 2, 4, 4, 4, 0, + 0, 1, 4, 1, 3, 4, 3, 4, + 5, 3, 2, 2, 4, 0, 2, 2, + 1, 1, 4, 6, 9, 9, 9, 8, + 5, 8, 8, 9, 4, 6, 7, 7, + 8, 5, 8, 4, 5, 1, 2, 2, + 2, 3, 3, 5, 0, 4, 1, 6, + 4, 3, 5, 5, 1, 4, 3, 2, + 3, 2, 2, 3, 3, 5, 6, 2, + 2, 6, 2, 0, 4, 4, 1, 3, + 2, 5, 0, 2, 1, 2, 3, 3, + 2, 2, 3, 5, 4, 4, 3, 6, + 2, 4, 3, 4, 4, 1, 5, 3, + 1, 2, 5, 0, 2, 0, 1, 3, + 7, 3, 0, 3, 3, 3, 4, 1, + 3, 6, 3, 4, 8, 7, 2, 4, + 3, 3, 3, 2, 2, 1, 2, 2, + 3, 2, 0, 4, 1, 2, 3, 1, + 2, 2, 2, 1, 3, 0, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 2, + 2, 1, 4, 1, 1, 1, 1, 2, + 0, 0, 0, 0, 0, 0, 0, 1, + 1, 5, 3, 1, 2, 3, 5, 2, + 1, 3, 7, 3, 0, 3, 3, 3, + 4, 1, 3, 6, 3, 4, 8, 7, + 2, 4, 3, 3, 3, 2, 2, 1, + 2, 2, 3, 2, 0, 0, 4, 1, + 1, 3, 0, 1, 0, 1, 1, 1, + 1, 2, 2, 1, 4, 1, 1, 1, + 1, 2, 4, 1, 1, 1, 2, 2, + 5, 6, 2, 2, 5, 1, 3, 2, + 3, 5, 2, 3, 1, 3, 1, 1, + 2, 1, 2, 1, 4, 0, 0, 1, + 5, 2, 1, 2, 2, 1, 2, 1, + 0, 2, 1, 2, 1, 2, 2, 2, + 1, 1, 4, 2, 0, 2, 2, 1, + 1, 0, 1, 0, 1, 1, 0, 2, + 1, 1, 1, 2, 2, 1, 1, 2, + 2, 1, 2, 3, 2, 2, 0, 0, + 2, 1, 0, 0, 0, 0, 1, 4, + 1, 0, 2, 1, 3, 2, 0, 2, + 2, 1, 1, 2, 6, 1, 1, 2, + 2, 1, 1, 1, 0, 1, 1, 1, + 1, 0, 2, 0, 2, 3, 1, 2, + 2, 2, 0, 1, 0, 0, 1, 1, + 1, 0, 0, 1, 0, 0, 1, 0, + 1, 1, 1, 1, 1, 1, 7, 0, + 0, 5, 5, 5, 5, 5, 5, 5, + 0, 5, 5, 5, 5, 0, 0, 3, + 5, 9, 0, 0, 8, 4, 5, 5, + 6, 6, 7, 7, 6, 9, 8, 1, + 1, 9, 6, 6, 7, 5, 5, 5, + 5, 5, 5, 5, 4, 2, 3, 0, + 0, 0, 2, 2, 4, 3, 3, 3, + 1, 1, 1, 2, 0, 3, 0, 0, + 1, 9, 6, 8, 0, 6, 10, 7, + 6, 7, 7, 8, 1, 1, 0, 0, + 9, 6, 5, 7, 6, 7, 6, 9, + 9, 7, 6, 6, 9, 7, 7, 7, + 6, 6, 5, 6, 6, 6, 7, 6, + 6, 6, 9, 9, 6, 6, 9, 9, + 6, 7, 8, 7, 7, 5, 7, 6, + 5, 5, 5, 5, 5, 5, 6, 6, + 9, 9, 12, 12, 9, 7, 10, 6, + 8, 9, 10, 10, 9, 10, 6, 8, + 6, 6, 7, 6, 7, 6, 9, 5, + 4, 1, 0, 1, 0, 1, 1, 1, + 2, 2, 1, 4, 1, 1, 1, 1, + 2, 2, 1, 4, 1, 1, 1, 1, + 2, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 2, 0, 0, 0, 0, + 0, 0, 0, 4, 3, 1, 3, 4, + 3, 4, 5, 3, 2, 2, 4, 0, + 4, 5, 1, 1, 0, 1, 5, 1, + 0, 0, 0, 4, 1, 1, 0, 1, + 0, 1, 1, 1, 1, 2, 2, 1, + 4, 1, 1, 1, 1, 2, 2, 1, + 4, 1, 1, 1, 1, 2, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, + 2, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 2, 5, 6, 2, 2, 5, + 1, 3, 2, 3, 5, 2, 3, 1, + 3, 1, 1, 2, 1, 2, 1, 4, + 0, 1, 5, 2, 1, 2, 2, 1, + 2, 1, 0, 2, 1, 2, 1, 2, + 2, 2, 1, 1, 4, 2, 2, 2, + 1, 1, 0, 1, 1, 1, 2, 1, + 1, 1, 2, 2, 1, 1, 2, 2, + 1, 2, 3, 2, 2, 0, 2, 1, + 0, 0, 0, 0, 0, 0, 1, 0, + 0, 1, 2, 5, 9, 6, 8, 0, + 1, 5, 9, 4, 1, 3, 4, 3, + 4, 5, 3, 8, 6, 6, 7, 7, + 6, 9, 8, 2, 2, 4, 0, 4, + 0, 0, 2, 6, 10, 7, 6, 7, + 7, 8, 0, 7, 7, 6, 6, 5, + 6, 6, 6, 7, 6, 6, 6, 9, + 1, 1, 0, 0, 9, 6, 6, 9, + 9, 6, 7, 8, 7, 7, 5, 7, + 6, 5, 5, 5, 5, 5, 5, 6, + 9, 6, 5, 7, 6, 7, 6, 9, + 9, 7, 6, 6, 9, 7, 9, 6, + 6, 7, 5, 5, 5, 5, 5, 5, + 5, 6, 9, 9, 12, 12, 9, 7, + 10, 6, 8, 9, 10, 10, 9, 10, + 6, 8, 6, 6, 7, 6, 7, 6, + 9, 5, 2, 1, 0, +} + +var _s_index_offsets []uint16 = []uint16{ + 0, 2, 4, 6, 8, 11, 15, 19, + 22, 27, 31, 33, 35, 37, 66, 71, + 73, 75, 78, 82, 86, 92, 99, 104, + 108, 114, 117, 122, 125, 131, 137, 140, + 146, 148, 154, 157, 159, 163, 165, 171, + 173, 178, 180, 202, 204, 210, 214, 216, + 219, 222, 224, 227, 229, 231, 234, 236, + 240, 242, 245, 248, 251, 253, 255, 261, + 264, 271, 274, 277, 279, 281, 283, 285, + 288, 290, 292, 308, 311, 313, 315, 320, + 323, 326, 328, 330, 333, 336, 338, 342, + 347, 351, 354, 360, 362, 365, 367, 374, + 380, 382, 384, 386, 392, 394, 414, 417, + 419, 423, 426, 428, 431, 434, 436, 438, + 442, 450, 452, 454, 457, 460, 462, 464, + 466, 471, 473, 475, 477, 479, 481, 484, + 491, 494, 498, 500, 503, 506, 510, 512, + 514, 516, 522, 525, 527, 528, 551, 586, + 591, 595, 596, 598, 600, 606, 608, 615, + 621, 623, 626, 628, 631, 636, 642, 647, + 652, 661, 666, 669, 672, 677, 710, 716, + 719, 721, 723, 726, 731, 742, 753, 764, + 774, 784, 792, 802, 811, 824, 830, 838, + 847, 856, 865, 872, 882, 888, 895, 898, + 900, 904, 906, 913, 917, 923, 925, 970, + 972, 978, 983, 988, 994, 1000, 1005, 1008, + 1012, 1015, 1018, 1020, 1023, 1026, 1029, 1035, + 1041, 1043, 1046, 1049, 1051, 1055, 1057, 1061, + 1064, 1068, 1070, 1074, 1078, 1084, 1087, 1090, + 1093, 1101, 1104, 1107, 1115, 1119, 1127, 1146, + 1149, 1154, 1156, 1158, 1170, 1174, 1176, 1178, + 1180, 1183, 1185, 1189, 1194, 1198, 1204, 1210, + 1212, 1218, 1222, 1224, 1227, 1230, 1260, 1262, + 1264, 1268, 1273, 1277, 1280, 1283, 1287, 1289, + 1295, 1297, 1301, 1307, 1311, 1315, 1319, 1323, + 1326, 1331, 1336, 1342, 1349, 1352, 1356, 1357, + 1361, 1363, 1366, 1383, 1391, 1395, 1397, 1399, + 1401, 1403, 1405, 1408, 1411, 1414, 1417, 1419, + 1421, 1424, 1430, 1441, 1479, 1485, 1488, 1490, + 1492, 1494, 1497, 1500, 1503, 1507, 1510, 1514, + 1516, 1519, 1521, 1523, 1526, 1533, 1536, 1538, + 1541, 1544, 1547, 1557, 1559, 1561, 1565, 1567, + 1570, 1572, 1574, 1599, 1603, 1605, 1609, 1611, + 1615, 1619, 1623, 1629, 1633, 1640, 1643, 1653, + 1663, 1666, 1670, 1674, 1678, 1681, 1684, 1686, + 1688, 1691, 1693, 1701, 1703, 1705, 1707, 1711, + 1715, 1717, 1729, 1731, 1734, 1737, 1741, 1743, + 1747, 1750, 1754, 1757, 1762, 1782, 1785, 1789, + 1791, 1793, 1801, 1803, 1810, 1815, 1817, 1821, + 1824, 1827, 1830, 1833, 1836, 1839, 1843, 1850, + 1854, 1864, 1884, 1890, 1894, 1896, 1899, 1901, + 1903, 1909, 1912, 1914, 1915, 1917, 1940, 1942, + 1944, 1946, 1948, 1951, 1955, 1959, 1964, 1970, + 1974, 1976, 1978, 1981, 2010, 2015, 2017, 2019, + 2022, 2028, 2032, 2040, 2048, 2055, 2059, 2066, + 2069, 2075, 2078, 2086, 2093, 2096, 2104, 2106, + 2113, 2116, 2119, 2123, 2126, 2133, 2135, 2140, + 2142, 2167, 2169, 2176, 2181, 2183, 2186, 2189, + 2191, 2196, 2199, 2201, 2204, 2206, 2208, 2210, + 2214, 2218, 2221, 2226, 2230, 2232, 2234, 2237, + 2243, 2246, 2253, 2256, 2259, 2261, 2263, 2265, + 2267, 2270, 2272, 2274, 2291, 2293, 2296, 2298, + 2300, 2305, 2308, 2313, 2316, 2318, 2321, 2328, + 2330, 2335, 2340, 2344, 2348, 2354, 2356, 2359, + 2361, 2368, 2375, 2377, 2379, 2381, 2387, 2389, + 2412, 2415, 2419, 2423, 2425, 2429, 2431, 2434, + 2439, 2441, 2444, 2448, 2456, 2458, 2462, 2465, + 2468, 2472, 2474, 2476, 2479, 2486, 2488, 2490, + 2492, 2494, 2496, 2499, 2507, 2510, 2514, 2516, + 2518, 2521, 2524, 2528, 2530, 2532, 2534, 2540, + 2543, 2545, 2546, 2551, 2553, 2560, 2563, 2568, + 2575, 2597, 2599, 2601, 2603, 2605, 2608, 2614, + 2619, 2621, 2628, 2631, 2636, 2643, 2648, 2655, + 2664, 2669, 2672, 2675, 2681, 2714, 2720, 2723, + 2725, 2728, 2735, 2746, 2758, 2769, 2780, 2790, + 2800, 2810, 2820, 2833, 2840, 2848, 2859, 2868, + 2878, 2885, 2897, 2903, 2911, 2914, 2917, 2921, + 2924, 2932, 2936, 2942, 2944, 2991, 2993, 3000, + 3006, 3010, 3016, 3022, 3024, 3029, 3033, 3037, + 3041, 3044, 3048, 3052, 3056, 3062, 3069, 3072, + 3075, 3080, 3088, 3091, 3110, 3114, 3122, 3124, + 3128, 3132, 3138, 3144, 3148, 3150, 3180, 3184, + 3189, 3193, 3196, 3202, 3206, 3214, 3219, 3223, + 3227, 3235, 3238, 3244, 3249, 3255, 3260, 3277, + 3285, 3290, 3294, 3298, 3301, 3304, 3307, 3313, + 3324, 3362, 3364, 3367, 3371, 3375, 3385, 3389, + 3415, 3419, 3423, 3427, 3430, 3435, 3439, 3443, + 3451, 3455, 3460, 3470, 3480, 3483, 3489, 3493, + 3497, 3502, 3505, 3508, 3512, 3524, 3527, 3530, + 3533, 3538, 3542, 3545, 3549, 3554, 3574, 3577, + 3581, 3583, 3588, 3591, 3594, 3598, 3605, 3609, + 3611, 3617, 3620, 3622, 3623, 3625, 3629, 3632, + 3637, 3641, 3643, 3645, 3647, 3676, 3681, 3683, + 3685, 3688, 3692, 3696, 3702, 3709, 3714, 3718, + 3724, 3727, 3732, 3735, 3741, 3747, 3750, 3756, + 3758, 3764, 3767, 3769, 3773, 3775, 3781, 3783, + 3788, 3790, 3812, 3814, 3820, 3824, 3826, 3829, + 3832, 3834, 3837, 3839, 3841, 3844, 3846, 3850, + 3852, 3855, 3858, 3861, 3863, 3865, 3871, 3874, + 3881, 3884, 3887, 3889, 3891, 3893, 3895, 3898, + 3900, 3902, 3918, 3921, 3923, 3925, 3930, 3933, + 3936, 3938, 3940, 3943, 3946, 3948, 3952, 3957, + 3961, 3964, 3971, 3977, 3981, 3984, 3986, 3993, + 3999, 4001, 4003, 4005, 4011, 4013, 4033, 4036, + 4038, 4042, 4045, 4047, 4050, 4053, 4055, 4057, + 4061, 4069, 4071, 4073, 4076, 4079, 4081, 4083, + 4085, 4090, 4092, 4094, 4096, 4098, 4100, 4103, + 4110, 4113, 4117, 4119, 4122, 4125, 4129, 4131, + 4133, 4135, 4141, 4144, 4146, 4147, 4153, 4160, + 4162, 4169, 4175, 4178, 4183, 4191, 4196, 4203, + 4212, 4217, 4220, 4223, 4229, 4262, 4268, 4271, + 4273, 4276, 4283, 4294, 4306, 4317, 4328, 4338, + 4348, 4358, 4368, 4381, 4388, 4396, 4407, 4416, + 4426, 4433, 4445, 4451, 4459, 4462, 4465, 4469, + 4472, 4480, 4484, 4490, 4492, 4539, 4541, 4548, + 4554, 4558, 4564, 4570, 4572, 4577, 4581, 4585, + 4589, 4592, 4596, 4600, 4604, 4610, 4617, 4620, + 4623, 4631, 4634, 4653, 4660, 4668, 4670, 4674, + 4678, 4684, 4690, 4694, 4696, 4726, 4731, 4735, + 4738, 4744, 4748, 4756, 4761, 4765, 4769, 4777, + 4780, 4786, 4791, 4797, 4802, 4819, 4826, 4831, + 4837, 4840, 4846, 4849, 4855, 4866, 4904, 4906, + 4909, 4913, 4923, 4927, 4953, 4957, 4961, 4965, + 4970, 4974, 4978, 4986, 4990, 4995, 5005, 5015, + 5018, 5024, 5028, 5032, 5037, 5040, 5043, 5055, + 5058, 5061, 5065, 5068, 5072, 5077, 5097, 5100, + 5104, 5106, 5109, 5112, 5116, 5123, 5127, 5129, + 5135, 5138, 5140, 5141, 5143, 5148, 5155, 5164, + 5169, 5172, 5175, 5181, 5214, 5220, 5223, 5225, + 5228, 5235, 5246, 5258, 5269, 5280, 5290, 5300, + 5310, 5320, 5333, 5340, 5348, 5359, 5368, 5378, + 5385, 5397, 5403, 5411, 5414, 5417, 5421, 5424, + 5432, 5436, 5442, 5444, 5491, 5493, 5500, 5506, + 5510, 5516, 5522, 5524, 5529, 5533, 5537, 5541, + 5544, 5548, 5552, 5556, 5562, 5569, 5572, 5575, + 5583, 5586, 5605, 5609, 5616, 5618, 5622, 5626, + 5632, 5643, 5648, 5650, 5652, 5654, 5656, 5659, + 5663, 5667, 5670, 5675, 5679, 5681, 5683, 5685, + 5714, 5719, 5721, 5723, 5726, 5730, 5734, 5740, + 5747, 5752, 5756, 5762, 5765, 5770, 5773, 5779, + 5785, 5788, 5794, 5796, 5802, 5805, 5807, 5811, + 5813, 5819, 5821, 5826, 5828, 5850, 5852, 5858, + 5862, 5864, 5867, 5870, 5872, 5875, 5877, 5879, + 5882, 5884, 5888, 5890, 5893, 5896, 5899, 5901, + 5903, 5909, 5912, 5919, 5923, 5929, 5931, 5933, + 5935, 5937, 5945, 5948, 5951, 5954, 5956, 5958, + 5960, 5976, 5979, 5981, 5983, 5988, 5991, 5994, + 5996, 5998, 6001, 6004, 6006, 6010, 6015, 6019, + 6022, 6031, 6033, 6037, 6039, 6041, 6043, 6045, + 6047, 6054, 6060, 6062, 6064, 6066, 6072, 6074, + 6094, 6097, 6099, 6103, 6106, 6108, 6111, 6114, + 6116, 6118, 6122, 6130, 6132, 6134, 6137, 6140, + 6142, 6144, 6146, 6151, 6153, 6155, 6157, 6159, + 6162, 6164, 6167, 6174, 6177, 6181, 6183, 6186, + 6189, 6193, 6195, 6197, 6199, 6205, 6208, 6210, + 6211, 6215, 6245, 6250, 6254, 6257, 6263, 6267, + 6275, 6280, 6284, 6288, 6296, 6299, 6305, 6310, + 6316, 6321, 6338, 6346, 6350, 6353, 6356, 6360, + 6366, 6377, 6415, 6417, 6420, 6424, 6434, 6438, + 6464, 6468, 6472, 6476, 6481, 6485, 6489, 6497, + 6501, 6506, 6516, 6526, 6529, 6535, 6539, 6543, + 6548, 6551, 6554, 6566, 6569, 6572, 6576, 6579, + 6584, 6589, 6609, 6612, 6616, 6618, 6621, 6624, + 6628, 6635, 6639, 6641, 6647, 6650, 6652, 6653, + 6655, 6660, 6662, 6669, 6672, 6678, 6685, 6691, + 6698, 6707, 6712, 6715, 6718, 6725, 6758, 6764, + 6767, 6769, 6772, 6778, 6789, 6800, 6811, 6821, + 6831, 6840, 6850, 6860, 6873, 6880, 6888, 6898, + 6907, 6917, 6924, 6935, 6941, 6949, 6952, 6955, + 6959, 6962, 6970, 6974, 6980, 6982, 7029, 7031, + 7038, 7042, 7046, 7052, 7058, 7060, 7064, 7068, + 7072, 7076, 7079, 7083, 7087, 7091, 7096, 7103, + 7106, 7109, 7117, 7120, 7139, 7145, 7154, 7156, + 7160, 7164, 7170, 7176, 7180, 7182, 7212, 7217, + 7221, 7224, 7230, 7234, 7241, 7246, 7250, 7254, + 7260, 7263, 7269, 7274, 7280, 7285, 7302, 7310, + 7316, 7323, 7326, 7333, 7336, 7342, 7353, 7391, + 7393, 7396, 7400, 7410, 7414, 7440, 7444, 7447, + 7451, 7456, 7460, 7464, 7471, 7475, 7480, 7490, + 7500, 7503, 7508, 7512, 7516, 7520, 7523, 7526, + 7538, 7541, 7544, 7548, 7551, 7555, 7560, 7580, + 7583, 7587, 7589, 7592, 7595, 7599, 7606, 7610, + 7612, 7618, 7621, 7623, 7624, 7626, 7632, 7637, + 7639, 7643, 7651, 7656, 7661, 7668, 7670, 7672, + 7676, 7709, 7711, 7713, 7715, 7719, 7727, 7736, + 7747, 7756, 7765, 7774, 7783, 7792, 7804, 7811, + 7818, 7827, 7835, 7844, 7850, 7859, 7865, 7873, + 7876, 7879, 7883, 7886, 7894, 7898, 7902, 7904, + 7951, 7953, 7960, 7966, 7969, 7973, 7978, 7980, + 7985, 7989, 7992, 7996, 8000, 8004, 8009, 8013, + 8015, 8017, 8021, 8024, 8043, 8050, 8058, 8060, + 8063, 8067, 8073, 8079, 8083, 8085, 8115, 8119, + 8121, 8128, 8132, 8135, 8142, 8144, 8148, 8153, + 8157, 8161, 8178, 8186, 8191, 8194, 8196, 8202, + 8213, 8251, 8253, 8256, 8259, 8267, 8270, 8295, + 8299, 8302, 8305, 8308, 8314, 8317, 8321, 8330, + 8339, 8344, 8347, 8350, 8355, 8358, 8370, 8373, + 8376, 8378, 8382, 8387, 8407, 8410, 8414, 8416, + 8419, 8422, 8426, 8433, 8436, 8438, 8444, 8447, + 8449, 8454, 8456, 8463, 8466, 8471, 8478, 8483, + 8490, 8499, 8504, 8507, 8510, 8516, 8549, 8555, + 8558, 8560, 8563, 8570, 8581, 8593, 8604, 8615, + 8625, 8635, 8645, 8655, 8668, 8675, 8683, 8694, + 8703, 8713, 8720, 8732, 8738, 8746, 8749, 8752, + 8756, 8759, 8767, 8771, 8777, 8779, 8826, 8828, + 8835, 8841, 8845, 8851, 8857, 8859, 8864, 8868, + 8872, 8876, 8878, 8880, 8883, 8887, 8891, 8895, + 8901, 8908, 8911, 8914, 8919, 8927, 8930, 8949, + 8953, 8960, 8962, 8966, 8970, 8976, 8987, 8992, + 8996, 9026, 9030, 9035, 9039, 9042, 9048, 9052, + 9060, 9065, 9069, 9073, 9081, 9084, 9090, 9095, + 9101, 9106, 9123, 9131, 9135, 9139, 9142, 9145, + 9149, 9155, 9166, 9204, 9206, 9209, 9213, 9217, + 9227, 9231, 9257, 9261, 9265, 9269, 9272, 9277, + 9281, 9285, 9293, 9297, 9302, 9312, 9322, 9325, + 9331, 9335, 9339, 9344, 9347, 9349, 9352, 9356, + 9368, 9371, 9374, 9377, 9382, 9386, 9389, 9394, + 9399, 9419, 9422, 9426, 9428, 9433, 9436, 9439, + 9443, 9450, 9454, 9456, 9462, 9465, 9467, 9468, + 9470, 9475, 9477, 9484, 9487, 9493, 9500, 9506, + 9513, 9522, 9527, 9530, 9533, 9540, 9573, 9579, + 9582, 9584, 9587, 9593, 9604, 9615, 9626, 9636, + 9646, 9655, 9665, 9675, 9688, 9695, 9703, 9713, + 9722, 9732, 9739, 9750, 9756, 9764, 9767, 9770, + 9774, 9777, 9785, 9789, 9795, 9797, 9844, 9846, + 9853, 9857, 9861, 9867, 9873, 9875, 9879, 9883, + 9887, 9891, 9894, 9898, 9902, 9906, 9911, 9918, + 9921, 9924, 9932, 9935, 9954, 9960, 9969, 9971, + 9975, 9979, 9985, 9991, 9995, 9997, 10027, 10032, + 10036, 10039, 10045, 10049, 10056, 10061, 10065, 10069, + 10075, 10078, 10084, 10089, 10095, 10100, 10117, 10125, + 10131, 10138, 10141, 10148, 10151, 10157, 10168, 10206, + 10208, 10211, 10215, 10225, 10229, 10255, 10259, 10262, + 10266, 10271, 10275, 10279, 10286, 10290, 10295, 10305, + 10315, 10318, 10323, 10327, 10331, 10335, 10338, 10341, + 10353, 10356, 10359, 10363, 10366, 10370, 10375, 10395, + 10398, 10402, 10404, 10407, 10410, 10414, 10421, 10425, + 10427, 10433, 10436, 10438, 10439, 10441, 10443, 10445, + 10447, 10449, 10452, 10456, 10460, 10465, 10471, 10475, + 10477, 10479, 10482, 10511, 10516, 10518, 10520, 10523, + 10529, 10533, 10541, 10549, 10556, 10560, 10567, 10570, + 10576, 10579, 10587, 10594, 10597, 10605, 10607, 10614, + 10617, 10620, 10624, 10627, 10634, 10636, 10641, 10643, + 10668, 10670, 10677, 10682, 10684, 10687, 10690, 10692, + 10697, 10700, 10702, 10705, 10707, 10711, 10715, 10718, + 10723, 10727, 10729, 10731, 10734, 10740, 10743, 10750, + 10753, 10756, 10758, 10760, 10762, 10764, 10767, 10769, + 10771, 10788, 10790, 10793, 10795, 10797, 10802, 10805, + 10810, 10813, 10815, 10818, 10825, 10827, 10832, 10837, + 10841, 10845, 10851, 10853, 10856, 10858, 10865, 10872, + 10874, 10876, 10878, 10884, 10886, 10909, 10912, 10916, + 10920, 10922, 10926, 10928, 10931, 10936, 10938, 10941, + 10945, 10953, 10955, 10959, 10962, 10965, 10969, 10971, + 10974, 10981, 10983, 10985, 10987, 10989, 10991, 10994, + 11002, 11005, 11009, 11011, 11013, 11016, 11019, 11023, + 11025, 11027, 11029, 11035, 11038, 11040, 11041, 11046, + 11048, 11055, 11058, 11064, 11071, 11077, 11085, 11094, + 11099, 11102, 11105, 11112, 11145, 11151, 11154, 11156, + 11159, 11166, 11177, 11189, 11200, 11211, 11221, 11231, + 11241, 11251, 11264, 11271, 11279, 11290, 11299, 11309, + 11316, 11328, 11334, 11342, 11345, 11348, 11352, 11355, + 11363, 11367, 11373, 11375, 11422, 11424, 11431, 11437, + 11441, 11447, 11453, 11455, 11460, 11464, 11468, 11472, + 11475, 11479, 11483, 11487, 11493, 11500, 11503, 11506, + 11514, 11517, 11536, 11542, 11551, 11553, 11557, 11561, + 11567, 11573, 11577, 11579, 11609, 11614, 11618, 11621, + 11627, 11631, 11639, 11644, 11648, 11652, 11660, 11663, + 11669, 11674, 11680, 11685, 11702, 11710, 11716, 11719, + 11722, 11728, 11739, 11777, 11779, 11782, 11786, 11796, + 11800, 11826, 11830, 11834, 11838, 11843, 11847, 11851, + 11859, 11863, 11868, 11878, 11888, 11891, 11897, 11901, + 11905, 11910, 11913, 11916, 11928, 11931, 11934, 11938, + 11941, 11945, 11950, 11970, 11973, 11977, 11979, 11982, + 11985, 11989, 11996, 12000, 12002, 12008, 12011, 12013, + 12014, 12016, 12022, 12024, 12031, 12034, 12039, 12047, + 12052, 12059, 12068, 12073, 12076, 12079, 12085, 12118, + 12124, 12127, 12129, 12132, 12139, 12150, 12162, 12173, + 12184, 12194, 12204, 12214, 12224, 12237, 12244, 12252, + 12263, 12272, 12282, 12289, 12301, 12307, 12315, 12318, + 12321, 12325, 12328, 12336, 12340, 12346, 12348, 12395, + 12397, 12404, 12410, 12414, 12420, 12426, 12428, 12433, + 12437, 12441, 12445, 12448, 12452, 12456, 12460, 12466, + 12473, 12476, 12479, 12487, 12490, 12509, 12516, 12524, + 12526, 12530, 12534, 12540, 12546, 12550, 12552, 12582, + 12587, 12591, 12594, 12600, 12604, 12612, 12617, 12621, + 12625, 12633, 12636, 12642, 12647, 12653, 12658, 12675, + 12683, 12688, 12691, 12694, 12700, 12711, 12749, 12751, + 12754, 12758, 12768, 12772, 12798, 12802, 12806, 12810, + 12815, 12819, 12823, 12831, 12835, 12840, 12850, 12860, + 12863, 12869, 12873, 12877, 12882, 12885, 12888, 12900, + 12903, 12906, 12910, 12913, 12917, 12922, 12942, 12945, + 12949, 12951, 12954, 12957, 12961, 12968, 12972, 12974, + 12980, 12983, 12985, 12986, 12988, 12993, 12995, 13002, + 13005, 13010, 13017, 13022, 13029, 13038, 13043, 13046, + 13049, 13055, 13088, 13094, 13097, 13099, 13102, 13109, + 13120, 13132, 13143, 13154, 13164, 13174, 13184, 13194, + 13207, 13214, 13222, 13233, 13242, 13252, 13259, 13271, + 13277, 13285, 13288, 13291, 13295, 13298, 13306, 13310, + 13316, 13318, 13365, 13367, 13374, 13380, 13384, 13390, + 13396, 13398, 13403, 13407, 13411, 13415, 13418, 13422, + 13426, 13430, 13436, 13443, 13446, 13449, 13457, 13460, + 13479, 13483, 13490, 13492, 13496, 13500, 13506, 13517, + 13522, 13526, 13556, 13561, 13565, 13568, 13574, 13578, + 13586, 13591, 13595, 13599, 13607, 13610, 13616, 13621, + 13627, 13632, 13649, 13657, 13661, 13665, 13668, 13671, + 13675, 13681, 13692, 13730, 13732, 13735, 13739, 13749, + 13753, 13779, 13783, 13787, 13791, 13796, 13800, 13804, + 13812, 13816, 13821, 13831, 13841, 13844, 13850, 13854, + 13858, 13863, 13866, 13869, 13881, 13884, 13887, 13891, + 13894, 13899, 13904, 13924, 13927, 13931, 13933, 13936, + 13939, 13943, 13950, 13954, 13956, 13962, 13965, 13967, + 13968, 13970, 13975, 13977, 13984, 13987, 13992, 13999, + 14004, 14011, 14020, 14025, 14028, 14031, 14037, 14070, + 14076, 14079, 14081, 14084, 14091, 14102, 14114, 14125, + 14136, 14146, 14156, 14166, 14176, 14189, 14196, 14204, + 14215, 14224, 14234, 14241, 14253, 14259, 14267, 14270, + 14273, 14277, 14280, 14288, 14292, 14298, 14300, 14347, + 14349, 14356, 14362, 14366, 14372, 14378, 14380, 14385, + 14389, 14393, 14397, 14400, 14404, 14408, 14412, 14418, + 14425, 14428, 14431, 14439, 14442, 14461, 14465, 14473, + 14475, 14479, 14483, 14489, 14500, 14505, 14509, 14539, + 14544, 14548, 14551, 14557, 14561, 14569, 14574, 14578, + 14582, 14590, 14593, 14599, 14604, 14610, 14615, 14632, + 14640, 14644, 14647, 14651, 14657, 14668, 14706, 14708, + 14711, 14715, 14725, 14729, 14755, 14759, 14763, 14767, + 14772, 14776, 14780, 14788, 14792, 14797, 14807, 14817, + 14820, 14826, 14830, 14834, 14839, 14842, 14845, 14857, + 14860, 14863, 14867, 14870, 14875, 14880, 14900, 14903, + 14907, 14909, 14912, 14915, 14919, 14926, 14930, 14932, + 14938, 14941, 14943, 14944, 14946, 14948, 14950, 14952, + 14954, 14957, 14961, 14965, 14968, 14973, 14977, 14979, + 14981, 14983, 15012, 15017, 15019, 15021, 15024, 15028, + 15032, 15038, 15045, 15050, 15054, 15060, 15063, 15068, + 15071, 15077, 15083, 15086, 15092, 15094, 15100, 15103, + 15105, 15109, 15111, 15117, 15119, 15124, 15126, 15148, + 15150, 15156, 15160, 15162, 15165, 15168, 15170, 15173, + 15175, 15177, 15180, 15182, 15186, 15188, 15191, 15194, + 15197, 15199, 15201, 15207, 15210, 15217, 15220, 15223, + 15225, 15227, 15229, 15231, 15234, 15236, 15238, 15254, + 15257, 15259, 15261, 15266, 15269, 15272, 15274, 15276, + 15279, 15282, 15284, 15288, 15293, 15297, 15300, 15306, + 15308, 15311, 15313, 15320, 15326, 15328, 15330, 15332, + 15338, 15340, 15360, 15363, 15365, 15369, 15372, 15374, + 15377, 15380, 15382, 15384, 15388, 15396, 15398, 15400, + 15403, 15406, 15408, 15410, 15412, 15417, 15419, 15421, + 15423, 15425, 15427, 15430, 15437, 15440, 15444, 15446, + 15449, 15452, 15456, 15458, 15460, 15462, 15468, 15471, + 15473, 15474, 15479, 15481, 15488, 15491, 15496, 15502, + 15507, 15512, 15521, 15526, 15529, 15532, 15537, 15570, + 15576, 15579, 15581, 15584, 15589, 15600, 15611, 15622, + 15632, 15642, 15650, 15660, 15669, 15682, 15688, 15696, + 15705, 15714, 15723, 15730, 15740, 15746, 15753, 15756, + 15758, 15762, 15764, 15771, 15775, 15781, 15783, 15828, + 15830, 15836, 15841, 15845, 15851, 15857, 15859, 15862, + 15865, 15869, 15873, 15876, 15880, 15882, 15886, 15890, + 15896, 15899, 15902, 15910, 15913, 15932, 15935, 15940, + 15942, 15946, 15950, 15956, 15962, 15966, 15968, 15998, + 16003, 16007, 16010, 16016, 16020, 16026, 16030, 16034, + 16038, 16042, 16045, 16050, 16055, 16061, 16065, 16082, + 16090, 16093, 16096, 16099, 16105, 16116, 16154, 16156, + 16159, 16163, 16173, 16177, 16202, 16206, 16208, 16212, + 16216, 16220, 16224, 16230, 16234, 16237, 16247, 16257, + 16260, 16264, 16268, 16272, 16275, 16278, 16280, 16292, + 16295, 16298, 16302, 16305, 16309, 16314, 16334, 16337, + 16341, 16343, 16346, 16349, 16353, 16360, 16364, 16366, + 16372, 16375, 16377, 16378, 16380, 16385, 16387, 16394, + 16397, 16403, 16410, 16416, 16424, 16433, 16438, 16441, + 16444, 16451, 16484, 16490, 16493, 16495, 16498, 16505, + 16516, 16528, 16539, 16550, 16560, 16570, 16580, 16590, + 16603, 16610, 16618, 16629, 16638, 16648, 16655, 16667, + 16673, 16681, 16684, 16687, 16691, 16694, 16702, 16706, + 16712, 16714, 16761, 16763, 16770, 16776, 16780, 16786, + 16792, 16794, 16799, 16803, 16807, 16811, 16814, 16818, + 16822, 16826, 16832, 16839, 16842, 16845, 16853, 16856, + 16875, 16881, 16890, 16892, 16896, 16900, 16906, 16912, + 16916, 16918, 16948, 16953, 16957, 16960, 16966, 16970, + 16978, 16983, 16987, 16991, 16999, 17002, 17008, 17013, + 17019, 17024, 17041, 17049, 17055, 17058, 17061, 17067, + 17078, 17116, 17118, 17121, 17125, 17135, 17139, 17165, + 17169, 17173, 17177, 17182, 17186, 17190, 17198, 17202, + 17207, 17217, 17227, 17230, 17236, 17240, 17244, 17249, + 17252, 17255, 17267, 17270, 17273, 17277, 17280, 17284, + 17289, 17309, 17312, 17316, 17318, 17321, 17324, 17328, + 17335, 17339, 17341, 17347, 17350, 17352, 17353, 17355, + 17360, 17362, 17369, 17372, 17377, 17384, 17389, 17396, + 17405, 17410, 17413, 17416, 17422, 17455, 17461, 17464, + 17466, 17469, 17476, 17487, 17499, 17510, 17521, 17531, + 17541, 17551, 17561, 17574, 17581, 17589, 17600, 17609, + 17619, 17626, 17638, 17644, 17652, 17655, 17658, 17662, + 17665, 17673, 17677, 17683, 17685, 17732, 17734, 17741, + 17747, 17751, 17757, 17763, 17765, 17770, 17774, 17778, + 17782, 17785, 17789, 17793, 17797, 17803, 17810, 17813, + 17816, 17824, 17827, 17846, 17850, 17858, 17860, 17864, + 17868, 17874, 17885, 17890, 17894, 17924, 17929, 17933, + 17936, 17942, 17946, 17954, 17959, 17963, 17967, 17975, + 17978, 17984, 17989, 17995, 18000, 18017, 18025, 18029, + 18032, 18036, 18042, 18053, 18091, 18093, 18096, 18100, + 18110, 18114, 18140, 18144, 18148, 18152, 18157, 18161, + 18165, 18173, 18177, 18182, 18192, 18202, 18205, 18211, + 18215, 18219, 18224, 18227, 18230, 18242, 18245, 18248, + 18252, 18255, 18260, 18265, 18285, 18288, 18292, 18294, + 18297, 18300, 18304, 18311, 18315, 18317, 18323, 18326, + 18328, 18329, 18331, 18333, 18335, 18337, 18339, 18342, + 18346, 18350, 18353, 18358, 18362, 18364, 18366, 18368, + 18397, 18419, 18426, 18429, 18445, 18451, 18458, 18460, + 18466, 18469, 18472, 18479, 18490, 18502, 18513, 18524, + 18534, 18544, 18554, 18564, 18577, 18584, 18592, 18603, + 18612, 18622, 18629, 18641, 18647, 18655, 18658, 18661, + 18669, 18673, 18679, 18686, 18692, 18694, 18700, 18702, + 18709, 18712, 18717, 18725, 18730, 18737, 18746, 18751, + 18754, 18757, 18763, 18796, 18802, 18805, 18807, 18810, + 18817, 18828, 18840, 18851, 18862, 18872, 18882, 18892, + 18902, 18915, 18922, 18930, 18941, 18950, 18960, 18967, + 18979, 18985, 18993, 18996, 18999, 19003, 19006, 19014, + 19018, 19024, 19026, 19076, 19078, 19085, 19091, 19092, + 19094, 19098, 19104, 19110, 19112, 19117, 19121, 19125, + 19129, 19132, 19136, 19140, 19144, 19150, 19157, 19160, + 19163, 19171, 19174, 19193, 19200, 19208, 19210, 19214, + 19218, 19224, 19232, 19236, 19238, 19241, 19245, 19247, + 19249, 19251, 19253, 19255, 19258, 19262, 19266, 19269, + 19274, 19278, 19280, 19282, 19284, 19313, 19318, 19320, + 19322, 19325, 19329, 19333, 19339, 19346, 19351, 19355, + 19361, 19364, 19369, 19372, 19378, 19384, 19387, 19393, + 19395, 19401, 19404, 19406, 19410, 19412, 19418, 19420, + 19425, 19427, 19452, 19454, 19460, 19464, 19465, 19467, + 19469, 19472, 19475, 19477, 19480, 19482, 19484, 19487, + 19489, 19493, 19495, 19498, 19501, 19504, 19506, 19508, + 19514, 19517, 19524, 19527, 19530, 19532, 19534, 19536, + 19538, 19546, 19548, 19550, 19552, 19554, 19556, 19574, + 19577, 19579, 19581, 19586, 19589, 19592, 19594, 19597, + 19600, 19603, 19605, 19609, 19614, 19618, 19621, 19622, + 19626, 19628, 19631, 19637, 19639, 19642, 19644, 19650, + 19657, 19663, 19665, 19667, 19669, 19675, 19677, 19697, + 19700, 19702, 19706, 19709, 19711, 19714, 19717, 19719, + 19721, 19725, 19733, 19735, 19737, 19740, 19743, 19745, + 19747, 19749, 19754, 19756, 19758, 19760, 19762, 19764, + 19767, 19774, 19777, 19781, 19783, 19786, 19789, 19793, + 19795, 19797, 19799, 19805, 19808, 19839, 19844, 19848, + 19851, 19857, 19861, 19869, 19874, 19879, 19883, 19891, + 19894, 19900, 19905, 19911, 19916, 19917, 19921, 19923, + 19926, 19943, 19951, 19956, 19959, 19961, 19967, 19978, + 20016, 20018, 20021, 20025, 20035, 20039, 20065, 20069, + 20073, 20077, 20082, 20086, 20090, 20098, 20102, 20107, + 20117, 20127, 20130, 20136, 20140, 20144, 20149, 20152, + 20155, 20167, 20170, 20173, 20177, 20180, 20184, 20189, + 20209, 20212, 20216, 20218, 20221, 20224, 20228, 20235, + 20239, 20241, 20247, 20250, 20252, 20254, 20258, 20264, + 20270, 20275, 20279, 20283, 20287, 20290, 20294, 20298, + 20304, 20311, 20314, 20317, 20325, 20330, 20338, 20342, + 20346, 20352, 20355, 20357, 20359, 20361, 20363, 20366, + 20370, 20374, 20377, 20382, 20386, 20388, 20390, 20392, + 20421, 20426, 20428, 20430, 20433, 20437, 20441, 20447, + 20454, 20459, 20463, 20469, 20472, 20477, 20480, 20486, + 20492, 20495, 20501, 20503, 20509, 20512, 20514, 20518, + 20520, 20526, 20528, 20533, 20535, 20557, 20559, 20565, + 20569, 20571, 20574, 20577, 20579, 20582, 20584, 20586, + 20589, 20591, 20595, 20597, 20600, 20603, 20606, 20608, + 20610, 20616, 20619, 20626, 20629, 20632, 20634, 20636, + 20638, 20640, 20643, 20645, 20647, 20663, 20666, 20668, + 20670, 20675, 20678, 20681, 20683, 20685, 20688, 20691, + 20693, 20697, 20702, 20706, 20709, 20715, 20717, 20720, + 20722, 20729, 20735, 20737, 20739, 20741, 20747, 20749, + 20769, 20772, 20774, 20778, 20781, 20783, 20786, 20789, + 20791, 20793, 20797, 20805, 20807, 20809, 20812, 20815, + 20817, 20819, 20821, 20826, 20828, 20830, 20832, 20834, + 20836, 20839, 20846, 20849, 20853, 20855, 20858, 20861, + 20865, 20867, 20869, 20871, 20877, 20880, 20882, 20883, + 20885, 20887, 20897, 20903, 20905, 20912, 20915, 20920, + 20928, 20933, 20940, 20949, 20954, 20957, 20960, 20966, + 20999, 21005, 21008, 21010, 21013, 21020, 21031, 21043, + 21054, 21065, 21075, 21085, 21095, 21105, 21118, 21125, + 21133, 21144, 21153, 21163, 21170, 21182, 21188, 21196, + 21199, 21202, 21206, 21209, 21217, 21221, 21227, 21229, + 21276, 21278, 21285, 21291, 21295, 21301, 21307, 21309, + 21314, 21318, 21322, 21326, 21329, 21333, 21337, 21341, + 21347, 21354, 21357, 21360, 21368, 21371, 21390, 21397, + 21405, 21407, 21411, 21415, 21421, 21427, 21431, 21433, + 21463, 21468, 21472, 21475, 21481, 21485, 21493, 21498, + 21502, 21506, 21514, 21517, 21523, 21528, 21534, 21539, + 21556, 21564, 21569, 21572, 21575, 21581, 21592, 21630, + 21632, 21635, 21639, 21649, 21653, 21679, 21683, 21687, + 21691, 21696, 21700, 21704, 21712, 21716, 21721, 21731, + 21741, 21744, 21750, 21754, 21758, 21763, 21766, 21769, + 21781, 21784, 21787, 21791, 21794, 21798, 21803, 21823, + 21826, 21830, 21832, 21835, 21838, 21842, 21849, 21853, + 21855, 21861, 21864, 21866, 21867, 21869, 21871, 21873, + 21875, 21877, 21880, 21884, 21888, 21891, 21896, 21900, + 21902, 21904, 21906, 21935, 21940, 21942, 21944, 21947, + 21951, 21955, 21961, 21968, 21973, 21977, 21983, 21986, + 21991, 21994, 22000, 22006, 22009, 22015, 22017, 22023, + 22026, 22028, 22032, 22034, 22040, 22042, 22047, 22049, + 22074, 22076, 22082, 22086, 22088, 22091, 22094, 22096, + 22099, 22101, 22103, 22106, 22108, 22112, 22114, 22117, + 22120, 22123, 22125, 22127, 22133, 22136, 22143, 22146, + 22149, 22151, 22153, 22155, 22157, 22165, 22167, 22169, + 22187, 22190, 22192, 22194, 22199, 22202, 22205, 22207, + 22210, 22213, 22216, 22218, 22222, 22227, 22231, 22234, + 22240, 22242, 22245, 22248, 22254, 22261, 22267, 22269, + 22271, 22273, 22279, 22281, 22301, 22304, 22306, 22310, + 22313, 22315, 22318, 22321, 22323, 22325, 22329, 22337, + 22339, 22341, 22344, 22347, 22349, 22351, 22353, 22358, + 22360, 22362, 22364, 22366, 22368, 22371, 22378, 22381, + 22385, 22387, 22390, 22393, 22397, 22399, 22401, 22403, + 22409, 22412, 22414, 22415, 22417, 22419, 22421, 22423, + 22426, 22430, 22434, 22437, 22442, 22446, 22448, 22450, + 22452, 22481, 22486, 22488, 22490, 22493, 22497, 22501, + 22507, 22514, 22519, 22523, 22529, 22532, 22537, 22540, + 22546, 22552, 22555, 22561, 22563, 22569, 22572, 22574, + 22578, 22580, 22586, 22588, 22593, 22595, 22617, 22619, + 22625, 22629, 22631, 22634, 22637, 22639, 22642, 22644, + 22646, 22649, 22651, 22655, 22657, 22660, 22663, 22666, + 22668, 22670, 22676, 22679, 22686, 22690, 22696, 22698, + 22700, 22702, 22704, 22712, 22715, 22718, 22721, 22723, + 22725, 22727, 22743, 22746, 22748, 22750, 22755, 22758, + 22761, 22763, 22765, 22768, 22771, 22773, 22777, 22782, + 22786, 22789, 22798, 22800, 22804, 22806, 22808, 22810, + 22817, 22823, 22825, 22827, 22829, 22835, 22837, 22857, + 22860, 22862, 22866, 22869, 22871, 22874, 22877, 22879, + 22881, 22885, 22893, 22895, 22897, 22900, 22903, 22905, + 22907, 22909, 22914, 22916, 22918, 22920, 22922, 22925, + 22927, 22930, 22937, 22940, 22944, 22946, 22949, 22952, + 22956, 22958, 22960, 22962, 22968, 22971, 22973, 22974, + 22976, 22978, 22980, 22982, 22984, 22987, 22991, 22995, + 22998, 23003, 23007, 23009, 23011, 23013, 23042, 23047, + 23049, 23051, 23054, 23058, 23062, 23068, 23075, 23080, + 23084, 23090, 23093, 23098, 23101, 23107, 23113, 23116, + 23122, 23124, 23130, 23133, 23135, 23139, 23141, 23147, + 23149, 23154, 23156, 23178, 23180, 23186, 23190, 23192, + 23195, 23198, 23200, 23203, 23205, 23207, 23210, 23212, + 23216, 23218, 23221, 23224, 23227, 23229, 23231, 23237, + 23240, 23247, 23250, 23253, 23255, 23257, 23259, 23261, + 23264, 23266, 23268, 23284, 23287, 23289, 23291, 23296, + 23299, 23302, 23304, 23306, 23309, 23312, 23314, 23318, + 23323, 23327, 23330, 23336, 23338, 23341, 23343, 23350, + 23356, 23358, 23360, 23362, 23368, 23370, 23390, 23393, + 23395, 23399, 23402, 23404, 23407, 23410, 23412, 23414, + 23418, 23426, 23428, 23430, 23433, 23436, 23438, 23440, + 23442, 23447, 23449, 23451, 23453, 23455, 23457, 23460, + 23467, 23470, 23474, 23476, 23479, 23482, 23486, 23488, + 23490, 23492, 23498, 23501, 23503, 23504, 23509, 23511, + 23513, 23515, 23517, 23519, 23522, 23526, 23530, 23533, + 23538, 23542, 23544, 23546, 23548, 23577, 23582, 23584, + 23586, 23589, 23593, 23597, 23603, 23610, 23615, 23619, + 23625, 23628, 23633, 23636, 23642, 23648, 23651, 23657, + 23659, 23665, 23668, 23670, 23674, 23676, 23682, 23684, + 23689, 23691, 23713, 23715, 23721, 23725, 23727, 23730, + 23733, 23735, 23738, 23740, 23742, 23745, 23747, 23751, + 23753, 23756, 23759, 23762, 23764, 23766, 23772, 23775, + 23782, 23785, 23788, 23790, 23792, 23794, 23796, 23799, + 23801, 23803, 23819, 23822, 23824, 23826, 23831, 23834, + 23837, 23839, 23841, 23844, 23847, 23849, 23853, 23858, + 23862, 23865, 23871, 23873, 23876, 23878, 23885, 23891, + 23893, 23895, 23897, 23903, 23905, 23925, 23928, 23930, + 23934, 23937, 23939, 23942, 23945, 23947, 23949, 23953, + 23961, 23963, 23965, 23968, 23971, 23973, 23975, 23977, + 23982, 23984, 23986, 23988, 23990, 23992, 23995, 24002, + 24005, 24009, 24011, 24014, 24017, 24021, 24023, 24025, + 24027, 24033, 24036, 24038, 24039, 24041, 24043, 24045, + 24048, 24052, 24056, 24059, 24064, 24068, 24070, 24072, + 24074, 24103, 24125, 24132, 24135, 24151, 24157, 24164, + 24166, 24168, 24173, 24177, 24180, 24186, 24190, 24198, + 24203, 24208, 24212, 24220, 24223, 24229, 24235, 24240, + 24242, 24248, 24250, 24257, 24260, 24265, 24273, 24278, + 24285, 24294, 24299, 24302, 24305, 24311, 24344, 24350, + 24353, 24355, 24358, 24365, 24376, 24388, 24399, 24410, + 24420, 24430, 24440, 24450, 24463, 24470, 24478, 24489, + 24498, 24508, 24515, 24527, 24533, 24541, 24544, 24547, + 24551, 24554, 24562, 24566, 24572, 24574, 24624, 24626, + 24633, 24639, 24643, 24649, 24655, 24657, 24662, 24666, + 24670, 24674, 24677, 24681, 24685, 24689, 24695, 24702, + 24705, 24708, 24716, 24719, 24738, 24745, 24753, 24755, + 24759, 24763, 24769, 24777, 24781, 24783, 24814, 24819, + 24823, 24826, 24832, 24836, 24844, 24849, 24854, 24858, + 24866, 24869, 24875, 24880, 24886, 24891, 24908, 24916, + 24921, 24924, 24927, 24933, 24944, 24982, 24984, 24987, + 24991, 25001, 25005, 25031, 25035, 25039, 25043, 25048, + 25052, 25056, 25064, 25068, 25073, 25083, 25093, 25096, + 25102, 25106, 25110, 25115, 25118, 25121, 25133, 25136, + 25139, 25143, 25146, 25150, 25155, 25175, 25178, 25182, + 25184, 25187, 25190, 25194, 25201, 25205, 25207, 25213, + 25216, 25218, 25219, 25221, 25223, 25225, 25227, 25230, + 25234, 25238, 25241, 25246, 25250, 25252, 25254, 25256, + 25285, 25307, 25314, 25317, 25333, 25339, 25346, 25348, + 25350, 25352, 25360, 25364, 25367, 25370, 25374, 25380, + 25418, 25421, 25425, 25435, 25439, 25465, 25469, 25473, + 25477, 25482, 25486, 25490, 25498, 25502, 25507, 25517, + 25527, 25530, 25536, 25540, 25544, 25549, 25552, 25555, + 25567, 25570, 25573, 25577, 25580, 25585, 25588, 25593, + 25613, 25620, 25624, 25630, 25632, 25634, 25636, 25638, + 25640, 25643, 25647, 25651, 25654, 25659, 25663, 25665, + 25667, 25669, 25698, 25703, 25705, 25707, 25710, 25714, + 25718, 25724, 25731, 25736, 25740, 25746, 25749, 25754, + 25757, 25763, 25769, 25772, 25778, 25780, 25786, 25789, + 25791, 25795, 25797, 25803, 25805, 25810, 25812, 25834, + 25836, 25842, 25846, 25848, 25851, 25854, 25856, 25859, + 25861, 25863, 25866, 25868, 25872, 25874, 25877, 25880, + 25883, 25885, 25887, 25893, 25896, 25903, 25906, 25909, + 25911, 25913, 25915, 25917, 25920, 25922, 25924, 25940, + 25943, 25945, 25947, 25952, 25955, 25958, 25960, 25962, + 25965, 25968, 25970, 25974, 25979, 25983, 25986, 25992, + 25994, 25997, 25999, 26007, 26013, 26015, 26017, 26019, + 26025, 26027, 26047, 26050, 26052, 26056, 26059, 26061, + 26064, 26067, 26069, 26071, 26075, 26083, 26085, 26087, + 26090, 26093, 26095, 26097, 26099, 26104, 26106, 26108, + 26110, 26112, 26114, 26117, 26124, 26127, 26131, 26133, + 26136, 26139, 26143, 26145, 26147, 26149, 26151, 26157, + 26160, 26162, 26163, 26165, 26168, 26169, 26172, 26174, + 26178, 26180, 26182, 26185, 26187, 26191, 26193, 26236, + 26258, 26260, 26301, 26342, 26382, 26423, 26460, 26501, + 26538, 26561, 26598, 26638, 26675, 26712, 26739, 26761, + 26786, 26827, 26871, 26898, 26920, 26963, 26998, 27039, + 27076, 27117, 27159, 27202, 27245, 27287, 27331, 27376, + 27399, 27422, 27466, 27507, 27548, 27616, 27677, 27723, + 27765, 27820, 27865, 27911, 27952, 27980, 28006, 28033, + 28056, 28079, 28102, 28126, 28151, 28180, 28206, 28232, + 28260, 28283, 28306, 28329, 28354, 28408, 28476, 28516, + 28543, 28594, 28638, 28679, 28722, 28744, 28785, 28830, + 28873, 28914, 28956, 28998, 29041, 29066, 29104, 29136, + 29159, 29203, 29244, 29285, 29327, 29368, 29411, 29452, + 29496, 29540, 29582, 29623, 29664, 29709, 29751, 29793, + 29835, 29876, 29917, 29958, 29999, 30040, 30081, 30123, + 30164, 30205, 30249, 30293, 30337, 30378, 30419, 30463, + 30508, 30549, 30592, 30636, 30679, 30721, 30762, 30804, + 30845, 30890, 30949, 30993, 31034, 31080, 31121, 31166, + 31208, 31253, 31298, 31345, 31394, 31440, 31483, 31528, + 31570, 31614, 31658, 31705, 31750, 31794, 31841, 31882, + 31927, 31969, 32010, 32053, 32094, 32139, 32180, 32224, + 32265, 32292, 32315, 32338, 32361, 32384, 32407, 32430, + 32454, 32479, 32504, 32528, 32554, 32579, 32602, 32625, + 32649, 32674, 32699, 32723, 32749, 32774, 32797, 32820, + 32843, 32893, 32936, 32964, 32988, 33025, 33052, 33080, + 33103, 33126, 33149, 33172, 33222, 33265, 33293, 33317, + 33354, 33381, 33409, 33432, 33460, 33487, 33511, 33537, + 33565, 33591, 33619, 33649, 33675, 33699, 33723, 33750, + 33804, 33875, 33915, 33939, 33984, 34006, 34043, 34083, + 34107, 34130, 34152, 34174, 34200, 34223, 34246, 34269, + 34292, 34315, 34338, 34361, 34384, 34408, 34433, 34458, + 34482, 34508, 34533, 34556, 34579, 34603, 34628, 34653, + 34677, 34703, 34728, 34751, 34774, 34797, 34847, 34890, + 34918, 34942, 34979, 35006, 35034, 35057, 35080, 35103, + 35126, 35176, 35219, 35247, 35271, 35308, 35335, 35363, + 35386, 35410, 35435, 35460, 35487, 35515, 35541, 35566, + 35593, 35617, 35643, 35667, 35694, 35721, 35745, 35772, + 35795, 35822, 35846, 35869, 35894, 35917, 35944, 35967, + 35993, 36016, 36039, 36066, 36091, 36114, 36138, 36162, + 36185, 36209, 36232, 36255, 36279, 36302, 36327, 36350, + 36374, 36398, 36422, 36445, 36468, 36495, 36519, 36543, + 36567, 36590, 36613, 36636, 36659, 36682, 36705, 36729, + 36752, 36775, 36801, 36825, 36849, 36872, 36895, 36919, + 36943, 36966, 36991, 37017, 37042, 37066, 37089, 37113, + 37136, 37163, 37204, 37230, 37253, 37281, 37304, 37331, + 37356, 37378, 37402, 37454, 37494, 37538, 37579, 37622, + 37649, 37672, 37713, 37757, 37785, 37809, 37835, 37864, + 37890, 37918, 37948, 37974, 38017, 38058, 38100, 38143, + 38186, 38228, 38272, 38317, 38341, 38365, 38392, 38446, + 38517, 38557, 38586, 38638, 38679, 38724, 38767, 38808, + 38850, 38892, 38935, 38957, 38999, 39041, 39082, 39123, + 39164, 39205, 39246, 39287, 39329, 39370, 39411, 39455, + 39499, 39524, 39562, 39594, 39617, 39661, 39702, 39743, + 39787, 39832, 39873, 39916, 39960, 40003, 40045, 40086, + 40128, 40169, 40214, 40273, 40317, 40358, 40404, 40445, + 40490, 40534, 40575, 40616, 40658, 40699, 40742, 40783, + 40827, 40871, 40913, 40954, 40995, 41040, 41082, 41126, + 41167, 41208, 41276, 41337, 41383, 41425, 41480, 41525, + 41571, 41612, 41654, 41699, 41744, 41791, 41840, 41886, + 41929, 41974, 42016, 42060, 42104, 42151, 42196, 42240, + 42287, 42328, 42373, 42415, 42456, 42499, 42540, 42585, + 42626, 42670, 42711, 42753, 42791, +} + +var _s_indicies []int16 = []int16{ + 1, 0, 2, 1, 2, 1, 1, 0, + 1, 1, 0, 1, 1, 1, 0, 1, + 1, 1, 0, 1, 1, 0, 1, 1, + 1, 1, 0, 1, 1, 1, 0, 0, + 1, 1, 0, 1, 0, 3, 4, 5, + 6, 7, 9, 10, 11, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 8, + 12, 0, 1, 1, 1, 1, 2, 1, + 2, 1, 2, 2, 2, 1, 2, 2, + 2, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 1, 2, 2, 2, 2, + 2, 2, 1, 2, 2, 2, 2, 1, + 1, 1, 1, 2, 1, 1, 1, 1, + 1, 2, 1, 1, 2, 1, 1, 1, + 1, 2, 1, 1, 2, 2, 2, 2, + 2, 2, 1, 1, 1, 1, 1, 1, + 2, 1, 1, 2, 2, 2, 2, 2, + 2, 1, 1, 2, 1, 1, 1, 1, + 1, 2, 1, 1, 2, 1, 2, 1, + 1, 1, 2, 1, 2, 1, 1, 1, + 1, 1, 2, 1, 2, 1, 1, 1, + 1, 2, 1, 2, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, + 51, 0, 1, 2, 1, 1, 1, 1, + 1, 2, 1, 1, 1, 2, 1, 2, + 1, 1, 2, 1, 1, 2, 1, 2, + 2, 2, 1, 1, 2, 1, 2, 1, + 1, 2, 1, 2, 1, 1, 1, 2, + 1, 2, 1, 1, 2, 2, 2, 1, + 1, 1, 2, 1, 2, 1, 2, 1, + 1, 1, 1, 1, 2, 1, 1, 2, + 52, 53, 54, 55, 56, 57, 0, 1, + 1, 2, 1, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 58, 59, 0, + 1, 2, 1, 2, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 0, 1, 1, 2, 1, + 2, 1, 2, 1, 1, 1, 1, 2, + 1, 1, 2, 2, 2, 1, 1, 2, + 1, 2, 1, 1, 2, 2, 2, 1, + 1, 2, 1, 1, 1, 2, 1, 1, + 1, 1, 2, 1, 1, 1, 2, 1, + 1, 2, 75, 76, 56, 61, 77, 0, + 1, 2, 1, 1, 2, 1, 2, 78, + 79, 80, 81, 82, 83, 0, 84, 85, + 86, 87, 88, 2, 1, 2, 1, 2, + 1, 2, 1, 1, 1, 1, 1, 2, + 1, 2, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, + 103, 100, 104, 105, 106, 2, 1, 1, + 2, 2, 1, 2, 2, 2, 1, 1, + 1, 2, 1, 2, 1, 1, 2, 2, + 2, 1, 1, 2, 1, 2, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 2, 2, 1, 1, 1, + 2, 2, 2, 1, 2, 1, 1, 2, + 1, 2, 107, 108, 109, 110, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 111, + 2, 1, 1, 2, 112, 113, 114, 115, + 116, 117, 2, 1, 1, 2, 2, 2, + 2, 1, 1, 2, 1, 1, 2, 2, + 2, 1, 1, 1, 1, 2, 118, 2, + 1, 2, 119, 0, 120, 121, 122, 124, + 123, 2, 1, 1, 2, 2, 1, 1, + 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 126, 125, 149, + 150, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, + 175, 177, 178, 179, 180, 148, 148, 151, + 176, 2, 148, 181, 148, 148, 2, 148, + 148, 148, 2, 148, 2, 148, 148, 2, + 2, 2, 2, 2, 2, 148, 2, 181, + 2, 2, 148, 2, 148, 2, 181, 148, + 148, 148, 148, 148, 2, 2, 148, 2, + 181, 148, 2, 148, 2, 2, 148, 2, + 2, 181, 2, 148, 181, 181, 181, 148, + 148, 2, 181, 181, 181, 148, 2, 181, + 148, 181, 148, 2, 2, 2, 2, 181, + 181, 2, 2, 2, 148, 148, 181, 148, + 181, 2, 2, 148, 181, 181, 2, 148, + 148, 148, 181, 148, 2, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 2, 148, 148, + 148, 148, 181, 2, 148, 181, 2, 148, + 2, 181, 2, 148, 148, 181, 148, 148, + 2, 148, 181, 2, 2, 2, 181, 181, + 2, 2, 2, 2, 181, 148, 148, 2, + 2, 2, 2, 2, 148, 2, 148, 2, + 181, 181, 181, 148, 148, 148, 148, 148, + 148, 148, 181, 2, 2, 2, 2, 2, + 2, 148, 2, 148, 2, 181, 148, 181, + 148, 148, 148, 148, 148, 148, 181, 2, + 2, 2, 148, 148, 2, 148, 2, 181, + 148, 181, 148, 148, 148, 148, 148, 148, + 181, 2, 148, 181, 181, 181, 181, 148, + 148, 181, 2, 181, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 181, 2, + 148, 181, 181, 181, 181, 2, 148, 181, + 148, 148, 148, 148, 181, 2, 2, 2, + 2, 2, 148, 2, 148, 2, 181, 148, + 181, 148, 148, 148, 148, 148, 181, 2, + 148, 181, 181, 181, 181, 148, 181, 148, + 2, 148, 181, 148, 148, 148, 181, 2, + 2, 2, 148, 2, 2, 148, 2, 148, + 2, 181, 148, 181, 148, 148, 148, 2, + 181, 181, 148, 181, 181, 181, 2, 181, + 181, 2, 181, 2, 181, 181, 181, 2, + 181, 2, 148, 181, 181, 181, 181, 181, + 2, 148, 148, 181, 2, 181, 181, 148, + 181, 181, 2, 181, 2, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 247, 151, + 152, 248, 249, 250, 251, 252, 151, 153, + 151, 2, 181, 2, 181, 181, 181, 181, + 181, 2, 181, 181, 181, 148, 2, 2, + 2, 2, 2, 148, 2, 2, 2, 2, + 2, 148, 2, 2, 2, 2, 2, 148, + 148, 148, 148, 148, 2, 2, 2, 148, + 2, 181, 2, 148, 148, 148, 2, 2, + 2, 148, 148, 2, 2, 2, 148, 148, + 148, 2, 2, 2, 148, 148, 148, 181, + 148, 181, 2, 148, 181, 148, 148, 181, + 2, 181, 2, 2, 2, 181, 181, 148, + 2, 2, 148, 181, 148, 148, 2, 2, + 148, 148, 181, 181, 2, 148, 181, 2, + 181, 181, 181, 2, 181, 2, 181, 148, + 181, 2, 148, 2, 2, 181, 181, 148, + 181, 148, 148, 2, 181, 2, 148, 148, + 181, 2, 148, 148, 2, 181, 181, 181, + 148, 181, 148, 181, 2, 181, 181, 2, + 2, 2, 148, 2, 2, 2, 2, 2, + 2, 2, 148, 148, 148, 148, 2, 148, + 148, 148, 148, 148, 148, 148, 2, 253, + 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 151, 264, 265, 266, 267, 268, + 269, 2, 181, 181, 2, 148, 148, 181, + 181, 2, 148, 2, 181, 2, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, + 148, 2, 148, 148, 148, 2, 2, 148, + 148, 2, 2, 148, 148, 148, 2, 2, + 148, 2, 181, 2, 148, 148, 148, 148, + 148, 2, 181, 2, 2, 148, 148, 148, + 148, 148, 148, 2, 148, 148, 148, 148, + 181, 2, 148, 2, 270, 271, 272, 151, + 273, 2, 148, 181, 148, 2, 181, 2, + 148, 148, 2, 2, 2, 148, 153, 274, + 275, 153, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 152, + 297, 153, 151, 2, 2, 148, 148, 2, + 2, 2, 2, 148, 148, 148, 181, 181, + 2, 148, 181, 148, 2, 181, 2, 148, + 148, 148, 2, 2, 2, 2, 148, 148, + 2, 181, 181, 181, 181, 2, 148, 148, + 2, 181, 148, 181, 2, 148, 148, 2, + 148, 2, 181, 148, 181, 148, 2, 181, + 2, 2, 148, 181, 148, 181, 2, 148, + 2, 2, 181, 148, 181, 2, 181, 148, + 181, 181, 2, 181, 181, 181, 181, 2, + 181, 148, 181, 148, 181, 2, 148, 148, + 148, 148, 148, 148, 2, 2, 2, 148, + 148, 181, 181, 2, 151, 298, 299, 2, + 151, 2, 148, 2, 2, 148, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 313, 314, 151, 2, 181, + 148, 148, 148, 148, 148, 148, 2, 148, + 148, 148, 2, 2, 148, 148, 2, 2, + 148, 148, 2, 2, 148, 2, 2, 148, + 181, 181, 2, 148, 148, 2, 181, 2, + 148, 148, 2, 148, 2, 181, 148, 2, + 148, 148, 148, 148, 181, 2, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, + 2, 325, 326, 153, 327, 328, 329, 330, + 331, 332, 333, 334, 335, 153, 151, 336, + 337, 338, 153, 339, 340, 341, 342, 343, + 344, 345, 346, 347, 348, 349, 350, 351, + 352, 353, 153, 259, 151, 354, 2, 148, + 148, 148, 148, 148, 2, 2, 2, 148, + 2, 148, 148, 2, 181, 2, 148, 148, + 2, 181, 2, 148, 148, 148, 2, 2, + 181, 2, 148, 148, 148, 2, 2, 2, + 2, 148, 2, 148, 148, 148, 2, 2, + 148, 2, 148, 148, 148, 2, 148, 148, + 148, 148, 148, 148, 2, 2, 2, 148, + 148, 2, 148, 148, 2, 148, 148, 2, + 148, 148, 2, 148, 181, 181, 181, 181, + 148, 148, 148, 181, 2, 148, 2, 148, + 2, 148, 148, 181, 2, 148, 2, 148, + 148, 2, 148, 2, 148, 2, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 368, + 372, 373, 374, 375, 376, 377, 2, 181, + 148, 181, 2, 2, 181, 148, 2, 2, + 181, 148, 2, 181, 148, 181, 2, 181, + 148, 148, 2, 181, 148, 181, 2, 148, + 148, 148, 2, 2, 181, 148, 148, 181, + 2, 148, 148, 148, 148, 148, 148, 2, + 181, 2, 148, 148, 181, 148, 148, 148, + 148, 148, 148, 181, 2, 148, 181, 181, + 181, 181, 148, 181, 181, 181, 2, 148, + 181, 2, 2, 148, 2, 181, 148, 181, + 181, 2, 2, 148, 2, 181, 148, 2, + 181, 148, 181, 2, 181, 2, 148, 2, + 2, 2, 148, 148, 2, 153, 378, 379, + 380, 151, 153, 151, 2, 2, 148, 2, + 148, 2, 148, 153, 379, 151, 2, 153, + 381, 151, 2, 2, 148, 153, 382, 343, + 383, 384, 385, 386, 153, 387, 388, 151, + 2, 2, 148, 148, 181, 2, 148, 181, + 2, 148, 148, 148, 2, 2, 148, 2, + 181, 2, 148, 181, 148, 2, 153, 389, + 390, 2, 2, 2, 148, 148, 148, 181, + 181, 2, 391, 392, 393, 153, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, + 404, 405, 406, 407, 151, 2, 181, 181, + 2, 2, 2, 2, 181, 181, 2, 2, + 148, 2, 2, 2, 2, 2, 2, 2, + 148, 2, 148, 2, 2, 2, 2, 2, + 2, 148, 148, 148, 148, 148, 2, 2, + 148, 2, 2, 2, 148, 2, 2, 148, + 2, 2, 148, 2, 2, 148, 2, 2, + 148, 181, 181, 2, 2, 2, 181, 181, + 181, 181, 2, 153, 408, 409, 410, 411, + 151, 2, 2, 181, 2, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 2, + 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 2, 148, 148, 148, 148, + 148, 2, 412, 413, 414, 2, 148, 2, + 2, 2, 148, 2, 148, 415, 2, 416, + 417, 155, 419, 418, 2, 181, 181, 2, + 2, 181, 181, 2, 181, 422, 423, 424, + 425, 426, 427, 428, 429, 430, 431, 432, + 433, 434, 435, 436, 437, 438, 439, 440, + 441, 442, 421, 420, 443, 420, 443, 420, + 420, 443, 443, 420, 443, 443, 420, 443, + 443, 443, 420, 443, 443, 443, 420, 421, + 443, 443, 421, 420, 443, 443, 443, 443, + 421, 420, 443, 443, 443, 420, 420, 443, + 443, 420, 421, 443, 420, 444, 445, 446, + 447, 448, 450, 451, 452, 454, 455, 456, + 457, 458, 459, 460, 461, 462, 463, 464, + 465, 466, 467, 468, 469, 470, 471, 449, + 453, 420, 443, 443, 443, 443, 420, 443, + 420, 443, 420, 420, 420, 443, 420, 420, + 420, 421, 420, 443, 443, 443, 443, 420, + 420, 420, 420, 420, 420, 421, 420, 443, + 420, 420, 420, 420, 421, 420, 420, 443, + 420, 420, 420, 420, 421, 420, 443, 443, + 443, 443, 420, 443, 443, 443, 443, 443, + 421, 420, 443, 443, 420, 443, 443, 443, + 443, 421, 420, 443, 443, 420, 420, 420, + 420, 420, 420, 421, 420, 443, 443, 443, + 443, 443, 443, 421, 420, 443, 443, 420, + 420, 420, 420, 420, 420, 421, 420, 443, + 443, 420, 443, 443, 443, 443, 421, 443, + 420, 443, 443, 420, 443, 421, 420, 443, + 443, 443, 420, 443, 421, 420, 443, 443, + 443, 443, 421, 443, 420, 443, 420, 443, + 443, 443, 443, 420, 443, 420, 472, 473, + 474, 475, 476, 477, 478, 479, 480, 481, + 482, 483, 484, 485, 486, 487, 488, 489, + 490, 491, 492, 493, 494, 495, 420, 443, + 420, 421, 443, 443, 443, 443, 443, 420, + 443, 443, 421, 443, 420, 443, 420, 443, + 443, 420, 443, 443, 420, 443, 420, 420, + 420, 421, 420, 443, 443, 421, 420, 443, + 420, 443, 443, 420, 421, 2, 421, 2, + 443, 420, 443, 443, 443, 420, 421, 421, + 443, 420, 443, 443, 420, 420, 421, 420, + 420, 443, 443, 443, 421, 420, 443, 420, + 443, 420, 421, 421, 420, 443, 443, 443, + 443, 443, 420, 443, 443, 420, 496, 497, + 498, 499, 500, 501, 420, 443, 443, 420, + 443, 443, 420, 443, 420, 443, 420, 443, + 420, 443, 420, 502, 503, 420, 443, 420, + 443, 420, 504, 505, 506, 507, 508, 509, + 510, 511, 512, 513, 514, 515, 516, 517, + 518, 519, 420, 421, 420, 443, 443, 420, + 443, 420, 443, 420, 443, 443, 443, 443, + 420, 443, 443, 420, 420, 421, 420, 420, + 443, 421, 443, 420, 443, 420, 443, 443, + 420, 420, 421, 420, 420, 421, 420, 443, + 443, 420, 443, 443, 421, 443, 420, 443, + 443, 443, 443, 420, 443, 443, 443, 420, + 443, 443, 421, 420, 520, 521, 500, 506, + 522, 420, 443, 420, 443, 443, 420, 443, + 420, 523, 524, 525, 526, 527, 528, 420, + 529, 530, 531, 504, 532, 533, 420, 443, + 420, 443, 420, 443, 420, 443, 443, 443, + 443, 443, 420, 443, 420, 534, 535, 536, + 537, 538, 539, 540, 541, 542, 543, 544, + 545, 546, 547, 548, 549, 546, 550, 551, + 552, 553, 504, 420, 443, 443, 420, 420, + 421, 420, 443, 420, 420, 420, 443, 421, + 420, 443, 443, 421, 420, 443, 420, 443, + 443, 420, 420, 420, 421, 420, 443, 443, + 420, 443, 421, 420, 443, 443, 443, 420, + 443, 443, 443, 443, 443, 443, 443, 420, + 443, 420, 420, 421, 420, 443, 443, 443, + 420, 420, 420, 443, 420, 421, 420, 443, + 443, 420, 421, 2, 443, 421, 420, 504, + 554, 555, 484, 556, 557, 420, 443, 420, + 443, 420, 443, 420, 443, 420, 558, 420, + 443, 443, 420, 559, 560, 561, 562, 563, + 564, 565, 420, 443, 443, 420, 420, 420, + 420, 443, 443, 420, 421, 420, 443, 443, + 420, 420, 420, 443, 443, 443, 443, 420, + 566, 420, 443, 420, 567, 420, 568, 569, + 423, 424, 570, 420, 443, 443, 420, 420, + 443, 443, 148, 571, 148, 148, 420, 571, + 420, 420, 420, 148, 420, 148, 420, 571, + 420, 571, 148, 420, 420, 571, 420, 148, + 571, 148, 571, 571, 572, 572, 420, 573, + 574, 575, 576, 577, 578, 579, 580, 581, + 582, 583, 584, 585, 586, 587, 588, 589, + 590, 591, 592, 593, 420, 594, 420, 594, + 420, 420, 594, 594, 420, 594, 594, 420, + 594, 594, 594, 595, 595, 420, 148, 595, + 148, 148, 420, 420, 595, 420, 420, 148, + 420, 148, 420, 595, 420, 595, 148, 420, + 420, 595, 420, 148, 595, 148, 595, 595, + 572, 572, 420, 595, 595, 595, 148, 420, + 421, 595, 148, 595, 421, 148, 420, 420, + 420, 420, 595, 595, 421, 420, 420, 148, + 148, 595, 148, 595, 420, 420, 148, 595, + 595, 420, 148, 148, 421, 148, 595, 148, + 420, 596, 597, 184, 598, 599, 600, 601, + 602, 603, 604, 605, 606, 607, 608, 609, + 610, 611, 612, 613, 614, 615, 616, 617, + 618, 619, 620, 621, 622, 623, 624, 625, + 626, 420, 148, 148, 148, 148, 595, 420, + 148, 595, 420, 595, 420, 148, 148, 595, + 148, 420, 148, 420, 421, 148, 595, 420, + 420, 420, 595, 595, 420, 420, 420, 420, + 595, 148, 148, 420, 420, 420, 420, 420, + 148, 420, 421, 148, 420, 595, 595, 595, + 148, 148, 148, 148, 148, 148, 148, 595, + 420, 420, 420, 420, 420, 420, 148, 420, + 421, 148, 420, 595, 148, 595, 148, 148, + 148, 148, 148, 148, 595, 420, 420, 420, + 148, 148, 420, 148, 420, 421, 420, 595, + 148, 595, 148, 148, 148, 148, 148, 148, + 595, 420, 148, 595, 595, 595, 595, 148, + 148, 595, 421, 420, 595, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 595, + 420, 148, 595, 595, 595, 595, 421, 420, + 148, 595, 148, 148, 148, 148, 595, 420, + 420, 420, 420, 420, 148, 420, 148, 420, + 421, 420, 595, 148, 595, 148, 148, 148, + 148, 148, 595, 420, 148, 595, 595, 595, + 595, 148, 595, 421, 148, 420, 148, 595, + 148, 148, 148, 595, 420, 420, 420, 148, + 420, 420, 148, 420, 421, 420, 148, 420, + 595, 148, 595, 148, 148, 148, 420, 595, + 595, 148, 595, 595, 421, 595, 420, 595, + 595, 420, 595, 421, 420, 595, 595, 595, + 420, 595, 421, 420, 148, 595, 595, 595, + 595, 421, 595, 420, 148, 148, 595, 420, + 595, 595, 148, 595, 595, 420, 595, 420, + 627, 628, 629, 217, 218, 219, 220, 221, + 630, 223, 224, 225, 226, 227, 228, 631, + 632, 633, 634, 635, 234, 636, 236, 637, + 483, 484, 638, 639, 640, 641, 642, 643, + 644, 645, 646, 647, 151, 152, 648, 249, + 250, 251, 252, 151, 153, 151, 420, 595, + 420, 421, 595, 595, 595, 595, 595, 420, + 595, 595, 421, 595, 148, 420, 420, 595, + 420, 148, 148, 148, 595, 148, 595, 420, + 148, 595, 148, 148, 595, 420, 595, 420, + 420, 420, 421, 420, 595, 595, 421, 148, + 420, 595, 148, 148, 420, 148, 595, 595, + 420, 148, 595, 420, 595, 595, 595, 420, + 421, 421, 595, 420, 595, 148, 595, 420, + 148, 420, 421, 420, 420, 595, 595, 148, + 595, 148, 421, 148, 420, 595, 420, 148, + 148, 595, 420, 421, 148, 421, 148, 2, + 595, 595, 595, 148, 595, 148, 595, 420, + 595, 595, 420, 649, 650, 255, 651, 257, + 258, 259, 260, 261, 262, 263, 151, 652, + 265, 653, 267, 654, 269, 420, 595, 595, + 571, 420, 420, 148, 148, 420, 420, 595, + 420, 571, 595, 420, 420, 595, 420, 148, + 595, 420, 420, 148, 148, 148, 148, 148, + 595, 420, 655, 656, 272, 151, 273, 420, + 148, 595, 148, 420, 595, 420, 153, 274, + 275, 153, 657, 658, 659, 660, 280, 281, + 282, 661, 284, 662, 663, 664, 665, 666, + 667, 668, 669, 670, 671, 295, 296, 152, + 672, 153, 151, 420, 2, 421, 2, 148, + 148, 148, 595, 595, 420, 148, 595, 148, + 420, 595, 420, 148, 595, 595, 595, 595, + 420, 148, 595, 148, 595, 420, 148, 148, + 420, 421, 420, 148, 420, 595, 421, 148, + 595, 148, 420, 595, 420, 420, 148, 595, + 148, 595, 420, 148, 420, 421, 420, 420, + 421, 420, 595, 148, 595, 420, 595, 148, + 595, 421, 595, 420, 595, 595, 595, 595, + 420, 595, 148, 595, 148, 595, 420, 148, + 595, 595, 421, 420, 673, 674, 302, 303, + 304, 305, 306, 307, 675, 676, 677, 678, + 312, 679, 680, 151, 420, 595, 572, 148, + 148, 572, 572, 572, 420, 572, 572, 572, + 148, 2, 595, 595, 571, 420, 571, 148, + 148, 420, 595, 420, 148, 571, 148, 420, + 595, 148, 420, 148, 148, 148, 148, 595, + 420, 681, 682, 317, 318, 319, 683, 684, + 685, 686, 324, 420, 325, 326, 153, 327, + 328, 687, 330, 688, 332, 689, 334, 335, + 153, 151, 690, 337, 338, 153, 339, 340, + 341, 342, 343, 344, 345, 346, 691, 348, + 349, 692, 351, 352, 353, 153, 259, 151, + 354, 420, 595, 420, 595, 420, 148, 420, + 595, 420, 148, 2, 421, 2, 148, 148, + 595, 595, 595, 595, 148, 148, 148, 595, + 420, 148, 148, 595, 420, 693, 694, 695, + 696, 697, 698, 699, 700, 701, 364, 702, + 703, 704, 705, 706, 707, 708, 705, 709, + 710, 552, 711, 375, 712, 377, 420, 595, + 148, 595, 420, 420, 421, 420, 595, 148, + 420, 420, 595, 148, 421, 2, 595, 148, + 595, 421, 420, 595, 148, 148, 420, 595, + 148, 595, 420, 420, 148, 420, 420, 421, + 148, 420, 595, 148, 148, 595, 420, 595, + 420, 421, 420, 148, 148, 595, 148, 148, + 148, 148, 148, 148, 595, 420, 148, 595, + 595, 595, 595, 148, 595, 595, 595, 420, + 148, 595, 420, 420, 148, 420, 421, 420, + 595, 148, 595, 595, 420, 420, 148, 420, + 595, 148, 420, 421, 420, 595, 148, 595, + 420, 595, 421, 420, 421, 2, 2, 148, + 153, 382, 713, 714, 715, 716, 386, 153, + 717, 718, 151, 420, 148, 421, 2, 148, + 595, 420, 148, 595, 420, 148, 421, 148, + 148, 2, 420, 595, 420, 148, 595, 148, + 420, 153, 389, 719, 420, 148, 148, 595, + 595, 420, 720, 721, 722, 153, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, + 723, 724, 725, 726, 151, 420, 595, 595, + 420, 420, 420, 420, 595, 595, 420, 2, + 2, 421, 2, 148, 595, 595, 420, 420, + 420, 595, 595, 595, 595, 420, 153, 727, + 409, 410, 411, 151, 420, 420, 595, 420, + 148, 728, 420, 729, 730, 731, 733, 732, + 420, 595, 595, 420, 420, 595, 595, 420, + 595, 594, 594, 594, 420, 594, 594, 420, + 594, 594, 594, 594, 420, 594, 594, 594, + 420, 420, 594, 594, 420, 594, 420, 734, + 735, 736, 737, 738, 740, 741, 742, 744, + 745, 746, 747, 748, 749, 750, 751, 752, + 753, 754, 755, 756, 757, 758, 759, 760, + 761, 739, 743, 420, 594, 594, 594, 594, + 420, 594, 420, 594, 420, 420, 420, 594, + 420, 420, 420, 594, 594, 594, 594, 420, + 420, 420, 420, 420, 420, 594, 420, 420, + 420, 420, 420, 420, 594, 420, 420, 420, + 420, 594, 594, 594, 594, 420, 594, 594, + 594, 594, 594, 420, 594, 594, 420, 594, + 594, 594, 594, 420, 594, 594, 420, 420, + 420, 420, 420, 420, 594, 594, 594, 594, + 594, 594, 420, 594, 594, 420, 420, 420, + 420, 420, 420, 594, 594, 420, 594, 594, + 594, 594, 594, 420, 594, 594, 420, 594, + 420, 594, 594, 594, 420, 594, 420, 594, + 594, 594, 594, 594, 420, 594, 420, 594, + 594, 594, 594, 420, 594, 420, 762, 763, + 764, 765, 766, 767, 768, 769, 770, 771, + 772, 773, 774, 775, 776, 777, 778, 779, + 780, 781, 782, 420, 594, 420, 594, 594, + 594, 594, 594, 420, 594, 594, 594, 420, + 594, 420, 594, 594, 420, 594, 594, 420, + 594, 420, 420, 420, 594, 594, 420, 594, + 420, 594, 594, 420, 594, 420, 594, 594, + 594, 420, 594, 420, 594, 594, 420, 420, + 420, 594, 594, 594, 420, 594, 420, 594, + 420, 594, 594, 594, 594, 594, 420, 594, + 594, 420, 783, 784, 785, 786, 787, 788, + 420, 594, 594, 420, 594, 594, 420, 594, + 420, 594, 420, 594, 420, 594, 420, 789, + 790, 420, 594, 420, 594, 420, 791, 792, + 793, 794, 795, 796, 797, 798, 799, 800, + 801, 802, 803, 804, 805, 420, 594, 594, + 420, 594, 420, 594, 420, 594, 594, 594, + 594, 420, 594, 594, 420, 420, 420, 594, + 594, 420, 594, 420, 594, 594, 420, 420, + 420, 594, 594, 420, 594, 594, 594, 420, + 594, 594, 594, 594, 420, 594, 594, 594, + 420, 594, 594, 420, 806, 807, 808, 787, + 792, 809, 420, 594, 595, 595, 595, 595, + 420, 595, 595, 595, 420, 594, 594, 420, + 594, 420, 810, 811, 812, 813, 814, 815, + 420, 816, 817, 818, 819, 820, 420, 594, + 420, 594, 420, 594, 420, 594, 594, 594, + 594, 594, 420, 594, 420, 821, 822, 823, + 824, 825, 826, 827, 828, 829, 830, 831, + 832, 833, 834, 835, 832, 836, 837, 838, + 420, 594, 594, 420, 420, 594, 420, 420, + 420, 594, 594, 594, 420, 594, 420, 594, + 594, 420, 420, 420, 594, 594, 420, 594, + 420, 594, 594, 594, 420, 594, 594, 594, + 594, 594, 594, 594, 420, 594, 420, 420, + 594, 594, 594, 420, 420, 420, 594, 420, + 594, 594, 420, 594, 420, 839, 840, 841, + 842, 420, 594, 420, 594, 420, 594, 420, + 594, 420, 843, 420, 594, 594, 420, 844, + 845, 846, 847, 848, 849, 420, 594, 594, + 420, 420, 420, 420, 594, 594, 420, 594, + 594, 420, 420, 420, 594, 594, 594, 594, + 420, 850, 420, 594, 420, 851, 420, 852, + 853, 574, 575, 854, 420, 594, 594, 420, + 420, 594, 594, 148, 572, 148, 181, 148, + 420, 181, 2, 2, 2, 2, 2, 148, + 572, 420, 420, 420, 148, 420, 148, 420, + 572, 181, 148, 148, 148, 148, 2, 420, + 572, 148, 420, 420, 572, 420, 148, 572, + 148, 181, 572, 572, 572, 572, 420, 572, + 572, 572, 148, 420, 421, 572, 148, 572, + 421, 148, 420, 420, 420, 420, 572, 572, + 421, 420, 420, 148, 148, 572, 148, 572, + 420, 420, 148, 572, 572, 420, 148, 148, + 421, 148, 572, 148, 420, 855, 856, 184, + 857, 858, 859, 860, 861, 862, 863, 864, + 865, 866, 867, 868, 869, 870, 871, 872, + 873, 874, 875, 876, 877, 878, 879, 880, + 881, 882, 883, 884, 885, 420, 148, 148, + 148, 148, 572, 420, 148, 572, 420, 572, + 420, 148, 148, 572, 148, 420, 148, 420, + 421, 148, 572, 420, 420, 420, 572, 572, + 420, 420, 420, 420, 572, 148, 148, 420, + 420, 420, 420, 420, 148, 420, 421, 148, + 420, 572, 572, 572, 148, 148, 148, 148, + 148, 148, 148, 572, 420, 420, 420, 420, + 420, 420, 148, 420, 421, 148, 420, 572, + 148, 572, 148, 148, 148, 148, 148, 148, + 572, 420, 420, 420, 148, 148, 420, 148, + 420, 421, 420, 572, 148, 572, 148, 148, + 148, 148, 148, 148, 572, 420, 148, 572, + 572, 572, 572, 148, 148, 572, 421, 420, + 572, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 572, 420, 148, 572, 572, + 572, 572, 421, 420, 148, 572, 148, 148, + 148, 148, 572, 420, 420, 420, 420, 420, + 148, 420, 148, 420, 421, 420, 572, 148, + 572, 148, 148, 148, 148, 148, 572, 420, + 148, 572, 572, 572, 572, 148, 572, 421, + 148, 420, 148, 572, 148, 148, 148, 572, + 420, 420, 420, 148, 420, 420, 148, 420, + 421, 420, 148, 420, 572, 148, 572, 148, + 148, 148, 420, 572, 572, 148, 572, 572, + 421, 572, 420, 572, 572, 420, 572, 421, + 420, 572, 572, 572, 420, 572, 421, 420, + 148, 572, 572, 572, 572, 421, 572, 420, + 148, 148, 572, 420, 572, 572, 148, 572, + 572, 420, 572, 420, 886, 887, 888, 217, + 218, 219, 220, 221, 889, 223, 224, 225, + 226, 227, 228, 890, 891, 892, 893, 894, + 234, 895, 236, 896, 483, 484, 897, 898, + 899, 900, 901, 902, 903, 904, 646, 905, + 151, 152, 906, 249, 250, 251, 252, 151, + 153, 151, 420, 572, 420, 421, 572, 572, + 572, 572, 572, 420, 572, 572, 421, 572, + 148, 420, 420, 572, 420, 148, 148, 148, + 572, 148, 572, 420, 148, 572, 148, 148, + 572, 420, 572, 420, 420, 420, 421, 420, + 572, 572, 421, 148, 420, 572, 148, 148, + 420, 148, 572, 572, 420, 148, 572, 420, + 572, 572, 572, 420, 421, 421, 572, 420, + 572, 148, 572, 420, 148, 420, 421, 420, + 420, 572, 572, 148, 572, 148, 421, 148, + 420, 572, 420, 148, 148, 572, 420, 572, + 572, 572, 148, 572, 148, 572, 420, 572, + 572, 420, 907, 908, 255, 909, 257, 258, + 259, 260, 261, 262, 263, 151, 910, 265, + 911, 267, 912, 269, 420, 181, 181, 572, + 181, 572, 571, 420, 420, 148, 148, 420, + 420, 572, 420, 571, 572, 420, 420, 572, + 420, 148, 572, 420, 420, 148, 148, 148, + 148, 148, 572, 420, 913, 914, 272, 151, + 273, 420, 148, 572, 148, 420, 572, 420, + 153, 274, 275, 153, 657, 915, 916, 917, + 280, 281, 282, 918, 284, 919, 920, 921, + 922, 923, 924, 925, 926, 927, 928, 295, + 296, 152, 929, 153, 151, 420, 148, 148, + 572, 572, 420, 148, 572, 148, 420, 572, + 420, 148, 572, 572, 572, 572, 420, 148, + 572, 148, 572, 420, 148, 148, 420, 421, + 420, 148, 420, 572, 421, 148, 572, 148, + 420, 572, 420, 420, 148, 572, 148, 572, + 420, 148, 420, 421, 420, 420, 421, 420, + 572, 148, 572, 420, 572, 148, 572, 421, + 572, 420, 572, 572, 572, 572, 420, 572, + 148, 572, 148, 572, 420, 148, 572, 572, + 421, 420, 930, 674, 302, 303, 304, 305, + 306, 307, 931, 932, 933, 934, 312, 935, + 936, 151, 420, 572, 148, 148, 572, 572, + 572, 420, 181, 572, 572, 571, 420, 181, + 181, 571, 148, 148, 2, 572, 420, 148, + 181, 181, 181, 571, 148, 2, 572, 148, + 420, 148, 148, 148, 148, 572, 420, 937, + 938, 317, 318, 319, 939, 940, 941, 942, + 324, 420, 325, 326, 153, 327, 328, 943, + 330, 944, 332, 945, 334, 335, 153, 151, + 690, 337, 338, 153, 339, 340, 341, 342, + 343, 344, 345, 346, 946, 348, 349, 947, + 351, 352, 353, 153, 259, 151, 354, 420, + 572, 420, 572, 420, 148, 420, 572, 420, + 148, 148, 572, 572, 572, 572, 148, 148, + 148, 572, 420, 148, 148, 572, 420, 948, + 949, 950, 696, 951, 952, 953, 954, 955, + 364, 956, 957, 958, 959, 960, 961, 962, + 959, 963, 964, 552, 965, 375, 712, 377, + 420, 572, 148, 572, 420, 420, 421, 420, + 572, 148, 420, 420, 572, 572, 148, 572, + 421, 420, 572, 148, 148, 420, 572, 148, + 572, 420, 420, 148, 420, 420, 421, 148, + 420, 572, 148, 148, 572, 420, 572, 420, + 421, 420, 148, 148, 572, 148, 148, 148, + 148, 148, 148, 572, 420, 148, 572, 572, + 572, 572, 148, 572, 572, 572, 420, 148, + 572, 420, 420, 148, 420, 421, 420, 572, + 148, 572, 572, 420, 420, 148, 420, 572, + 148, 420, 421, 420, 572, 148, 572, 420, + 572, 421, 420, 153, 382, 713, 966, 967, + 716, 386, 153, 968, 969, 151, 420, 148, + 572, 420, 148, 572, 420, 420, 572, 420, + 148, 572, 148, 420, 153, 389, 970, 420, + 148, 148, 572, 572, 420, 971, 972, 973, + 153, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, 723, 974, 975, 976, 151, + 420, 572, 572, 420, 420, 420, 420, 572, + 572, 420, 572, 572, 420, 420, 420, 572, + 572, 572, 572, 420, 153, 977, 409, 410, + 411, 151, 420, 420, 572, 420, 148, 978, + 420, 979, 980, 981, 983, 982, 420, 572, + 572, 420, 420, 572, 572, 420, 572, 571, + 571, 571, 148, 420, 421, 571, 148, 571, + 421, 148, 420, 420, 420, 420, 571, 571, + 421, 420, 420, 148, 148, 571, 148, 571, + 420, 420, 148, 571, 571, 420, 148, 148, + 421, 148, 571, 148, 420, 984, 985, 184, + 986, 987, 988, 989, 990, 991, 992, 993, + 994, 995, 996, 997, 998, 999, 1000, 1001, + 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, + 1010, 1011, 1012, 1013, 1014, 420, 148, 148, + 148, 148, 571, 420, 148, 571, 420, 571, + 420, 148, 148, 571, 148, 420, 148, 420, + 421, 148, 571, 420, 420, 420, 571, 571, + 420, 420, 420, 420, 571, 148, 148, 420, + 420, 420, 420, 420, 148, 420, 421, 148, + 420, 571, 571, 571, 148, 148, 148, 148, + 148, 148, 148, 571, 420, 420, 420, 420, + 420, 420, 148, 420, 421, 148, 420, 571, + 148, 571, 148, 148, 148, 148, 148, 148, + 571, 420, 420, 420, 148, 148, 420, 148, + 420, 421, 420, 571, 148, 571, 148, 148, + 148, 148, 148, 148, 571, 420, 148, 571, + 571, 571, 571, 148, 148, 571, 421, 420, + 571, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 571, 420, 148, 571, 571, + 571, 571, 421, 420, 148, 571, 148, 148, + 148, 148, 571, 420, 420, 420, 420, 420, + 148, 420, 148, 420, 421, 420, 571, 148, + 571, 148, 148, 148, 148, 148, 571, 420, + 148, 571, 571, 571, 571, 148, 571, 421, + 148, 420, 148, 571, 148, 148, 148, 571, + 420, 420, 420, 148, 420, 420, 148, 420, + 421, 420, 148, 420, 571, 148, 571, 148, + 148, 148, 420, 571, 571, 148, 571, 571, + 421, 571, 420, 571, 571, 420, 571, 421, + 420, 571, 571, 571, 420, 571, 421, 420, + 148, 571, 571, 571, 571, 421, 571, 420, + 148, 148, 571, 420, 571, 571, 148, 571, + 571, 420, 571, 420, 1015, 1016, 1017, 217, + 218, 219, 220, 221, 1018, 223, 224, 225, + 226, 227, 228, 1019, 1020, 1021, 1022, 1023, + 234, 1024, 236, 1025, 483, 484, 1026, 1027, + 1028, 1029, 1030, 1031, 1032, 1033, 646, 1034, + 151, 152, 1035, 249, 250, 251, 252, 151, + 153, 151, 420, 571, 420, 421, 571, 571, + 571, 571, 571, 420, 571, 571, 421, 571, + 148, 420, 420, 571, 420, 148, 148, 148, + 571, 148, 571, 420, 148, 571, 148, 148, + 571, 420, 571, 420, 420, 420, 421, 420, + 571, 571, 421, 148, 420, 571, 148, 148, + 420, 148, 571, 571, 420, 148, 571, 420, + 571, 571, 571, 420, 421, 421, 571, 420, + 571, 148, 571, 420, 148, 420, 421, 420, + 420, 571, 571, 148, 571, 148, 421, 148, + 420, 571, 420, 148, 148, 571, 420, 571, + 571, 571, 148, 571, 148, 571, 420, 571, + 571, 420, 1036, 1037, 255, 1038, 257, 258, + 259, 260, 261, 262, 263, 151, 1039, 265, + 1040, 267, 1041, 269, 420, 571, 571, 571, + 420, 420, 148, 148, 420, 420, 420, 571, + 571, 420, 420, 571, 420, 148, 571, 420, + 420, 148, 148, 148, 148, 148, 571, 420, + 1042, 1043, 1044, 272, 151, 273, 1045, 1046, + 1047, 1048, 420, 148, 571, 1049, 148, 420, + 1049, 420, 1049, 2, 420, 1049, 1049, 420, + 1049, 1049, 420, 1049, 1049, 1049, 420, 1049, + 1049, 1049, 420, 1049, 1049, 420, 1049, 1049, + 1049, 1049, 420, 1049, 1049, 1049, 420, 420, + 1049, 1049, 420, 1049, 420, 1050, 1051, 1052, + 1053, 1054, 1056, 1057, 1058, 1060, 1061, 1062, + 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, + 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1055, + 1059, 420, 1049, 1049, 1049, 1049, 420, 1049, + 420, 1049, 420, 420, 420, 1049, 420, 420, + 420, 1049, 1049, 1049, 1049, 420, 420, 420, + 420, 420, 420, 1049, 420, 420, 420, 420, + 420, 420, 1049, 420, 420, 420, 420, 1049, + 1049, 1049, 1049, 420, 1049, 1049, 1049, 1049, + 1049, 420, 1049, 1049, 420, 1049, 1049, 1049, + 1049, 420, 1049, 1049, 420, 420, 420, 420, + 420, 420, 1049, 1049, 1049, 1049, 1049, 1049, + 420, 1049, 1049, 420, 420, 420, 420, 420, + 420, 1049, 1049, 420, 1049, 1049, 1049, 1049, + 1049, 420, 1049, 1049, 420, 1049, 420, 1049, + 1049, 1049, 420, 1049, 420, 1049, 1049, 1049, + 1049, 1049, 420, 1049, 420, 1049, 1049, 1049, + 1049, 420, 1049, 420, 1078, 1079, 1080, 1081, + 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, + 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, + 1098, 420, 1049, 420, 1049, 1049, 1049, 1049, + 1049, 420, 1049, 1049, 1049, 420, 1049, 420, + 1049, 1049, 420, 1049, 1049, 420, 1049, 420, + 420, 420, 1049, 1049, 420, 1049, 420, 1049, + 1049, 420, 1049, 420, 1049, 1049, 1049, 420, + 1049, 420, 1049, 1049, 420, 420, 420, 1049, + 1049, 1049, 420, 1049, 420, 1049, 420, 1049, + 1049, 1049, 1049, 1049, 420, 1049, 1049, 420, + 1099, 1100, 1101, 1102, 1103, 1104, 420, 1049, + 1049, 571, 420, 420, 420, 420, 1049, 420, + 571, 1049, 420, 1049, 420, 1049, 420, 1049, + 420, 1105, 1106, 1044, 1045, 1046, 1047, 1048, + 420, 1049, 1049, 420, 1049, 1049, 420, 2, + 2, 1049, 1049, 2, 1049, 2, 2, 1049, + 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, + 1115, 1116, 1117, 1118, 1119, 1120, 1121, 420, + 1049, 1049, 420, 1049, 420, 1049, 420, 1049, + 1049, 1049, 1049, 420, 1049, 1049, 420, 420, + 420, 1049, 1049, 420, 1049, 420, 1049, 1049, + 420, 420, 420, 1049, 1049, 420, 1049, 1049, + 1049, 420, 1049, 1049, 1049, 1049, 420, 1049, + 1049, 1049, 420, 1049, 1049, 420, 1122, 1123, + 1124, 1103, 1125, 1126, 1127, 1128, 420, 1049, + 420, 1049, 1049, 571, 420, 571, 2, 571, + 2, 1049, 420, 420, 1049, 1049, 420, 1129, + 1130, 1131, 1132, 1133, 1134, 420, 1135, 1136, + 1137, 1138, 1139, 420, 1049, 420, 1049, 420, + 1049, 420, 1049, 1049, 1049, 1049, 1049, 420, + 1049, 420, 1140, 1141, 1142, 1143, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, + 1154, 1151, 1155, 1156, 1157, 420, 1049, 1049, + 420, 420, 1049, 420, 420, 420, 1049, 1049, + 1049, 420, 1049, 420, 1049, 1049, 420, 420, + 420, 1049, 1049, 420, 1049, 420, 1049, 1049, + 1049, 420, 1049, 1049, 1049, 1049, 1049, 1049, + 1049, 420, 1049, 420, 420, 1049, 1049, 1049, + 420, 420, 420, 1049, 420, 1049, 1049, 420, + 1049, 420, 1158, 1159, 1160, 1161, 420, 1049, + 420, 1049, 420, 1049, 420, 1049, 420, 1162, + 1163, 420, 1049, 2, 1049, 1049, 420, 1164, + 1165, 1166, 1167, 1168, 1169, 420, 1049, 1049, + 420, 420, 420, 420, 1049, 1049, 420, 1049, + 1049, 420, 420, 420, 1049, 1049, 1049, 1049, + 420, 1170, 420, 1049, 420, 1171, 420, 1172, + 1173, 1047, 1175, 1174, 420, 1049, 1049, 420, + 420, 1049, 1049, 571, 1049, 1049, 420, 153, + 274, 275, 153, 657, 1176, 1177, 1178, 280, + 281, 282, 1179, 284, 1180, 1181, 1182, 1183, + 1184, 1185, 1186, 1187, 1188, 1189, 295, 296, + 152, 1190, 153, 151, 420, 148, 148, 571, + 571, 420, 148, 571, 148, 420, 571, 420, + 148, 571, 571, 571, 571, 420, 148, 571, + 148, 571, 420, 148, 148, 420, 421, 420, + 148, 420, 571, 421, 148, 571, 148, 420, + 571, 420, 420, 148, 571, 148, 571, 420, + 148, 420, 421, 420, 420, 421, 420, 571, + 148, 571, 420, 571, 148, 571, 421, 571, + 420, 571, 571, 571, 571, 420, 571, 148, + 571, 148, 571, 420, 148, 571, 571, 421, + 420, 1191, 674, 302, 303, 304, 305, 306, + 307, 1192, 676, 1193, 678, 1194, 1195, 1196, + 151, 420, 571, 572, 148, 148, 572, 572, + 572, 420, 571, 571, 571, 420, 571, 420, + 148, 148, 1049, 2, 571, 148, 420, 1049, + 148, 148, 148, 148, 571, 420, 1197, 1198, + 317, 318, 319, 1199, 1200, 1201, 1202, 324, + 420, 325, 326, 153, 327, 328, 1203, 330, + 1204, 332, 1205, 334, 335, 153, 151, 690, + 337, 338, 153, 339, 340, 341, 342, 343, + 344, 345, 346, 1206, 348, 349, 1207, 351, + 352, 353, 153, 259, 151, 354, 420, 571, + 420, 571, 420, 148, 420, 571, 420, 148, + 148, 571, 571, 571, 571, 148, 148, 148, + 571, 420, 148, 148, 571, 420, 1208, 1209, + 1210, 696, 1211, 1212, 1213, 1214, 1215, 364, + 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1219, + 1223, 1224, 552, 1225, 375, 712, 377, 420, + 571, 148, 571, 420, 420, 421, 420, 571, + 148, 420, 420, 571, 571, 148, 571, 421, + 420, 571, 148, 148, 420, 571, 148, 571, + 420, 420, 148, 420, 420, 421, 148, 420, + 571, 148, 148, 571, 420, 571, 420, 421, + 420, 148, 148, 571, 148, 148, 148, 148, + 148, 148, 571, 420, 148, 571, 571, 571, + 571, 148, 571, 571, 571, 420, 148, 571, + 420, 420, 148, 420, 421, 420, 571, 148, + 571, 571, 420, 420, 148, 420, 571, 148, + 420, 421, 420, 571, 148, 571, 420, 571, + 421, 420, 153, 382, 713, 1226, 1227, 716, + 386, 153, 1228, 1229, 151, 420, 148, 571, + 420, 148, 571, 420, 420, 571, 420, 148, + 571, 148, 420, 1162, 153, 389, 1230, 420, + 148, 148, 571, 571, 420, 1231, 1232, 1233, + 153, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, 723, 1234, 1235, 1236, 151, + 420, 571, 571, 420, 420, 420, 420, 571, + 571, 420, 571, 571, 420, 420, 420, 571, + 571, 571, 571, 420, 153, 1237, 409, 410, + 411, 151, 420, 420, 571, 420, 148, 1238, + 420, 1239, 1240, 1241, 1243, 1242, 420, 571, + 571, 420, 420, 571, 571, 420, 571, 148, + 421, 148, 148, 420, 420, 421, 420, 443, + 148, 420, 148, 420, 421, 420, 421, 148, + 443, 420, 420, 421, 420, 148, 421, 148, + 421, 421, 572, 572, 420, 421, 421, 443, + 421, 148, 420, 421, 443, 421, 148, 421, + 148, 420, 420, 420, 420, 421, 421, 421, + 420, 420, 148, 148, 421, 148, 421, 420, + 420, 148, 421, 421, 420, 148, 443, 148, + 421, 148, 421, 148, 420, 1244, 1245, 184, + 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, + 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, + 1270, 1271, 1272, 1273, 1274, 420, 148, 148, + 148, 148, 421, 420, 148, 421, 420, 421, + 420, 148, 148, 421, 148, 420, 148, 420, + 148, 421, 420, 420, 420, 421, 421, 420, + 420, 420, 420, 421, 148, 148, 420, 420, + 420, 420, 420, 148, 420, 148, 420, 421, + 421, 421, 148, 148, 148, 148, 148, 148, + 148, 421, 420, 420, 420, 420, 420, 420, + 148, 420, 148, 420, 421, 148, 421, 148, + 148, 148, 148, 148, 148, 421, 420, 420, + 420, 148, 148, 420, 148, 420, 420, 421, + 148, 421, 148, 148, 148, 148, 148, 148, + 421, 420, 148, 421, 421, 421, 421, 148, + 148, 421, 421, 420, 421, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 421, + 420, 148, 421, 421, 421, 421, 421, 420, + 148, 421, 148, 148, 148, 148, 421, 420, + 420, 420, 420, 420, 148, 420, 148, 420, + 420, 421, 148, 421, 148, 148, 148, 148, + 148, 421, 420, 148, 421, 421, 421, 421, + 148, 421, 421, 148, 420, 148, 421, 148, + 148, 148, 421, 420, 420, 420, 148, 420, + 420, 148, 420, 420, 148, 420, 421, 148, + 421, 148, 148, 148, 420, 421, 421, 148, + 421, 421, 421, 421, 420, 421, 421, 420, + 421, 421, 420, 421, 421, 421, 420, 421, + 421, 420, 148, 421, 421, 421, 421, 421, + 421, 420, 148, 148, 421, 420, 421, 421, + 148, 421, 421, 420, 421, 420, 1275, 1276, + 1277, 217, 218, 219, 220, 221, 1278, 223, + 224, 225, 226, 227, 228, 1279, 1280, 1281, + 1282, 1283, 234, 1284, 236, 1285, 483, 484, + 1286, 1287, 1288, 1289, 1290, 1291, 1292, 1293, + 646, 1294, 151, 152, 1295, 249, 250, 251, + 252, 151, 153, 151, 420, 421, 420, 421, + 421, 421, 421, 421, 421, 420, 421, 421, + 148, 420, 420, 421, 420, 148, 148, 148, + 421, 148, 421, 420, 148, 421, 148, 148, + 421, 420, 421, 420, 420, 420, 420, 421, + 421, 421, 148, 420, 421, 148, 148, 420, + 148, 421, 421, 420, 148, 421, 420, 421, + 421, 421, 420, 421, 421, 421, 420, 421, + 148, 421, 420, 148, 420, 420, 420, 421, + 421, 148, 421, 148, 421, 148, 420, 421, + 420, 148, 148, 421, 420, 421, 421, 421, + 148, 421, 148, 421, 420, 421, 421, 420, + 1296, 1297, 255, 1298, 257, 258, 259, 260, + 261, 262, 263, 151, 1299, 265, 1300, 267, + 1301, 269, 420, 443, 421, 443, 421, 571, + 420, 443, 420, 148, 148, 420, 420, 421, + 420, 571, 421, 420, 420, 421, 420, 148, + 421, 420, 420, 148, 148, 148, 148, 148, + 421, 420, 1302, 1303, 272, 151, 273, 420, + 148, 421, 148, 420, 421, 420, 153, 274, + 275, 153, 657, 1304, 1305, 1306, 280, 281, + 282, 1307, 284, 1308, 1309, 1310, 1311, 1312, + 1313, 1314, 1315, 1316, 1317, 295, 296, 152, + 1318, 153, 151, 420, 148, 148, 421, 421, + 420, 148, 421, 148, 420, 421, 420, 148, + 421, 421, 421, 421, 420, 148, 421, 148, + 421, 420, 148, 148, 420, 420, 148, 420, + 421, 421, 148, 421, 148, 420, 421, 420, + 420, 148, 421, 148, 421, 420, 148, 420, + 420, 420, 420, 421, 148, 421, 420, 421, + 148, 421, 421, 421, 420, 421, 421, 421, + 421, 420, 421, 148, 421, 148, 421, 420, + 148, 421, 421, 421, 420, 1319, 674, 302, + 303, 304, 305, 306, 307, 1320, 1321, 1322, + 1323, 312, 1324, 1325, 151, 420, 421, 572, + 148, 148, 572, 572, 572, 420, 443, 443, + 421, 421, 571, 420, 443, 443, 443, 571, + 148, 148, 420, 421, 420, 148, 443, 443, + 443, 443, 571, 148, 420, 421, 148, 420, + 148, 148, 148, 148, 421, 420, 1326, 1327, + 317, 318, 319, 1328, 1329, 1330, 1331, 324, + 420, 325, 326, 153, 327, 328, 1332, 330, + 1333, 332, 1334, 334, 335, 153, 151, 690, + 337, 338, 153, 339, 340, 341, 342, 343, + 344, 345, 346, 1335, 348, 349, 1336, 351, + 352, 353, 153, 259, 151, 354, 420, 421, + 420, 421, 420, 148, 420, 421, 420, 148, + 148, 421, 421, 421, 421, 148, 148, 148, + 421, 420, 148, 148, 421, 420, 1337, 1338, + 1339, 696, 1340, 1341, 1342, 1343, 1344, 364, + 1345, 1346, 1347, 1348, 1349, 1350, 1351, 1348, + 1352, 1353, 552, 1354, 375, 712, 377, 420, + 421, 148, 421, 420, 420, 420, 421, 148, + 420, 420, 421, 421, 148, 421, 421, 420, + 421, 148, 148, 420, 421, 148, 421, 420, + 420, 148, 420, 420, 148, 420, 421, 148, + 148, 421, 420, 421, 420, 421, 420, 148, + 148, 421, 148, 148, 148, 148, 148, 148, + 421, 420, 148, 421, 421, 421, 421, 148, + 421, 421, 421, 420, 148, 421, 420, 420, + 148, 420, 420, 421, 148, 421, 421, 420, + 420, 148, 420, 421, 148, 420, 420, 421, + 148, 421, 420, 421, 421, 420, 153, 382, + 713, 1355, 1356, 716, 386, 153, 1357, 1358, + 151, 420, 148, 421, 420, 148, 421, 420, + 420, 421, 420, 148, 421, 148, 420, 153, + 389, 1359, 420, 148, 148, 421, 421, 420, + 1360, 1361, 1362, 153, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 723, 1363, + 1364, 1365, 151, 420, 421, 421, 420, 420, + 420, 420, 421, 421, 420, 421, 421, 420, + 420, 420, 421, 421, 421, 421, 420, 153, + 1366, 409, 410, 411, 151, 420, 420, 421, + 420, 148, 1367, 420, 1368, 1369, 1370, 1372, + 1371, 420, 421, 421, 420, 420, 421, 421, + 420, 421, 148, 148, 148, 181, 148, 420, + 420, 420, 420, 420, 148, 420, 148, 420, + 420, 420, 148, 148, 148, 181, 148, 148, + 572, 572, 420, 148, 148, 148, 148, 420, + 421, 148, 421, 148, 420, 420, 420, 420, + 421, 420, 420, 148, 148, 420, 420, 148, + 148, 421, 148, 420, 1373, 1374, 184, 1375, + 151, 1376, 1377, 1378, 1379, 1380, 1381, 1382, + 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, + 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, + 1399, 1400, 1401, 1402, 420, 148, 2, 148, + 2, 148, 2, 2, 2, 421, 148, 2, + 2, 2, 2, 2, 2, 2, 148, 2, + 2, 2, 2, 2, 2, 421, 2, 148, + 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 2, 2, 2, 2, 2, 2, + 2, 421, 2, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 2, 2, 2, 2, + 2, 2, 421, 2, 2, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 2, 148, + 148, 148, 148, 148, 148, 148, 421, 2, + 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 2, 148, 148, 148, 148, + 148, 421, 2, 148, 148, 148, 148, 148, + 148, 2, 2, 2, 2, 2, 2, 2, + 421, 2, 148, 148, 148, 148, 148, 148, + 148, 148, 2, 148, 148, 148, 148, 148, + 148, 421, 148, 2, 148, 148, 148, 148, + 148, 2, 2, 2, 2, 2, 2, 421, + 2, 2, 148, 148, 148, 148, 148, 148, + 2, 148, 148, 148, 148, 148, 421, 148, + 2, 148, 148, 2, 148, 421, 2, 148, + 148, 148, 2, 148, 421, 2, 148, 148, + 148, 148, 148, 421, 148, 2, 148, 148, + 148, 2, 148, 148, 148, 2, 148, 2, + 1403, 1404, 1405, 217, 218, 219, 220, 221, + 1406, 223, 224, 225, 226, 227, 228, 1407, + 1408, 1409, 1410, 1411, 234, 1412, 236, 1413, + 483, 484, 1374, 1414, 1415, 153, 1416, 1417, + 1418, 1419, 646, 1420, 151, 152, 1421, 249, + 250, 251, 252, 151, 153, 151, 420, 148, + 2, 421, 148, 148, 148, 148, 148, 2, + 148, 148, 421, 148, 148, 2, 2, 2, + 148, 148, 148, 148, 2, 148, 148, 148, + 148, 2, 148, 2, 2, 2, 421, 2, + 148, 148, 421, 148, 2, 148, 148, 2, + 148, 148, 148, 2, 148, 148, 148, 2, + 421, 421, 148, 2, 2, 421, 2, 2, + 148, 148, 421, 148, 2, 2, 148, 148, + 2, 148, 148, 148, 2, 148, 148, 2, + 1422, 1423, 255, 1424, 257, 258, 259, 260, + 261, 262, 263, 151, 1425, 265, 1426, 267, + 1427, 269, 420, 181, 181, 148, 181, 148, + 571, 2, 2, 2, 148, 2, 2, 148, + 2, 571, 148, 2, 2, 2, 148, 2, + 2, 2, 148, 148, 148, 148, 148, 148, + 2, 1428, 1429, 272, 151, 273, 420, 148, + 148, 148, 2, 148, 2, 153, 274, 275, + 153, 657, 1430, 153, 302, 280, 281, 282, + 1431, 284, 153, 1432, 1433, 1434, 153, 1435, + 1436, 1437, 1438, 1439, 295, 296, 152, 1440, + 153, 151, 420, 148, 148, 148, 2, 2, + 148, 2, 2, 421, 2, 2, 2, 148, + 421, 148, 148, 2, 2, 2, 148, 2, + 421, 2, 2, 421, 2, 148, 148, 2, + 148, 421, 148, 2, 148, 148, 148, 148, + 2, 148, 148, 148, 2, 148, 148, 421, + 2, 1441, 674, 302, 303, 304, 305, 306, + 307, 1442, 932, 1443, 934, 312, 1444, 1445, + 151, 420, 148, 572, 148, 148, 572, 572, + 572, 2, 181, 148, 148, 571, 2, 2, + 2, 148, 148, 2, 148, 148, 148, 148, + 148, 2, 1446, 1447, 317, 318, 319, 1448, + 1449, 1450, 1451, 324, 420, 325, 326, 153, + 327, 328, 1452, 330, 1453, 332, 1454, 334, + 335, 153, 151, 690, 337, 338, 153, 339, + 340, 341, 342, 343, 344, 345, 346, 1455, + 348, 349, 1456, 351, 352, 353, 153, 259, + 151, 354, 2, 148, 2, 2, 2, 148, + 2, 2, 148, 148, 148, 148, 148, 148, + 148, 148, 2, 148, 148, 2, 1457, 1458, + 696, 1459, 1460, 1461, 1462, 364, 1463, 1464, + 1465, 153, 1466, 1467, 1468, 153, 1469, 1419, + 552, 1470, 375, 712, 377, 153, 2, 2, + 421, 2, 148, 2, 2, 148, 148, 421, + 2, 148, 148, 2, 2, 2, 2, 421, + 2, 148, 148, 148, 2, 2, 421, 2, + 148, 148, 148, 148, 148, 148, 148, 148, + 148, 2, 148, 148, 148, 148, 148, 148, + 148, 148, 2, 2, 2, 421, 2, 148, + 148, 148, 2, 2, 2, 148, 2, 2, + 421, 2, 148, 148, 421, 2, 153, 382, + 713, 1471, 1436, 716, 386, 153, 1472, 1473, + 151, 2, 148, 148, 2, 2, 2, 148, + 148, 2, 153, 389, 1474, 2, 148, 148, + 148, 148, 2, 1475, 1476, 1477, 153, 394, + 395, 396, 397, 398, 399, 400, 401, 402, + 403, 723, 1478, 1479, 1480, 151, 2, 148, + 148, 2, 2, 2, 2, 148, 148, 2, + 148, 148, 2, 2, 2, 148, 148, 148, + 148, 2, 153, 1481, 409, 410, 411, 151, + 2, 2, 2, 148, 1482, 420, 1483, 152, + 153, 1484, 151, 2, 148, 148, 2, 2, + 148, 148, 1485, 148, 148, 125, 1485, 125, + 125, 125, 148, 125, 148, 125, 1485, 125, + 1485, 148, 125, 125, 1485, 125, 148, 1485, + 148, 1485, 1485, 572, 572, 125, 1485, 1485, + 1485, 148, 125, 126, 1485, 148, 1485, 126, + 148, 125, 125, 125, 125, 1485, 1485, 126, + 125, 125, 148, 148, 1485, 148, 1485, 125, + 125, 148, 1485, 1485, 125, 148, 148, 126, + 148, 1485, 148, 125, 1486, 1487, 184, 1488, + 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, + 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, + 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, + 1513, 1514, 1515, 1516, 125, 148, 148, 148, + 148, 1485, 125, 148, 1485, 125, 1485, 125, + 148, 148, 1485, 148, 125, 148, 125, 126, + 148, 1485, 125, 125, 125, 1485, 1485, 125, + 125, 125, 125, 1485, 148, 148, 125, 125, + 125, 125, 125, 148, 125, 126, 148, 125, + 1485, 1485, 1485, 148, 148, 148, 148, 148, + 148, 148, 1485, 125, 125, 125, 125, 125, + 125, 148, 125, 126, 148, 125, 1485, 148, + 1485, 148, 148, 148, 148, 148, 148, 1485, + 125, 125, 125, 148, 148, 125, 148, 125, + 126, 125, 1485, 148, 1485, 148, 148, 148, + 148, 148, 148, 1485, 125, 148, 1485, 1485, + 1485, 1485, 148, 148, 1485, 126, 125, 1485, + 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 1485, 125, 148, 1485, 1485, 1485, + 1485, 126, 125, 148, 1485, 148, 148, 148, + 148, 1485, 125, 125, 125, 125, 125, 148, + 125, 148, 125, 126, 125, 1485, 148, 1485, + 148, 148, 148, 148, 148, 1485, 125, 148, + 1485, 1485, 1485, 1485, 148, 1485, 126, 148, + 125, 148, 1485, 148, 148, 148, 1485, 125, + 125, 125, 148, 125, 125, 148, 125, 126, + 125, 148, 125, 1485, 148, 1485, 148, 148, + 148, 125, 1485, 1485, 148, 1485, 1485, 126, + 1485, 125, 1485, 1485, 125, 1485, 126, 125, + 1485, 1485, 1485, 125, 1485, 126, 125, 148, + 1485, 1485, 1485, 1485, 126, 1485, 125, 148, + 148, 1485, 125, 1485, 1485, 148, 1485, 1485, + 125, 1485, 125, 1517, 1518, 1519, 217, 218, + 219, 220, 221, 1520, 223, 224, 225, 226, + 227, 228, 1521, 1522, 1523, 1524, 1525, 234, + 1526, 236, 1527, 1528, 1529, 1530, 1531, 1532, + 1533, 1534, 1535, 1536, 1537, 1538, 1539, 151, + 152, 1540, 249, 250, 251, 252, 151, 153, + 151, 125, 1485, 125, 126, 1485, 1485, 1485, + 1485, 1485, 125, 1485, 1485, 126, 1485, 148, + 125, 125, 1485, 125, 148, 148, 148, 1485, + 148, 1485, 125, 148, 1485, 148, 148, 1485, + 125, 1485, 125, 125, 125, 126, 125, 1485, + 1485, 126, 148, 125, 1485, 148, 148, 125, + 148, 1485, 1485, 125, 126, 2, 126, 2, + 148, 1485, 125, 1485, 1485, 1485, 125, 126, + 126, 1485, 125, 1485, 148, 1485, 125, 148, + 125, 126, 125, 125, 1485, 1485, 148, 1485, + 148, 126, 148, 125, 1485, 125, 148, 148, + 1485, 125, 126, 148, 126, 148, 2, 1485, + 1485, 1485, 148, 1485, 148, 1485, 125, 1485, + 1485, 125, 1541, 1542, 255, 1543, 257, 258, + 259, 260, 261, 262, 263, 151, 1544, 265, + 1545, 267, 1546, 269, 125, 1485, 1485, 1485, + 125, 125, 148, 148, 125, 125, 125, 1485, + 1485, 125, 125, 1485, 125, 148, 1485, 125, + 125, 148, 148, 148, 148, 148, 1485, 125, + 1547, 1548, 1044, 272, 151, 273, 1045, 1046, + 1047, 1048, 125, 148, 1485, 1049, 148, 125, + 1485, 1049, 1049, 125, 153, 274, 275, 153, + 1549, 1550, 1551, 1552, 280, 281, 282, 1553, + 284, 1554, 1555, 1556, 1557, 1558, 1559, 1560, + 1561, 1562, 1563, 295, 296, 152, 1564, 153, + 151, 125, 2, 126, 2, 148, 148, 148, + 1485, 1485, 125, 148, 1485, 148, 125, 1485, + 125, 148, 1485, 1485, 1485, 1485, 125, 148, + 1485, 148, 1485, 125, 148, 148, 125, 126, + 125, 148, 125, 1485, 126, 148, 1485, 148, + 125, 1485, 125, 125, 148, 1485, 148, 1485, + 125, 148, 125, 126, 125, 125, 126, 125, + 1485, 148, 1485, 125, 1485, 148, 1485, 126, + 1485, 125, 1485, 1485, 1485, 1485, 125, 1485, + 148, 1485, 148, 1485, 125, 148, 1485, 1485, + 126, 125, 1565, 674, 302, 303, 304, 305, + 306, 307, 1566, 1567, 1568, 1569, 1194, 1570, + 1571, 151, 125, 1485, 572, 148, 148, 572, + 572, 572, 125, 1485, 1485, 1485, 125, 1485, + 148, 148, 125, 1485, 125, 148, 1485, 148, + 125, 1485, 148, 125, 1049, 148, 148, 148, + 148, 1485, 125, 1572, 1573, 317, 318, 319, + 1574, 1575, 1576, 1577, 324, 125, 325, 326, + 153, 327, 328, 1578, 330, 1579, 332, 1580, + 334, 335, 153, 151, 1581, 337, 338, 153, + 339, 340, 341, 342, 343, 344, 345, 346, + 1582, 348, 349, 1583, 351, 352, 353, 153, + 259, 151, 354, 125, 1485, 125, 1485, 125, + 148, 125, 1485, 125, 148, 2, 126, 2, + 148, 148, 1485, 1485, 1485, 1485, 148, 148, + 148, 1485, 125, 148, 148, 1485, 125, 1584, + 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, + 364, 1593, 1594, 1595, 1596, 1597, 1598, 1599, + 1596, 1600, 1601, 1602, 1603, 375, 1604, 377, + 125, 1485, 148, 1485, 125, 125, 126, 125, + 1485, 148, 125, 125, 1485, 148, 126, 2, + 1485, 148, 1485, 126, 125, 1485, 148, 148, + 125, 1485, 148, 1485, 125, 125, 148, 125, + 125, 126, 148, 125, 1485, 148, 148, 1485, + 125, 1485, 125, 126, 125, 148, 148, 1485, + 148, 148, 148, 148, 148, 148, 1485, 125, + 148, 1485, 1485, 1485, 1485, 148, 1485, 1485, + 1485, 125, 148, 1485, 125, 125, 148, 125, + 126, 125, 1485, 148, 1485, 1485, 125, 125, + 148, 125, 1485, 148, 125, 126, 125, 1485, + 148, 1485, 125, 126, 2, 1485, 126, 125, + 126, 2, 2, 148, 153, 382, 1605, 1606, + 1607, 1608, 386, 153, 1609, 1610, 151, 125, + 148, 126, 2, 148, 1485, 125, 148, 1485, + 125, 148, 126, 148, 148, 2, 125, 1485, + 125, 148, 1485, 148, 125, 1162, 153, 389, + 1611, 125, 148, 148, 1485, 1485, 125, 1612, + 1613, 1614, 153, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, 1615, 1616, 1617, + 1618, 151, 125, 1485, 1485, 125, 125, 125, + 125, 1485, 1485, 125, 2, 2, 126, 2, + 148, 1485, 1485, 125, 125, 125, 1485, 1485, + 1485, 1485, 125, 153, 1619, 409, 410, 411, + 151, 125, 125, 1485, 125, 148, 1620, 125, + 1621, 1622, 1623, 1625, 1624, 125, 1485, 1485, + 125, 125, 1485, 1485, 125, 1485, 148, 126, + 148, 148, 125, 126, 125, 125, 1626, 148, + 125, 148, 125, 126, 125, 126, 148, 1626, + 125, 125, 126, 125, 148, 126, 148, 126, + 126, 572, 572, 125, 126, 126, 1626, 126, + 148, 125, 126, 1626, 126, 148, 126, 148, + 125, 125, 125, 125, 126, 126, 126, 125, + 125, 148, 148, 126, 148, 126, 125, 125, + 148, 126, 126, 125, 148, 1626, 148, 126, + 148, 126, 148, 125, 1627, 1628, 184, 1629, + 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, + 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1645, + 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, + 1654, 1655, 1656, 1657, 125, 148, 148, 148, + 148, 126, 125, 148, 126, 125, 126, 125, + 148, 148, 126, 148, 125, 148, 125, 148, + 126, 125, 125, 125, 126, 126, 125, 125, + 125, 125, 126, 148, 148, 125, 125, 125, + 125, 125, 148, 125, 148, 125, 126, 126, + 126, 148, 148, 148, 148, 148, 148, 148, + 126, 125, 125, 125, 125, 125, 125, 148, + 125, 148, 125, 126, 148, 126, 148, 148, + 148, 148, 148, 148, 126, 125, 125, 125, + 148, 148, 125, 148, 125, 125, 126, 148, + 126, 148, 148, 148, 148, 148, 148, 126, + 125, 148, 126, 126, 126, 126, 148, 148, + 126, 126, 125, 126, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 126, 125, + 148, 126, 126, 126, 126, 126, 125, 148, + 126, 148, 148, 148, 148, 126, 125, 125, + 125, 125, 125, 148, 125, 148, 125, 125, + 126, 148, 126, 148, 148, 148, 148, 148, + 126, 125, 148, 126, 126, 126, 126, 148, + 126, 126, 148, 125, 148, 126, 148, 148, + 148, 126, 125, 125, 125, 148, 125, 125, + 148, 125, 125, 148, 125, 126, 148, 126, + 148, 148, 148, 125, 126, 126, 148, 126, + 126, 126, 126, 125, 126, 126, 125, 126, + 126, 125, 126, 126, 126, 125, 126, 126, + 125, 148, 126, 126, 126, 126, 126, 126, + 125, 148, 148, 126, 125, 126, 126, 148, + 126, 126, 125, 126, 125, 1658, 1659, 1660, + 217, 218, 219, 220, 221, 1661, 223, 224, + 225, 226, 227, 228, 1662, 1663, 1664, 1665, + 1666, 234, 1667, 236, 1668, 1528, 1529, 1669, + 1670, 1671, 1672, 1673, 1674, 1675, 1676, 1538, + 1677, 151, 152, 1678, 249, 250, 251, 252, + 151, 153, 151, 125, 126, 125, 126, 126, + 126, 126, 126, 126, 125, 126, 126, 148, + 125, 125, 126, 125, 148, 148, 148, 126, + 148, 126, 125, 148, 126, 148, 148, 126, + 125, 126, 125, 125, 125, 125, 126, 126, + 126, 148, 125, 126, 148, 148, 125, 148, + 126, 126, 125, 148, 126, 125, 126, 126, + 126, 125, 126, 126, 126, 125, 126, 148, + 126, 125, 148, 125, 125, 125, 126, 126, + 148, 126, 148, 126, 148, 125, 126, 125, + 148, 148, 126, 125, 126, 126, 126, 148, + 126, 148, 126, 125, 126, 126, 125, 1679, + 1680, 255, 1681, 257, 258, 259, 260, 261, + 262, 263, 151, 1682, 265, 1683, 267, 1684, + 269, 125, 1626, 126, 1626, 126, 1485, 125, + 1626, 125, 148, 148, 125, 125, 126, 125, + 1485, 126, 125, 125, 126, 125, 148, 126, + 125, 125, 148, 148, 148, 148, 148, 126, + 125, 1685, 1686, 272, 151, 273, 125, 148, + 126, 148, 125, 126, 125, 153, 274, 275, + 153, 1549, 1687, 1688, 1689, 280, 281, 282, + 1690, 284, 1691, 1692, 1693, 1694, 1695, 1696, + 1697, 1698, 1699, 1700, 295, 296, 152, 1701, + 153, 151, 125, 148, 148, 126, 126, 125, + 148, 126, 148, 125, 126, 125, 148, 126, + 126, 126, 126, 125, 148, 126, 148, 126, + 125, 148, 148, 125, 125, 148, 125, 126, + 126, 148, 126, 148, 125, 126, 125, 125, + 148, 126, 148, 126, 125, 148, 125, 125, + 125, 125, 126, 148, 126, 125, 126, 148, + 126, 126, 126, 125, 126, 126, 126, 126, + 125, 126, 148, 126, 148, 126, 125, 148, + 126, 126, 126, 125, 1702, 674, 302, 303, + 304, 305, 306, 307, 1703, 1704, 1705, 1706, + 312, 1707, 1708, 151, 125, 126, 572, 148, + 148, 572, 572, 572, 125, 1626, 1626, 126, + 126, 1485, 125, 1626, 1626, 1626, 1485, 148, + 148, 125, 126, 125, 148, 1626, 1626, 1626, + 1626, 1485, 148, 125, 126, 148, 125, 148, + 148, 148, 148, 126, 125, 1709, 1710, 317, + 318, 319, 1711, 1712, 1713, 1714, 324, 125, + 325, 326, 153, 327, 328, 1715, 330, 1716, + 332, 1717, 334, 335, 153, 151, 1581, 337, + 338, 153, 339, 340, 341, 342, 343, 344, + 345, 346, 1718, 348, 349, 1719, 351, 352, + 353, 153, 259, 151, 354, 125, 126, 125, + 126, 125, 148, 125, 126, 125, 148, 148, + 126, 126, 126, 126, 148, 148, 148, 126, + 125, 148, 148, 126, 125, 1720, 1721, 1722, + 1587, 1723, 1724, 1725, 1726, 1727, 364, 1728, + 1729, 1730, 1731, 1732, 1733, 1734, 1731, 1735, + 1736, 1602, 1737, 375, 1604, 377, 125, 126, + 148, 126, 125, 125, 125, 126, 148, 125, + 125, 126, 126, 148, 126, 126, 125, 126, + 148, 148, 125, 126, 148, 126, 125, 125, + 148, 125, 125, 148, 125, 126, 148, 148, + 126, 125, 126, 125, 126, 125, 148, 148, + 126, 148, 148, 148, 148, 148, 148, 126, + 125, 148, 126, 126, 126, 126, 148, 126, + 126, 126, 125, 148, 126, 125, 125, 148, + 125, 125, 126, 148, 126, 126, 125, 125, + 148, 125, 126, 148, 125, 125, 126, 148, + 126, 125, 126, 126, 125, 153, 382, 1605, + 1738, 1739, 1608, 386, 153, 1740, 1741, 151, + 125, 148, 126, 125, 148, 126, 125, 125, + 126, 125, 148, 126, 148, 125, 153, 389, + 1742, 125, 148, 148, 126, 126, 125, 1743, + 1744, 1745, 153, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, 1615, 1746, 1747, + 1748, 151, 125, 126, 126, 125, 125, 125, + 125, 126, 126, 125, 126, 126, 125, 125, + 125, 126, 126, 126, 126, 125, 153, 1749, + 409, 410, 411, 151, 125, 125, 126, 125, + 148, 1750, 125, 1751, 1752, 1753, 1755, 1754, + 125, 126, 126, 125, 125, 126, 126, 125, + 126, 1626, 125, 1626, 125, 125, 1626, 1626, + 125, 1626, 1626, 125, 1626, 1626, 1626, 125, + 1626, 1626, 1626, 125, 126, 1626, 1626, 126, + 125, 1626, 1626, 1626, 1626, 126, 125, 1626, + 1626, 1626, 125, 125, 1626, 1626, 125, 126, + 1626, 125, 1756, 1757, 1758, 1759, 1760, 1762, + 1763, 1764, 1766, 1767, 1768, 1769, 1770, 1771, + 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, + 1780, 1781, 1782, 1783, 1761, 1765, 125, 1626, + 1626, 1626, 1626, 125, 1626, 125, 1626, 125, + 125, 125, 1626, 125, 125, 125, 126, 125, + 1626, 1626, 1626, 1626, 125, 125, 125, 125, + 125, 125, 126, 125, 1626, 125, 125, 125, + 125, 126, 125, 125, 1626, 125, 125, 125, + 125, 126, 125, 1626, 1626, 1626, 1626, 125, + 1626, 1626, 1626, 1626, 1626, 126, 125, 1626, + 1626, 125, 1626, 1626, 1626, 1626, 126, 125, + 1626, 1626, 125, 125, 125, 125, 125, 125, + 126, 125, 1626, 1626, 1626, 1626, 1626, 1626, + 126, 125, 1626, 1626, 125, 125, 125, 125, + 125, 125, 126, 125, 1626, 1626, 125, 1626, + 1626, 1626, 1626, 126, 1626, 125, 1626, 1626, + 125, 1626, 126, 125, 1626, 1626, 1626, 125, + 1626, 126, 125, 1626, 1626, 1626, 1626, 126, + 1626, 125, 1626, 125, 1626, 1626, 1626, 1626, + 125, 1626, 125, 1784, 1785, 1786, 1787, 1788, + 1789, 1790, 1791, 1792, 1793, 1794, 1528, 1529, + 1795, 1796, 1797, 1798, 1799, 1800, 1801, 1802, + 1803, 1804, 1805, 125, 1626, 125, 126, 1626, + 1626, 1626, 1626, 1626, 125, 1626, 1626, 126, + 1626, 125, 1626, 125, 1626, 1626, 125, 1626, + 1626, 125, 1626, 125, 125, 125, 126, 125, + 1626, 1626, 126, 125, 1626, 125, 1626, 1626, + 125, 1626, 125, 1626, 1626, 1626, 125, 126, + 126, 1626, 125, 1626, 1626, 125, 125, 126, + 125, 125, 1626, 1626, 1626, 126, 125, 1626, + 125, 1626, 125, 126, 126, 125, 1626, 1626, + 1626, 1626, 1626, 125, 1626, 1626, 125, 1806, + 1807, 1808, 1809, 1810, 1811, 125, 1626, 1626, + 125, 1626, 1626, 125, 1626, 125, 1626, 125, + 1626, 125, 1626, 125, 1812, 1813, 125, 1626, + 125, 1626, 125, 1814, 1815, 1816, 1817, 1818, + 1819, 1820, 1821, 1822, 1823, 1824, 1825, 1826, + 1827, 1828, 1829, 125, 126, 125, 1626, 1626, + 125, 1626, 125, 1626, 125, 1626, 1626, 1626, + 1626, 125, 1626, 1626, 125, 125, 126, 125, + 125, 1626, 126, 1626, 125, 1626, 125, 1626, + 1626, 125, 125, 126, 125, 125, 126, 125, + 1626, 1626, 125, 1626, 1626, 126, 1626, 125, + 1626, 1626, 1626, 1626, 125, 1626, 1626, 1626, + 125, 1626, 1626, 126, 125, 1830, 1831, 1810, + 1816, 1832, 125, 1626, 125, 1626, 1626, 125, + 1626, 125, 1833, 1834, 1835, 1836, 1837, 1838, + 125, 1839, 1840, 1841, 1814, 1842, 1843, 125, + 1626, 125, 1626, 125, 1626, 125, 1626, 1626, + 1626, 1626, 1626, 125, 1626, 125, 1844, 1845, + 1846, 1847, 1848, 1849, 1850, 1851, 1852, 1853, + 1854, 1855, 1856, 1857, 1858, 1859, 1856, 1860, + 1861, 1602, 1862, 1814, 125, 1626, 1626, 125, + 125, 126, 125, 1626, 125, 125, 125, 1626, + 126, 125, 1626, 1626, 126, 125, 1626, 125, + 1626, 1626, 125, 125, 125, 126, 125, 1626, + 1626, 125, 1626, 126, 125, 1626, 1626, 1626, + 125, 1626, 1626, 1626, 1626, 1626, 1626, 1626, + 125, 1626, 125, 125, 126, 125, 1626, 1626, + 1626, 125, 125, 125, 1626, 125, 126, 125, + 1626, 1626, 125, 1626, 126, 125, 1814, 1863, + 1864, 1529, 1865, 1866, 125, 1626, 125, 1626, + 125, 1626, 125, 1626, 125, 1867, 125, 1626, + 1626, 125, 1868, 1869, 1870, 1871, 1872, 1873, + 1874, 125, 1626, 1626, 125, 125, 125, 125, + 1626, 1626, 125, 126, 125, 1626, 1626, 125, + 125, 125, 1626, 1626, 1626, 1626, 125, 1875, + 125, 1626, 125, 1876, 125, 1877, 1878, 128, + 129, 1879, 125, 1626, 1626, 125, 125, 1626, + 1626, 148, 1880, 148, 148, 125, 1880, 125, + 125, 1626, 148, 125, 148, 125, 1880, 125, + 1880, 148, 1626, 125, 125, 1880, 125, 148, + 1880, 148, 1880, 1880, 572, 572, 125, 1880, + 1880, 1626, 1880, 148, 125, 126, 1626, 1880, + 148, 1880, 126, 148, 125, 125, 125, 125, + 1880, 1880, 126, 125, 125, 148, 148, 1880, + 148, 1880, 125, 125, 148, 1880, 1880, 125, + 148, 1626, 148, 126, 148, 1880, 148, 125, + 1881, 1882, 184, 1883, 1884, 1885, 1886, 1887, + 1888, 1889, 1890, 1891, 1892, 1893, 1894, 1895, + 1896, 1897, 1898, 1899, 1900, 1901, 1902, 1903, + 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911, + 125, 148, 148, 148, 148, 1880, 125, 148, + 1880, 125, 1880, 125, 148, 148, 1880, 148, + 125, 148, 125, 126, 148, 1880, 125, 125, + 125, 1880, 1880, 125, 125, 125, 125, 1880, + 148, 148, 125, 125, 125, 125, 125, 148, + 125, 126, 148, 125, 1880, 1880, 1880, 148, + 148, 148, 148, 148, 148, 148, 1880, 125, + 125, 125, 125, 125, 125, 148, 125, 126, + 148, 125, 1880, 148, 1880, 148, 148, 148, + 148, 148, 148, 1880, 125, 125, 125, 148, + 148, 125, 148, 125, 126, 125, 1880, 148, + 1880, 148, 148, 148, 148, 148, 148, 1880, + 125, 148, 1880, 1880, 1880, 1880, 148, 148, + 1880, 126, 125, 1880, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 1880, 125, + 148, 1880, 1880, 1880, 1880, 126, 125, 148, + 1880, 148, 148, 148, 148, 1880, 125, 125, + 125, 125, 125, 148, 125, 148, 125, 126, + 125, 1880, 148, 1880, 148, 148, 148, 148, + 148, 1880, 125, 148, 1880, 1880, 1880, 1880, + 148, 1880, 126, 148, 125, 148, 1880, 148, + 148, 148, 1880, 125, 125, 125, 148, 125, + 125, 148, 125, 126, 125, 148, 125, 1880, + 148, 1880, 148, 148, 148, 125, 1880, 1880, + 148, 1880, 1880, 126, 1880, 125, 1880, 1880, + 125, 1880, 126, 125, 1880, 1880, 1880, 125, + 1880, 126, 125, 148, 1880, 1880, 1880, 1880, + 126, 1880, 125, 148, 148, 1880, 125, 1880, + 1880, 148, 1880, 1880, 125, 1880, 125, 1912, + 1913, 1914, 217, 218, 219, 220, 221, 1915, + 223, 224, 225, 226, 227, 228, 1916, 1917, + 1918, 1919, 1920, 234, 1921, 236, 1922, 1528, + 1529, 1923, 1924, 1925, 1926, 1927, 1928, 1929, + 1930, 1538, 1931, 151, 152, 1932, 249, 250, + 251, 252, 151, 153, 151, 125, 1880, 125, + 126, 1880, 1880, 1880, 1880, 1880, 125, 1880, + 1880, 126, 1880, 148, 125, 125, 1880, 125, + 148, 148, 148, 1880, 148, 1880, 125, 148, + 1880, 148, 148, 1880, 125, 1880, 125, 125, + 125, 126, 125, 1880, 1880, 126, 148, 125, + 1880, 148, 148, 125, 148, 1880, 1880, 125, + 148, 1880, 125, 1880, 1880, 1880, 125, 126, + 126, 1880, 125, 1880, 148, 1880, 125, 148, + 125, 126, 125, 125, 1880, 1880, 148, 1880, + 148, 126, 148, 125, 1880, 125, 148, 148, + 1880, 125, 1880, 1880, 1880, 148, 1880, 148, + 1880, 125, 1880, 1880, 125, 1933, 1934, 255, + 1935, 257, 258, 259, 260, 261, 262, 263, + 151, 1936, 265, 1937, 267, 1938, 269, 125, + 1626, 1880, 1626, 1880, 1485, 125, 1626, 125, + 148, 148, 125, 125, 1880, 125, 1485, 1880, + 125, 125, 1880, 125, 148, 1880, 125, 125, + 148, 148, 148, 148, 148, 1880, 125, 1939, + 1940, 272, 151, 273, 125, 148, 1880, 148, + 125, 1880, 125, 153, 274, 275, 153, 1549, + 1941, 1942, 1943, 280, 281, 282, 1944, 284, + 1945, 1946, 1947, 1948, 1949, 1950, 1951, 1952, + 1953, 1954, 295, 296, 152, 1955, 153, 151, + 125, 148, 148, 1880, 1880, 125, 148, 1880, + 148, 125, 1880, 125, 148, 1880, 1880, 1880, + 1880, 125, 148, 1880, 148, 1880, 125, 148, + 148, 125, 126, 125, 148, 125, 1880, 126, + 148, 1880, 148, 125, 1880, 125, 125, 148, + 1880, 148, 1880, 125, 148, 125, 126, 125, + 125, 126, 125, 1880, 148, 1880, 125, 1880, + 148, 1880, 126, 1880, 125, 1880, 1880, 1880, + 1880, 125, 1880, 148, 1880, 148, 1880, 125, + 148, 1880, 1880, 126, 125, 1956, 674, 302, + 303, 304, 305, 306, 307, 1957, 1704, 1958, + 1706, 312, 1959, 1960, 151, 125, 1880, 572, + 148, 148, 572, 572, 572, 125, 1626, 1626, + 1880, 1880, 1485, 125, 1880, 125, 148, 1880, + 148, 125, 148, 148, 148, 148, 1880, 125, + 1961, 1962, 317, 318, 319, 1963, 1964, 1965, + 1966, 324, 125, 325, 326, 153, 327, 328, + 1967, 330, 1968, 332, 1969, 334, 335, 153, + 151, 1581, 337, 338, 153, 339, 340, 341, + 342, 343, 344, 345, 346, 1970, 348, 349, + 1971, 351, 352, 353, 153, 259, 151, 354, + 125, 1880, 125, 1880, 125, 148, 125, 1880, + 125, 148, 148, 1880, 1880, 1880, 1880, 148, + 148, 148, 1880, 125, 148, 148, 1880, 125, + 1972, 1973, 1974, 1587, 1975, 1976, 1977, 1978, + 1979, 364, 1980, 1981, 1982, 1983, 1984, 1985, + 1986, 1983, 1987, 1988, 1602, 1989, 375, 1604, + 377, 125, 1880, 148, 1880, 125, 125, 126, + 125, 1880, 148, 125, 125, 1880, 1880, 148, + 1880, 126, 125, 1880, 148, 148, 125, 1880, + 148, 1880, 125, 125, 148, 125, 125, 126, + 148, 125, 1880, 148, 148, 1880, 125, 1880, + 125, 126, 125, 148, 148, 1880, 148, 148, + 148, 148, 148, 148, 1880, 125, 148, 1880, + 1880, 1880, 1880, 148, 1880, 1880, 1880, 125, + 148, 1880, 125, 125, 148, 125, 126, 125, + 1880, 148, 1880, 1880, 125, 125, 148, 125, + 1880, 148, 125, 126, 125, 1880, 148, 1880, + 125, 1880, 126, 125, 153, 382, 1605, 1990, + 1991, 1608, 386, 153, 1992, 1993, 151, 125, + 148, 1880, 125, 148, 1880, 125, 125, 1880, + 125, 148, 1880, 148, 125, 153, 389, 1994, + 125, 148, 148, 1880, 1880, 125, 1995, 1996, + 1997, 153, 394, 395, 396, 397, 398, 399, + 400, 401, 402, 403, 1615, 1998, 1999, 2000, + 151, 125, 1880, 1880, 125, 125, 125, 125, + 1880, 1880, 125, 1880, 1880, 125, 125, 125, + 1880, 1880, 1880, 1880, 125, 153, 2001, 409, + 410, 411, 151, 125, 125, 1880, 125, 148, + 2002, 125, 2003, 2004, 2005, 2007, 2006, 125, + 1880, 1880, 125, 125, 1880, 1880, 125, 1880, + 148, 2008, 148, 181, 148, 420, 2008, 420, + 420, 420, 148, 420, 148, 420, 2008, 420, + 2008, 148, 420, 420, 2008, 420, 148, 2008, + 148, 181, 2008, 2008, 572, 572, 420, 2008, + 2008, 2008, 148, 420, 421, 2008, 148, 2008, + 421, 148, 420, 420, 420, 420, 2008, 2008, + 421, 420, 420, 148, 148, 2008, 148, 2008, + 420, 420, 148, 2008, 2008, 420, 148, 148, + 421, 148, 2008, 148, 420, 2009, 2010, 184, + 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, + 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, + 2027, 2028, 2029, 2030, 2031, 2032, 2033, 2034, + 2035, 2036, 2037, 2038, 2039, 420, 148, 148, + 148, 148, 2008, 420, 148, 2008, 420, 2008, + 420, 148, 148, 2008, 148, 420, 148, 420, + 421, 148, 2008, 420, 420, 420, 2008, 2008, + 420, 420, 420, 420, 2008, 148, 148, 420, + 420, 420, 420, 420, 148, 420, 421, 148, + 420, 2008, 2008, 2008, 148, 148, 148, 148, + 148, 148, 148, 2008, 420, 420, 420, 420, + 420, 420, 148, 420, 421, 148, 420, 2008, + 148, 2008, 148, 148, 148, 148, 148, 148, + 2008, 420, 420, 420, 148, 148, 420, 148, + 420, 421, 420, 2008, 148, 2008, 148, 148, + 148, 148, 148, 148, 2008, 420, 148, 2008, + 2008, 2008, 2008, 148, 148, 2008, 421, 420, + 2008, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 2008, 420, 148, 2008, 2008, + 2008, 2008, 421, 420, 148, 2008, 148, 148, + 148, 148, 2008, 420, 420, 420, 420, 420, + 148, 420, 148, 420, 421, 420, 2008, 148, + 2008, 148, 148, 148, 148, 148, 2008, 420, + 148, 2008, 2008, 2008, 2008, 148, 2008, 421, + 148, 420, 148, 2008, 148, 148, 148, 2008, + 420, 420, 420, 148, 420, 420, 148, 420, + 421, 420, 148, 420, 2008, 148, 2008, 148, + 148, 148, 420, 2008, 2008, 148, 2008, 2008, + 421, 2008, 420, 2008, 2008, 420, 2008, 421, + 420, 2008, 2008, 2008, 420, 2008, 421, 420, + 148, 2008, 2008, 2008, 2008, 421, 2008, 420, + 148, 148, 2008, 420, 2008, 2008, 148, 2008, + 2008, 420, 2008, 420, 2040, 2041, 2042, 217, + 218, 219, 220, 221, 2043, 223, 224, 225, + 226, 227, 228, 2044, 2045, 2046, 2047, 2048, + 234, 2049, 236, 2050, 483, 484, 2051, 2052, + 2053, 2054, 2055, 2056, 2057, 2058, 646, 2059, + 151, 152, 2060, 249, 250, 251, 252, 151, + 153, 151, 420, 2008, 420, 421, 2008, 2008, + 2008, 2008, 2008, 420, 2008, 2008, 421, 2008, + 148, 420, 420, 2008, 420, 148, 148, 148, + 2008, 148, 2008, 420, 148, 2008, 148, 148, + 2008, 420, 2008, 420, 420, 420, 421, 420, + 2008, 2008, 421, 148, 420, 2008, 148, 148, + 420, 148, 2008, 2008, 420, 148, 2008, 420, + 2008, 2008, 2008, 420, 421, 421, 2008, 420, + 2008, 148, 2008, 420, 148, 420, 421, 420, + 420, 2008, 2008, 148, 2008, 148, 421, 148, + 420, 2008, 420, 148, 148, 2008, 420, 2008, + 2008, 2008, 148, 2008, 148, 2008, 420, 2008, + 2008, 420, 2061, 2062, 255, 2063, 257, 258, + 259, 260, 261, 262, 263, 151, 2064, 265, + 2065, 267, 2066, 269, 420, 181, 181, 2008, + 181, 2008, 571, 420, 420, 148, 148, 420, + 420, 2008, 420, 571, 2008, 420, 420, 2008, + 420, 148, 2008, 420, 420, 148, 148, 148, + 148, 148, 2008, 420, 2067, 2068, 272, 151, + 273, 420, 148, 2008, 148, 420, 2008, 420, + 153, 274, 275, 153, 657, 2069, 2070, 2071, + 280, 281, 282, 2072, 284, 2073, 2074, 2075, + 2076, 2077, 2078, 2079, 2080, 2081, 2082, 295, + 296, 152, 2083, 153, 151, 420, 148, 148, + 2008, 2008, 420, 148, 2008, 148, 420, 2008, + 420, 148, 2008, 2008, 2008, 2008, 420, 148, + 2008, 148, 2008, 420, 148, 148, 420, 421, + 420, 148, 420, 2008, 421, 148, 2008, 148, + 420, 2008, 420, 420, 148, 2008, 148, 2008, + 420, 148, 420, 421, 420, 420, 421, 420, + 2008, 148, 2008, 420, 2008, 148, 2008, 421, + 2008, 420, 2008, 2008, 2008, 2008, 420, 2008, + 148, 2008, 148, 2008, 420, 148, 2008, 2008, + 421, 420, 2084, 674, 302, 303, 304, 305, + 306, 307, 2085, 932, 2086, 934, 312, 2087, + 2088, 151, 420, 2008, 572, 148, 148, 572, + 572, 572, 420, 181, 2008, 2008, 571, 420, + 2008, 420, 148, 2008, 148, 420, 148, 148, + 148, 148, 2008, 420, 2089, 2090, 317, 318, + 319, 2091, 2092, 2093, 2094, 324, 420, 325, + 326, 153, 327, 328, 2095, 330, 2096, 332, + 2097, 334, 335, 153, 151, 690, 337, 338, + 153, 339, 340, 341, 342, 343, 344, 345, + 346, 2098, 348, 349, 2099, 351, 352, 353, + 153, 259, 151, 354, 420, 2008, 420, 2008, + 420, 148, 420, 2008, 420, 148, 148, 2008, + 2008, 2008, 2008, 148, 148, 148, 2008, 420, + 148, 148, 2008, 420, 2100, 2101, 2102, 696, + 2103, 2104, 2105, 2106, 2107, 364, 2108, 2109, + 2110, 2111, 2112, 2113, 2114, 2111, 2115, 2116, + 552, 2117, 375, 712, 377, 420, 2008, 148, + 2008, 420, 420, 421, 420, 2008, 148, 420, + 420, 2008, 2008, 148, 2008, 421, 420, 2008, + 148, 148, 420, 2008, 148, 2008, 420, 420, + 148, 420, 420, 421, 148, 420, 2008, 148, + 148, 2008, 420, 2008, 420, 421, 420, 148, + 148, 2008, 148, 148, 148, 148, 148, 148, + 2008, 420, 148, 2008, 2008, 2008, 2008, 148, + 2008, 2008, 2008, 420, 148, 2008, 420, 420, + 148, 420, 421, 420, 2008, 148, 2008, 2008, + 420, 420, 148, 420, 2008, 148, 420, 421, + 420, 2008, 148, 2008, 420, 2008, 421, 420, + 153, 382, 713, 2118, 2119, 716, 386, 153, + 2120, 2121, 151, 420, 148, 2008, 420, 148, + 2008, 420, 420, 2008, 420, 148, 2008, 148, + 420, 153, 389, 2122, 420, 148, 148, 2008, + 2008, 420, 2123, 2124, 2125, 153, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, + 723, 2126, 2127, 2128, 151, 420, 2008, 2008, + 420, 420, 420, 420, 2008, 2008, 420, 2008, + 2008, 420, 420, 420, 2008, 2008, 2008, 2008, + 420, 153, 2129, 409, 410, 411, 151, 420, + 420, 2008, 420, 148, 2130, 420, 2131, 2132, + 2133, 2135, 2134, 420, 2008, 2008, 420, 420, + 2008, 2008, 420, 2008, 148, 2136, 148, 148, + 420, 2136, 420, 420, 420, 148, 420, 148, + 420, 2136, 420, 2136, 148, 420, 420, 2136, + 420, 148, 2136, 148, 2136, 2136, 572, 572, + 420, 2136, 2136, 2136, 148, 420, 126, 2136, + 148, 2136, 126, 148, 420, 420, 420, 420, + 2136, 2136, 126, 420, 420, 148, 148, 2136, + 148, 2136, 420, 420, 148, 2136, 2136, 420, + 148, 148, 126, 148, 2136, 148, 420, 2137, + 2138, 184, 2139, 2140, 2141, 2142, 2143, 2144, + 2145, 2146, 2147, 2148, 2149, 2150, 2151, 2152, + 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, + 2161, 2162, 2163, 2164, 2165, 2166, 2167, 420, + 148, 148, 148, 148, 2136, 420, 148, 2136, + 420, 2136, 420, 148, 148, 2136, 148, 420, + 148, 420, 126, 148, 2136, 420, 420, 420, + 2136, 2136, 420, 420, 420, 420, 2136, 148, + 148, 420, 420, 420, 420, 420, 148, 420, + 126, 148, 420, 2136, 2136, 2136, 148, 148, + 148, 148, 148, 148, 148, 2136, 420, 420, + 420, 420, 420, 420, 148, 420, 126, 148, + 420, 2136, 148, 2136, 148, 148, 148, 148, + 148, 148, 2136, 420, 420, 420, 148, 148, + 420, 148, 420, 126, 420, 2136, 148, 2136, + 148, 148, 148, 148, 148, 148, 2136, 420, + 148, 2136, 2136, 2136, 2136, 148, 148, 2136, + 126, 420, 2136, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 2136, 420, 148, + 2136, 2136, 2136, 2136, 126, 420, 148, 2136, + 148, 148, 148, 148, 2136, 420, 420, 420, + 420, 420, 148, 420, 148, 420, 126, 420, + 2136, 148, 2136, 148, 148, 148, 148, 148, + 2136, 420, 148, 2136, 2136, 2136, 2136, 148, + 2136, 126, 148, 420, 148, 2136, 148, 148, + 148, 2136, 420, 420, 420, 148, 420, 420, + 148, 420, 126, 420, 148, 420, 2136, 148, + 2136, 148, 148, 148, 420, 2136, 2136, 148, + 2136, 2136, 126, 2136, 420, 2136, 2136, 420, + 2136, 126, 420, 2136, 2136, 2136, 420, 2136, + 126, 420, 148, 2136, 2136, 2136, 2136, 126, + 2136, 420, 148, 148, 2136, 420, 2136, 2136, + 148, 2136, 2136, 420, 2136, 420, 2168, 2169, + 2170, 217, 218, 219, 220, 221, 2171, 223, + 224, 225, 226, 227, 228, 2172, 2173, 2174, + 2175, 2176, 234, 2177, 236, 2178, 1528, 1529, + 2179, 2180, 2181, 2182, 2183, 2184, 2185, 2186, + 1538, 2187, 151, 152, 2188, 249, 250, 251, + 252, 151, 153, 151, 420, 2136, 420, 126, + 2136, 2136, 2136, 2136, 2136, 420, 2136, 2136, + 126, 2136, 148, 420, 420, 2136, 420, 148, + 148, 148, 2136, 148, 2136, 420, 148, 2136, + 148, 148, 2136, 420, 2136, 420, 420, 420, + 126, 420, 2136, 2136, 126, 148, 420, 2136, + 148, 148, 420, 148, 2136, 2136, 420, 148, + 2136, 420, 2136, 2136, 2136, 420, 126, 126, + 2136, 420, 2136, 148, 2136, 420, 148, 420, + 126, 420, 420, 2136, 2136, 148, 2136, 148, + 126, 148, 420, 2136, 420, 148, 148, 2136, + 420, 2136, 2136, 2136, 148, 2136, 148, 2136, + 420, 2136, 2136, 420, 2189, 2190, 255, 2191, + 257, 258, 259, 260, 261, 262, 263, 151, + 2192, 265, 2193, 267, 2194, 269, 420, 2136, + 2136, 2136, 420, 420, 148, 148, 420, 420, + 420, 2136, 2136, 420, 420, 2136, 420, 148, + 2136, 420, 420, 148, 148, 148, 148, 148, + 2136, 420, 2195, 2196, 1044, 272, 151, 273, + 1045, 1046, 1047, 1048, 420, 148, 2136, 1049, + 148, 420, 2136, 1049, 1049, 420, 153, 274, + 275, 153, 1549, 2197, 2198, 2199, 280, 281, + 282, 2200, 284, 2201, 2202, 2203, 2204, 2205, + 2206, 2207, 2208, 2209, 2210, 295, 296, 152, + 2211, 153, 151, 420, 148, 148, 2136, 2136, + 420, 148, 2136, 148, 420, 2136, 420, 148, + 2136, 2136, 2136, 2136, 420, 148, 2136, 148, + 2136, 420, 148, 148, 420, 126, 420, 148, + 420, 2136, 126, 148, 2136, 148, 420, 2136, + 420, 420, 148, 2136, 148, 2136, 420, 148, + 420, 126, 420, 420, 126, 420, 2136, 148, + 2136, 420, 2136, 148, 2136, 126, 2136, 420, + 2136, 2136, 2136, 2136, 420, 2136, 148, 2136, + 148, 2136, 420, 148, 2136, 2136, 126, 420, + 2212, 674, 302, 303, 304, 305, 306, 307, + 2213, 2214, 2215, 2216, 1194, 2217, 2218, 151, + 420, 2136, 572, 148, 148, 572, 572, 572, + 420, 2136, 2136, 2136, 420, 2136, 148, 148, + 2, 2136, 420, 148, 2136, 148, 2, 2136, + 148, 420, 1049, 148, 148, 148, 148, 2136, + 420, 2219, 2220, 317, 318, 319, 2221, 2222, + 2223, 2224, 324, 420, 325, 326, 153, 327, + 328, 2225, 330, 2226, 332, 2227, 334, 335, + 153, 151, 1581, 337, 338, 153, 339, 340, + 341, 342, 343, 344, 345, 346, 2228, 348, + 349, 2229, 351, 352, 353, 153, 259, 151, + 354, 420, 2136, 420, 2136, 420, 148, 420, + 2136, 420, 148, 148, 2136, 2136, 2136, 2136, + 148, 148, 148, 2136, 420, 148, 148, 2136, + 420, 2230, 2231, 2232, 1587, 2233, 2234, 2235, + 2236, 2237, 364, 2238, 2239, 2240, 2241, 2242, + 2243, 2244, 2241, 2245, 2246, 1602, 2247, 375, + 1604, 377, 420, 2136, 148, 2136, 420, 420, + 126, 420, 2136, 148, 420, 420, 2136, 2136, + 148, 2136, 126, 420, 2136, 148, 148, 420, + 2136, 148, 2136, 420, 420, 148, 420, 420, + 126, 148, 420, 2136, 148, 148, 2136, 420, + 2136, 420, 126, 420, 148, 148, 2136, 148, + 148, 148, 148, 148, 148, 2136, 420, 148, + 2136, 2136, 2136, 2136, 148, 2136, 2136, 2136, + 420, 148, 2136, 420, 420, 148, 420, 126, + 420, 2136, 148, 2136, 2136, 420, 420, 148, + 420, 2136, 148, 420, 126, 420, 2136, 148, + 2136, 420, 2136, 126, 420, 153, 382, 1605, + 2248, 2249, 1608, 386, 153, 2250, 2251, 151, + 420, 148, 2136, 420, 148, 2136, 420, 420, + 2136, 420, 148, 2136, 148, 420, 1162, 153, + 389, 2252, 420, 148, 148, 2136, 2136, 420, + 2253, 2254, 2255, 153, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 1615, 2256, + 2257, 2258, 151, 420, 2136, 2136, 420, 420, + 420, 420, 2136, 2136, 420, 2136, 2136, 420, + 420, 420, 2136, 2136, 2136, 2136, 420, 153, + 2259, 409, 410, 411, 151, 420, 420, 2136, + 420, 148, 2260, 420, 2261, 2262, 2263, 2265, + 2264, 420, 2136, 2136, 420, 420, 2136, 2136, + 420, 2136, 148, 2266, 148, 148, 420, 420, + 2266, 420, 420, 148, 420, 148, 420, 2266, + 420, 2266, 148, 420, 420, 2266, 420, 148, + 2266, 148, 2266, 2266, 572, 572, 420, 2266, + 2266, 2266, 148, 420, 126, 2266, 148, 2266, + 126, 148, 420, 420, 420, 420, 2266, 2266, + 126, 420, 420, 148, 148, 2266, 148, 2266, + 420, 420, 148, 2266, 2266, 420, 148, 148, + 126, 148, 2266, 148, 420, 2267, 2268, 184, + 2269, 2270, 2271, 2272, 2273, 2274, 2275, 2276, + 2277, 2278, 2279, 2280, 2281, 2282, 2283, 2284, + 2285, 2286, 2287, 2288, 2289, 2290, 2291, 2292, + 2293, 2294, 2295, 2296, 2297, 420, 148, 148, + 148, 148, 2266, 420, 148, 2266, 420, 2266, + 420, 148, 148, 2266, 148, 420, 148, 420, + 126, 148, 2266, 420, 420, 420, 2266, 2266, + 420, 420, 420, 420, 2266, 148, 148, 420, + 420, 420, 420, 420, 148, 420, 126, 148, + 420, 2266, 2266, 2266, 148, 148, 148, 148, + 148, 148, 148, 2266, 420, 420, 420, 420, + 420, 420, 148, 420, 126, 148, 420, 2266, + 148, 2266, 148, 148, 148, 148, 148, 148, + 2266, 420, 420, 420, 148, 148, 420, 148, + 420, 126, 420, 2266, 148, 2266, 148, 148, + 148, 148, 148, 148, 2266, 420, 148, 2266, + 2266, 2266, 2266, 148, 148, 2266, 126, 420, + 2266, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 2266, 420, 148, 2266, 2266, + 2266, 2266, 126, 420, 148, 2266, 148, 148, + 148, 148, 2266, 420, 420, 420, 420, 420, + 148, 420, 148, 420, 126, 420, 2266, 148, + 2266, 148, 148, 148, 148, 148, 2266, 420, + 148, 2266, 2266, 2266, 2266, 148, 2266, 126, + 148, 420, 148, 2266, 148, 148, 148, 2266, + 420, 420, 420, 148, 420, 420, 148, 420, + 126, 420, 148, 420, 2266, 148, 2266, 148, + 148, 148, 420, 2266, 2266, 148, 2266, 2266, + 126, 2266, 420, 2266, 2266, 420, 2266, 126, + 420, 2266, 2266, 2266, 420, 2266, 126, 420, + 148, 2266, 2266, 2266, 2266, 126, 2266, 420, + 148, 148, 2266, 420, 2266, 2266, 148, 2266, + 2266, 420, 2266, 420, 2298, 2299, 2300, 217, + 218, 219, 220, 221, 2301, 223, 224, 225, + 226, 227, 228, 2302, 2303, 2304, 2305, 2306, + 234, 2307, 236, 2308, 1528, 1529, 2309, 2310, + 2311, 2312, 2313, 2314, 2315, 2316, 1538, 2317, + 151, 152, 2318, 249, 250, 251, 252, 151, + 153, 151, 420, 2266, 420, 126, 2266, 2266, + 2266, 2266, 2266, 420, 2266, 2266, 126, 2266, + 148, 420, 420, 2266, 420, 148, 148, 148, + 2266, 148, 2266, 420, 148, 2266, 148, 148, + 2266, 420, 2266, 420, 420, 420, 126, 420, + 2266, 2266, 126, 148, 420, 2266, 148, 148, + 420, 148, 2266, 2266, 420, 148, 2266, 420, + 2266, 2266, 2266, 420, 126, 126, 2266, 420, + 2266, 148, 2266, 420, 148, 420, 126, 420, + 420, 2266, 2266, 148, 2266, 148, 126, 148, + 420, 2266, 420, 148, 148, 2266, 420, 2266, + 2266, 2266, 148, 2266, 148, 2266, 420, 2266, + 2266, 420, 2319, 2320, 255, 2321, 257, 258, + 259, 260, 261, 262, 263, 151, 2322, 265, + 2323, 267, 2324, 269, 420, 2266, 2266, 2136, + 420, 420, 148, 148, 420, 420, 2266, 420, + 2136, 2266, 420, 420, 2266, 420, 148, 2266, + 420, 420, 148, 148, 148, 148, 148, 2266, + 420, 2325, 2326, 1044, 272, 151, 273, 1045, + 1046, 1047, 1048, 420, 148, 2266, 1049, 148, + 420, 2266, 1049, 1049, 420, 153, 274, 275, + 153, 1549, 2327, 2328, 2329, 280, 281, 282, + 2330, 284, 2331, 2332, 2333, 2334, 2335, 2336, + 2337, 2338, 2339, 2340, 295, 296, 152, 2341, + 153, 151, 420, 148, 148, 2266, 2266, 420, + 148, 2266, 148, 420, 2266, 420, 148, 2266, + 2266, 2266, 2266, 420, 148, 2266, 148, 2266, + 420, 148, 148, 420, 126, 420, 148, 420, + 2266, 126, 148, 2266, 148, 420, 2266, 420, + 420, 148, 2266, 148, 2266, 420, 148, 420, + 126, 420, 420, 126, 420, 2266, 148, 2266, + 420, 2266, 148, 2266, 126, 2266, 420, 2266, + 2266, 2266, 2266, 420, 2266, 148, 2266, 148, + 2266, 420, 148, 2266, 2266, 126, 420, 2342, + 674, 302, 303, 304, 305, 306, 307, 2343, + 2214, 2344, 2216, 1194, 2345, 2346, 151, 420, + 2266, 572, 148, 148, 572, 572, 572, 420, + 2266, 2266, 2136, 420, 2266, 420, 148, 2266, + 148, 420, 1049, 148, 148, 148, 148, 2266, + 420, 2347, 2348, 317, 318, 319, 2349, 2350, + 2351, 2352, 324, 420, 325, 326, 153, 327, + 328, 2353, 330, 2354, 332, 2355, 334, 335, + 153, 151, 1581, 337, 338, 153, 339, 340, + 341, 342, 343, 344, 345, 346, 2356, 348, + 349, 2357, 351, 352, 353, 153, 259, 151, + 354, 420, 2266, 420, 2266, 420, 148, 420, + 2266, 420, 148, 148, 2266, 2266, 2266, 2266, + 148, 148, 148, 2266, 420, 148, 148, 2266, + 420, 2358, 2359, 2360, 1587, 2361, 2362, 2363, + 2364, 2365, 364, 2366, 2367, 2368, 2369, 2370, + 2371, 2372, 2369, 2373, 2374, 1602, 2375, 375, + 1604, 377, 420, 2266, 148, 2266, 420, 420, + 126, 420, 2266, 148, 420, 420, 2266, 2266, + 148, 2266, 126, 420, 2266, 148, 148, 420, + 2266, 148, 2266, 420, 420, 148, 420, 420, + 126, 148, 420, 2266, 148, 148, 2266, 420, + 2266, 420, 126, 420, 148, 148, 2266, 148, + 148, 148, 148, 148, 148, 2266, 420, 148, + 2266, 2266, 2266, 2266, 148, 2266, 2266, 2266, + 420, 148, 2266, 420, 420, 148, 420, 126, + 420, 2266, 148, 2266, 2266, 420, 420, 148, + 420, 2266, 148, 420, 126, 420, 2266, 148, + 2266, 420, 2266, 126, 420, 153, 382, 1605, + 2376, 2377, 1608, 386, 153, 2378, 2379, 151, + 420, 148, 2266, 420, 148, 2266, 420, 420, + 2266, 420, 148, 2266, 148, 420, 1162, 153, + 389, 2380, 420, 148, 148, 2266, 2266, 420, + 2381, 2382, 2383, 153, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 1615, 2384, + 2385, 2386, 151, 420, 2266, 2266, 420, 420, + 420, 420, 2266, 2266, 420, 2266, 2266, 420, + 420, 420, 2266, 2266, 2266, 2266, 420, 153, + 2387, 409, 410, 411, 151, 420, 420, 2266, + 420, 148, 2388, 420, 2389, 2390, 2391, 2393, + 2392, 420, 2266, 2266, 420, 420, 2266, 2266, + 420, 2266, 2395, 2394, 2, 2395, 2, 2395, + 2395, 2394, 2395, 2395, 2394, 2395, 2395, 2395, + 2394, 2395, 2395, 2395, 2394, 2395, 2395, 2394, + 2395, 2395, 2395, 2395, 2394, 2395, 2395, 2395, + 2394, 2394, 2395, 2395, 2394, 2395, 2394, 2396, + 2397, 2398, 2399, 2400, 2402, 2403, 2404, 2406, + 2407, 2408, 2409, 2410, 2411, 2412, 2413, 2414, + 2415, 2416, 2417, 2418, 2419, 2420, 2421, 2422, + 2423, 2401, 2405, 2394, 2395, 2395, 2395, 2395, + 2, 2395, 2, 2395, 2, 2, 2, 2395, + 2, 2, 2, 2395, 2395, 2395, 2395, 2, + 2, 2, 2, 2, 2, 2395, 2, 2, + 2, 2, 2, 2, 2395, 2, 2, 2, + 2, 2395, 2395, 2395, 2395, 2, 2395, 2395, + 2395, 2395, 2395, 2, 2395, 2395, 2, 2395, + 2395, 2395, 2395, 2, 2395, 2395, 2, 2, + 2, 2, 2, 2, 2395, 2395, 2395, 2395, + 2395, 2395, 2, 2395, 2395, 2, 2, 2, + 2, 2, 2, 2395, 2395, 2, 2395, 2395, + 2395, 2395, 2395, 2, 2395, 2395, 2, 2395, + 2, 2395, 2395, 2395, 2, 2395, 2, 2395, + 2395, 2395, 2395, 2395, 2, 2395, 2, 2395, + 2395, 2395, 2395, 2, 2395, 2, 2424, 2425, + 2426, 2427, 2428, 2429, 2430, 2431, 2432, 2433, + 2434, 2435, 2436, 2437, 2438, 2439, 2440, 2441, + 2442, 2443, 2444, 2394, 2395, 2, 2395, 2395, + 2395, 2395, 2395, 2, 2395, 2395, 2395, 2, + 2395, 2, 2395, 2395, 2, 2395, 2395, 2, + 2395, 2, 2, 2, 2395, 2395, 2, 2395, + 2, 2395, 2395, 2, 2395, 2, 2395, 2395, + 2395, 2, 2395, 2, 2395, 2395, 2, 2, + 2, 2395, 2395, 2395, 2, 2395, 2, 2395, + 2, 2395, 2395, 2395, 2395, 2395, 2, 2395, + 2395, 2, 2445, 2446, 2447, 2448, 2449, 2450, + 2394, 2395, 2395, 2, 2395, 2395, 2, 2395, + 2, 2395, 2, 2395, 2, 2395, 2, 2451, + 2452, 2394, 2395, 2, 2395, 2, 2453, 2454, + 2455, 2456, 2457, 2458, 2459, 2460, 2461, 2462, + 2463, 2464, 2465, 2466, 2467, 2394, 2395, 2395, + 2, 2395, 2, 2395, 2, 2395, 2395, 2395, + 2395, 2, 2395, 2395, 2, 2, 2, 2395, + 2395, 2, 2395, 2, 2395, 2395, 2, 2, + 2, 2395, 2395, 2, 2395, 2395, 2395, 2, + 2395, 2395, 2395, 2395, 2, 2395, 2395, 2395, + 2, 2395, 2395, 2, 2468, 2469, 2449, 2454, + 2470, 2394, 2395, 2, 2395, 2395, 2, 2395, + 2, 2471, 2472, 2473, 2474, 2475, 2476, 2394, + 2477, 2478, 2479, 2480, 2481, 2, 2395, 2, + 2395, 2, 2395, 2, 2395, 2395, 2395, 2395, + 2395, 2, 2395, 2, 2482, 2483, 2484, 2485, + 2486, 2487, 2488, 2489, 2490, 2491, 2492, 2493, + 2494, 2495, 2496, 2493, 2497, 2498, 2499, 2, + 2395, 2395, 2, 2, 2395, 2, 2, 2, + 2395, 2395, 2395, 2, 2395, 2, 2395, 2395, + 2, 2, 2, 2395, 2395, 2, 2395, 2, + 2395, 2395, 2395, 2, 2395, 2395, 2395, 2395, + 2395, 2395, 2395, 2, 2395, 2, 2, 2395, + 2395, 2395, 2, 2, 2, 2395, 2, 2395, + 2395, 2, 2395, 2, 2500, 2501, 2502, 2503, + 2, 2395, 2, 2395, 2, 2395, 2, 2395, + 2, 2504, 2, 2395, 2395, 2, 2505, 2506, + 2507, 2508, 2509, 2510, 2, 2395, 2395, 2, + 2, 2, 2, 2395, 2395, 2, 2395, 2395, + 2, 2, 2, 2395, 2395, 2395, 2395, 2, + 2511, 2, 2395, 2, 2512, 2394, 2513, 2514, + 2515, 2517, 2516, 2, 2395, 2395, 2, 2, + 2395, 2395, 148, 2518, 148, 148, 0, 0, + 2518, 0, 0, 148, 0, 148, 0, 2518, + 0, 2518, 148, 0, 0, 2518, 0, 148, + 2518, 2518, 2518, 148, 148, 0, 2518, 2518, + 2518, 148, 0, 2518, 148, 2518, 148, 0, + 0, 0, 0, 2518, 2518, 0, 0, 0, + 148, 148, 2518, 148, 2518, 0, 0, 148, + 2518, 2518, 0, 148, 148, 148, 2518, 148, + 0, 2519, 2520, 184, 2521, 2522, 2523, 2524, + 2525, 2526, 2527, 2528, 2529, 2530, 2531, 2532, + 2533, 2534, 2535, 2536, 2537, 2538, 2539, 2540, + 2541, 2542, 2543, 2544, 2545, 2546, 2547, 2548, + 2549, 0, 148, 148, 148, 148, 2518, 0, + 148, 2518, 0, 2518, 0, 148, 148, 2518, + 148, 148, 0, 148, 2518, 0, 0, 0, + 2518, 2518, 0, 0, 0, 0, 2518, 148, + 148, 0, 0, 0, 0, 0, 148, 0, + 148, 0, 2518, 2518, 2518, 148, 148, 148, + 148, 148, 148, 148, 2518, 0, 0, 0, + 0, 0, 0, 148, 0, 148, 0, 2518, + 148, 2518, 148, 148, 148, 148, 148, 148, + 2518, 0, 0, 0, 148, 148, 0, 148, + 0, 2518, 148, 2518, 148, 148, 148, 148, + 148, 148, 2518, 0, 148, 2518, 2518, 2518, + 2518, 148, 148, 2518, 0, 2518, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, + 2518, 0, 148, 2518, 2518, 2518, 2518, 0, + 148, 2518, 148, 148, 148, 148, 2518, 0, + 0, 0, 0, 0, 148, 0, 148, 0, + 2518, 148, 2518, 148, 148, 148, 148, 148, + 2518, 0, 148, 2518, 2518, 2518, 2518, 148, + 2518, 148, 0, 148, 2518, 148, 148, 148, + 2518, 0, 0, 0, 148, 0, 0, 148, + 0, 148, 0, 2518, 148, 2518, 148, 148, + 148, 0, 2518, 2518, 148, 2518, 2518, 2518, + 0, 2518, 2518, 0, 2518, 0, 2518, 2518, + 2518, 0, 2518, 0, 148, 2518, 2518, 2518, + 2518, 2518, 0, 148, 148, 2518, 0, 2518, + 2518, 148, 2518, 2518, 0, 2518, 0, 2550, + 2551, 2552, 217, 218, 219, 220, 221, 2553, + 223, 224, 225, 226, 227, 228, 2554, 2555, + 2556, 2557, 2558, 234, 2559, 236, 2560, 2561, + 2562, 2563, 2564, 2565, 2566, 2567, 2568, 246, + 2569, 151, 152, 2570, 249, 250, 251, 252, + 151, 153, 151, 0, 2518, 0, 2518, 2518, + 2518, 2518, 2518, 0, 2518, 2518, 2518, 148, + 0, 0, 2518, 0, 148, 148, 148, 2518, + 148, 2518, 0, 148, 2518, 148, 148, 2518, + 0, 2518, 0, 0, 0, 2518, 2518, 148, + 0, 2518, 148, 148, 0, 148, 2518, 2518, + 0, 148, 2518, 0, 2518, 2518, 2518, 0, + 2518, 0, 2518, 148, 2518, 0, 148, 0, + 0, 2518, 2518, 148, 2518, 148, 148, 0, + 2518, 0, 148, 148, 2518, 0, 2518, 2518, + 2518, 148, 2518, 148, 2518, 0, 2518, 2518, + 0, 2571, 2572, 255, 2573, 257, 258, 259, + 260, 261, 262, 263, 151, 2574, 265, 2575, + 267, 2576, 269, 0, 2518, 2518, 0, 148, + 148, 2518, 2518, 0, 2518, 0, 0, 2518, + 0, 148, 2518, 0, 0, 148, 148, 148, + 148, 148, 2518, 0, 2577, 2578, 272, 151, + 273, 0, 148, 2518, 148, 0, 2518, 0, + 153, 274, 275, 153, 276, 2579, 2580, 2581, + 280, 281, 282, 2582, 284, 2583, 2584, 2585, + 2586, 2587, 2588, 2589, 2590, 2591, 2592, 295, + 296, 152, 2593, 153, 151, 0, 148, 148, + 2518, 2518, 0, 148, 2518, 148, 0, 2518, + 0, 148, 2518, 2518, 2518, 2518, 0, 148, + 2518, 148, 2518, 0, 148, 148, 0, 148, + 0, 2518, 148, 2518, 148, 0, 2518, 0, + 0, 148, 2518, 148, 2518, 0, 148, 0, + 0, 2518, 148, 2518, 0, 2518, 148, 2518, + 2518, 0, 2518, 2518, 2518, 2518, 0, 2518, + 148, 2518, 148, 2518, 0, 148, 2518, 2518, + 0, 2594, 301, 302, 303, 304, 305, 306, + 307, 2595, 309, 2596, 311, 312, 2597, 2598, + 151, 0, 2518, 148, 148, 148, 148, 148, + 148, 0, 2518, 2518, 0, 2518, 0, 148, + 2518, 148, 0, 148, 148, 148, 148, 2518, + 0, 2599, 2600, 317, 318, 319, 2601, 2602, + 2603, 2604, 324, 0, 325, 326, 153, 327, + 328, 2605, 330, 2606, 332, 2607, 334, 335, + 153, 151, 336, 337, 338, 153, 339, 340, + 341, 342, 343, 344, 345, 346, 2608, 348, + 349, 2609, 351, 352, 353, 153, 259, 151, + 354, 0, 2518, 0, 2518, 0, 148, 0, + 2518, 0, 148, 148, 2518, 2518, 2518, 2518, + 148, 148, 148, 2518, 0, 148, 148, 2518, + 0, 2610, 2611, 2612, 358, 2613, 2614, 2615, + 2616, 2617, 364, 2618, 2619, 2620, 2621, 2622, + 2623, 2624, 2621, 2625, 2626, 2627, 375, 376, + 377, 0, 2518, 148, 2518, 0, 0, 2518, + 148, 0, 0, 2518, 2518, 148, 2518, 0, + 2518, 148, 148, 0, 2518, 148, 2518, 0, + 148, 148, 148, 0, 0, 2518, 148, 148, + 2518, 0, 2518, 0, 148, 148, 2518, 148, + 148, 148, 148, 148, 148, 2518, 0, 148, + 2518, 2518, 2518, 2518, 148, 2518, 2518, 2518, + 0, 148, 2518, 0, 0, 148, 0, 2518, + 148, 2518, 2518, 0, 0, 148, 0, 2518, + 148, 0, 2518, 148, 2518, 0, 2518, 0, + 153, 382, 343, 2628, 2629, 385, 386, 153, + 2630, 2631, 151, 0, 148, 2518, 0, 148, + 2518, 0, 0, 2518, 0, 148, 2518, 148, + 0, 153, 389, 2632, 0, 148, 148, 2518, + 2518, 0, 2633, 2634, 2635, 153, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, + 404, 2636, 2637, 2638, 151, 0, 2518, 2518, + 0, 0, 0, 0, 2518, 2518, 0, 2518, + 2518, 0, 0, 0, 2518, 2518, 2518, 2518, + 0, 153, 2639, 409, 410, 411, 151, 0, + 0, 2518, 0, 148, 2640, 0, 2641, 2642, + 2643, 2645, 2644, 0, 2518, 2518, 0, 0, + 2518, 2518, 0, 2518, 148, 2646, 148, 148, + 420, 420, 2646, 420, 443, 148, 420, 148, + 420, 2646, 420, 2646, 148, 443, 420, 420, + 2646, 420, 148, 2646, 148, 2646, 2646, 572, + 572, 420, 2646, 2646, 443, 2646, 148, 420, + 421, 443, 2646, 148, 2646, 421, 148, 420, + 420, 420, 420, 2646, 2646, 421, 420, 420, + 148, 148, 2646, 148, 2646, 420, 420, 148, + 2646, 2646, 420, 148, 443, 148, 421, 148, + 2646, 148, 420, 2647, 2648, 184, 2649, 2650, + 2651, 2652, 2653, 2654, 2655, 2656, 2657, 2658, + 2659, 2660, 2661, 2662, 2663, 2664, 2665, 2666, + 2667, 2668, 2669, 2670, 2671, 2672, 2673, 2674, + 2675, 2676, 2677, 420, 148, 148, 148, 148, + 2646, 420, 148, 2646, 420, 2646, 420, 148, + 148, 2646, 148, 420, 148, 420, 421, 148, + 2646, 420, 420, 420, 2646, 2646, 420, 420, + 420, 420, 2646, 148, 148, 420, 420, 420, + 420, 420, 148, 420, 421, 148, 420, 2646, + 2646, 2646, 148, 148, 148, 148, 148, 148, + 148, 2646, 420, 420, 420, 420, 420, 420, + 148, 420, 421, 148, 420, 2646, 148, 2646, + 148, 148, 148, 148, 148, 148, 2646, 420, + 420, 420, 148, 148, 420, 148, 420, 421, + 420, 2646, 148, 2646, 148, 148, 148, 148, + 148, 148, 2646, 420, 148, 2646, 2646, 2646, + 2646, 148, 148, 2646, 421, 420, 2646, 148, + 148, 148, 148, 148, 148, 148, 148, 148, + 148, 2646, 420, 148, 2646, 2646, 2646, 2646, + 421, 420, 148, 2646, 148, 148, 148, 148, + 2646, 420, 420, 420, 420, 420, 148, 420, + 148, 420, 421, 420, 2646, 148, 2646, 148, + 148, 148, 148, 148, 2646, 420, 148, 2646, + 2646, 2646, 2646, 148, 2646, 421, 148, 420, + 148, 2646, 148, 148, 148, 2646, 420, 420, + 420, 148, 420, 420, 148, 420, 421, 420, + 148, 420, 2646, 148, 2646, 148, 148, 148, + 420, 2646, 2646, 148, 2646, 2646, 421, 2646, + 420, 2646, 2646, 420, 2646, 421, 420, 2646, + 2646, 2646, 420, 2646, 421, 420, 148, 2646, + 2646, 2646, 2646, 421, 2646, 420, 148, 148, + 2646, 420, 2646, 2646, 148, 2646, 2646, 420, + 2646, 420, 2678, 2679, 2680, 217, 218, 219, + 220, 221, 2681, 223, 224, 225, 226, 227, + 228, 2682, 2683, 2684, 2685, 2686, 234, 2687, + 236, 2688, 483, 484, 2689, 2690, 2691, 2692, + 2693, 2694, 2695, 2696, 646, 2697, 151, 152, + 2698, 249, 250, 251, 252, 151, 153, 151, + 420, 2646, 420, 421, 2646, 2646, 2646, 2646, + 2646, 420, 2646, 2646, 421, 2646, 148, 420, + 420, 2646, 420, 148, 148, 148, 2646, 148, + 2646, 420, 148, 2646, 148, 148, 2646, 420, + 2646, 420, 420, 420, 421, 420, 2646, 2646, + 421, 148, 420, 2646, 148, 148, 420, 148, + 2646, 2646, 420, 148, 2646, 420, 2646, 2646, + 2646, 420, 421, 421, 2646, 420, 2646, 148, + 2646, 420, 148, 420, 421, 420, 420, 2646, + 2646, 148, 2646, 148, 421, 148, 420, 2646, + 420, 148, 148, 2646, 420, 2646, 2646, 2646, + 148, 2646, 148, 2646, 420, 2646, 2646, 420, + 2699, 2700, 255, 2701, 257, 258, 259, 260, + 261, 262, 263, 151, 2702, 265, 2703, 267, + 2704, 269, 420, 443, 2646, 443, 2646, 571, + 420, 443, 420, 148, 148, 420, 420, 2646, + 420, 571, 2646, 420, 420, 2646, 420, 148, + 2646, 420, 420, 148, 148, 148, 148, 148, + 2646, 420, 2705, 2706, 272, 151, 273, 420, + 148, 2646, 148, 420, 2646, 420, 153, 274, + 275, 153, 657, 2707, 2708, 2709, 280, 281, + 282, 2710, 284, 2711, 2712, 2713, 2714, 2715, + 2716, 2717, 2718, 2719, 2720, 295, 296, 152, + 2721, 153, 151, 420, 148, 148, 2646, 2646, + 420, 148, 2646, 148, 420, 2646, 420, 148, + 2646, 2646, 2646, 2646, 420, 148, 2646, 148, + 2646, 420, 148, 148, 420, 421, 420, 148, + 420, 2646, 421, 148, 2646, 148, 420, 2646, + 420, 420, 148, 2646, 148, 2646, 420, 148, + 420, 421, 420, 420, 421, 420, 2646, 148, + 2646, 420, 2646, 148, 2646, 421, 2646, 420, + 2646, 2646, 2646, 2646, 420, 2646, 148, 2646, + 148, 2646, 420, 148, 2646, 2646, 421, 420, + 2722, 674, 302, 303, 304, 305, 306, 307, + 2723, 1321, 2724, 1323, 312, 2725, 2726, 151, + 420, 2646, 572, 148, 148, 572, 572, 572, + 420, 443, 443, 2646, 2646, 571, 420, 2646, + 420, 148, 2646, 148, 420, 148, 148, 148, + 148, 2646, 420, 2727, 2728, 317, 318, 319, + 2729, 2730, 2731, 2732, 324, 420, 325, 326, + 153, 327, 328, 2733, 330, 2734, 332, 2735, + 334, 335, 153, 151, 690, 337, 338, 153, + 339, 340, 341, 342, 343, 344, 345, 346, + 2736, 348, 349, 2737, 351, 352, 353, 153, + 259, 151, 354, 420, 2646, 420, 2646, 420, + 148, 420, 2646, 420, 148, 148, 2646, 2646, + 2646, 2646, 148, 148, 148, 2646, 420, 148, + 148, 2646, 420, 2738, 2739, 2740, 696, 2741, + 2742, 2743, 2744, 2745, 364, 2746, 2747, 2748, + 2749, 2750, 2751, 2752, 2749, 2753, 2754, 552, + 2755, 375, 712, 377, 420, 2646, 148, 2646, + 420, 420, 421, 420, 2646, 148, 420, 420, + 2646, 2646, 148, 2646, 421, 420, 2646, 148, + 148, 420, 2646, 148, 2646, 420, 420, 148, + 420, 420, 421, 148, 420, 2646, 148, 148, + 2646, 420, 2646, 420, 421, 420, 148, 148, + 2646, 148, 148, 148, 148, 148, 148, 2646, + 420, 148, 2646, 2646, 2646, 2646, 148, 2646, + 2646, 2646, 420, 148, 2646, 420, 420, 148, + 420, 421, 420, 2646, 148, 2646, 2646, 420, + 420, 148, 420, 2646, 148, 420, 421, 420, + 2646, 148, 2646, 420, 2646, 421, 420, 153, + 382, 713, 2756, 2757, 716, 386, 153, 2758, + 2759, 151, 420, 148, 2646, 420, 148, 2646, + 420, 420, 2646, 420, 148, 2646, 148, 420, + 153, 389, 2760, 420, 148, 148, 2646, 2646, + 420, 2761, 2762, 2763, 153, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 723, + 2764, 2765, 2766, 151, 420, 2646, 2646, 420, + 420, 420, 420, 2646, 2646, 420, 2646, 2646, + 420, 420, 420, 2646, 2646, 2646, 2646, 420, + 153, 2767, 409, 410, 411, 151, 420, 420, + 2646, 420, 148, 2768, 420, 2769, 2770, 2771, + 2773, 2772, 420, 2646, 2646, 420, 420, 2646, + 2646, 420, 2646, 148, 2774, 148, 148, 420, + 420, 2774, 420, 420, 148, 420, 148, 420, + 2774, 420, 2774, 148, 420, 420, 2774, 420, + 148, 2774, 148, 2774, 2774, 572, 572, 420, + 2774, 2774, 2774, 148, 420, 421, 2774, 148, + 2774, 421, 148, 420, 420, 420, 420, 2774, + 2774, 421, 420, 420, 148, 148, 2774, 148, + 2774, 420, 420, 148, 2774, 2774, 420, 148, + 148, 421, 148, 2774, 148, 420, 2775, 2776, + 184, 2777, 2778, 2779, 2780, 2781, 2782, 2783, + 2784, 2785, 2786, 2787, 2788, 2789, 2790, 2791, + 2792, 2793, 2794, 2795, 2796, 2797, 2798, 2799, + 2800, 2801, 2802, 2803, 2804, 2805, 420, 148, + 148, 148, 148, 2774, 420, 148, 2774, 420, + 2774, 420, 148, 148, 2774, 148, 420, 148, + 420, 421, 148, 2774, 420, 420, 420, 2774, + 2774, 420, 420, 420, 420, 2774, 148, 148, + 420, 420, 420, 420, 420, 148, 420, 421, + 148, 420, 2774, 2774, 2774, 148, 148, 148, + 148, 148, 148, 148, 2774, 420, 420, 420, + 420, 420, 420, 148, 420, 421, 148, 420, + 2774, 148, 2774, 148, 148, 148, 148, 148, + 148, 2774, 420, 420, 420, 148, 148, 420, + 148, 420, 421, 420, 2774, 148, 2774, 148, + 148, 148, 148, 148, 148, 2774, 420, 148, + 2774, 2774, 2774, 2774, 148, 148, 2774, 421, + 420, 2774, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 2774, 420, 148, 2774, + 2774, 2774, 2774, 421, 420, 148, 2774, 148, + 148, 148, 148, 2774, 420, 420, 420, 420, + 420, 148, 420, 148, 420, 421, 420, 2774, + 148, 2774, 148, 148, 148, 148, 148, 2774, + 420, 148, 2774, 2774, 2774, 2774, 148, 2774, + 421, 148, 420, 148, 2774, 148, 148, 148, + 2774, 420, 420, 420, 148, 420, 420, 148, + 420, 421, 420, 148, 420, 2774, 148, 2774, + 148, 148, 148, 420, 2774, 2774, 148, 2774, + 2774, 421, 2774, 420, 2774, 2774, 420, 2774, + 421, 420, 2774, 2774, 2774, 420, 2774, 421, + 420, 148, 2774, 2774, 2774, 2774, 421, 2774, + 420, 148, 148, 2774, 420, 2774, 2774, 148, + 2774, 2774, 420, 2774, 420, 2806, 2807, 2808, + 217, 218, 219, 220, 221, 2809, 223, 224, + 225, 226, 227, 228, 2810, 2811, 2812, 2813, + 2814, 234, 2815, 236, 2816, 483, 484, 2817, + 2818, 2819, 2820, 2821, 2822, 2823, 2824, 646, + 2825, 151, 152, 2826, 249, 250, 251, 252, + 151, 153, 151, 420, 2774, 420, 421, 2774, + 2774, 2774, 2774, 2774, 420, 2774, 2774, 421, + 2774, 148, 420, 420, 2774, 420, 148, 148, + 148, 2774, 148, 2774, 420, 148, 2774, 148, + 148, 2774, 420, 2774, 420, 420, 420, 421, + 420, 2774, 2774, 421, 148, 420, 2774, 148, + 148, 420, 148, 2774, 2774, 420, 148, 2774, + 420, 2774, 2774, 2774, 420, 421, 421, 2774, + 420, 2774, 148, 2774, 420, 148, 420, 421, + 420, 420, 2774, 2774, 148, 2774, 148, 421, + 148, 420, 2774, 420, 148, 148, 2774, 420, + 2774, 2774, 2774, 148, 2774, 148, 2774, 420, + 2774, 2774, 420, 2827, 2828, 255, 2829, 257, + 258, 259, 260, 261, 262, 263, 151, 2830, + 265, 2831, 267, 2832, 269, 420, 2774, 2774, + 571, 420, 420, 148, 148, 420, 420, 2774, + 420, 571, 2774, 420, 420, 2774, 420, 148, + 2774, 420, 420, 148, 148, 148, 148, 148, + 2774, 420, 2833, 2834, 1044, 272, 151, 273, + 1045, 1046, 1047, 1048, 420, 148, 2774, 1049, + 148, 420, 2774, 1049, 1049, 420, 153, 274, + 275, 153, 657, 2835, 2836, 2837, 280, 281, + 282, 2838, 284, 2839, 2840, 2841, 2842, 2843, + 2844, 2845, 2846, 2847, 2848, 295, 296, 152, + 2849, 153, 151, 420, 148, 148, 2774, 2774, + 420, 148, 2774, 148, 420, 2774, 420, 148, + 2774, 2774, 2774, 2774, 420, 148, 2774, 148, + 2774, 420, 148, 148, 420, 421, 420, 148, + 420, 2774, 421, 148, 2774, 148, 420, 2774, + 420, 420, 148, 2774, 148, 2774, 420, 148, + 420, 421, 420, 420, 421, 420, 2774, 148, + 2774, 420, 2774, 148, 2774, 421, 2774, 420, + 2774, 2774, 2774, 2774, 420, 2774, 148, 2774, + 148, 2774, 420, 148, 2774, 2774, 421, 420, + 2850, 674, 302, 303, 304, 305, 306, 307, + 2851, 676, 2852, 678, 1194, 2853, 2854, 151, + 420, 2774, 572, 148, 148, 572, 572, 572, + 420, 2774, 2774, 571, 420, 2774, 420, 148, + 2774, 148, 420, 1049, 148, 148, 148, 148, + 2774, 420, 2855, 2856, 317, 318, 319, 2857, + 2858, 2859, 2860, 324, 420, 325, 326, 153, + 327, 328, 2861, 330, 2862, 332, 2863, 334, + 335, 153, 151, 690, 337, 338, 153, 339, + 340, 341, 342, 343, 344, 345, 346, 2864, + 348, 349, 2865, 351, 352, 353, 153, 259, + 151, 354, 420, 2774, 420, 2774, 420, 148, + 420, 2774, 420, 148, 148, 2774, 2774, 2774, + 2774, 148, 148, 148, 2774, 420, 148, 148, + 2774, 420, 2866, 2867, 2868, 696, 2869, 2870, + 2871, 2872, 2873, 364, 2874, 2875, 2876, 2877, + 2878, 2879, 2880, 2877, 2881, 2882, 552, 2883, + 375, 712, 377, 420, 2774, 148, 2774, 420, + 420, 421, 420, 2774, 148, 420, 420, 2774, + 2774, 148, 2774, 421, 420, 2774, 148, 148, + 420, 2774, 148, 2774, 420, 420, 148, 420, + 420, 421, 148, 420, 2774, 148, 148, 2774, + 420, 2774, 420, 421, 420, 148, 148, 2774, + 148, 148, 148, 148, 148, 148, 2774, 420, + 148, 2774, 2774, 2774, 2774, 148, 2774, 2774, + 2774, 420, 148, 2774, 420, 420, 148, 420, + 421, 420, 2774, 148, 2774, 2774, 420, 420, + 148, 420, 2774, 148, 420, 421, 420, 2774, + 148, 2774, 420, 2774, 421, 420, 153, 382, + 713, 2884, 2885, 716, 386, 153, 2886, 2887, + 151, 420, 148, 2774, 420, 148, 2774, 420, + 420, 2774, 420, 148, 2774, 148, 420, 1162, + 153, 389, 2888, 420, 148, 148, 2774, 2774, + 420, 2889, 2890, 2891, 153, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 723, + 2892, 2893, 2894, 151, 420, 2774, 2774, 420, + 420, 420, 420, 2774, 2774, 420, 2774, 2774, + 420, 420, 420, 2774, 2774, 2774, 2774, 420, + 153, 2895, 409, 410, 411, 151, 420, 420, + 2774, 420, 148, 2896, 420, 2897, 2898, 2899, + 2901, 2900, 420, 2774, 2774, 420, 420, 2774, + 2774, 420, 2774, 2008, 148, 148, 2008, 148, + 2008, 2008, 148, 2008, 2008, 148, 2008, 2008, + 2008, 148, 2008, 2008, 2008, 148, 2008, 2008, + 148, 2008, 2008, 2008, 2008, 148, 2008, 2008, + 2008, 148, 148, 2008, 2008, 148, 2008, 148, + 2902, 2903, 2904, 2905, 2906, 2908, 2909, 2910, + 2912, 2913, 2914, 2915, 2916, 2917, 2918, 2919, + 2920, 2921, 2922, 2923, 2924, 2925, 2926, 2927, + 2928, 2929, 2907, 2911, 148, 2930, 2931, 2932, + 2933, 2934, 2935, 2936, 2937, 2938, 2939, 2940, + 2941, 2942, 2943, 2944, 2945, 2946, 2947, 2948, + 2949, 2950, 148, 2951, 2952, 2953, 2954, 2955, + 2956, 148, 2957, 2958, 148, 2959, 2960, 2961, + 2962, 2963, 2964, 2965, 2966, 2967, 2968, 2969, + 2970, 2971, 2972, 2973, 148, 2974, 2975, 2955, + 2960, 2976, 148, 2977, 2978, 2979, 2980, 2981, + 2982, 148, 2983, 148, 148, 148, 148, 148, + 2395, 0, 148, 2395, 0, 148, 148, 2395, + 148, 0, 148, 0, 126, 148, 2395, 0, + 0, 0, 2395, 2395, 0, 0, 0, 0, + 2395, 148, 148, 0, 0, 0, 0, 0, + 148, 0, 126, 148, 0, 2395, 2395, 2395, + 148, 148, 148, 148, 148, 148, 148, 2395, + 0, 0, 0, 0, 0, 0, 148, 0, + 126, 148, 0, 2395, 148, 2395, 148, 148, + 148, 148, 148, 148, 2395, 0, 0, 0, + 148, 148, 0, 148, 0, 126, 0, 2395, + 148, 2395, 148, 148, 148, 148, 148, 148, + 2395, 0, 148, 2395, 2395, 2395, 2395, 148, + 148, 2395, 126, 0, 2395, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 2395, + 0, 148, 2395, 2395, 2395, 2395, 126, 0, + 148, 2395, 148, 148, 148, 148, 2395, 0, + 0, 0, 0, 0, 148, 0, 148, 0, + 126, 0, 2395, 148, 2395, 148, 148, 148, + 148, 148, 2395, 0, 148, 2395, 2395, 2395, + 2395, 148, 2395, 126, 148, 0, 148, 2395, + 148, 148, 148, 2395, 0, 0, 0, 148, + 0, 0, 148, 0, 126, 0, 148, 0, + 2395, 148, 2395, 148, 148, 148, 0, 2395, + 2395, 148, 2395, 2395, 126, 2395, 0, 2395, + 126, 0, 2395, 126, 0, 148, 2395, 2395, + 2395, 2395, 126, 2395, 0, 148, 148, 2395, + 0, 2395, 2395, 148, 2395, 2395, 0, 126, + 2395, 2395, 2395, 2395, 2395, 0, 2395, 2395, + 126, 2395, 148, 0, 148, 2984, 148, 2984, + 148, 181, 148, 2985, 2, 2984, 2985, 2985, + 148, 2985, 148, 2985, 2984, 2985, 2984, 148, + 2985, 2985, 2984, 2985, 148, 2984, 148, 181, + 2984, 2984, 572, 572, 2985, 2984, 2984, 2984, + 148, 2985, 421, 2984, 148, 2984, 421, 148, + 2985, 2985, 2985, 2985, 2984, 2984, 421, 2985, + 2985, 148, 148, 2984, 148, 2984, 2985, 2985, + 148, 2984, 2984, 2985, 148, 148, 421, 148, + 2984, 148, 2985, 2986, 2987, 184, 2988, 2989, + 2990, 2991, 2992, 2993, 2994, 2995, 2996, 2997, + 2998, 2999, 3000, 3001, 3002, 3003, 3004, 3005, + 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013, + 3014, 3015, 3016, 2985, 148, 148, 148, 148, + 2984, 2, 148, 2984, 2, 2984, 2, 148, + 148, 2984, 148, 2, 148, 2, 421, 148, + 2984, 2, 2, 2, 2984, 2984, 2, 2, + 2, 2, 2984, 148, 148, 2, 2, 2, + 2, 2, 148, 2, 421, 148, 2, 2984, + 2984, 2984, 148, 148, 148, 148, 148, 148, + 148, 2984, 2, 2, 2, 2, 2, 2, + 148, 2, 421, 148, 2, 2984, 148, 2984, + 148, 148, 148, 148, 148, 148, 2984, 2, + 2, 2, 148, 148, 2, 148, 2, 421, + 2, 2984, 148, 2984, 148, 148, 148, 148, + 148, 148, 2984, 2, 148, 2984, 2984, 2984, + 2984, 148, 148, 2984, 421, 2, 2984, 148, + 148, 148, 148, 148, 148, 148, 148, 148, + 148, 2984, 2, 148, 2984, 2984, 2984, 2984, + 421, 2, 148, 2984, 148, 148, 148, 148, + 2984, 2, 2, 2, 2, 2, 148, 2, + 148, 2, 421, 2, 2984, 148, 2984, 148, + 148, 148, 148, 148, 2984, 2, 148, 2984, + 2984, 2984, 2984, 148, 2984, 421, 148, 2, + 148, 2984, 148, 148, 148, 2984, 2, 2, + 2, 148, 2, 2, 148, 2, 421, 2, + 148, 2, 2984, 148, 2984, 148, 148, 148, + 2, 2984, 2984, 148, 2984, 2984, 421, 2984, + 2, 2984, 2984, 2, 2984, 421, 2, 2984, + 2984, 2984, 2, 2984, 421, 2, 148, 2984, + 2984, 2984, 2984, 421, 2984, 2, 148, 148, + 2984, 2, 2984, 2984, 148, 2984, 2984, 2, + 2984, 2, 3017, 3018, 3019, 217, 3020, 3022, + 218, 219, 220, 221, 3023, 223, 224, 225, + 226, 227, 228, 3024, 3025, 3026, 3027, 3028, + 234, 3029, 236, 3030, 483, 484, 3031, 3032, + 3033, 3034, 3035, 3036, 3037, 3038, 646, 3039, + 151, 152, 3040, 249, 250, 251, 252, 3021, + 151, 153, 151, 2985, 2984, 2, 421, 2984, + 2984, 2984, 2984, 2984, 2, 2984, 2984, 421, + 2984, 148, 2, 2984, 148, 2984, 2, 2984, + 2, 148, 148, 148, 2984, 148, 2984, 2, + 148, 2984, 148, 148, 2984, 2, 2984, 2, + 2, 2, 421, 2, 2984, 2984, 421, 148, + 2, 2984, 148, 148, 2, 148, 2984, 2984, + 2, 148, 2984, 2, 2984, 2984, 2984, 2, + 421, 421, 2984, 2, 2984, 148, 2984, 2, + 148, 2, 421, 2, 2, 2984, 2984, 148, + 2984, 148, 421, 148, 2, 2984, 2, 148, + 148, 2984, 2, 2984, 2984, 2984, 148, 2984, + 148, 2984, 2, 2984, 2984, 2, 3041, 3042, + 255, 3043, 257, 258, 259, 260, 261, 262, + 263, 151, 3044, 265, 3045, 267, 3046, 269, + 2985, 181, 181, 2984, 181, 2984, 571, 2, + 2, 148, 148, 2, 2, 2984, 2, 571, + 2984, 2, 2, 2984, 2, 148, 2984, 2, + 2, 148, 148, 148, 148, 148, 2984, 2, + 3047, 3048, 3049, 3021, 3050, 3051, 3052, 2985, + 148, 2984, 148, 2, 2984, 2, 148, 2984, + 2, 2, 148, 2, 2984, 3053, 2, 3053, + 2985, 2985, 3053, 2985, 3053, 3053, 2985, 3053, + 3053, 2985, 3053, 3053, 3053, 2985, 3053, 3053, + 3053, 2985, 3053, 3053, 2985, 3053, 3053, 3053, + 3053, 2985, 3053, 3053, 3053, 2985, 2985, 3053, + 3053, 2985, 3053, 2985, 3054, 3055, 3056, 3057, + 3058, 3060, 3061, 3062, 3064, 3065, 3066, 3067, + 3068, 3069, 3070, 3071, 3072, 3073, 3074, 3075, + 3076, 3077, 3078, 3079, 3080, 3081, 3059, 3063, + 2985, 3053, 3053, 3053, 3053, 2985, 3053, 2985, + 3053, 2985, 2985, 2985, 3053, 2985, 2985, 2985, + 3053, 3053, 3053, 3053, 2985, 2985, 2985, 2985, + 2985, 2985, 3053, 2985, 2985, 2985, 2985, 2985, + 2985, 3053, 2985, 2985, 2985, 2985, 3053, 3053, + 3053, 3053, 2985, 3053, 3053, 3053, 3053, 3053, + 2985, 3053, 3053, 2985, 3053, 3053, 3053, 3053, + 2985, 3053, 3053, 2985, 2985, 2985, 2985, 2985, + 2985, 3053, 3053, 3053, 3053, 3053, 3053, 2985, + 3053, 3053, 2985, 2985, 2985, 2985, 2985, 2985, + 3053, 3053, 2985, 3053, 3053, 3053, 3053, 3053, + 2985, 3053, 3053, 2985, 3053, 2985, 3053, 3053, + 3053, 2985, 3053, 2985, 3053, 3053, 3053, 3053, + 3053, 2985, 3053, 2985, 3053, 3053, 3053, 3053, + 2985, 3053, 2985, 3082, 3083, 3084, 3085, 3087, + 3088, 3089, 3090, 3091, 3092, 3093, 3094, 3095, + 3096, 3097, 3098, 3099, 3100, 3101, 3102, 3103, + 3104, 3105, 3086, 2985, 3053, 2985, 3053, 3053, + 3053, 3053, 3053, 2985, 3053, 3053, 3053, 2985, + 3053, 2985, 3053, 3053, 2985, 3053, 3053, 2985, + 3053, 3053, 2985, 3053, 2985, 2985, 2985, 3053, + 3053, 2985, 3053, 2985, 3053, 3053, 2985, 3053, + 2985, 3053, 3053, 3053, 2985, 3053, 2985, 3053, + 3053, 2985, 2985, 2985, 3053, 3053, 3053, 2985, + 3053, 2985, 3053, 2985, 3053, 3053, 3053, 3053, + 3053, 2985, 3053, 3053, 2985, 3106, 3107, 3108, + 3109, 3110, 3111, 2985, 3053, 3053, 2985, 3053, + 3053, 2985, 3053, 2985, 3053, 2985, 3053, 2985, + 3053, 2985, 3112, 3113, 3114, 3086, 3115, 3051, + 3052, 2985, 3053, 2985, 3053, 2985, 3053, 2985, + 2985, 3053, 3053, 2, 3116, 3117, 3118, 3119, + 3120, 3121, 3122, 3123, 3124, 3125, 3126, 3127, + 3128, 3129, 3130, 3085, 3086, 2985, 3053, 3053, + 2985, 3053, 2985, 3053, 2985, 3053, 3053, 3053, + 3053, 2985, 3053, 3053, 2985, 2985, 2985, 3053, + 3053, 2985, 3053, 3053, 2985, 3053, 3053, 2985, + 2985, 2985, 3053, 3053, 2985, 3053, 3053, 3053, + 2985, 3053, 3053, 3053, 3053, 2985, 3053, 3053, + 3053, 2985, 3053, 3053, 2985, 3086, 3131, 3132, + 2985, 3086, 2985, 3053, 2985, 2985, 3053, 3133, + 3134, 3110, 3135, 3136, 2985, 3053, 2985, 3053, + 3053, 2985, 3053, 2985, 3053, 3053, 3053, 3053, + 3053, 2985, 3137, 3138, 3139, 3140, 3141, 3142, + 2985, 3143, 3144, 3145, 3146, 3147, 2985, 3053, + 2985, 3053, 2985, 3053, 2985, 3053, 3053, 3053, + 3053, 3053, 2985, 3053, 2985, 3148, 3149, 3150, + 3151, 3152, 3153, 3154, 3155, 3156, 3157, 3158, + 3159, 3160, 3161, 3162, 3159, 3163, 3164, 3165, + 2985, 3053, 3053, 2985, 2985, 3053, 2985, 2985, + 2985, 3053, 3053, 3053, 2985, 3053, 2985, 3053, + 3053, 2985, 2985, 2985, 3053, 3053, 2985, 3053, + 2985, 3053, 3053, 3053, 2985, 3053, 3053, 3053, + 3053, 3053, 3053, 3053, 2985, 3053, 2985, 2985, + 3053, 3053, 3053, 2985, 2985, 2985, 3053, 2985, + 3053, 3053, 2985, 3053, 2985, 3166, 3167, 3168, + 3169, 2985, 3053, 2985, 3053, 2985, 3053, 2985, + 3053, 2985, 3170, 2985, 3053, 3053, 2985, 3171, + 3172, 3173, 3174, 3175, 3176, 2985, 3053, 3053, + 2985, 2985, 2985, 2985, 3053, 3053, 2985, 3053, + 3053, 2985, 2985, 2985, 3053, 3053, 3053, 3053, + 2985, 3177, 2985, 3053, 2985, 3178, 2985, 3179, + 3087, 3085, 3180, 3086, 2985, 3053, 3053, 2985, + 153, 274, 275, 153, 657, 3181, 3182, 3183, + 280, 281, 282, 3184, 284, 3185, 3186, 3187, + 3188, 3189, 3190, 3191, 3192, 3193, 3194, 295, + 296, 152, 3195, 3196, 151, 3021, 2985, 148, + 148, 2984, 2984, 2, 148, 2984, 148, 2, + 2984, 2, 148, 2984, 2984, 2984, 2984, 2, + 148, 2984, 148, 2984, 2, 148, 148, 2, + 421, 2, 148, 2, 2984, 421, 148, 2984, + 148, 2, 2984, 2, 2984, 2, 148, 2984, + 148, 2984, 2, 148, 2, 421, 2, 2, + 421, 2, 2984, 148, 2984, 2, 2984, 148, + 2984, 421, 2984, 2, 2984, 2984, 2984, 2984, + 2, 2984, 148, 2984, 148, 2984, 2, 148, + 2984, 2984, 421, 2, 3021, 3197, 3198, 2985, + 3021, 2, 2984, 2, 2, 2984, 3199, 674, + 302, 303, 304, 305, 306, 307, 3200, 932, + 3201, 934, 312, 3202, 3203, 151, 2985, 2984, + 572, 148, 148, 572, 572, 572, 2, 181, + 2984, 2984, 571, 2, 2984, 2, 148, 2984, + 2, 2984, 2984, 2984, 2984, 2984, 2, 3204, + 3205, 317, 318, 319, 3206, 3207, 3208, 3209, + 324, 2985, 325, 326, 153, 327, 328, 3210, + 330, 3211, 332, 3212, 334, 335, 153, 151, + 690, 337, 338, 153, 339, 340, 341, 342, + 343, 344, 345, 346, 3213, 348, 349, 3214, + 351, 352, 353, 153, 259, 151, 354, 2, + 2984, 2, 2984, 2, 148, 2, 2984, 2, + 148, 148, 2984, 2984, 2984, 2984, 148, 148, + 148, 2984, 2, 148, 148, 2984, 2, 3215, + 3216, 3217, 696, 3218, 3219, 3220, 3221, 3222, + 364, 3223, 3224, 3225, 3226, 3227, 3228, 3229, + 3226, 3230, 3231, 552, 3232, 375, 712, 377, + 2, 2984, 148, 2984, 2, 2, 421, 2, + 2984, 148, 2, 2, 2984, 2984, 148, 2984, + 421, 2, 2984, 148, 148, 2, 2984, 148, + 2984, 2, 2, 148, 2, 2, 421, 148, + 2, 2984, 148, 148, 2984, 2, 2984, 2, + 421, 2, 148, 148, 2984, 148, 148, 148, + 148, 148, 148, 2984, 2, 148, 2984, 2984, + 2984, 2984, 148, 2984, 2984, 2984, 2, 148, + 2984, 2, 2, 148, 2, 421, 2, 2984, + 148, 2984, 2984, 2, 2, 148, 2, 2984, + 148, 2, 421, 2, 2984, 148, 2984, 2, + 2984, 421, 2, 153, 382, 713, 3233, 3234, + 716, 386, 153, 3235, 3236, 151, 2, 148, + 2984, 2, 148, 2984, 2, 2, 2984, 2, + 148, 2984, 148, 2, 153, 389, 3237, 2, + 148, 148, 2984, 2984, 2, 3238, 3239, 3240, + 153, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, 723, 3241, 3242, 3243, 151, + 2, 2984, 2984, 2, 2, 2, 2, 2984, + 2984, 2, 2984, 2984, 2, 2, 2, 2984, + 2984, 2984, 2984, 2, 153, 3244, 409, 410, + 411, 151, 2, 2, 2984, 2, 148, 3245, + 2985, 3246, 3247, 3196, 3248, 3021, 2, 2984, + 2984, 2, 2, 2984, 2, 2984, 0, 2395, + 0, 148, 148, 148, 2395, 148, 2395, 0, + 148, 2395, 148, 148, 2395, 0, 0, 0, + 126, 0, 2395, 2395, 126, 148, 0, 2395, + 148, 148, 0, 148, 2395, 2395, 0, 148, + 2395, 0, 126, 126, 2395, 0, 2395, 148, + 2395, 0, 148, 0, 126, 0, 0, 2395, + 2395, 148, 2395, 148, 126, 148, 0, 2395, + 0, 148, 148, 2395, 0, 2395, 2395, 2395, + 148, 2395, 148, 2395, 0, 2395, 3249, 2395, + 2136, 0, 0, 148, 148, 0, 0, 2395, + 0, 2136, 0, 2395, 0, 148, 2395, 0, + 0, 148, 148, 148, 148, 148, 2395, 0, + 3250, 3250, 0, 3250, 3251, 2, 3250, 2, + 3250, 3250, 3251, 3250, 3250, 3251, 3250, 3250, + 3250, 3251, 3250, 3250, 3250, 3251, 3250, 3250, + 3251, 3250, 3250, 3250, 3250, 3251, 3250, 3250, + 3250, 3251, 3251, 3250, 3250, 3251, 3250, 3251, + 3252, 3253, 3254, 3255, 3256, 3258, 3259, 3260, + 3262, 3263, 3264, 3265, 3266, 3267, 3268, 3269, + 3270, 3271, 3272, 3273, 3274, 3275, 3276, 3277, + 3278, 3279, 3257, 3261, 3251, 3250, 3250, 3250, + 3250, 2, 3250, 2, 3250, 2, 2, 2, + 3250, 2, 2, 2, 3250, 3250, 3250, 3250, + 2, 2, 2, 2, 2, 2, 3250, 2, + 2, 2, 2, 2, 2, 3250, 2, 2, + 2, 2, 3250, 3250, 3250, 3250, 2, 3250, + 3250, 3250, 3250, 3250, 2, 3250, 3250, 2, + 3250, 3250, 3250, 3250, 2, 3250, 3250, 2, + 2, 2, 2, 2, 2, 3250, 3250, 3250, + 3250, 3250, 3250, 2, 3250, 3250, 2, 2, + 2, 2, 2, 2, 3250, 3250, 2, 3250, + 3250, 3250, 3250, 3250, 2, 3250, 3250, 2, + 3250, 2, 3250, 3250, 3250, 2, 3250, 2, + 3250, 3250, 3250, 3250, 3250, 2, 3250, 2, + 3250, 3250, 3250, 3250, 2, 3250, 2, 3280, + 3281, 3282, 3283, 3284, 3285, 3286, 3287, 3288, + 3289, 3290, 3291, 3292, 3293, 3294, 3295, 3296, + 3297, 3298, 3299, 3300, 3251, 3250, 2, 3250, + 3250, 3250, 3250, 3250, 2, 3250, 3250, 3250, + 2, 3250, 2, 3250, 3250, 2, 3250, 3250, + 2, 3250, 2, 2, 2, 3250, 3250, 2, + 3250, 2, 3250, 3250, 2, 3250, 2, 3250, + 3250, 3250, 2, 3250, 2, 3250, 3250, 2, + 2, 2, 3250, 3250, 3250, 2, 3250, 2, + 3250, 2, 3250, 3250, 3250, 3250, 3250, 2, + 3250, 3250, 2, 3301, 3302, 3303, 3304, 3305, + 3306, 3251, 3250, 3250, 2, 3250, 3250, 2, + 3250, 2, 3250, 2, 3250, 2, 3250, 2, + 3307, 3308, 3251, 3250, 2, 3250, 2, 3309, + 3310, 3311, 3312, 3313, 3314, 3315, 3316, 3317, + 3318, 3319, 3320, 3321, 3322, 3323, 3251, 3250, + 3250, 2, 3250, 2, 3250, 2, 3250, 3250, + 3250, 3250, 2, 3250, 3250, 2, 2, 2, + 3250, 3250, 2, 3250, 2, 3250, 3250, 2, + 2, 2, 3250, 3250, 2, 3250, 3250, 3250, + 2, 3250, 3250, 3250, 3250, 2, 3250, 3250, + 3250, 2, 3250, 3250, 2, 3324, 3325, 3305, + 3310, 3326, 3251, 3250, 2, 3250, 3250, 2, + 3250, 2, 3327, 3328, 3329, 3330, 3331, 3332, + 3251, 3333, 3334, 3335, 3336, 3337, 2, 3250, + 2, 3250, 2, 3250, 2, 3250, 3250, 3250, + 3250, 3250, 2, 3250, 2, 3338, 3339, 3340, + 3341, 3342, 3343, 3344, 3345, 3346, 3347, 3348, + 3349, 3350, 3351, 3352, 3349, 3353, 3354, 3355, + 2, 3250, 3250, 2, 2, 3250, 2, 2, + 2, 3250, 3250, 3250, 2, 3250, 2, 3250, + 3250, 2, 2, 2, 3250, 3250, 2, 3250, + 2, 3250, 3250, 3250, 2, 3250, 3250, 3250, + 3250, 3250, 3250, 3250, 2, 3250, 2, 2, + 3250, 3250, 3250, 2, 2, 2, 3250, 2, + 3250, 3250, 2, 3250, 2, 3356, 3357, 3358, + 3359, 2, 3250, 2, 3250, 2, 3250, 2, + 3250, 2, 3360, 2, 3250, 3250, 2, 3361, + 3362, 3363, 3364, 3365, 3366, 2, 3250, 3250, + 2, 2, 2, 2, 3250, 3250, 2, 3250, + 3250, 2, 2, 2, 3250, 3250, 3250, 3250, + 2, 3367, 2, 3250, 2, 3368, 3251, 3369, + 3370, 3371, 3373, 3372, 2, 3250, 3250, 2, + 2, 3250, 3250, 0, 3250, 0, 3250, 3374, + 3250, 3374, 148, 3250, 2395, 3375, 3376, 3250, + 0, 148, 3374, 148, 181, 148, 420, 420, + 3374, 420, 420, 148, 420, 148, 420, 3374, + 420, 3374, 148, 420, 420, 3374, 420, 148, + 3374, 148, 181, 3374, 3374, 572, 572, 420, + 3374, 3374, 3374, 148, 420, 421, 3374, 148, + 3374, 421, 148, 420, 420, 420, 420, 3374, + 3374, 421, 420, 420, 148, 148, 3374, 148, + 3374, 420, 420, 148, 3374, 3374, 420, 148, + 148, 421, 148, 3374, 148, 420, 3377, 3378, + 184, 3379, 3380, 3381, 3382, 3383, 3384, 3385, + 3386, 3387, 3388, 3389, 3390, 3391, 3392, 3393, + 3394, 3395, 3396, 3397, 3398, 3399, 3400, 3401, + 3402, 3403, 3404, 3405, 3406, 3407, 420, 148, + 148, 148, 148, 3374, 420, 148, 3374, 420, + 3374, 420, 148, 148, 3374, 148, 420, 148, + 420, 421, 148, 3374, 420, 420, 420, 3374, + 3374, 420, 420, 420, 420, 3374, 148, 148, + 420, 420, 420, 420, 420, 148, 420, 421, + 148, 420, 3374, 3374, 3374, 148, 148, 148, + 148, 148, 148, 148, 3374, 420, 420, 420, + 420, 420, 420, 148, 420, 421, 148, 420, + 3374, 148, 3374, 148, 148, 148, 148, 148, + 148, 3374, 420, 420, 420, 148, 148, 420, + 148, 420, 421, 420, 3374, 148, 3374, 148, + 148, 148, 148, 148, 148, 3374, 420, 148, + 3374, 3374, 3374, 3374, 148, 148, 3374, 421, + 420, 3374, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 3374, 420, 148, 3374, + 3374, 3374, 3374, 421, 420, 148, 3374, 148, + 148, 148, 148, 3374, 420, 420, 420, 420, + 420, 148, 420, 148, 420, 421, 420, 3374, + 148, 3374, 148, 148, 148, 148, 148, 3374, + 420, 148, 3374, 3374, 3374, 3374, 148, 3374, + 421, 148, 420, 148, 3374, 148, 148, 148, + 3374, 420, 420, 420, 148, 420, 420, 148, + 420, 421, 420, 148, 420, 3374, 148, 3374, + 148, 148, 148, 420, 3374, 3374, 148, 3374, + 3374, 421, 3374, 420, 3374, 3374, 420, 3374, + 421, 420, 3374, 3374, 3374, 420, 3374, 421, + 420, 148, 3374, 3374, 3374, 3374, 421, 3374, + 420, 148, 148, 3374, 420, 3374, 3374, 148, + 3374, 3374, 420, 3374, 420, 3408, 3409, 3410, + 217, 218, 219, 220, 221, 3411, 223, 224, + 225, 226, 227, 228, 3412, 3413, 3414, 3415, + 3416, 234, 3417, 236, 3418, 483, 484, 3419, + 3420, 3421, 3422, 3423, 3424, 3425, 3426, 646, + 3427, 151, 152, 3428, 249, 250, 251, 252, + 151, 153, 151, 420, 3374, 420, 421, 3374, + 3374, 3374, 3374, 3374, 420, 3374, 3374, 421, + 3374, 148, 420, 420, 3374, 420, 148, 148, + 148, 3374, 148, 3374, 420, 148, 3374, 148, + 148, 3374, 420, 3374, 420, 420, 420, 421, + 420, 3374, 3374, 421, 148, 420, 3374, 148, + 148, 420, 148, 3374, 3374, 420, 148, 3374, + 420, 3374, 3374, 3374, 420, 421, 421, 3374, + 420, 3374, 148, 3374, 420, 148, 420, 421, + 420, 420, 3374, 3374, 148, 3374, 148, 421, + 148, 420, 3374, 420, 148, 148, 3374, 420, + 3374, 3374, 3374, 148, 3374, 148, 3374, 420, + 3374, 3374, 420, 3429, 3430, 255, 3431, 257, + 258, 259, 260, 261, 262, 263, 151, 3432, + 265, 3433, 267, 3434, 269, 420, 181, 181, + 3374, 181, 3374, 571, 420, 420, 148, 148, + 420, 420, 3374, 420, 571, 3374, 420, 420, + 3374, 420, 148, 3374, 420, 420, 148, 148, + 148, 148, 148, 3374, 420, 3435, 3436, 272, + 151, 273, 420, 148, 3374, 148, 420, 3374, + 420, 153, 274, 275, 153, 657, 3437, 3438, + 3439, 280, 281, 282, 3440, 284, 3441, 3442, + 3443, 3444, 3445, 3446, 3447, 3448, 3449, 3450, + 295, 296, 152, 3451, 153, 151, 420, 148, + 148, 3374, 3374, 420, 148, 3374, 148, 420, + 3374, 420, 148, 3374, 3374, 3374, 3374, 420, + 148, 3374, 148, 3374, 420, 148, 148, 420, + 421, 420, 148, 420, 3374, 421, 148, 3374, + 148, 420, 3374, 420, 420, 148, 3374, 148, + 3374, 420, 148, 420, 421, 420, 420, 421, + 420, 3374, 148, 3374, 420, 3374, 148, 3374, + 421, 3374, 420, 3374, 3374, 3374, 3374, 420, + 3374, 148, 3374, 148, 3374, 420, 148, 3374, + 3374, 421, 420, 3452, 674, 302, 303, 304, + 305, 306, 307, 3453, 932, 3454, 934, 312, + 3455, 3456, 151, 420, 3374, 572, 148, 148, + 572, 572, 572, 420, 181, 3374, 3374, 571, + 420, 3374, 420, 148, 3374, 148, 420, 148, + 148, 148, 148, 3374, 420, 3457, 3458, 317, + 318, 319, 3459, 3460, 3461, 3462, 324, 420, + 325, 326, 153, 327, 328, 3463, 330, 3464, + 332, 3465, 334, 335, 153, 151, 690, 337, + 338, 153, 339, 340, 341, 342, 343, 344, + 345, 346, 3466, 348, 349, 3467, 351, 352, + 353, 153, 259, 151, 354, 420, 3374, 420, + 3374, 420, 148, 420, 3374, 420, 148, 148, + 3374, 3374, 3374, 3374, 148, 148, 148, 3374, + 420, 148, 148, 3374, 420, 3468, 3469, 3470, + 696, 3471, 3472, 3473, 3474, 3475, 364, 3476, + 3477, 3478, 3479, 3480, 3481, 3482, 3479, 3483, + 3484, 552, 3485, 375, 712, 377, 420, 3374, + 148, 3374, 420, 420, 421, 420, 3374, 148, + 420, 420, 3374, 3374, 148, 3374, 421, 420, + 3374, 148, 148, 420, 3374, 148, 3374, 420, + 420, 148, 420, 420, 421, 148, 420, 3374, + 148, 148, 3374, 420, 3374, 420, 421, 420, + 148, 148, 3374, 148, 148, 148, 148, 148, + 148, 3374, 420, 148, 3374, 3374, 3374, 3374, + 148, 3374, 3374, 3374, 420, 148, 3374, 420, + 420, 148, 420, 421, 420, 3374, 148, 3374, + 3374, 420, 420, 148, 420, 3374, 148, 420, + 421, 420, 3374, 148, 3374, 420, 3374, 421, + 420, 153, 382, 713, 3486, 3487, 716, 386, + 153, 3488, 3489, 151, 420, 148, 3374, 420, + 148, 3374, 420, 420, 3374, 420, 148, 3374, + 148, 420, 153, 389, 3490, 420, 148, 148, + 3374, 3374, 420, 3491, 3492, 3493, 153, 394, + 395, 396, 397, 398, 399, 400, 401, 402, + 403, 723, 3494, 3495, 3496, 151, 420, 3374, + 3374, 420, 420, 420, 420, 3374, 3374, 420, + 3374, 3374, 420, 420, 420, 3374, 3374, 3374, + 3374, 420, 153, 3497, 409, 410, 411, 151, + 420, 420, 3374, 420, 148, 3498, 420, 3499, + 3500, 3501, 3503, 3502, 420, 3374, 3374, 420, + 420, 3374, 3374, 420, 3374, 3375, 2985, 2985, + 3375, 2985, 3375, 3375, 2985, 3375, 3375, 2985, + 3375, 3375, 3375, 2985, 3375, 3375, 3375, 2985, + 3375, 3375, 2985, 3375, 3375, 3375, 3375, 2985, + 3375, 3375, 3375, 2985, 2985, 3375, 3375, 2985, + 3375, 2985, 3504, 3505, 3506, 3507, 3508, 3510, + 3511, 3512, 3514, 3515, 3516, 3517, 3518, 3519, + 3520, 3521, 3522, 3523, 3524, 3525, 3526, 3527, + 3528, 3529, 3530, 3531, 3509, 3513, 2985, 3375, + 3375, 3375, 3375, 2985, 3375, 2985, 3375, 2985, + 2985, 2985, 3375, 2985, 2985, 2985, 3375, 3375, + 3375, 3375, 2985, 2985, 2985, 2985, 2985, 2985, + 3375, 2985, 2985, 2985, 2985, 2985, 2985, 3375, + 2985, 2985, 2985, 2985, 3375, 3375, 3375, 3375, + 2985, 3375, 3375, 3375, 3375, 3375, 2985, 3375, + 3375, 2985, 3375, 3375, 3375, 3375, 2985, 3375, + 3375, 2985, 2985, 2985, 2985, 2985, 2985, 3375, + 3375, 3375, 3375, 3375, 3375, 2985, 3375, 3375, + 2985, 2985, 2985, 2985, 2985, 2985, 3375, 3375, + 2985, 3375, 3375, 3375, 3375, 3375, 2985, 3375, + 3375, 2985, 3375, 2985, 3375, 3375, 3375, 2985, + 3375, 2985, 3375, 3375, 3375, 3375, 3375, 2985, + 3375, 2985, 3375, 3375, 3375, 3375, 2985, 3375, + 2985, 3532, 3533, 3534, 3085, 3087, 3535, 3536, + 3537, 3538, 3539, 3540, 3541, 3542, 3543, 3544, + 3545, 3546, 3547, 3548, 3549, 3550, 3551, 3552, + 3086, 2985, 3375, 2985, 3375, 3375, 3375, 3375, + 3375, 2985, 3375, 3375, 3375, 2985, 3375, 2985, + 3375, 3375, 2985, 3375, 3375, 2985, 3375, 2985, + 2985, 2985, 3375, 3375, 2985, 3375, 2985, 3375, + 3375, 2985, 3375, 2985, 3375, 3375, 3375, 2985, + 3375, 2985, 3375, 3375, 2985, 2985, 2985, 3375, + 3375, 3375, 2985, 3375, 2985, 3375, 2985, 3375, + 3375, 3375, 3375, 3375, 2985, 3375, 3375, 2985, + 3553, 3554, 3555, 3556, 3557, 3558, 2985, 3375, + 3375, 2985, 3375, 3375, 2985, 3375, 2985, 3375, + 2985, 3375, 2985, 3375, 2985, 3559, 3560, 3114, + 3086, 3115, 3051, 3052, 2985, 3375, 2985, 3375, + 2985, 3561, 3562, 3563, 3564, 3565, 3566, 3567, + 3568, 3569, 3570, 3571, 3572, 3573, 3574, 3575, + 3085, 3086, 2985, 3375, 3375, 2985, 3375, 2985, + 3375, 2985, 3375, 3375, 3375, 3375, 2985, 3375, + 3375, 2985, 2985, 2985, 3375, 3375, 2985, 3375, + 3053, 2985, 3375, 3375, 2985, 2985, 2985, 3375, + 3375, 2985, 3375, 3375, 3375, 2985, 3375, 3375, + 3375, 3375, 2985, 3375, 3375, 3375, 2985, 3375, + 3375, 2985, 3576, 3577, 3557, 3578, 3579, 2985, + 3375, 2985, 3375, 3375, 2985, 3375, 3053, 2985, + 3053, 3053, 3053, 3053, 3375, 2985, 3580, 3581, + 3582, 3583, 3584, 3585, 2985, 3586, 3587, 3588, + 3589, 3590, 2985, 3375, 2985, 3375, 2985, 3375, + 2985, 3375, 3375, 3375, 3375, 3375, 2985, 3375, + 2985, 3591, 3592, 3593, 3594, 3595, 3596, 3597, + 3598, 3599, 3600, 3601, 3602, 3603, 3604, 3605, + 3602, 3606, 3607, 3608, 2985, 3375, 3375, 2985, + 2985, 3375, 2985, 2985, 2985, 3375, 3375, 3375, + 2985, 3375, 2985, 3375, 3375, 2985, 2985, 2985, + 3375, 3375, 2985, 3375, 2985, 3375, 3375, 3375, + 2985, 3375, 3375, 3375, 3375, 3375, 3375, 3375, + 2985, 3375, 2985, 2985, 3375, 3375, 3375, 2985, + 2985, 2985, 3375, 2985, 3375, 3375, 2985, 3375, + 2985, 3609, 3610, 3611, 3612, 2985, 3375, 2985, + 3375, 2985, 3375, 2985, 3375, 2985, 3613, 2985, + 3375, 3375, 2985, 3614, 3615, 3616, 3617, 3618, + 3619, 2985, 3375, 3375, 2985, 2985, 2985, 2985, + 3375, 3375, 2985, 3375, 3375, 2985, 2985, 2985, + 3375, 3375, 3375, 3375, 2985, 3620, 2985, 3375, + 2985, 3621, 2985, 3622, 3623, 3624, 3626, 3625, + 2985, 3375, 3375, 2985, 2985, 3375, 3375, 3376, + 3627, 2, 3376, 3627, 3376, 3376, 3627, 3376, + 3376, 3627, 3376, 3376, 3376, 3627, 3376, 3376, + 3376, 3627, 3376, 3376, 3627, 3376, 3376, 3376, + 3376, 3627, 3376, 3376, 3376, 3627, 3627, 3376, + 3376, 3627, 3376, 3627, 3628, 3629, 3630, 3631, + 3632, 3634, 3635, 3636, 3638, 3639, 3640, 3641, + 3642, 3643, 3644, 3645, 3646, 3647, 3648, 3649, + 3650, 3651, 3652, 3653, 3654, 3655, 3633, 3637, + 3627, 3376, 3376, 3376, 3376, 3627, 3376, 3627, + 3376, 3627, 3627, 3627, 3376, 3627, 3627, 3627, + 3376, 3376, 3376, 3376, 3627, 3627, 3627, 3627, + 3627, 3627, 3376, 3627, 3627, 3627, 3627, 3627, + 3627, 3376, 3627, 3627, 3627, 3627, 3376, 3376, + 3376, 3376, 3627, 3376, 3376, 3376, 3376, 3376, + 3627, 3376, 3376, 3627, 3376, 3376, 3376, 3376, + 3627, 3376, 3376, 3627, 3627, 3627, 3627, 3627, + 3627, 3376, 3376, 3376, 3376, 3376, 3376, 3627, + 3376, 3376, 3627, 3627, 3627, 3627, 3627, 3627, + 3376, 3376, 3627, 3376, 3376, 3376, 3376, 3376, + 3627, 3376, 3376, 3627, 3376, 3627, 3376, 3376, + 3376, 3627, 3376, 3627, 3376, 3376, 3376, 3376, + 3376, 3627, 3376, 3627, 3376, 3376, 3376, 3376, + 3627, 3376, 3627, 3656, 3657, 3658, 3659, 3660, + 3661, 3662, 3663, 3664, 3665, 3666, 3667, 3668, + 3669, 3670, 3671, 3672, 3673, 3674, 3675, 3676, + 3627, 3376, 3627, 3376, 3376, 3376, 3376, 3376, + 3627, 3376, 3376, 3376, 3627, 3376, 3627, 3376, + 3376, 3627, 3376, 3376, 3627, 3376, 3627, 3627, + 3627, 3376, 3376, 3627, 3376, 3627, 3376, 3376, + 3627, 3376, 3627, 3376, 3376, 3376, 3627, 3376, + 3627, 3376, 3376, 3627, 3627, 3627, 3376, 3376, + 3376, 3627, 3376, 3627, 3376, 3627, 3376, 3376, + 3376, 3376, 3376, 3627, 3376, 3376, 3627, 3677, + 3678, 3679, 3680, 3681, 3682, 3627, 3376, 3376, + 571, 3627, 3627, 3627, 3627, 3376, 3627, 571, + 3376, 3627, 3376, 3627, 3376, 3627, 3376, 3627, + 3683, 3684, 3685, 3686, 3687, 3688, 3689, 3627, + 3376, 3376, 3627, 3376, 3376, 3627, 2, 2, + 3376, 3376, 2, 3376, 2, 2, 3376, 3690, + 3691, 3692, 3693, 3694, 3695, 3696, 3697, 3698, + 3699, 3700, 3701, 3702, 3703, 3704, 3627, 3376, + 3376, 3627, 3376, 3627, 3376, 3627, 3376, 3376, + 3376, 3376, 3627, 3376, 3376, 3627, 3627, 3627, + 3376, 3376, 3627, 3376, 3627, 3376, 3376, 3627, + 3627, 3627, 3376, 3376, 3627, 3376, 3376, 3376, + 3627, 3376, 3376, 3376, 3376, 3627, 3376, 3376, + 3376, 3627, 3376, 3376, 3627, 3705, 3706, 1124, + 3681, 1125, 3707, 3708, 3709, 3627, 3376, 3627, + 3376, 3376, 571, 3627, 3376, 3627, 3627, 3376, + 3376, 3627, 3710, 3711, 3712, 3713, 3714, 3715, + 3627, 3716, 3717, 3718, 3719, 3720, 3627, 3376, + 3627, 3376, 3627, 3376, 3627, 3376, 3376, 3376, + 3376, 3376, 3627, 3376, 3627, 3721, 3722, 3723, + 3724, 3725, 3726, 3727, 3728, 3729, 3730, 3731, + 3732, 3733, 3734, 3735, 3732, 3736, 3737, 3738, + 3627, 3376, 3376, 3627, 3627, 3376, 3627, 3627, + 3627, 3376, 3376, 3376, 3627, 3376, 3627, 3376, + 3376, 3627, 3627, 3627, 3376, 3376, 3627, 3376, + 3627, 3376, 3376, 3376, 3627, 3376, 3376, 3376, + 3376, 3376, 3376, 3376, 3627, 3376, 3627, 3627, + 3376, 3376, 3376, 3627, 3627, 3627, 3376, 3627, + 3376, 3376, 3627, 3376, 3627, 3739, 3740, 3741, + 3742, 3627, 3376, 3627, 3376, 3627, 3376, 3627, + 3376, 3627, 3743, 3744, 3627, 3376, 3627, 3376, + 3376, 3627, 3745, 3746, 3747, 3748, 3749, 3750, + 3627, 3376, 3376, 3627, 3627, 3627, 3627, 3376, + 3376, 3627, 3376, 3376, 3627, 3627, 3627, 3376, + 3376, 3376, 3376, 3627, 3751, 3627, 3376, 3627, + 3752, 3627, 3753, 3754, 3688, 3756, 3755, 3627, + 3376, 3376, 3627, 3627, 3376, 3376, 3757, 0, + 3757, 3758, 3757, 3758, 3758, 3757, 3757, 3758, + 3757, 3757, 3758, 3757, 3757, 3757, 3758, 3757, + 3757, 3757, 3758, 3757, 3757, 3758, 3757, 3757, + 3757, 3757, 3758, 3757, 3757, 3757, 3758, 3758, + 3757, 3757, 3758, 3757, 3758, 3759, 3760, 3761, + 3762, 3763, 3765, 3766, 3767, 3769, 3770, 3771, + 3772, 3773, 3774, 3775, 3776, 3777, 3778, 3779, + 3780, 3781, 3782, 3783, 3784, 3785, 3786, 3764, + 3768, 3758, 3757, 3757, 3757, 3757, 3758, 3757, + 3758, 3757, 3758, 3758, 3758, 3757, 3758, 3758, + 3758, 3757, 3757, 3757, 3757, 3758, 3758, 3758, + 3758, 3758, 3758, 3757, 3758, 3758, 3758, 3758, + 3758, 3758, 3757, 3758, 3758, 3758, 3758, 3757, + 3757, 3757, 3757, 3758, 3757, 3757, 3757, 3757, + 3757, 3758, 3757, 3757, 3758, 3757, 3757, 3757, + 3757, 3758, 3757, 3757, 3758, 3758, 3758, 3758, + 3758, 3758, 3757, 3757, 3757, 3757, 3757, 3757, + 3758, 3757, 3757, 3758, 3758, 3758, 3758, 3758, + 3758, 3757, 3757, 3758, 3757, 3757, 3757, 3757, + 3757, 3758, 3757, 3757, 3758, 3757, 3758, 3757, + 3757, 3757, 3758, 3757, 3758, 3757, 3757, 3757, + 3757, 3757, 3758, 3757, 3758, 3757, 3757, 3757, + 3757, 3758, 3757, 3758, 3787, 3788, 3789, 3790, + 3791, 3792, 3793, 3794, 3795, 3796, 3797, 3798, + 3799, 3800, 3801, 3802, 3803, 3804, 3805, 3806, + 3807, 3758, 3757, 3758, 3757, 3757, 3757, 3757, + 3757, 3758, 3757, 3757, 3757, 3758, 3757, 3758, + 3757, 3757, 3758, 3757, 3757, 3758, 3757, 3758, + 3758, 3758, 3757, 3757, 3758, 3757, 3758, 3757, + 3757, 3758, 3757, 3758, 3757, 3757, 3757, 3758, + 3757, 3758, 3757, 3757, 3758, 3758, 3758, 3757, + 3757, 3757, 3758, 3757, 3758, 3757, 3758, 3757, + 3757, 3757, 3757, 3757, 3758, 3757, 3757, 3758, + 3808, 3809, 3810, 3811, 3812, 3813, 3758, 3757, + 3757, 3758, 3757, 3757, 3758, 3757, 3758, 3757, + 3758, 3757, 3758, 3757, 3758, 3814, 3815, 3758, + 3757, 3758, 3757, 3758, 3816, 3817, 3818, 3819, + 3820, 3821, 3822, 3823, 3824, 3825, 3826, 3827, + 3828, 3829, 3830, 3758, 3757, 3757, 3758, 3757, + 3758, 3757, 3758, 3757, 3757, 3757, 3757, 3758, + 3757, 3757, 3758, 3758, 3758, 3757, 3757, 3758, + 3757, 3758, 3757, 3757, 3758, 3758, 3758, 3757, + 3757, 3758, 3757, 3757, 3757, 3758, 3757, 3757, + 3757, 3757, 3758, 3757, 3757, 3757, 3758, 3757, + 3757, 3758, 3831, 3832, 3812, 3817, 3833, 3758, + 3757, 3758, 3757, 3757, 3758, 3757, 3758, 3834, + 3835, 3836, 3837, 3838, 3839, 3758, 3840, 3841, + 3842, 3843, 3844, 3758, 3757, 3758, 3757, 3758, + 3757, 3758, 3757, 3757, 3757, 3757, 3757, 3758, + 3757, 3758, 3845, 3846, 3847, 3848, 3849, 3850, + 3851, 3852, 3853, 3854, 3855, 3856, 3857, 3858, + 3859, 3856, 3860, 3861, 3862, 3758, 3757, 3757, + 3758, 3758, 3757, 3758, 3758, 3758, 3757, 3757, + 3757, 3758, 3757, 3758, 3757, 3757, 3758, 3758, + 3758, 3757, 3757, 3758, 3757, 3758, 3757, 3757, + 3757, 3758, 3757, 3757, 3757, 3757, 3757, 3757, + 3757, 3758, 3757, 3758, 3758, 3757, 3757, 3757, + 3758, 3758, 3758, 3757, 3758, 3757, 3757, 3758, + 3757, 3758, 3863, 3864, 3865, 3866, 3758, 3757, + 3758, 3757, 3758, 3757, 3758, 3757, 3758, 3867, + 3758, 3757, 3757, 3758, 3868, 3869, 3870, 3871, + 3872, 3873, 3758, 3757, 3757, 3758, 3758, 3758, + 3758, 3757, 3757, 3758, 3757, 3757, 3758, 3758, + 3758, 3757, 3757, 3757, 3757, 3758, 3874, 3758, + 3757, 3758, 3875, 3758, 3876, 3877, 3878, 3880, + 3879, 3758, 3757, 3757, 3758, 3758, 3757, 3757, + 0, 2395, 3376, 3376, 3757, 3881, 3250, 3881, + 3251, 3881, 3251, 3251, 3881, 3881, 3251, 3881, + 3881, 3251, 3881, 3881, 3881, 3251, 3881, 3881, + 3881, 3251, 3881, 3881, 3251, 3881, 3881, 3881, + 3881, 3251, 3881, 3881, 3881, 3251, 3251, 3881, + 3881, 3251, 3881, 3251, 3882, 3883, 3884, 3885, + 3886, 3888, 3889, 3890, 3892, 3893, 3894, 3895, + 3896, 3897, 3898, 3899, 3900, 3901, 3902, 3903, + 3904, 3905, 3906, 3907, 3908, 3909, 3887, 3891, + 3251, 3881, 3881, 3881, 3881, 3251, 3881, 3251, + 3881, 3251, 3251, 3251, 3881, 3251, 3251, 3251, + 3881, 3881, 3881, 3881, 3251, 3251, 3251, 3251, + 3251, 3251, 3881, 3251, 3251, 3251, 3251, 3251, + 3251, 3881, 3251, 3251, 3251, 3251, 3881, 3881, + 3881, 3881, 3251, 3881, 3881, 3881, 3881, 3881, + 3251, 3881, 3881, 3251, 3881, 3881, 3881, 3881, + 3251, 3881, 3881, 3251, 3251, 3251, 3251, 3251, + 3251, 3881, 3881, 3881, 3881, 3881, 3881, 3251, + 3881, 3881, 3251, 3251, 3251, 3251, 3251, 3251, + 3881, 3881, 3251, 3881, 3881, 3881, 3881, 3881, + 3251, 3881, 3881, 3251, 3881, 3251, 3881, 3881, + 3881, 3251, 3881, 3251, 3881, 3881, 3881, 3881, + 3881, 3251, 3881, 3251, 3881, 3881, 3881, 3881, + 3251, 3881, 3251, 3910, 3911, 3912, 3913, 3914, + 3915, 3916, 3917, 3918, 3919, 3920, 3921, 3922, + 3923, 3924, 3925, 3926, 3927, 3928, 3929, 3930, + 3251, 3881, 3251, 3881, 3881, 3881, 3881, 3881, + 3251, 3881, 3881, 3881, 3251, 3881, 3251, 3881, + 3881, 3251, 3881, 3881, 3251, 3881, 3251, 3251, + 3251, 3881, 3881, 3251, 3881, 3251, 3881, 3881, + 3251, 3881, 3251, 3881, 3881, 3881, 3251, 3881, + 3251, 3881, 3881, 3251, 3251, 3251, 3881, 3881, + 3881, 3251, 3881, 3251, 3881, 3251, 3881, 3881, + 3881, 3881, 3881, 3251, 3881, 3881, 3251, 3931, + 3932, 3933, 3934, 3935, 3936, 3251, 3881, 3881, + 3251, 3881, 3881, 3251, 3881, 3251, 3881, 3251, + 3881, 3251, 3881, 3251, 3937, 3938, 3251, 3881, + 3251, 3881, 3251, 3939, 3940, 3941, 3942, 3943, + 3944, 3945, 3946, 3947, 3948, 3949, 3950, 3951, + 3952, 3953, 3251, 3881, 3881, 3251, 3881, 3251, + 3881, 3251, 3881, 3881, 3881, 3881, 3251, 3881, + 3881, 3251, 3251, 3251, 3881, 3881, 3251, 3881, + 3251, 3881, 3881, 3251, 3251, 3251, 3881, 3881, + 3251, 3881, 3881, 3881, 3251, 3881, 3881, 3881, + 3881, 3251, 3881, 3881, 3881, 3251, 3881, 3881, + 3251, 3954, 3955, 3935, 3940, 3956, 3251, 3881, + 3251, 3881, 3881, 3251, 3881, 3251, 3957, 3958, + 3959, 3960, 3961, 3962, 3251, 3963, 3964, 3965, + 3966, 3967, 3251, 3881, 3251, 3881, 3251, 3881, + 3251, 3881, 3881, 3881, 3881, 3881, 3251, 3881, + 3251, 3968, 3969, 3970, 3971, 3972, 3973, 3974, + 3975, 3976, 3977, 3978, 3979, 3980, 3981, 3982, + 3979, 3983, 3984, 3985, 3251, 3881, 3881, 3251, + 3251, 3881, 3251, 3251, 3251, 3881, 3881, 3881, + 3251, 3881, 3251, 3881, 3881, 3251, 3251, 3251, + 3881, 3881, 3251, 3881, 3251, 3881, 3881, 3881, + 3251, 3881, 3881, 3881, 3881, 3881, 3881, 3881, + 3251, 3881, 3251, 3251, 3881, 3881, 3881, 3251, + 3251, 3251, 3881, 3251, 3881, 3881, 3251, 3881, + 3251, 3986, 3987, 3988, 3989, 3251, 3881, 3251, + 3881, 3251, 3881, 3251, 3881, 3251, 3990, 3251, + 3881, 3881, 3251, 3991, 3992, 3993, 3994, 3995, + 3996, 3251, 3881, 3881, 3251, 3251, 3251, 3251, + 3881, 3881, 3251, 3881, 3881, 3251, 3251, 3251, + 3881, 3881, 3881, 3881, 3251, 3997, 3251, 3881, + 3251, 3998, 3251, 3999, 4000, 4001, 4003, 4002, + 3251, 3881, 3881, 3251, 3251, 3881, 3881, 3881, + 3250, 3250, 3881, 3881, 3250, 3881, 3881, 3250, + 3881, 3881, 3881, 3250, 3881, 3881, 3881, 3250, + 3881, 3881, 3250, 3881, 3881, 3881, 3881, 3250, + 3881, 3881, 3881, 3250, 3250, 3881, 3881, 3250, + 3881, 3250, 4004, 4005, 4006, 4007, 4008, 4010, + 4011, 4012, 4014, 4015, 4016, 4017, 4018, 4019, + 4020, 4021, 4022, 4023, 4024, 4025, 4026, 4027, + 4028, 4029, 4030, 4031, 4009, 4013, 3250, 4032, + 4033, 4034, 4035, 4036, 4037, 4038, 4039, 4040, + 4041, 4042, 4043, 4044, 4045, 4046, 4047, 4048, + 4049, 4050, 4051, 4052, 3250, 4053, 4054, 4055, + 4056, 4057, 4058, 3250, 4059, 4060, 3250, 4061, + 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, + 4070, 4071, 4072, 4073, 4074, 4075, 3250, 4076, + 4077, 4057, 4062, 4078, 3250, 4079, 4080, 4081, + 4082, 4083, 4084, 3250, 4085, 3250, 0, 3250, + 148, 148, 2395, 2395, 0, 148, 2395, 148, + 0, 2395, 0, 148, 2395, 2395, 2395, 2395, + 0, 148, 2395, 148, 2395, 0, 148, 148, + 0, 126, 0, 148, 0, 2395, 126, 148, + 2395, 148, 0, 2395, 0, 2984, 0, 148, + 2395, 148, 2395, 0, 148, 0, 126, 0, + 0, 126, 0, 2395, 148, 2395, 0, 2395, + 148, 2395, 126, 2395, 0, 2395, 148, 2395, + 148, 2395, 0, 148, 2395, 2395, 126, 0, + 4086, 2984, 148, 4086, 148, 181, 148, 2985, + 4086, 2985, 2985, 2985, 148, 2985, 148, 2985, + 4086, 2985, 4086, 148, 2985, 2985, 4086, 2985, + 148, 4086, 148, 181, 4086, 4086, 572, 572, + 2985, 4086, 4086, 4086, 148, 2985, 421, 4086, + 148, 4086, 421, 148, 2985, 2985, 2985, 2985, + 4086, 4086, 421, 2985, 2985, 148, 148, 4086, + 148, 4086, 2985, 2985, 148, 4086, 4086, 2985, + 148, 148, 421, 148, 4086, 148, 2985, 4087, + 4088, 184, 4089, 4090, 4091, 4092, 4093, 4094, + 4095, 4096, 4097, 4098, 4099, 4100, 4101, 4102, + 4103, 4104, 4105, 4106, 4107, 4108, 4109, 4110, + 4111, 4112, 4113, 4114, 4115, 4116, 4117, 2985, + 148, 148, 148, 148, 4086, 2985, 148, 4086, + 2985, 4086, 2985, 148, 148, 4086, 148, 2985, + 148, 2985, 421, 148, 4086, 2985, 2985, 2985, + 4086, 4086, 2985, 2985, 2985, 2985, 4086, 148, + 148, 2985, 2985, 2985, 2985, 2985, 148, 2985, + 421, 148, 2985, 4086, 4086, 4086, 148, 148, + 148, 148, 148, 148, 148, 4086, 2985, 2985, + 2985, 2985, 2985, 2985, 148, 2985, 421, 148, + 2985, 4086, 148, 4086, 148, 148, 148, 148, + 148, 148, 4086, 2985, 2985, 2985, 148, 148, + 2985, 148, 2985, 421, 2985, 4086, 148, 4086, + 148, 148, 148, 148, 148, 148, 4086, 2985, + 148, 4086, 4086, 4086, 4086, 148, 148, 4086, + 421, 2985, 4086, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 4086, 2985, 148, + 4086, 4086, 4086, 4086, 421, 2985, 148, 4086, + 148, 148, 148, 148, 4086, 2985, 2985, 2985, + 2985, 2985, 148, 2985, 148, 2985, 421, 2985, + 4086, 148, 4086, 148, 148, 148, 148, 148, + 4086, 2985, 148, 4086, 4086, 4086, 4086, 148, + 4086, 421, 148, 2985, 148, 4086, 148, 148, + 148, 4086, 2985, 2985, 2985, 148, 2985, 2985, + 148, 2985, 421, 2985, 148, 2985, 4086, 148, + 4086, 148, 148, 148, 2985, 4086, 4086, 148, + 4086, 4086, 421, 4086, 2985, 4086, 4086, 2985, + 4086, 421, 2985, 4086, 4086, 4086, 2985, 4086, + 421, 2985, 148, 4086, 4086, 4086, 4086, 421, + 4086, 2985, 148, 148, 4086, 2985, 4086, 4086, + 148, 4086, 4086, 2985, 4086, 2985, 4118, 4119, + 4120, 217, 3020, 3022, 218, 219, 220, 221, + 4121, 223, 224, 225, 226, 227, 228, 4122, + 4123, 4124, 4125, 4126, 234, 4127, 236, 4128, + 483, 484, 4129, 4130, 4131, 4132, 4133, 4134, + 4135, 4136, 646, 4137, 151, 152, 4138, 249, + 250, 251, 252, 3021, 151, 153, 151, 2985, + 4086, 2985, 421, 4086, 4086, 4086, 4086, 4086, + 2985, 4086, 4086, 421, 4086, 148, 2985, 2985, + 4086, 2985, 148, 148, 148, 4086, 148, 4086, + 2985, 148, 4086, 148, 148, 4086, 2985, 4086, + 2985, 2985, 2985, 421, 2985, 4086, 4086, 421, + 148, 2985, 4086, 148, 148, 2985, 148, 4086, + 4086, 2985, 148, 4086, 2985, 4086, 4086, 4086, + 2985, 421, 421, 4086, 2985, 4086, 148, 4086, + 2985, 148, 2985, 421, 2985, 2985, 4086, 4086, + 148, 4086, 148, 421, 148, 2985, 4086, 2985, + 148, 148, 4086, 2985, 4086, 4086, 4086, 148, + 4086, 148, 4086, 2985, 4086, 4086, 2985, 4139, + 4140, 255, 4141, 257, 258, 259, 260, 261, + 262, 263, 151, 4142, 265, 4143, 267, 4144, + 269, 2985, 181, 181, 4086, 181, 4086, 571, + 2985, 2985, 148, 148, 2985, 2985, 4086, 2985, + 571, 4086, 2985, 2985, 4086, 2985, 148, 4086, + 2985, 2985, 148, 148, 148, 148, 148, 4086, + 2985, 4145, 4146, 3049, 3021, 3050, 3051, 3052, + 2985, 148, 4086, 148, 2985, 4086, 2985, 153, + 274, 275, 153, 657, 4147, 4148, 4149, 280, + 281, 282, 4150, 284, 4151, 4152, 4153, 4154, + 4155, 4156, 4157, 4158, 4159, 4160, 295, 296, + 152, 4161, 3196, 151, 3021, 2985, 148, 148, + 4086, 4086, 2985, 148, 4086, 148, 2985, 4086, + 2985, 148, 4086, 4086, 4086, 4086, 2985, 148, + 4086, 148, 4086, 2985, 148, 148, 2985, 421, + 2985, 148, 2985, 4086, 421, 148, 4086, 148, + 2985, 4086, 2985, 2984, 2985, 148, 4086, 148, + 4086, 2985, 148, 2985, 421, 2985, 2985, 421, + 2985, 4086, 148, 4086, 2985, 4086, 148, 4086, + 421, 4086, 2985, 4086, 4086, 4086, 4086, 2985, + 4086, 148, 4086, 148, 4086, 2985, 148, 4086, + 4086, 421, 2985, 4162, 674, 302, 303, 304, + 305, 306, 307, 4163, 932, 4164, 934, 312, + 4165, 4166, 151, 2985, 4086, 572, 148, 148, + 572, 572, 572, 2985, 181, 4086, 4086, 571, + 2985, 4086, 2985, 148, 4086, 2984, 2985, 2984, + 2984, 2984, 2984, 4086, 2985, 4167, 4168, 317, + 318, 319, 4169, 4170, 4171, 4172, 324, 2985, + 325, 326, 153, 327, 328, 4173, 330, 4174, + 332, 4175, 334, 335, 153, 151, 690, 337, + 338, 153, 339, 340, 341, 342, 343, 344, + 345, 346, 4176, 348, 349, 4177, 351, 352, + 353, 153, 259, 151, 354, 2985, 4086, 2985, + 4086, 2985, 148, 2985, 4086, 2985, 148, 148, + 4086, 4086, 4086, 4086, 148, 148, 148, 4086, + 2985, 148, 148, 4086, 2985, 4178, 4179, 4180, + 696, 4181, 4182, 4183, 4184, 4185, 364, 4186, + 4187, 4188, 4189, 4190, 4191, 4192, 4189, 4193, + 4194, 552, 4195, 375, 712, 377, 2985, 4086, + 148, 4086, 2985, 2985, 421, 2985, 4086, 148, + 2985, 2985, 4086, 4086, 148, 4086, 421, 2985, + 4086, 148, 148, 2985, 4086, 148, 4086, 2985, + 2985, 148, 2985, 2985, 421, 148, 2985, 4086, + 148, 148, 4086, 2985, 4086, 2985, 421, 2985, + 148, 148, 4086, 148, 148, 148, 148, 148, + 148, 4086, 2985, 148, 4086, 4086, 4086, 4086, + 148, 4086, 4086, 4086, 2985, 148, 4086, 2985, + 2985, 148, 2985, 421, 2985, 4086, 148, 4086, + 4086, 2985, 2985, 148, 2985, 4086, 148, 2985, + 421, 2985, 4086, 148, 4086, 2985, 4086, 421, + 2985, 153, 382, 713, 4196, 4197, 716, 386, + 153, 4198, 4199, 151, 2985, 148, 4086, 2985, + 148, 4086, 2985, 2985, 4086, 2985, 148, 4086, + 148, 2985, 153, 389, 4200, 2985, 148, 148, + 4086, 4086, 2985, 4201, 4202, 4203, 153, 394, + 395, 396, 397, 398, 399, 400, 401, 402, + 403, 723, 4204, 4205, 4206, 151, 2985, 4086, + 4086, 2985, 2985, 2985, 2985, 4086, 4086, 2985, + 4086, 4086, 2985, 2985, 2985, 4086, 4086, 4086, + 4086, 2985, 153, 4207, 409, 410, 411, 151, + 2985, 2985, 4086, 2985, 148, 4208, 2985, 4209, + 4210, 4211, 4213, 4212, 2985, 4086, 4086, 2985, + 2985, 4086, 4086, 2985, 4086, 4086, 2984, 2984, + 4086, 4086, 2984, 4086, 4086, 2984, 4086, 4086, + 4086, 2984, 4086, 4086, 4086, 2984, 4086, 4086, + 2984, 4086, 4086, 4086, 4086, 2984, 4086, 4086, + 4086, 2984, 2984, 4086, 4086, 2984, 4086, 2984, + 4214, 4215, 4216, 4217, 4218, 4220, 4221, 4222, + 4224, 4225, 4226, 4227, 4228, 4229, 4230, 4231, + 4232, 4233, 4234, 4235, 4236, 4237, 4238, 4239, + 4240, 4241, 4219, 4223, 2984, 4242, 4243, 4244, + 4245, 4246, 4247, 4248, 4249, 4250, 4251, 4252, + 4253, 4254, 4255, 4256, 4257, 4258, 4259, 4260, + 4261, 4262, 2984, 4263, 4264, 4265, 4266, 4267, + 4268, 2984, 4269, 4270, 2984, 4271, 4272, 4273, + 4274, 4275, 4276, 4277, 4278, 4279, 4280, 4281, + 4282, 4283, 4284, 4285, 2984, 4286, 4287, 4267, + 4272, 4288, 2984, 4289, 4290, 4291, 4292, 4293, + 4294, 2984, 4295, 2984, 0, 3250, 0, 3250, + 2395, 572, 148, 148, 572, 572, 572, 0, + 2395, 2395, 2136, 0, 2395, 0, 148, 148, + 3376, 0, 2395, 2984, 0, 3376, 2984, 2984, + 2984, 2984, 2395, 0, 325, 326, 153, 327, + 328, 2477, 330, 4296, 332, 4297, 334, 335, + 153, 151, 1581, 337, 338, 153, 339, 340, + 341, 342, 343, 344, 345, 346, 4298, 348, + 349, 4299, 351, 352, 353, 153, 259, 151, + 354, 0, 2395, 0, 148, 0, 2395, 0, + 148, 148, 2395, 2395, 2395, 2395, 148, 148, + 148, 2395, 0, 148, 148, 2395, 0, 4300, + 4301, 4302, 1587, 4303, 4304, 4305, 4306, 4307, + 364, 4308, 4309, 4310, 4311, 4312, 4313, 4314, + 4311, 4315, 4316, 1602, 4317, 375, 1604, 377, + 0, 2395, 148, 2395, 0, 0, 126, 0, + 2395, 148, 0, 0, 2395, 2395, 148, 2395, + 126, 0, 2395, 148, 148, 0, 2395, 148, + 2395, 0, 0, 148, 0, 0, 126, 148, + 0, 2395, 148, 148, 2395, 0, 2395, 0, + 126, 0, 148, 148, 2395, 148, 148, 148, + 148, 148, 148, 2395, 0, 148, 2395, 2395, + 2395, 2395, 148, 2395, 2395, 2395, 0, 148, + 2395, 0, 0, 148, 0, 126, 0, 2395, + 148, 2395, 2395, 0, 0, 148, 0, 2395, + 148, 0, 126, 0, 2395, 148, 2395, 0, + 2395, 126, 0, 153, 382, 1605, 4318, 4319, + 1608, 386, 153, 4320, 4321, 151, 0, 148, + 2395, 0, 148, 2395, 0, 0, 2395, 0, + 148, 2395, 148, 0, 4322, 153, 389, 4323, + 0, 3376, 3757, 0, 148, 148, 2395, 2395, + 0, 2505, 2506, 2507, 153, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 1615, + 2508, 2509, 2510, 151, 0, 153, 4324, 409, + 410, 411, 151, 0, 0, 2395, 0, 148, + 412, 413, 414, 4325, 4326, 0, 4327, 2, + 4327, 4328, 4328, 4327, 4328, 4327, 4327, 4328, + 4327, 4327, 4328, 4327, 4327, 4327, 4328, 4327, + 4327, 4327, 4328, 4327, 4327, 4328, 4327, 4327, + 4327, 4327, 4328, 4327, 4327, 4327, 4328, 4328, + 4327, 4327, 4328, 4327, 4328, 4329, 4330, 4331, + 4332, 4333, 4335, 4336, 4337, 4339, 4340, 4341, + 4342, 4343, 4344, 4345, 4346, 4347, 4348, 4349, + 4350, 4351, 4352, 4353, 4354, 4355, 4356, 4334, + 4338, 4328, 4327, 4327, 4327, 4327, 4328, 4327, + 4328, 4327, 4328, 4328, 4328, 4327, 4328, 4328, + 4328, 4327, 4327, 4327, 4327, 4328, 4328, 4328, + 4328, 4328, 4328, 4327, 4328, 4328, 4328, 4328, + 4328, 4328, 4327, 4328, 4328, 4328, 4328, 4327, + 4327, 4327, 4327, 4328, 4327, 4327, 4327, 4327, + 4327, 4328, 4327, 4327, 4328, 4327, 4327, 4327, + 4327, 4328, 4327, 4327, 4328, 4328, 4328, 4328, + 4328, 4328, 4327, 4327, 4327, 4327, 4327, 4327, + 4328, 4327, 4327, 4328, 4328, 4328, 4328, 4328, + 4328, 4327, 4327, 4328, 4327, 4327, 4327, 4327, + 4327, 4328, 4327, 4327, 4328, 4327, 4328, 4327, + 4327, 4327, 4328, 4327, 4328, 4327, 4327, 4327, + 4327, 4327, 4328, 4327, 4328, 4327, 4327, 4327, + 4327, 4328, 4327, 4328, 4357, 4358, 4359, 4360, + 4361, 4362, 4363, 4364, 4365, 4366, 4367, 4368, + 4369, 4370, 4371, 4372, 4373, 4374, 4375, 4376, + 4377, 4328, 4327, 4328, 4327, 4327, 4327, 4327, + 4327, 4328, 4327, 4327, 4327, 4328, 4327, 4328, + 4327, 4327, 4328, 4327, 4327, 4328, 4327, 4328, + 4328, 4328, 4327, 4327, 4328, 4327, 4328, 4327, + 4327, 4328, 4327, 4328, 4327, 4327, 4327, 4328, + 4327, 4328, 4327, 4327, 4328, 4328, 4328, 4327, + 4327, 4327, 4328, 4327, 4328, 4327, 4328, 4327, + 4327, 4327, 4327, 4327, 4328, 4327, 4327, 4328, + 4378, 4379, 4380, 4381, 4382, 4383, 4328, 4327, + 4327, 4328, 4327, 4327, 4328, 4327, 4328, 4327, + 4328, 4327, 4328, 4327, 4328, 4384, 4385, 4328, + 4327, 4328, 4327, 4328, 4386, 4387, 4388, 4389, + 4390, 4391, 4392, 4393, 4394, 4395, 4396, 4397, + 4398, 4399, 4400, 4328, 4327, 4327, 4328, 4327, + 4328, 4327, 4328, 4327, 4327, 4327, 4327, 4328, + 4327, 4327, 4328, 4328, 4328, 4327, 4327, 4328, + 4327, 4328, 4327, 4327, 4328, 4328, 4328, 4327, + 4327, 4328, 4327, 4327, 4327, 4328, 4327, 4327, + 4327, 4327, 4328, 4327, 4327, 4327, 4328, 4327, + 4327, 4328, 4401, 4402, 4382, 4387, 4403, 4328, + 4327, 4328, 4327, 4327, 4328, 4327, 4328, 4404, + 4405, 4406, 4407, 4408, 4409, 4410, 4328, 4411, + 4412, 4413, 4414, 4415, 4328, 4327, 4328, 4327, + 4328, 4327, 4328, 4327, 4327, 4327, 4327, 4327, + 4328, 4327, 4328, 4416, 4417, 4418, 4419, 4420, + 4421, 4422, 4423, 4424, 4425, 4426, 4427, 4428, + 4429, 4430, 4427, 4431, 4432, 4433, 4328, 4327, + 4327, 4328, 4328, 4327, 4328, 4328, 4328, 4327, + 4327, 4327, 4328, 4327, 4328, 4327, 4327, 4328, + 4328, 4328, 4327, 4327, 4328, 4327, 4328, 4327, + 4327, 4327, 4328, 4327, 4327, 4327, 4327, 4327, + 4327, 4327, 4328, 4327, 4328, 4328, 4327, 4327, + 4327, 4328, 4328, 4328, 4327, 4328, 4327, 4327, + 4328, 4327, 4328, 4434, 4435, 4436, 4437, 4328, + 4327, 4328, 4327, 4328, 4327, 4328, 4327, 4328, + 4438, 4328, 4327, 4327, 4328, 4439, 4440, 4441, + 4442, 4443, 4444, 4328, 4327, 4327, 4328, 4328, + 4328, 4328, 4327, 4327, 4328, 4327, 4327, 4328, + 4328, 4328, 4327, 4327, 4327, 4327, 4328, 4445, + 4328, 4327, 4328, 4325, 4328, 4446, 4328, 4447, + 4448, 4449, 4451, 4450, 4328, 4327, 4327, 4328, + 4328, 4327, 4327, 3757, 0, 3371, 3372, 0, + 3372, 4452, 3371, 3372, 0, 3250, 4453, 3371, + 4454, 3372, 0, 3250, 0, 3250, 4455, 0, + 3372, 0, 3250, 3371, 4456, 3372, 0, 0, + 3250, 4458, 4460, 4463, 4464, 4465, 4467, 4468, + 4469, 4470, 4471, 4472, 4473, 4474, 4475, 4476, + 4477, 4478, 4479, 4480, 4481, 4482, 4483, 4484, + 4485, 4486, 4487, 4488, 4489, 4490, 4492, 4493, + 4495, 4496, 4497, 4498, 4459, 4461, 4462, 4462, + 4466, 4491, 4494, 4457, 4500, 122, 124, 4501, + 4502, 4503, 4504, 4505, 4506, 4507, 4508, 4509, + 4510, 4511, 4512, 4513, 4514, 4515, 4516, 4517, + 4518, 4499, 4520, 4519, 1626, 1626, 1626, 1626, + 1485, 4522, 150, 152, 153, 154, 2005, 4523, + 157, 158, 4524, 160, 161, 4525, 4526, 4527, + 4528, 4529, 4530, 4531, 4532, 4533, 4534, 4535, + 4536, 4537, 4538, 177, 4539, 4540, 4541, 126, + 148, 148, 151, 176, 4521, 1626, 1626, 1626, + 1626, 1485, 4542, 150, 152, 153, 154, 1753, + 4543, 157, 158, 4544, 160, 161, 4545, 4546, + 4547, 4548, 4549, 4550, 4551, 4552, 4553, 4554, + 4555, 4556, 4557, 4558, 177, 4559, 4560, 4561, + 126, 148, 148, 151, 176, 4521, 181, 181, + 181, 571, 4563, 150, 152, 153, 4564, 153, + 4565, 4566, 158, 4567, 160, 161, 4568, 4569, + 4570, 4571, 4572, 4573, 4574, 302, 4575, 4576, + 4577, 4578, 4579, 4580, 177, 4581, 4582, 4583, + 421, 148, 148, 151, 176, 4562, 443, 443, + 443, 443, 571, 4584, 150, 152, 153, 154, + 1370, 4585, 157, 158, 4586, 160, 161, 4587, + 4588, 4589, 4590, 4591, 4592, 4593, 4594, 4595, + 4596, 4597, 4598, 4599, 4600, 177, 4601, 4602, + 4603, 421, 148, 148, 151, 176, 4562, 571, + 4604, 150, 152, 153, 154, 1241, 4605, 157, + 158, 4606, 160, 161, 4607, 4608, 4609, 4610, + 4611, 4612, 4613, 4614, 4615, 4616, 4617, 4618, + 4619, 4620, 177, 4621, 4622, 4623, 421, 148, + 148, 151, 176, 4562, 594, 595, 181, 181, + 571, 4624, 150, 152, 153, 4564, 981, 4625, + 4566, 158, 4626, 160, 161, 4627, 4628, 4629, + 4630, 4631, 4632, 4633, 4634, 4635, 4636, 4637, + 4638, 4639, 4640, 177, 4641, 4642, 4643, 421, + 148, 148, 151, 176, 4562, 571, 4644, 150, + 152, 153, 154, 731, 4645, 157, 158, 4646, + 160, 161, 4647, 4648, 4649, 4650, 4651, 4652, + 4653, 4654, 4655, 4656, 4657, 4658, 4659, 4660, + 177, 4661, 4662, 4663, 421, 148, 148, 151, + 176, 4562, 571, 4664, 1047, 1175, 4665, 4666, + 4667, 4668, 4669, 4670, 4671, 4672, 4673, 4674, + 4675, 4676, 4677, 4678, 4679, 4680, 4681, 4682, + 4562, 1485, 4683, 150, 152, 153, 154, 1623, + 4684, 157, 158, 4685, 160, 161, 4686, 4687, + 4688, 4689, 4690, 4691, 4692, 4693, 4694, 4695, + 4696, 4697, 4698, 4699, 177, 4700, 4701, 4702, + 126, 148, 148, 151, 176, 4521, 181, 181, + 181, 571, 4703, 150, 152, 153, 4564, 2133, + 4704, 4566, 158, 4705, 160, 161, 4706, 4707, + 4708, 4709, 4710, 4711, 4712, 4713, 4714, 4715, + 4716, 4717, 4718, 4719, 177, 4720, 4721, 4722, + 421, 148, 148, 151, 176, 4562, 2136, 4723, + 150, 152, 153, 154, 2391, 4724, 157, 158, + 4725, 160, 161, 4726, 4727, 4728, 4729, 4730, + 4731, 4732, 4733, 4734, 4735, 4736, 4737, 4738, + 4739, 177, 4740, 4741, 4742, 126, 148, 148, + 151, 176, 4562, 2136, 4743, 150, 152, 153, + 154, 2263, 4744, 157, 158, 4745, 160, 161, + 4746, 4747, 4748, 4749, 4750, 4751, 4752, 4753, + 4754, 4755, 4756, 4757, 4758, 4759, 177, 4760, + 4761, 4762, 126, 148, 148, 151, 176, 4562, + 3249, 148, 2395, 148, 148, 4500, 122, 124, + 4501, 4502, 4503, 4504, 4505, 4506, 4507, 4508, + 4509, 4510, 4511, 4512, 4513, 4514, 4515, 4516, + 4517, 4518, 4499, 4764, 2515, 2517, 4765, 4766, + 4767, 4768, 4769, 4770, 4771, 4772, 4773, 4774, + 4775, 4776, 4777, 4778, 4779, 4780, 4781, 4782, + 4763, 4783, 4784, 4785, 4786, 4787, 4788, 4789, + 4790, 4791, 4792, 4793, 4794, 4795, 4796, 4797, + 4798, 4799, 4800, 4801, 4802, 4803, 148, 148, + 148, 4499, 181, 181, 181, 571, 1, 4563, + 150, 152, 153, 4564, 153, 4565, 4566, 158, + 4567, 160, 161, 4568, 4569, 4570, 4571, 4572, + 4573, 4574, 302, 4575, 4576, 4577, 4578, 4579, + 4580, 177, 4581, 4582, 4583, 421, 148, 148, + 151, 176, 4562, 181, 181, 181, 571, 4804, + 4805, 4807, 4808, 4809, 4808, 4810, 4811, 4812, + 4813, 4814, 4815, 4816, 4817, 4818, 4819, 4820, + 4821, 4822, 4823, 4824, 4825, 4826, 4827, 4828, + 4829, 4831, 4832, 4833, 4834, 4562, 421, 4562, + 148, 4562, 148, 4562, 4806, 4830, 1, 148, + 148, 148, 181, 148, 4500, 122, 124, 4501, + 4502, 4503, 4504, 4505, 4506, 4507, 4508, 4509, + 4510, 4511, 4512, 4513, 4514, 4515, 4516, 4517, + 4518, 4499, 4783, 4784, 4785, 4786, 4787, 4788, + 4789, 4790, 4791, 4792, 4793, 4794, 4795, 4796, + 4797, 4798, 4799, 4800, 4801, 4802, 4803, 148, + 2518, 2518, 2518, 2774, 4563, 150, 152, 153, + 4564, 153, 4565, 4566, 158, 4567, 160, 161, + 4568, 4569, 4570, 4571, 4572, 4573, 4574, 302, + 4575, 4576, 4577, 4578, 4579, 4580, 177, 4581, + 4582, 4583, 2646, 2008, 2008, 4562, 151, 4562, + 176, 4562, 1, 4835, 150, 152, 153, 154, + 2643, 4836, 157, 158, 4837, 160, 161, 4838, + 4839, 4840, 4841, 4842, 4843, 4844, 4845, 4846, + 4847, 4848, 4849, 4850, 4851, 177, 4852, 4853, + 4854, 148, 148, 151, 176, 4499, 443, 443, + 443, 443, 571, 4855, 150, 152, 153, 154, + 2771, 4856, 157, 158, 4857, 160, 161, 4858, + 4859, 4860, 4861, 4862, 4863, 4864, 4865, 4866, + 4867, 4868, 4869, 4870, 4871, 177, 4872, 4873, + 4874, 421, 148, 148, 151, 176, 4562, 571, + 4875, 150, 152, 153, 154, 2899, 4876, 157, + 158, 4877, 160, 161, 4878, 4879, 4880, 4881, + 4882, 4883, 4884, 4885, 4886, 4887, 4888, 4889, + 4890, 4891, 177, 4892, 4893, 4894, 421, 148, + 148, 151, 176, 4562, 181, 181, 181, 571, + 4563, 150, 152, 153, 4564, 153, 4565, 4566, + 158, 4567, 160, 161, 4568, 4569, 4570, 4571, + 4572, 4573, 4574, 302, 4575, 4576, 4577, 4578, + 4579, 4580, 177, 4581, 4582, 4583, 421, 148, + 148, 1, 151, 176, 4562, 181, 181, 181, + 571, 1, 4563, 150, 152, 153, 4564, 153, + 4565, 4566, 158, 4567, 160, 161, 4568, 4569, + 4570, 4571, 4572, 4573, 4574, 302, 4575, 4576, + 4577, 4578, 4579, 4580, 177, 4581, 4582, 4583, + 421, 148, 148, 1, 151, 176, 4562, 181, + 181, 181, 571, 1, 4563, 150, 152, 153, + 4564, 153, 4565, 4566, 158, 4567, 160, 161, + 4568, 4569, 4570, 4571, 4572, 4573, 4574, 302, + 4575, 4576, 4577, 4578, 4579, 4580, 177, 4581, + 4582, 4583, 421, 148, 148, 1, 1, 151, + 176, 4562, 181, 181, 181, 571, 1, 4563, + 150, 152, 153, 4564, 153, 4565, 4566, 158, + 4567, 160, 161, 4568, 4569, 4570, 4571, 4572, + 4573, 4574, 302, 4575, 4576, 4577, 4578, 4579, + 4580, 177, 4581, 4582, 4583, 421, 148, 148, + 1, 1, 151, 176, 4562, 181, 181, 181, + 571, 1, 4563, 150, 152, 153, 4564, 153, + 4565, 4566, 158, 4567, 160, 161, 4568, 4569, + 4570, 4571, 4572, 4573, 4574, 302, 4575, 4576, + 4577, 4578, 4579, 4580, 177, 4581, 4582, 4583, + 421, 148, 148, 1, 151, 176, 4562, 181, + 181, 181, 571, 4563, 150, 152, 153, 4564, + 153, 4565, 4566, 158, 4567, 160, 161, 4568, + 4569, 4570, 4571, 4572, 4573, 4574, 302, 4575, + 4576, 4577, 4578, 4579, 4580, 177, 4581, 4582, + 4583, 421, 148, 148, 1, 1, 1, 1, + 151, 176, 4562, 181, 181, 181, 571, 1, + 1, 4804, 4805, 4807, 4808, 4809, 4808, 4810, + 4811, 4812, 4813, 4814, 4815, 4816, 4817, 4818, + 4819, 4820, 4821, 4822, 4823, 4824, 4825, 4826, + 4827, 4828, 4829, 4831, 4832, 4833, 4834, 421, + 148, 148, 1, 4806, 1, 4830, 1, 4562, + 4500, 122, 124, 4501, 4502, 4503, 4504, 4505, + 4506, 4507, 4508, 4509, 4510, 4511, 4512, 4513, + 4514, 4515, 4516, 4517, 4518, 4499, 148, 4783, + 4784, 4785, 4786, 4787, 4788, 4789, 4790, 4791, + 4792, 4793, 4794, 4795, 4796, 4797, 4798, 4799, + 4800, 4801, 4802, 4803, 148, 4499, 2518, 2518, + 2518, 2774, 4563, 150, 152, 153, 4564, 153, + 4565, 4566, 158, 4567, 160, 161, 4568, 4569, + 4570, 4571, 4572, 4573, 4574, 302, 4575, 4576, + 4577, 4578, 4579, 4580, 177, 4581, 4582, 4583, + 1, 2646, 1, 2008, 1, 2008, 1, 151, + 176, 4562, 181, 181, 181, 571, 4563, 150, + 152, 153, 4564, 153, 4565, 4566, 158, 4567, + 160, 161, 4568, 4569, 4570, 4571, 4572, 4573, + 4574, 302, 4575, 4576, 4577, 4578, 4579, 4580, + 177, 4581, 4582, 4583, 421, 148, 148, 1, + 151, 176, 4562, 181, 181, 181, 571, 4563, + 150, 152, 153, 4564, 153, 4565, 4566, 158, + 4567, 160, 161, 4568, 4569, 4570, 4571, 4572, + 4573, 4574, 302, 4575, 4576, 4577, 4578, 4579, + 4580, 177, 4581, 4582, 4583, 421, 148, 148, + 1, 151, 176, 4562, 181, 181, 181, 571, + 3, 4, 5, 6, 7, 9, 10, 11, + 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 4563, 150, 152, 153, 4564, 153, + 4565, 4566, 158, 4567, 160, 161, 4568, 4569, + 4570, 4571, 4572, 4573, 4574, 302, 4575, 4576, + 4577, 4578, 4579, 4580, 177, 4581, 4582, 4583, + 421, 148, 148, 8, 12, 151, 176, 4562, + 181, 181, 181, 571, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, + 51, 4563, 150, 152, 153, 4564, 153, 4565, + 4566, 158, 4567, 160, 161, 4568, 4569, 4570, + 4571, 4572, 4573, 4574, 302, 4575, 4576, 4577, + 4578, 4579, 4580, 177, 4581, 4582, 4583, 421, + 148, 148, 151, 176, 4562, 181, 181, 181, + 571, 52, 53, 54, 55, 56, 57, 4563, + 150, 152, 153, 4564, 153, 4565, 4566, 158, + 4567, 160, 161, 4568, 4569, 4570, 4571, 4572, + 4573, 4574, 302, 4575, 4576, 4577, 4578, 4579, + 4580, 177, 4581, 4582, 4583, 421, 148, 148, + 151, 176, 4562, 181, 181, 181, 571, 58, + 59, 4563, 150, 152, 153, 4564, 153, 4565, + 4566, 158, 4567, 160, 161, 4568, 4569, 4570, + 4571, 4572, 4573, 4574, 302, 4575, 4576, 4577, + 4578, 4579, 4580, 177, 4581, 4582, 4583, 421, + 148, 148, 151, 176, 4562, 181, 181, 181, + 571, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, + 4563, 150, 152, 153, 4564, 153, 4565, 4566, + 158, 4567, 160, 161, 4568, 4569, 4570, 4571, + 4572, 4573, 4574, 302, 4575, 4576, 4577, 4578, + 4579, 4580, 177, 4581, 4582, 4583, 421, 148, + 148, 151, 176, 4562, 181, 181, 181, 571, + 75, 76, 56, 61, 77, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 421, 148, 148, 151, 176, + 4562, 181, 181, 181, 571, 78, 79, 80, + 81, 82, 83, 4563, 150, 152, 153, 4564, + 153, 4565, 4566, 158, 4567, 160, 161, 4568, + 4569, 4570, 4571, 4572, 4573, 4574, 302, 4575, + 4576, 4577, 4578, 4579, 4580, 177, 4581, 4582, + 4583, 421, 148, 148, 151, 176, 4562, 181, + 181, 181, 571, 119, 4563, 150, 152, 153, + 4564, 153, 4565, 4566, 158, 4567, 160, 161, + 4568, 4569, 4570, 4571, 4572, 4573, 4574, 302, + 4575, 4576, 4577, 4578, 4579, 4580, 177, 4581, + 4582, 4583, 421, 148, 148, 151, 176, 4562, + 181, 4499, 4500, 122, 124, 4501, 4502, 4503, + 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, + 4512, 4513, 4514, 4515, 4516, 4517, 4518, 4499, + 4499, 4499, 4499, 148, 4499, 4499, 4500, 122, + 124, 4501, 4502, 4503, 4504, 4505, 4506, 4507, + 4508, 4509, 4510, 4511, 4512, 4513, 4514, 4515, + 4516, 4517, 4518, 4499, 4499, 148, 181, 148, + 4783, 4784, 4785, 4786, 4787, 4788, 4789, 4790, + 4791, 4792, 4793, 4794, 4795, 4796, 4797, 4798, + 4799, 4800, 4801, 4802, 4803, 148, 148, 148, + 4499, 4499, 4783, 4784, 4785, 4786, 4787, 4788, + 4789, 4790, 4791, 4792, 4793, 4794, 4795, 4796, + 4797, 4798, 4799, 4800, 4801, 4802, 4803, 148, + 4499, 4783, 4784, 4785, 4786, 4787, 4788, 4789, + 4790, 4791, 4792, 4793, 4794, 4795, 4796, 4797, + 4798, 4799, 4800, 4801, 4802, 4803, 148, 4499, + 4783, 4784, 4785, 4786, 4787, 4788, 4789, 4790, + 4791, 4792, 4793, 4794, 4795, 4796, 4797, 4798, + 4799, 4800, 4801, 4802, 4803, 148, 4783, 4784, + 4785, 4786, 4787, 4788, 4789, 4790, 4791, 4792, + 4793, 4794, 4795, 4796, 4797, 4798, 4799, 4800, + 4801, 4802, 4803, 4499, 4499, 148, 4499, 4500, + 122, 124, 4501, 4502, 4503, 4504, 4505, 4506, + 4507, 4508, 4509, 4510, 4511, 4512, 4513, 4514, + 4515, 4516, 4517, 4518, 4499, 4499, 148, 148, + 148, 181, 4500, 122, 124, 4501, 4502, 4503, + 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, + 4512, 4513, 4514, 4515, 4516, 4517, 4518, 148, + 148, 572, 572, 4499, 148, 4500, 122, 124, + 4501, 4502, 4503, 4504, 4505, 4506, 4507, 4508, + 4509, 4510, 4511, 4512, 4513, 4514, 4515, 4516, + 4517, 4518, 148, 148, 148, 4499, 421, 4783, + 4784, 4785, 4786, 4787, 4788, 4789, 4790, 4791, + 4792, 4793, 4794, 4795, 4796, 4797, 4798, 4799, + 4800, 4801, 4802, 4803, 148, 421, 148, 4499, + 4499, 4499, 4499, 4500, 122, 124, 4501, 4502, + 4503, 4504, 4505, 4506, 4507, 4508, 4509, 4510, + 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, + 421, 4499, 4499, 148, 4783, 4784, 4785, 4786, + 4787, 4788, 4789, 4790, 4791, 4792, 4793, 4794, + 4795, 4796, 4797, 4798, 4799, 4800, 4801, 4802, + 4803, 148, 4499, 4783, 4784, 4785, 4786, 4787, + 4788, 4789, 4790, 4791, 4792, 4793, 4794, 4795, + 4796, 4797, 4798, 4799, 4800, 4801, 4802, 4803, + 4499, 148, 4500, 122, 124, 4501, 4502, 4503, + 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, + 4512, 4513, 4514, 4515, 4516, 4517, 4518, 4499, + 148, 148, 4500, 122, 124, 4501, 4502, 4503, + 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, + 4512, 4513, 4514, 4515, 4516, 4517, 4518, 421, + 148, 4499, 1373, 1374, 184, 1375, 151, 1376, + 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, + 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, + 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, + 1401, 1402, 4500, 122, 124, 4501, 4502, 4503, + 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, + 4512, 4513, 4514, 4515, 4516, 4517, 4518, 4499, + 1403, 1404, 1405, 217, 218, 219, 220, 221, + 1406, 223, 224, 225, 226, 227, 228, 1407, + 1408, 1409, 1410, 1411, 234, 1412, 236, 1413, + 483, 484, 1374, 1414, 1415, 153, 1416, 1417, + 1418, 1419, 646, 1420, 151, 152, 1421, 249, + 250, 251, 252, 4500, 122, 124, 4501, 4502, + 4503, 4504, 4505, 4506, 4507, 4508, 4509, 4510, + 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, + 151, 153, 151, 4499, 1422, 1423, 255, 1424, + 257, 258, 259, 260, 261, 262, 263, 151, + 1425, 265, 1426, 267, 1427, 269, 4500, 122, + 124, 4501, 4502, 4503, 4504, 4505, 4506, 4507, + 4508, 4509, 4510, 4511, 4512, 4513, 4514, 4515, + 4516, 4517, 4518, 4499, 1428, 1429, 272, 151, + 273, 4500, 122, 124, 4501, 4502, 4503, 4504, + 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, + 4513, 4514, 4515, 4516, 4517, 4518, 4499, 153, + 274, 275, 153, 657, 1430, 153, 302, 280, + 281, 282, 1431, 284, 153, 1432, 1433, 1434, + 153, 1435, 1436, 1437, 1438, 1439, 295, 296, + 152, 1440, 153, 4895, 4896, 4897, 4898, 4899, + 4900, 4901, 4902, 4903, 4904, 4905, 4906, 4907, + 4908, 4909, 4910, 4911, 4912, 4913, 4914, 4915, + 151, 4499, 181, 181, 181, 571, 4563, 150, + 152, 153, 4564, 153, 4565, 4566, 158, 4567, + 160, 161, 4568, 4569, 4570, 4571, 4572, 4573, + 4574, 302, 4575, 4576, 4577, 4578, 4579, 4580, + 177, 4581, 4582, 4583, 421, 148, 148, 1, + 1, 1, 1, 151, 176, 4562, 181, 181, + 181, 571, 4563, 150, 152, 153, 4564, 153, + 4565, 4566, 158, 4567, 160, 161, 4568, 4569, + 4570, 4571, 4572, 4573, 4574, 302, 4575, 4576, + 4577, 4578, 4579, 4580, 177, 4581, 4582, 4583, + 421, 148, 148, 1, 151, 176, 4562, 181, + 181, 181, 571, 4804, 4805, 4807, 4808, 4809, + 4808, 4810, 4811, 4812, 4813, 4814, 4815, 4816, + 4817, 4818, 4819, 4820, 4821, 4822, 4823, 4824, + 4825, 4826, 4827, 4828, 4829, 4831, 4832, 4833, + 4834, 421, 148, 148, 1, 4806, 1, 4830, + 1, 4562, 4895, 4896, 4897, 4898, 4899, 4900, + 4901, 4902, 4903, 4904, 4905, 4906, 4907, 4908, + 4909, 4910, 4911, 4912, 4913, 4914, 4915, 151, + 181, 181, 181, 571, 4563, 150, 152, 153, + 4564, 153, 4565, 4566, 158, 4567, 160, 161, + 4568, 4569, 4570, 4571, 4572, 4573, 4574, 302, + 4575, 4576, 4577, 4578, 4579, 4580, 177, 4581, + 4582, 4583, 421, 148, 148, 1, 151, 176, + 4562, 181, 181, 181, 571, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 421, 148, 148, 1, 1, + 1, 1, 1, 151, 176, 4562, 181, 181, + 181, 571, 1, 4563, 150, 152, 153, 4564, + 153, 4565, 4566, 158, 4567, 160, 161, 4568, + 4569, 4570, 4571, 4572, 4573, 4574, 302, 4575, + 4576, 4577, 4578, 4579, 4580, 177, 4581, 4582, + 4583, 421, 148, 148, 1, 1, 151, 176, + 4562, 181, 181, 181, 571, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 421, 148, 148, 1, 151, + 176, 4562, 181, 181, 181, 571, 4563, 150, + 152, 153, 4564, 153, 4565, 4566, 158, 4567, + 160, 161, 4568, 4569, 4570, 4571, 4572, 4573, + 4574, 302, 4575, 4576, 4577, 4578, 4579, 4580, + 177, 4581, 4582, 4583, 421, 148, 148, 1, + 1, 151, 176, 4562, 181, 181, 181, 571, + 4563, 150, 152, 153, 4564, 153, 4565, 4566, + 158, 4567, 160, 161, 4568, 4569, 4570, 4571, + 4572, 4573, 4574, 302, 4575, 4576, 4577, 4578, + 4579, 4580, 177, 4581, 4582, 4583, 421, 148, + 148, 1, 1, 151, 176, 4562, 181, 181, + 181, 571, 4804, 4805, 4807, 4808, 4809, 4808, + 4810, 4811, 4812, 4813, 4814, 4815, 4816, 4817, + 4818, 4819, 4820, 4821, 4822, 4823, 4824, 4825, + 4826, 4827, 4828, 4829, 4831, 4832, 4833, 4834, + 421, 148, 148, 1, 4806, 1, 4830, 1, + 4562, 298, 299, 4500, 122, 124, 4501, 4502, + 4503, 4504, 4505, 4506, 4507, 4508, 4509, 4510, + 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, + 4499, 151, 1441, 674, 302, 303, 304, 305, + 306, 307, 1442, 932, 1443, 934, 312, 1444, + 1445, 4500, 122, 124, 4501, 4502, 4503, 4504, + 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, + 4513, 4514, 4515, 4516, 4517, 4518, 151, 4499, + 1446, 1447, 317, 318, 319, 1448, 1449, 1450, + 1451, 324, 4500, 122, 124, 4501, 4502, 4503, + 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, + 4512, 4513, 4514, 4515, 4516, 4517, 4518, 4499, + 1482, 4500, 122, 124, 4501, 4502, 4503, 4504, + 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, + 4513, 4514, 4515, 4516, 4517, 4518, 4499, 2518, + 2518, 2518, 2774, 4563, 150, 152, 153, 4564, + 153, 4565, 4566, 158, 4567, 160, 161, 4568, + 4569, 4570, 4571, 4572, 4573, 4574, 302, 4575, + 4576, 4577, 4578, 4579, 4580, 177, 4581, 4582, + 4583, 2646, 2008, 2008, 4562, 4562, 151, 4562, + 176, 4562, 1, 181, 181, 181, 571, 4563, + 150, 152, 153, 4564, 153, 4565, 4566, 158, + 4567, 160, 161, 4568, 4569, 4570, 4571, 4572, + 4573, 4574, 302, 4575, 4576, 4577, 4578, 4579, + 4580, 177, 4581, 4582, 4583, 421, 148, 148, + 1, 151, 176, 4562, 181, 181, 181, 571, + 1, 4563, 150, 152, 153, 4564, 153, 4565, + 4566, 158, 4567, 160, 161, 4568, 4569, 4570, + 4571, 4572, 4573, 4574, 302, 4575, 4576, 4577, + 4578, 4579, 4580, 177, 4581, 4582, 4583, 421, + 148, 148, 151, 176, 4562, 181, 181, 181, + 571, 4563, 150, 152, 153, 4564, 153, 4565, + 4566, 158, 4567, 160, 161, 4568, 4569, 4570, + 4571, 4572, 4573, 4574, 302, 4575, 4576, 4577, + 4578, 4579, 4580, 177, 4581, 4582, 4583, 421, + 148, 148, 1, 1, 151, 176, 4562, 181, + 181, 181, 571, 4563, 150, 152, 153, 4564, + 153, 4565, 4566, 158, 4567, 160, 161, 4568, + 4569, 4570, 4571, 4572, 4573, 4574, 302, 4575, + 4576, 4577, 4578, 4579, 4580, 177, 4581, 4582, + 4583, 421, 148, 148, 1, 151, 176, 4562, + 181, 181, 181, 571, 1, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 421, 148, 148, 1, 1, + 151, 176, 4562, 181, 181, 181, 571, 4563, + 150, 152, 153, 4564, 153, 4565, 4566, 158, + 4567, 160, 161, 4568, 4569, 4570, 4571, 4572, + 4573, 4574, 302, 4575, 4576, 4577, 4578, 4579, + 4580, 177, 4581, 4582, 4583, 421, 148, 148, + 1, 151, 176, 4562, 181, 181, 181, 571, + 4804, 4805, 4807, 4808, 4809, 4808, 4810, 4811, + 4812, 4813, 4814, 4815, 4816, 4817, 4818, 4819, + 4820, 4821, 4822, 4823, 4824, 4825, 4826, 4827, + 4828, 4829, 4831, 4832, 4833, 4834, 421, 148, + 148, 1, 1, 4806, 1, 4830, 1, 4562, + 2518, 2518, 2518, 2774, 4563, 150, 152, 153, + 4564, 153, 4565, 4566, 158, 4567, 160, 161, + 4568, 4569, 4570, 4571, 4572, 4573, 4574, 302, + 4575, 4576, 4577, 4578, 4579, 4580, 177, 4581, + 4582, 4583, 2646, 2008, 2008, 4562, 4562, 151, + 4562, 176, 4562, 1, 181, 181, 181, 571, + 4563, 150, 152, 153, 4564, 153, 4565, 4566, + 158, 4567, 160, 161, 4568, 4569, 4570, 4571, + 4572, 4573, 4574, 302, 4575, 4576, 4577, 4578, + 4579, 4580, 177, 4581, 4582, 4583, 421, 148, + 148, 1, 1, 151, 176, 4562, 181, 181, + 181, 571, 4563, 150, 152, 153, 4564, 153, + 4565, 4566, 158, 4567, 160, 161, 4568, 4569, + 4570, 4571, 4572, 4573, 4574, 302, 4575, 4576, + 4577, 4578, 4579, 4580, 177, 4581, 4582, 4583, + 421, 148, 148, 1, 151, 176, 4562, 181, + 181, 181, 571, 4563, 150, 152, 153, 4564, + 153, 4565, 4566, 158, 4567, 160, 161, 4568, + 4569, 4570, 4571, 4572, 4573, 4574, 302, 4575, + 4576, 4577, 4578, 4579, 4580, 177, 4581, 4582, + 4583, 421, 148, 148, 1, 151, 176, 4562, + 181, 181, 181, 571, 1, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 421, 148, 148, 1, 1, + 1, 1, 151, 176, 4562, 181, 181, 181, + 571, 4563, 150, 152, 153, 4564, 153, 4565, + 4566, 158, 4567, 160, 161, 4568, 4569, 4570, + 4571, 4572, 4573, 4574, 302, 4575, 4576, 4577, + 4578, 4579, 4580, 177, 4581, 4582, 4583, 421, + 148, 148, 1, 1, 151, 176, 4562, 181, + 181, 181, 571, 4563, 150, 152, 153, 4564, + 153, 4565, 4566, 158, 4567, 160, 161, 4568, + 4569, 4570, 4571, 4572, 4573, 4574, 302, 4575, + 4576, 4577, 4578, 4579, 4580, 177, 4581, 4582, + 4583, 421, 148, 148, 1, 1, 151, 176, + 4562, 181, 181, 181, 571, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 421, 148, 148, 1, 1, + 151, 176, 4562, 181, 181, 181, 571, 4563, + 150, 152, 153, 4564, 153, 4565, 4566, 158, + 4567, 160, 161, 4568, 4569, 4570, 4571, 4572, + 4573, 4574, 302, 4575, 4576, 4577, 4578, 4579, + 4580, 177, 4581, 4582, 4583, 421, 148, 148, + 1, 151, 176, 4562, 181, 181, 181, 571, + 4563, 150, 152, 153, 4564, 153, 4565, 4566, + 158, 4567, 160, 161, 4568, 4569, 4570, 4571, + 4572, 4573, 4574, 302, 4575, 4576, 4577, 4578, + 4579, 4580, 177, 4581, 4582, 4583, 421, 148, + 148, 1, 151, 176, 4562, 181, 181, 181, + 571, 1, 4563, 150, 152, 153, 4564, 153, + 4565, 4566, 158, 4567, 160, 161, 4568, 4569, + 4570, 4571, 4572, 4573, 4574, 302, 4575, 4576, + 4577, 4578, 4579, 4580, 177, 4581, 4582, 4583, + 421, 148, 148, 151, 176, 4562, 181, 181, + 181, 571, 4563, 150, 152, 153, 4564, 153, + 4565, 4566, 158, 4567, 160, 161, 4568, 4569, + 4570, 4571, 4572, 4573, 4574, 302, 4575, 4576, + 4577, 4578, 4579, 4580, 177, 4581, 4582, 4583, + 421, 148, 148, 1, 151, 176, 4562, 181, + 181, 181, 571, 4563, 150, 152, 153, 4564, + 153, 4565, 4566, 158, 4567, 160, 161, 4568, + 4569, 4570, 4571, 4572, 4573, 4574, 302, 4575, + 4576, 4577, 4578, 4579, 4580, 177, 4581, 4582, + 4583, 421, 148, 148, 1, 151, 176, 4562, + 181, 181, 181, 571, 4563, 150, 152, 153, + 4564, 153, 4565, 4566, 158, 4567, 160, 161, + 4568, 4569, 4570, 4571, 4572, 4573, 4574, 302, + 4575, 4576, 4577, 4578, 4579, 4580, 177, 4581, + 4582, 4583, 421, 148, 148, 1, 151, 176, + 4562, 181, 181, 181, 571, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 421, 148, 148, 1, 1, + 151, 176, 4562, 181, 181, 181, 571, 4563, + 150, 152, 153, 4564, 153, 4565, 4566, 158, + 4567, 160, 161, 4568, 4569, 4570, 4571, 4572, + 4573, 4574, 302, 4575, 4576, 4577, 4578, 4579, + 4580, 177, 4581, 4582, 4583, 421, 148, 148, + 1, 151, 176, 4562, 181, 181, 181, 571, + 4563, 150, 152, 153, 4564, 153, 4565, 4566, + 158, 4567, 160, 161, 4568, 4569, 4570, 4571, + 4572, 4573, 4574, 302, 4575, 4576, 4577, 4578, + 4579, 4580, 177, 4581, 4582, 4583, 421, 148, + 148, 1, 151, 176, 4562, 181, 181, 181, + 571, 1, 1, 1, 4563, 150, 152, 153, + 4564, 153, 4565, 4566, 158, 4567, 160, 161, + 4568, 4569, 4570, 4571, 4572, 4573, 4574, 302, + 4575, 4576, 4577, 4578, 4579, 4580, 177, 4581, + 4582, 4583, 421, 148, 148, 1, 151, 176, + 4562, 181, 181, 181, 571, 4804, 4805, 4807, + 4808, 4809, 4808, 4810, 4811, 4812, 4813, 4814, + 4815, 4816, 4817, 4818, 4819, 4820, 4821, 4822, + 4823, 4824, 4825, 4826, 4827, 4828, 4829, 4831, + 4832, 4833, 4834, 421, 148, 148, 1, 1, + 4806, 1, 4830, 1, 4562, 2518, 2518, 2518, + 2774, 4563, 150, 152, 153, 4564, 153, 4565, + 4566, 158, 4567, 160, 161, 4568, 4569, 4570, + 4571, 4572, 4573, 4574, 302, 4575, 4576, 4577, + 4578, 4579, 4580, 177, 4581, 4582, 4583, 2646, + 2008, 2008, 4562, 4562, 151, 4562, 176, 4562, + 1, 181, 181, 181, 571, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 421, 148, 148, 1, 151, + 176, 4562, 181, 181, 181, 571, 4563, 150, + 152, 153, 4564, 153, 4565, 4566, 158, 4567, + 160, 161, 4568, 4569, 4570, 4571, 4572, 4573, + 4574, 302, 4575, 4576, 4577, 4578, 4579, 4580, + 177, 4581, 4582, 4583, 421, 148, 148, 1, + 151, 176, 4562, 181, 181, 181, 571, 4804, + 4805, 4807, 4808, 4809, 4808, 4810, 4811, 4812, + 4813, 4814, 4815, 4816, 4817, 4818, 4819, 4820, + 4821, 4822, 4823, 4824, 4825, 4826, 4827, 4828, + 4829, 4831, 4832, 4833, 4834, 421, 148, 148, + 1, 1, 4806, 1, 4830, 1, 4562, 2518, + 2518, 2518, 2774, 1, 4563, 150, 152, 153, + 4564, 153, 4565, 4566, 158, 4567, 160, 161, + 4568, 4569, 4570, 4571, 4572, 4573, 4574, 302, + 4575, 4576, 4577, 4578, 4579, 4580, 177, 4581, + 4582, 4583, 1, 2646, 1, 2008, 1, 2008, + 1, 151, 176, 4562, 181, 181, 181, 571, + 4563, 150, 152, 153, 4564, 153, 4565, 4566, + 158, 4567, 160, 161, 4568, 4569, 4570, 4571, + 4572, 4573, 4574, 302, 4575, 4576, 4577, 4578, + 4579, 4580, 177, 4581, 4582, 4583, 421, 148, + 148, 1, 151, 176, 4562, 181, 181, 181, + 571, 1, 4563, 150, 152, 153, 4564, 153, + 4565, 4566, 158, 4567, 160, 161, 4568, 4569, + 4570, 4571, 4572, 4573, 4574, 302, 4575, 4576, + 4577, 4578, 4579, 4580, 177, 4581, 4582, 4583, + 421, 148, 148, 1, 1, 151, 176, 4562, + 181, 181, 181, 571, 1, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 421, 148, 148, 1, 1, + 1, 151, 176, 4562, 181, 181, 181, 571, + 1, 4563, 150, 152, 153, 4564, 153, 4565, + 4566, 158, 4567, 160, 161, 4568, 4569, 4570, + 4571, 4572, 4573, 4574, 302, 4575, 4576, 4577, + 4578, 4579, 4580, 177, 4581, 4582, 4583, 421, + 148, 148, 1, 1, 151, 176, 4562, 181, + 181, 181, 571, 4563, 150, 152, 153, 4564, + 153, 4565, 4566, 158, 4567, 160, 161, 4568, + 4569, 4570, 4571, 4572, 4573, 4574, 302, 4575, + 4576, 4577, 4578, 4579, 4580, 177, 4581, 4582, + 4583, 421, 148, 148, 1, 1, 151, 176, + 4562, 181, 181, 181, 571, 1, 4563, 150, + 152, 153, 4564, 153, 4565, 4566, 158, 4567, + 160, 161, 4568, 4569, 4570, 4571, 4572, 4573, + 4574, 302, 4575, 4576, 4577, 4578, 4579, 4580, + 177, 4581, 4582, 4583, 421, 148, 148, 151, + 176, 4562, 181, 181, 181, 571, 4563, 150, + 152, 153, 4564, 153, 4565, 4566, 158, 4567, + 160, 161, 4568, 4569, 4570, 4571, 4572, 4573, + 4574, 302, 4575, 4576, 4577, 4578, 4579, 4580, + 177, 4581, 4582, 4583, 421, 148, 148, 1, + 1, 151, 176, 4562, 181, 181, 181, 571, + 4563, 150, 152, 153, 4564, 153, 4565, 4566, + 158, 4567, 160, 161, 4568, 4569, 4570, 4571, + 4572, 4573, 4574, 302, 4575, 4576, 4577, 4578, + 4579, 4580, 177, 4581, 4582, 4583, 421, 148, + 148, 1, 151, 176, 4562, 181, 181, 181, + 571, 84, 85, 86, 87, 88, 4563, 150, + 152, 153, 4564, 153, 4565, 4566, 158, 4567, + 160, 161, 4568, 4569, 4570, 4571, 4572, 4573, + 4574, 302, 4575, 4576, 4577, 4578, 4579, 4580, + 177, 4581, 4582, 4583, 421, 148, 148, 151, + 176, 4562, 181, 181, 181, 571, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 100, 104, 105, + 106, 4563, 150, 152, 153, 4564, 153, 4565, + 4566, 158, 4567, 160, 161, 4568, 4569, 4570, + 4571, 4572, 4573, 4574, 302, 4575, 4576, 4577, + 4578, 4579, 4580, 177, 4581, 4582, 4583, 421, + 148, 148, 151, 176, 4562, 181, 181, 181, + 571, 107, 108, 109, 110, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 421, 148, 148, 151, 176, + 4562, 181, 181, 181, 571, 111, 4563, 150, + 152, 153, 4564, 153, 4565, 4566, 158, 4567, + 160, 161, 4568, 4569, 4570, 4571, 4572, 4573, + 4574, 302, 4575, 4576, 4577, 4578, 4579, 4580, + 177, 4581, 4582, 4583, 421, 148, 148, 151, + 176, 4562, 181, 181, 181, 571, 112, 113, + 114, 115, 116, 117, 4563, 150, 152, 153, + 4564, 153, 4565, 4566, 158, 4567, 160, 161, + 4568, 4569, 4570, 4571, 4572, 4573, 4574, 302, + 4575, 4576, 4577, 4578, 4579, 4580, 177, 4581, + 4582, 4583, 421, 148, 148, 151, 176, 4562, + 181, 181, 181, 571, 118, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 421, 148, 148, 151, 176, + 4562, 181, 181, 181, 571, 120, 121, 122, + 124, 4563, 150, 152, 153, 4564, 153, 4565, + 4566, 158, 4567, 160, 161, 4568, 4569, 4570, + 4571, 4572, 4573, 4574, 302, 4575, 4576, 4577, + 4578, 4579, 4580, 177, 4581, 4582, 4583, 421, + 148, 148, 123, 151, 176, 4562, 2518, 2518, + 2518, 2774, 4562, 4804, 4805, 4807, 4808, 4809, + 4808, 4810, 4811, 4812, 4813, 4814, 4815, 4816, + 4817, 4818, 4819, 4820, 4821, 4822, 4823, 4824, + 4825, 4826, 4827, 4828, 4829, 4831, 4832, 4833, + 4834, 2646, 2008, 2008, 4562, 4806, 4830, 1, + 2518, 2518, 2518, 2774, 4562, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 2646, 2008, 2008, 4562, 4562, + 151, 4562, 176, 4562, 1, 181, 181, 181, + 571, 1, 4804, 4805, 4807, 4808, 4809, 4808, + 4810, 4811, 4812, 4813, 4814, 4815, 4816, 4817, + 4818, 4819, 4820, 4821, 4822, 4823, 4824, 4825, + 4826, 4827, 4828, 4829, 4831, 4832, 4833, 4834, + 421, 148, 148, 1, 1, 4806, 1, 4830, + 1, 4562, 2518, 2518, 2518, 2774, 4563, 150, + 152, 153, 4564, 153, 4565, 4566, 158, 4567, + 160, 161, 4568, 4569, 4570, 4571, 4572, 4573, + 4574, 302, 4575, 4576, 4577, 4578, 4579, 4580, + 177, 4581, 4582, 4583, 2646, 2008, 2008, 4562, + 4562, 4562, 4562, 4562, 151, 4562, 176, 4562, + 1, 2518, 2518, 2518, 2774, 1, 1, 4563, + 150, 152, 153, 4564, 153, 4565, 4566, 158, + 4567, 160, 161, 4568, 4569, 4570, 4571, 4572, + 4573, 4574, 302, 4575, 4576, 4577, 4578, 4579, + 4580, 177, 4581, 4582, 4583, 1, 2646, 1, + 2008, 1, 2008, 1, 1, 1, 1, 151, + 176, 4562, 2518, 2518, 2518, 2774, 4562, 4562, + 4563, 150, 152, 153, 4564, 153, 4565, 4566, + 158, 4567, 160, 161, 4568, 4569, 4570, 4571, + 4572, 4573, 4574, 302, 4575, 4576, 4577, 4578, + 4579, 4580, 177, 4581, 4582, 4583, 2646, 2008, + 2008, 4562, 4562, 151, 4562, 176, 4562, 1, + 181, 181, 181, 571, 1, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 421, 148, 148, 1, 1, + 151, 176, 4562, 181, 181, 181, 571, 4563, + 150, 152, 153, 4564, 153, 4565, 4566, 158, + 4567, 160, 161, 4568, 4569, 4570, 4571, 4572, + 4573, 4574, 302, 4575, 4576, 4577, 4578, 4579, + 4580, 177, 4581, 4582, 4583, 421, 148, 148, + 1, 1, 1, 1, 1, 151, 176, 4562, + 181, 181, 181, 571, 1, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 421, 148, 148, 1, 151, + 176, 4562, 181, 181, 181, 571, 1, 4563, + 150, 152, 153, 4564, 153, 4565, 4566, 158, + 4567, 160, 161, 4568, 4569, 4570, 4571, 4572, + 4573, 4574, 302, 4575, 4576, 4577, 4578, 4579, + 4580, 177, 4581, 4582, 4583, 421, 148, 148, + 1, 1, 1, 151, 176, 4562, 181, 181, + 181, 571, 4804, 4805, 4807, 4808, 4809, 4808, + 4810, 4811, 4812, 4813, 4814, 4815, 4816, 4817, + 4818, 4819, 4820, 4821, 4822, 4823, 4824, 4825, + 4826, 4827, 4828, 4829, 4831, 4832, 4833, 4834, + 421, 148, 148, 1, 1, 4806, 1, 4830, + 1, 4562, 2518, 2518, 2518, 2774, 4562, 4562, + 4563, 150, 152, 153, 4564, 153, 4565, 4566, + 158, 4567, 160, 161, 4568, 4569, 4570, 4571, + 4572, 4573, 4574, 302, 4575, 4576, 4577, 4578, + 4579, 4580, 177, 4581, 4582, 4583, 2646, 2008, + 2008, 4562, 4562, 4562, 151, 4562, 176, 4562, + 1, 181, 181, 181, 571, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 421, 148, 148, 1, 1, + 1, 1, 1, 151, 176, 4562, 181, 181, + 181, 571, 4804, 4805, 4807, 4808, 4809, 4808, + 4810, 4811, 4812, 4813, 4814, 4815, 4816, 4817, + 4818, 4819, 4820, 4821, 4822, 4823, 4824, 4825, + 4826, 4827, 4828, 4829, 4831, 4832, 4833, 4834, + 421, 148, 148, 1, 1, 4806, 1, 4830, + 1, 4562, 2518, 2518, 2518, 2774, 4562, 4562, + 4563, 150, 152, 153, 4564, 153, 4565, 4566, + 158, 4567, 160, 161, 4568, 4569, 4570, 4571, + 4572, 4573, 4574, 302, 4575, 4576, 4577, 4578, + 4579, 4580, 177, 4581, 4582, 4583, 2646, 2008, + 2008, 4562, 4562, 4562, 151, 4562, 176, 4562, + 1, 181, 181, 181, 571, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 421, 148, 148, 1, 151, + 176, 4562, 181, 181, 181, 571, 1, 1, + 4563, 150, 152, 153, 4564, 153, 4565, 4566, + 158, 4567, 160, 161, 4568, 4569, 4570, 4571, + 4572, 4573, 4574, 302, 4575, 4576, 4577, 4578, + 4579, 4580, 177, 4581, 4582, 4583, 421, 148, + 148, 1, 1, 1, 151, 176, 4562, 181, + 181, 181, 571, 1, 4563, 150, 152, 153, + 4564, 153, 4565, 4566, 158, 4567, 160, 161, + 4568, 4569, 4570, 4571, 4572, 4573, 4574, 302, + 4575, 4576, 4577, 4578, 4579, 4580, 177, 4581, + 4582, 4583, 421, 148, 148, 1, 151, 176, + 4562, 181, 181, 181, 571, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 421, 148, 148, 1, 151, + 176, 4562, 181, 181, 181, 571, 1, 4563, + 150, 152, 153, 4564, 153, 4565, 4566, 158, + 4567, 160, 161, 4568, 4569, 4570, 4571, 4572, + 4573, 4574, 302, 4575, 4576, 4577, 4578, 4579, + 4580, 177, 4581, 4582, 4583, 421, 148, 148, + 1, 1, 151, 176, 4562, 181, 181, 181, + 571, 4563, 150, 152, 153, 4564, 153, 4565, + 4566, 158, 4567, 160, 161, 4568, 4569, 4570, + 4571, 4572, 4573, 4574, 302, 4575, 4576, 4577, + 4578, 4579, 4580, 177, 4581, 4582, 4583, 421, + 148, 148, 1, 151, 176, 4562, 181, 181, + 181, 571, 1, 1, 1, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 421, 148, 148, 1, 1, + 151, 176, 4562, 181, 181, 181, 571, 4563, + 150, 152, 153, 4564, 153, 4565, 4566, 158, + 4567, 160, 161, 4568, 4569, 4570, 4571, 4572, + 4573, 4574, 302, 4575, 4576, 4577, 4578, 4579, + 4580, 177, 4581, 4582, 4583, 421, 148, 148, + 1, 151, 176, 4562, 181, 181, 181, 571, + 4563, 150, 152, 153, 4564, 153, 4565, 4566, + 158, 4567, 160, 161, 4568, 4569, 4570, 4571, + 4572, 4573, 4574, 302, 4575, 4576, 4577, 4578, + 4579, 4580, 177, 4581, 4582, 4583, 421, 148, + 148, 1, 1, 1, 1, 151, 176, 4562, + 181, 181, 181, 571, 1, 4563, 150, 152, + 153, 4564, 153, 4565, 4566, 158, 4567, 160, + 161, 4568, 4569, 4570, 4571, 4572, 4573, 4574, + 302, 4575, 4576, 4577, 4578, 4579, 4580, 177, + 4581, 4582, 4583, 421, 148, 148, 151, 176, + 4562, 4499, 4500, 122, 124, 4501, 4502, 4503, + 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, + 4512, 4513, 4514, 4515, 4516, 4517, 4518, 4499, + 4499, 4499, 4499, 148, 4916, 4917, 4918, 4919, + 4920, 4921, 4922, 4923, 4924, 4925, 4926, 4927, + 4928, 4929, 4930, 4931, 4932, 4933, 4934, 4935, + 4936, 2395, 4499, 1, 4764, 2515, 2517, 4765, + 4766, 4767, 4768, 4769, 4770, 4771, 4772, 4773, + 4774, 4775, 4776, 4777, 4778, 4779, 4780, 4781, + 4782, 4763, 4937, 4938, 4939, 4940, 4941, 4942, + 4943, 4944, 4945, 4946, 4947, 4948, 4949, 4950, + 4951, 4952, 4953, 4954, 4955, 4956, 4957, 1, + 4763, 2395, 4500, 122, 124, 4501, 4502, 4503, + 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, + 4512, 4513, 4514, 4515, 4516, 4517, 4518, 4499, + 4500, 122, 124, 4501, 4502, 4503, 4504, 4505, + 4506, 4507, 4508, 4509, 4510, 4511, 4512, 4513, + 4514, 4515, 4516, 4517, 4518, 4499, 2395, 4500, + 122, 124, 4501, 4502, 4503, 4504, 4505, 4506, + 4507, 4508, 4509, 4510, 4511, 4512, 4513, 4514, + 4515, 4516, 4517, 4518, 2395, 4499, 2395, 4500, + 122, 124, 4501, 4502, 4503, 4504, 4505, 4506, + 4507, 4508, 4509, 4510, 4511, 4512, 4513, 4514, + 4515, 4516, 4517, 4518, 2395, 4499, 2395, 4500, + 122, 124, 4501, 4502, 4503, 4504, 4505, 4506, + 4507, 4508, 4509, 4510, 4511, 4512, 4513, 4514, + 4515, 4516, 4517, 4518, 2395, 2395, 4499, 2395, + 4500, 122, 124, 4501, 4502, 4503, 4504, 4505, + 4506, 4507, 4508, 4509, 4510, 4511, 4512, 4513, + 4514, 4515, 4516, 4517, 4518, 2395, 2395, 4499, + 2395, 4500, 122, 124, 4501, 4502, 4503, 4504, + 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, + 4513, 4514, 4515, 4516, 4517, 4518, 2395, 4499, + 4500, 122, 124, 4501, 4502, 4503, 4504, 4505, + 4506, 4507, 4508, 4509, 4510, 4511, 4512, 4513, + 4514, 4515, 4516, 4517, 4518, 2395, 2395, 2395, + 2395, 4499, 2395, 2395, 4916, 4917, 4918, 4919, + 4920, 4921, 4922, 4923, 4924, 4925, 4926, 4927, + 4928, 4929, 4930, 4931, 4932, 4933, 4934, 4935, + 4936, 2395, 4499, 4764, 2515, 2517, 4765, 4766, + 4767, 4768, 4769, 4770, 4771, 4772, 4773, 4774, + 4775, 4776, 4777, 4778, 4779, 4780, 4781, 4782, + 4763, 1, 4764, 2515, 2517, 4765, 4766, 4767, + 4768, 4769, 4770, 4771, 4772, 4773, 4774, 4775, + 4776, 4777, 4778, 4779, 4780, 4781, 4782, 1, + 4763, 1, 4764, 2515, 2517, 4765, 4766, 4767, + 4768, 4769, 4770, 4771, 4772, 4773, 4774, 4775, + 4776, 4777, 4778, 4779, 4780, 4781, 4782, 1, + 4763, 1, 4764, 2515, 2517, 4765, 4766, 4767, + 4768, 4769, 4770, 4771, 4772, 4773, 4774, 4775, + 4776, 4777, 4778, 4779, 4780, 4781, 4782, 1, + 1, 4763, 1, 4764, 2515, 2517, 4765, 4766, + 4767, 4768, 4769, 4770, 4771, 4772, 4773, 4774, + 4775, 4776, 4777, 4778, 4779, 4780, 4781, 4782, + 1, 1, 4763, 1, 4764, 2515, 2517, 4765, + 4766, 4767, 4768, 4769, 4770, 4771, 4772, 4773, + 4774, 4775, 4776, 4777, 4778, 4779, 4780, 4781, + 4782, 1, 4763, 4764, 2515, 2517, 4765, 4766, + 4767, 4768, 4769, 4770, 4771, 4772, 4773, 4774, + 4775, 4776, 4777, 4778, 4779, 4780, 4781, 4782, + 1, 1, 1, 1, 4763, 1, 1, 4937, + 4938, 4939, 4940, 4941, 4942, 4943, 4944, 4945, + 4946, 4947, 4948, 4949, 4950, 4951, 4952, 4953, + 4954, 4955, 4956, 4957, 1, 4763, 4500, 122, + 124, 4501, 4502, 4503, 4504, 4505, 4506, 4507, + 4508, 4509, 4510, 4511, 4512, 4513, 4514, 4515, + 4516, 4517, 4518, 4499, 2395, 4500, 122, 124, + 4501, 4502, 4503, 4504, 4505, 4506, 4507, 4508, + 4509, 4510, 4511, 4512, 4513, 4514, 4515, 4516, + 4517, 4518, 2395, 4499, 4500, 122, 124, 4501, + 4502, 4503, 4504, 4505, 4506, 4507, 4508, 4509, + 4510, 4511, 4512, 4513, 4514, 4515, 4516, 4517, + 4518, 2395, 4499, 2396, 2397, 2398, 2399, 2400, + 2402, 2403, 2404, 2406, 2407, 2408, 2409, 2410, + 2411, 2412, 2413, 2414, 2415, 2416, 2417, 2418, + 2419, 2420, 2421, 2422, 2423, 4500, 122, 124, + 4501, 4502, 4503, 4504, 4505, 4506, 4507, 4508, + 4509, 4510, 4511, 4512, 4513, 4514, 4515, 4516, + 4517, 4518, 2401, 2405, 4499, 2424, 2425, 2426, + 2427, 2428, 2429, 2430, 2431, 2432, 2433, 2434, + 2435, 2436, 2437, 2438, 2439, 2440, 2441, 2442, + 2443, 2444, 4500, 122, 124, 4501, 4502, 4503, + 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, + 4512, 4513, 4514, 4515, 4516, 4517, 4518, 4499, + 2445, 2446, 2447, 2448, 2449, 2450, 4500, 122, + 124, 4501, 4502, 4503, 4504, 4505, 4506, 4507, + 4508, 4509, 4510, 4511, 4512, 4513, 4514, 4515, + 4516, 4517, 4518, 4499, 2451, 2452, 4500, 122, + 124, 4501, 4502, 4503, 4504, 4505, 4506, 4507, + 4508, 4509, 4510, 4511, 4512, 4513, 4514, 4515, + 4516, 4517, 4518, 4499, 2453, 2454, 2455, 2456, + 2457, 2458, 2459, 2460, 2461, 2462, 2463, 2464, + 2465, 2466, 2467, 4500, 122, 124, 4501, 4502, + 4503, 4504, 4505, 4506, 4507, 4508, 4509, 4510, + 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, + 4499, 2468, 2469, 2449, 2454, 2470, 4500, 122, + 124, 4501, 4502, 4503, 4504, 4505, 4506, 4507, + 4508, 4509, 4510, 4511, 4512, 4513, 4514, 4515, + 4516, 4517, 4518, 4499, 2471, 2472, 2473, 2474, + 2475, 2476, 4500, 122, 124, 4501, 4502, 4503, + 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, + 4512, 4513, 4514, 4515, 4516, 4517, 4518, 4499, + 2512, 4500, 122, 124, 4501, 4502, 4503, 4504, + 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, + 4513, 4514, 4515, 4516, 4517, 4518, 4499, 4764, + 2515, 2517, 4765, 4766, 4767, 4768, 4769, 4770, + 4771, 4772, 4773, 4774, 4775, 4776, 4777, 4778, + 4779, 4780, 4781, 4782, 4763, 1, 4764, 2515, + 2517, 4765, 4766, 4767, 4768, 4769, 4770, 4771, + 4772, 4773, 4774, 4775, 4776, 4777, 4778, 4779, + 4780, 4781, 4782, 1, 4763, 4764, 2515, 2517, + 4765, 4766, 4767, 4768, 4769, 4770, 4771, 4772, + 4773, 4774, 4775, 4776, 4777, 4778, 4779, 4780, + 4781, 4782, 1, 4763, 3, 4, 5, 6, + 7, 9, 10, 11, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 4764, 2515, + 2517, 4765, 4766, 4767, 4768, 4769, 4770, 4771, + 4772, 4773, 4774, 4775, 4776, 4777, 4778, 4779, + 4780, 4781, 4782, 8, 12, 4763, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 4764, 2515, 2517, 4765, 4766, + 4767, 4768, 4769, 4770, 4771, 4772, 4773, 4774, + 4775, 4776, 4777, 4778, 4779, 4780, 4781, 4782, + 4763, 52, 53, 54, 55, 56, 57, 4764, + 2515, 2517, 4765, 4766, 4767, 4768, 4769, 4770, + 4771, 4772, 4773, 4774, 4775, 4776, 4777, 4778, + 4779, 4780, 4781, 4782, 4763, 58, 59, 4764, + 2515, 2517, 4765, 4766, 4767, 4768, 4769, 4770, + 4771, 4772, 4773, 4774, 4775, 4776, 4777, 4778, + 4779, 4780, 4781, 4782, 4763, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 4764, 2515, 2517, 4765, + 4766, 4767, 4768, 4769, 4770, 4771, 4772, 4773, + 4774, 4775, 4776, 4777, 4778, 4779, 4780, 4781, + 4782, 4763, 75, 76, 56, 61, 77, 4764, + 2515, 2517, 4765, 4766, 4767, 4768, 4769, 4770, + 4771, 4772, 4773, 4774, 4775, 4776, 4777, 4778, + 4779, 4780, 4781, 4782, 4763, 78, 79, 80, + 81, 82, 83, 4764, 2515, 2517, 4765, 4766, + 4767, 4768, 4769, 4770, 4771, 4772, 4773, 4774, + 4775, 4776, 4777, 4778, 4779, 4780, 4781, 4782, + 4763, 119, 4764, 2515, 2517, 4765, 4766, 4767, + 4768, 4769, 4770, 4771, 4772, 4773, 4774, 4775, + 4776, 4777, 4778, 4779, 4780, 4781, 4782, 4763, + 4499, 4499, 4500, 122, 124, 4501, 4502, 4503, + 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, + 4512, 4513, 4514, 4515, 4516, 4517, 4518, 148, + 4499, 148, 4499, 2395, 148, 148, 4783, 4784, + 4785, 4786, 4787, 4788, 4789, 4790, 4791, 4792, + 4793, 4794, 4795, 4796, 4797, 4798, 4799, 4800, + 4801, 4802, 4803, 148, 148, 148, 4499, 4499, + 4783, 4784, 4785, 4786, 4787, 4788, 4789, 4790, + 4791, 4792, 4793, 4794, 4795, 4796, 4797, 4798, + 4799, 4800, 4801, 4802, 4803, 2395, 148, 4499, + 4500, 122, 124, 4501, 4502, 4503, 4504, 4505, + 4506, 4507, 4508, 4509, 4510, 4511, 4512, 4513, + 4514, 4515, 4516, 4517, 4518, 4499, 2395, 4499, + 148, 2395, 148, 4500, 122, 124, 4501, 4502, + 4503, 4504, 4505, 4506, 4507, 4508, 4509, 4510, + 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, + 2395, 2395, 572, 572, 4499, 2395, 4500, 122, + 124, 4501, 4502, 4503, 4504, 4505, 4506, 4507, + 4508, 4509, 4510, 4511, 4512, 4513, 4514, 4515, + 4516, 4517, 4518, 2395, 2395, 148, 4499, 126, + 2395, 4783, 4784, 4785, 4786, 4787, 4788, 4789, + 4790, 4791, 4792, 4793, 4794, 4795, 4796, 4797, + 4798, 4799, 4800, 4801, 4802, 4803, 148, 2395, + 126, 148, 4499, 4499, 4499, 4499, 4500, 122, + 124, 4501, 4502, 4503, 4504, 4505, 4506, 4507, + 4508, 4509, 4510, 4511, 4512, 4513, 4514, 4515, + 4516, 4517, 4518, 2395, 2395, 126, 4499, 4499, + 148, 148, 4916, 4917, 4918, 4919, 4920, 4921, + 4922, 4923, 4924, 4925, 4926, 4927, 4928, 4929, + 4930, 4931, 4932, 4933, 4934, 4935, 4936, 2395, + 148, 2395, 4499, 4783, 4784, 4785, 4786, 4787, + 4788, 4789, 4790, 4791, 4792, 4793, 4794, 4795, + 4796, 4797, 4798, 4799, 4800, 4801, 4802, 4803, + 4499, 148, 2395, 4500, 122, 124, 4501, 4502, + 4503, 4504, 4505, 4506, 4507, 4508, 4509, 4510, + 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, + 2395, 4499, 148, 148, 4500, 122, 124, 4501, + 4502, 4503, 4504, 4505, 4506, 4507, 4508, 4509, + 4510, 4511, 4512, 4513, 4514, 4515, 4516, 4517, + 4518, 126, 148, 2395, 148, 4499, 4958, 4959, + 184, 2398, 4960, 4961, 4962, 4963, 4964, 4965, + 4966, 4967, 4968, 4969, 4970, 4971, 4972, 4973, + 4974, 4975, 4976, 4977, 4978, 4979, 2416, 4980, + 2418, 4981, 4982, 4983, 4984, 2423, 4500, 122, + 124, 4501, 4502, 4503, 4504, 4505, 4506, 4507, + 4508, 4509, 4510, 4511, 4512, 4513, 4514, 4515, + 4516, 4517, 4518, 4499, 2424, 4985, 4986, 217, + 3020, 3022, 218, 219, 220, 221, 4987, 223, + 224, 225, 226, 227, 228, 4988, 4989, 2430, + 4990, 4991, 234, 4992, 236, 4993, 1528, 1529, + 4994, 2436, 4995, 4996, 4997, 4998, 4999, 5000, + 1538, 5001, 151, 152, 2444, 249, 250, 251, + 252, 4500, 122, 124, 4501, 4502, 4503, 4504, + 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, + 4513, 4514, 4515, 4516, 4517, 4518, 3021, 151, + 153, 151, 4499, 181, 181, 181, 571, 5003, + 150, 152, 153, 4564, 3196, 5004, 4566, 158, + 5005, 160, 161, 5006, 5007, 5008, 5009, 5010, + 5011, 5012, 5013, 5014, 5015, 5016, 5017, 5018, + 5019, 5021, 5022, 5023, 5024, 421, 148, 148, + 151, 5020, 5002, 5025, 3085, 3180, 5026, 5027, + 5028, 5029, 5030, 5031, 5032, 5033, 5034, 5035, + 5036, 5037, 5038, 5039, 5040, 5042, 5043, 5044, + 5045, 5041, 5002, 5046, 5047, 255, 2447, 257, + 258, 259, 260, 261, 262, 263, 151, 5048, + 265, 5049, 267, 5050, 269, 5051, 5052, 3371, + 5053, 4500, 122, 124, 4501, 4502, 4503, 4504, + 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, + 4513, 4514, 4515, 4516, 4517, 4518, 3372, 4499, + 5055, 3371, 3373, 5056, 5057, 5058, 5059, 5060, + 5061, 5062, 5063, 5064, 5065, 5066, 5067, 5068, + 5069, 5070, 5071, 5072, 5073, 5054, 5074, 5075, + 5076, 3685, 3049, 3021, 3050, 3686, 3051, 3052, + 3687, 3688, 3689, 3371, 5077, 5078, 5079, 5080, + 5081, 5082, 5083, 5084, 5085, 5086, 5087, 5088, + 5089, 5090, 5091, 5092, 5093, 5094, 5095, 5096, + 5097, 3372, 4499, 181, 181, 181, 571, 5098, + 150, 152, 153, 4564, 3501, 5099, 4566, 158, + 5100, 160, 161, 5101, 5102, 5103, 5104, 5105, + 5106, 5107, 5108, 5109, 5110, 5111, 5112, 5113, + 5114, 177, 5115, 5116, 5117, 421, 148, 148, + 151, 176, 4562, 5118, 3624, 3626, 5119, 5120, + 5121, 5122, 5123, 5124, 5125, 5126, 5127, 5128, + 5129, 5130, 5131, 5132, 5133, 5042, 5134, 5135, + 5136, 5041, 5002, 571, 5138, 3688, 3756, 5139, + 5140, 5141, 5142, 5143, 5144, 5145, 5146, 5147, + 5148, 5149, 5150, 5151, 5152, 5153, 5154, 5155, + 5156, 5137, 5158, 3878, 3880, 5159, 5160, 5161, + 5162, 5163, 5164, 5165, 5166, 5167, 5168, 5169, + 5170, 5171, 5172, 5173, 5174, 5175, 5176, 5157, + 5177, 4001, 4003, 5178, 5179, 5180, 5181, 5182, + 5183, 5184, 5185, 5186, 5187, 5188, 5189, 5190, + 5191, 5192, 5193, 5194, 5195, 5054, 5055, 3371, + 3373, 5056, 5057, 5058, 5059, 5060, 5061, 5062, + 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, + 5071, 5072, 5073, 1, 1, 1, 1, 5054, + 5055, 3371, 3373, 5056, 5057, 5058, 5059, 5060, + 5061, 5062, 5063, 5064, 5065, 5066, 5067, 5068, + 5069, 5070, 5071, 5072, 5073, 1, 5054, 5196, + 5197, 5198, 5199, 5200, 5201, 5202, 5203, 5204, + 5205, 5206, 5207, 5208, 5209, 5210, 5211, 5212, + 5213, 5214, 5215, 5216, 1, 5054, 3250, 4500, + 122, 124, 4501, 4502, 4503, 4504, 4505, 4506, + 4507, 4508, 4509, 4510, 4511, 4512, 4513, 4514, + 4515, 4516, 4517, 4518, 4499, 5217, 5218, 5219, + 5220, 5221, 5222, 5223, 5224, 5225, 5226, 5227, + 5228, 5229, 5230, 5231, 5232, 5233, 5234, 5235, + 5236, 5237, 3250, 4499, 1, 5055, 3371, 3373, + 5056, 5057, 5058, 5059, 5060, 5061, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5073, 5054, 5196, 5197, 5198, 5199, 5200, + 5201, 5202, 5203, 5204, 5205, 5206, 5207, 5208, + 5209, 5210, 5211, 5212, 5213, 5214, 5215, 5216, + 1, 5054, 4500, 122, 124, 4501, 4502, 4503, + 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, + 4512, 4513, 4514, 4515, 4516, 4517, 4518, 4499, + 3250, 4500, 122, 124, 4501, 4502, 4503, 4504, + 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, + 4513, 4514, 4515, 4516, 4517, 4518, 3250, 4499, + 3250, 4500, 122, 124, 4501, 4502, 4503, 4504, + 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, + 4513, 4514, 4515, 4516, 4517, 4518, 3250, 4499, + 3250, 4500, 122, 124, 4501, 4502, 4503, 4504, + 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, + 4513, 4514, 4515, 4516, 4517, 4518, 3250, 3250, + 4499, 3250, 4500, 122, 124, 4501, 4502, 4503, + 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, + 4512, 4513, 4514, 4515, 4516, 4517, 4518, 3250, + 3250, 4499, 3250, 4500, 122, 124, 4501, 4502, + 4503, 4504, 4505, 4506, 4507, 4508, 4509, 4510, + 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, + 3250, 4499, 4500, 122, 124, 4501, 4502, 4503, + 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, + 4512, 4513, 4514, 4515, 4516, 4517, 4518, 3250, + 3250, 3250, 3250, 4499, 3250, 3250, 5217, 5218, + 5219, 5220, 5221, 5222, 5223, 5224, 5225, 5226, + 5227, 5228, 5229, 5230, 5231, 5232, 5233, 5234, + 5235, 5236, 5237, 3250, 4499, 5055, 3371, 3373, + 5056, 5057, 5058, 5059, 5060, 5061, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5073, 5054, 1, 5055, 3371, 3373, 5056, + 5057, 5058, 5059, 5060, 5061, 5062, 5063, 5064, + 5065, 5066, 5067, 5068, 5069, 5070, 5071, 5072, + 5073, 1, 5054, 1, 5055, 3371, 3373, 5056, + 5057, 5058, 5059, 5060, 5061, 5062, 5063, 5064, + 5065, 5066, 5067, 5068, 5069, 5070, 5071, 5072, + 5073, 1, 5054, 1, 5055, 3371, 3373, 5056, + 5057, 5058, 5059, 5060, 5061, 5062, 5063, 5064, + 5065, 5066, 5067, 5068, 5069, 5070, 5071, 5072, + 5073, 1, 1, 5054, 1, 5055, 3371, 3373, + 5056, 5057, 5058, 5059, 5060, 5061, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5073, 1, 1, 5054, 1, 5055, 3371, + 3373, 5056, 5057, 5058, 5059, 5060, 5061, 5062, + 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, + 5071, 5072, 5073, 1, 5054, 5055, 3371, 3373, + 5056, 5057, 5058, 5059, 5060, 5061, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5073, 1, 1, 1, 1, 5054, 1, + 1, 5196, 5197, 5198, 5199, 5200, 5201, 5202, + 5203, 5204, 5205, 5206, 5207, 5208, 5209, 5210, + 5211, 5212, 5213, 5214, 5215, 5216, 1, 5054, + 4500, 122, 124, 4501, 4502, 4503, 4504, 4505, + 4506, 4507, 4508, 4509, 4510, 4511, 4512, 4513, + 4514, 4515, 4516, 4517, 4518, 4499, 3250, 4500, + 122, 124, 4501, 4502, 4503, 4504, 4505, 4506, + 4507, 4508, 4509, 4510, 4511, 4512, 4513, 4514, + 4515, 4516, 4517, 4518, 3250, 4499, 4500, 122, + 124, 4501, 4502, 4503, 4504, 4505, 4506, 4507, + 4508, 4509, 4510, 4511, 4512, 4513, 4514, 4515, + 4516, 4517, 4518, 3250, 4499, 3252, 3253, 3254, + 3255, 3256, 3258, 3259, 3260, 3262, 3263, 3264, + 3265, 3266, 3267, 3268, 3269, 3270, 3271, 3272, + 3273, 3274, 3275, 3276, 3277, 3278, 3279, 4500, + 122, 124, 4501, 4502, 4503, 4504, 4505, 4506, + 4507, 4508, 4509, 4510, 4511, 4512, 4513, 4514, + 4515, 4516, 4517, 4518, 3257, 3261, 4499, 3280, + 3281, 3282, 3283, 3284, 3285, 3286, 3287, 3288, + 3289, 3290, 3291, 3292, 3293, 3294, 3295, 3296, + 3297, 3298, 3299, 3300, 4500, 122, 124, 4501, + 4502, 4503, 4504, 4505, 4506, 4507, 4508, 4509, + 4510, 4511, 4512, 4513, 4514, 4515, 4516, 4517, + 4518, 4499, 3301, 3302, 3303, 3304, 3305, 3306, + 4500, 122, 124, 4501, 4502, 4503, 4504, 4505, + 4506, 4507, 4508, 4509, 4510, 4511, 4512, 4513, + 4514, 4515, 4516, 4517, 4518, 4499, 3307, 3308, + 4500, 122, 124, 4501, 4502, 4503, 4504, 4505, + 4506, 4507, 4508, 4509, 4510, 4511, 4512, 4513, + 4514, 4515, 4516, 4517, 4518, 4499, 3309, 3310, + 3311, 3312, 3313, 3314, 3315, 3316, 3317, 3318, + 3319, 3320, 3321, 3322, 3323, 4500, 122, 124, + 4501, 4502, 4503, 4504, 4505, 4506, 4507, 4508, + 4509, 4510, 4511, 4512, 4513, 4514, 4515, 4516, + 4517, 4518, 4499, 3324, 3325, 3305, 3310, 3326, + 4500, 122, 124, 4501, 4502, 4503, 4504, 4505, + 4506, 4507, 4508, 4509, 4510, 4511, 4512, 4513, + 4514, 4515, 4516, 4517, 4518, 4499, 3327, 3328, + 3329, 3330, 3331, 3332, 4500, 122, 124, 4501, + 4502, 4503, 4504, 4505, 4506, 4507, 4508, 4509, + 4510, 4511, 4512, 4513, 4514, 4515, 4516, 4517, + 4518, 4499, 3368, 4500, 122, 124, 4501, 4502, + 4503, 4504, 4505, 4506, 4507, 4508, 4509, 4510, + 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, + 4499, 5055, 3371, 3373, 5056, 5057, 5058, 5059, + 5060, 5061, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5073, 5054, 1, + 5055, 3371, 3373, 5056, 5057, 5058, 5059, 5060, + 5061, 5062, 5063, 5064, 5065, 5066, 5067, 5068, + 5069, 5070, 5071, 5072, 5073, 1, 5054, 5055, + 3371, 3373, 5056, 5057, 5058, 5059, 5060, 5061, + 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, + 5070, 5071, 5072, 5073, 1, 5054, 3, 4, + 5, 6, 7, 9, 10, 11, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, + 5055, 3371, 3373, 5056, 5057, 5058, 5059, 5060, + 5061, 5062, 5063, 5064, 5065, 5066, 5067, 5068, + 5069, 5070, 5071, 5072, 5073, 8, 12, 5054, + 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 5055, 3371, 3373, + 5056, 5057, 5058, 5059, 5060, 5061, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5073, 5054, 52, 53, 54, 55, 56, + 57, 5055, 3371, 3373, 5056, 5057, 5058, 5059, + 5060, 5061, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5073, 5054, 58, + 59, 5055, 3371, 3373, 5056, 5057, 5058, 5059, + 5060, 5061, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5073, 5054, 60, + 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 5055, 3371, + 3373, 5056, 5057, 5058, 5059, 5060, 5061, 5062, + 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, + 5071, 5072, 5073, 5054, 75, 76, 56, 61, + 77, 5055, 3371, 3373, 5056, 5057, 5058, 5059, + 5060, 5061, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5073, 5054, 78, + 79, 80, 81, 82, 83, 5055, 3371, 3373, + 5056, 5057, 5058, 5059, 5060, 5061, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5073, 5054, 119, 5055, 3371, 3373, 5056, + 5057, 5058, 5059, 5060, 5061, 5062, 5063, 5064, + 5065, 5066, 5067, 5068, 5069, 5070, 5071, 5072, + 5073, 5054, 5054, 5196, 5197, 5198, 5199, 5200, + 5201, 5202, 5203, 5204, 5205, 5206, 5207, 5208, + 5209, 5210, 5211, 5212, 5213, 5214, 5215, 5216, + 5054, 1, 5054, 5055, 3371, 3373, 5056, 5057, + 5058, 5059, 5060, 5061, 5062, 5063, 5064, 5065, + 5066, 5067, 5068, 5069, 5070, 5071, 5072, 5073, + 5054, 5054, 1, 1, 5196, 5197, 5198, 5199, + 5200, 5201, 5202, 5203, 5204, 5205, 5206, 5207, + 5208, 5209, 5210, 5211, 5212, 5213, 5214, 5215, + 5216, 1, 1, 5054, 5055, 3371, 3373, 5056, + 5057, 5058, 5059, 5060, 5061, 5062, 5063, 5064, + 5065, 5066, 5067, 5068, 5069, 5070, 5071, 5072, + 5073, 5054, 5054, 5054, 5054, 5054, 1, 5055, + 3371, 3373, 5056, 5057, 5058, 5059, 5060, 5061, + 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, + 5070, 5071, 5072, 5073, 5054, 5054, 5054, 5054, + 5054, 5054, 1, 5054, 5054, 5055, 3371, 3373, + 5056, 5057, 5058, 5059, 5060, 5061, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5073, 5054, 5054, 1, 1, 5055, 3371, + 3373, 5056, 5057, 5058, 5059, 5060, 5061, 5062, + 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, + 5071, 5072, 5073, 1, 1, 5054, 5055, 3371, + 3373, 5056, 5057, 5058, 5059, 5060, 5061, 5062, + 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, + 5071, 5072, 5073, 1, 1, 1, 1, 1, + 5054, 1, 5055, 3371, 3373, 5056, 5057, 5058, + 5059, 5060, 5061, 5062, 5063, 5064, 5065, 5066, + 5067, 5068, 5069, 5070, 5071, 5072, 5073, 1, + 5054, 1, 5055, 3371, 3373, 5056, 5057, 5058, + 5059, 5060, 5061, 5062, 5063, 5064, 5065, 5066, + 5067, 5068, 5069, 5070, 5071, 5072, 5073, 1, + 1, 1, 5054, 5196, 5197, 5198, 5199, 5200, + 5201, 5202, 5203, 5204, 5205, 5206, 5207, 5208, + 5209, 5210, 5211, 5212, 5213, 5214, 5215, 5216, + 1, 1, 5054, 5054, 5054, 5055, 3371, 3373, + 5056, 5057, 5058, 5059, 5060, 5061, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5073, 5054, 5054, 5054, 1, 5055, 3371, + 3373, 5056, 5057, 5058, 5059, 5060, 5061, 5062, + 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, + 5071, 5072, 5073, 1, 1, 1, 1, 1, + 5054, 5196, 5197, 5198, 5199, 5200, 5201, 5202, + 5203, 5204, 5205, 5206, 5207, 5208, 5209, 5210, + 5211, 5212, 5213, 5214, 5215, 5216, 1, 1, + 5054, 5054, 5054, 5055, 3371, 3373, 5056, 5057, + 5058, 5059, 5060, 5061, 5062, 5063, 5064, 5065, + 5066, 5067, 5068, 5069, 5070, 5071, 5072, 5073, + 5054, 5054, 5054, 1, 5055, 3371, 3373, 5056, + 5057, 5058, 5059, 5060, 5061, 5062, 5063, 5064, + 5065, 5066, 5067, 5068, 5069, 5070, 5071, 5072, + 5073, 1, 5054, 1, 1, 5055, 3371, 3373, + 5056, 5057, 5058, 5059, 5060, 5061, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5073, 1, 1, 1, 5054, 1, 5055, + 3371, 3373, 5056, 5057, 5058, 5059, 5060, 5061, + 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, + 5070, 5071, 5072, 5073, 1, 5054, 5055, 3371, + 3373, 5056, 5057, 5058, 5059, 5060, 5061, 5062, + 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, + 5071, 5072, 5073, 1, 5054, 1, 5055, 3371, + 3373, 5056, 5057, 5058, 5059, 5060, 5061, 5062, + 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, + 5071, 5072, 5073, 1, 1, 5054, 5055, 3371, + 3373, 5056, 5057, 5058, 5059, 5060, 5061, 5062, + 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, + 5071, 5072, 5073, 1, 5054, 1, 1, 1, + 5055, 3371, 3373, 5056, 5057, 5058, 5059, 5060, + 5061, 5062, 5063, 5064, 5065, 5066, 5067, 5068, + 5069, 5070, 5071, 5072, 5073, 1, 1, 5054, + 5055, 3371, 3373, 5056, 5057, 5058, 5059, 5060, + 5061, 5062, 5063, 5064, 5065, 5066, 5067, 5068, + 5069, 5070, 5071, 5072, 5073, 1, 5054, 5055, + 3371, 3373, 5056, 5057, 5058, 5059, 5060, 5061, + 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, + 5070, 5071, 5072, 5073, 1, 1, 1, 1, + 5054, 1, 5055, 3371, 3373, 5056, 5057, 5058, + 5059, 5060, 5061, 5062, 5063, 5064, 5065, 5066, + 5067, 5068, 5069, 5070, 5071, 5072, 5073, 5054, + 5055, 3371, 3373, 5056, 5057, 5058, 5059, 5060, + 5061, 5062, 5063, 5064, 5065, 5066, 5067, 5068, + 5069, 5070, 5071, 5072, 5073, 1, 5054, 5055, + 3371, 3373, 5056, 5057, 5058, 5059, 5060, 5061, + 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, + 5070, 5071, 5072, 5073, 1, 1, 1, 1, + 1, 5054, 1, 5055, 3371, 3373, 5056, 5057, + 5058, 5059, 5060, 5061, 5062, 5063, 5064, 5065, + 5066, 5067, 5068, 5069, 5070, 5071, 5072, 5073, + 1, 1, 5054, 5055, 3371, 3373, 5056, 5057, + 5058, 5059, 5060, 5061, 5062, 5063, 5064, 5065, + 5066, 5067, 5068, 5069, 5070, 5071, 5072, 5073, + 1, 5054, 5055, 3371, 3373, 5056, 5057, 5058, + 5059, 5060, 5061, 5062, 5063, 5064, 5065, 5066, + 5067, 5068, 5069, 5070, 5071, 5072, 5073, 1, + 1, 5054, 5055, 3371, 3373, 5056, 5057, 5058, + 5059, 5060, 5061, 5062, 5063, 5064, 5065, 5066, + 5067, 5068, 5069, 5070, 5071, 5072, 5073, 1, + 1, 5054, 5196, 5197, 5198, 5199, 5200, 5201, + 5202, 5203, 5204, 5205, 5206, 5207, 5208, 5209, + 5210, 5211, 5212, 5213, 5214, 5215, 5216, 1, + 5054, 5055, 3371, 3373, 5056, 5057, 5058, 5059, + 5060, 5061, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5073, 5054, 5054, + 1, 5055, 3371, 3373, 5056, 5057, 5058, 5059, + 5060, 5061, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5073, 1, 5054, + 1, 5055, 3371, 3373, 5056, 5057, 5058, 5059, + 5060, 5061, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5073, 5054, 5055, + 3371, 3373, 5056, 5057, 5058, 5059, 5060, 5061, + 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, + 5070, 5071, 5072, 5073, 1, 1, 5054, 5055, + 3371, 3373, 5056, 5057, 5058, 5059, 5060, 5061, + 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, + 5070, 5071, 5072, 5073, 1, 5054, 1, 5055, + 3371, 3373, 5056, 5057, 5058, 5059, 5060, 5061, + 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, + 5070, 5071, 5072, 5073, 1, 1, 5054, 5055, + 3371, 3373, 5056, 5057, 5058, 5059, 5060, 5061, + 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, + 5070, 5071, 5072, 5073, 1, 5054, 5196, 5197, + 5198, 5199, 5200, 5201, 5202, 5203, 5204, 5205, + 5206, 5207, 5208, 5209, 5210, 5211, 5212, 5213, + 5214, 5215, 5216, 1, 1, 5054, 5055, 3371, + 3373, 5056, 5057, 5058, 5059, 5060, 5061, 5062, + 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, + 5071, 5072, 5073, 5054, 5054, 1, 5055, 3371, + 3373, 5056, 5057, 5058, 5059, 5060, 5061, 5062, + 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, + 5071, 5072, 5073, 1, 1, 5054, 5055, 3371, + 3373, 5056, 5057, 5058, 5059, 5060, 5061, 5062, + 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, + 5071, 5072, 5073, 1, 5054, 5055, 3371, 3373, + 5056, 5057, 5058, 5059, 5060, 5061, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5073, 1, 5054, 1, 5055, 3371, 3373, + 5056, 5057, 5058, 5059, 5060, 5061, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5073, 1, 1, 1, 1, 5054, 5055, + 3371, 3373, 5056, 5057, 5058, 5059, 5060, 5061, + 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, + 5070, 5071, 5072, 5073, 1, 1, 5054, 5055, + 3371, 3373, 5056, 5057, 5058, 5059, 5060, 5061, + 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, + 5070, 5071, 5072, 5073, 1, 1, 5054, 5055, + 3371, 3373, 5056, 5057, 5058, 5059, 5060, 5061, + 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, + 5070, 5071, 5072, 5073, 1, 1, 5054, 5055, + 3371, 3373, 5056, 5057, 5058, 5059, 5060, 5061, + 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, + 5070, 5071, 5072, 5073, 1, 5054, 5055, 3371, + 3373, 5056, 5057, 5058, 5059, 5060, 5061, 5062, + 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, + 5071, 5072, 5073, 1, 5054, 1, 5055, 3371, + 3373, 5056, 5057, 5058, 5059, 5060, 5061, 5062, + 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, + 5071, 5072, 5073, 5054, 5055, 3371, 3373, 5056, + 5057, 5058, 5059, 5060, 5061, 5062, 5063, 5064, + 5065, 5066, 5067, 5068, 5069, 5070, 5071, 5072, + 5073, 1, 5054, 5055, 3371, 3373, 5056, 5057, + 5058, 5059, 5060, 5061, 5062, 5063, 5064, 5065, + 5066, 5067, 5068, 5069, 5070, 5071, 5072, 5073, + 1, 5054, 5055, 3371, 3373, 5056, 5057, 5058, + 5059, 5060, 5061, 5062, 5063, 5064, 5065, 5066, + 5067, 5068, 5069, 5070, 5071, 5072, 5073, 1, + 5054, 5055, 3371, 3373, 5056, 5057, 5058, 5059, + 5060, 5061, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5073, 1, 1, + 5054, 5055, 3371, 3373, 5056, 5057, 5058, 5059, + 5060, 5061, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5073, 1, 5054, + 5055, 3371, 3373, 5056, 5057, 5058, 5059, 5060, + 5061, 5062, 5063, 5064, 5065, 5066, 5067, 5068, + 5069, 5070, 5071, 5072, 5073, 1, 5054, 1, + 1, 1, 5055, 3371, 3373, 5056, 5057, 5058, + 5059, 5060, 5061, 5062, 5063, 5064, 5065, 5066, + 5067, 5068, 5069, 5070, 5071, 5072, 5073, 1, + 5054, 5196, 5197, 5198, 5199, 5200, 5201, 5202, + 5203, 5204, 5205, 5206, 5207, 5208, 5209, 5210, + 5211, 5212, 5213, 5214, 5215, 5216, 1, 1, + 5054, 5055, 3371, 3373, 5056, 5057, 5058, 5059, + 5060, 5061, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5073, 5054, 5054, + 1, 5055, 3371, 3373, 5056, 5057, 5058, 5059, + 5060, 5061, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5073, 1, 5054, + 5055, 3371, 3373, 5056, 5057, 5058, 5059, 5060, + 5061, 5062, 5063, 5064, 5065, 5066, 5067, 5068, + 5069, 5070, 5071, 5072, 5073, 1, 5054, 5196, + 5197, 5198, 5199, 5200, 5201, 5202, 5203, 5204, + 5205, 5206, 5207, 5208, 5209, 5210, 5211, 5212, + 5213, 5214, 5215, 5216, 1, 1, 5054, 5055, + 3371, 3373, 5056, 5057, 5058, 5059, 5060, 5061, + 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, + 5070, 5071, 5072, 5073, 5054, 5054, 1, 5055, + 3371, 3373, 5056, 5057, 5058, 5059, 5060, 5061, + 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, + 5070, 5071, 5072, 5073, 1, 5054, 1, 5055, + 3371, 3373, 5056, 5057, 5058, 5059, 5060, 5061, + 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, + 5070, 5071, 5072, 5073, 1, 1, 5054, 1, + 5055, 3371, 3373, 5056, 5057, 5058, 5059, 5060, + 5061, 5062, 5063, 5064, 5065, 5066, 5067, 5068, + 5069, 5070, 5071, 5072, 5073, 1, 1, 1, + 5054, 1, 5055, 3371, 3373, 5056, 5057, 5058, + 5059, 5060, 5061, 5062, 5063, 5064, 5065, 5066, + 5067, 5068, 5069, 5070, 5071, 5072, 5073, 1, + 1, 5054, 5055, 3371, 3373, 5056, 5057, 5058, + 5059, 5060, 5061, 5062, 5063, 5064, 5065, 5066, + 5067, 5068, 5069, 5070, 5071, 5072, 5073, 1, + 1, 5054, 1, 5055, 3371, 3373, 5056, 5057, + 5058, 5059, 5060, 5061, 5062, 5063, 5064, 5065, + 5066, 5067, 5068, 5069, 5070, 5071, 5072, 5073, + 5054, 5055, 3371, 3373, 5056, 5057, 5058, 5059, + 5060, 5061, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5073, 1, 1, + 5054, 5055, 3371, 3373, 5056, 5057, 5058, 5059, + 5060, 5061, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5073, 1, 5054, + 84, 85, 86, 87, 88, 5055, 3371, 3373, + 5056, 5057, 5058, 5059, 5060, 5061, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5073, 5054, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 100, 104, 105, 106, 5055, 3371, + 3373, 5056, 5057, 5058, 5059, 5060, 5061, 5062, + 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, + 5071, 5072, 5073, 5054, 107, 108, 109, 110, + 5055, 3371, 3373, 5056, 5057, 5058, 5059, 5060, + 5061, 5062, 5063, 5064, 5065, 5066, 5067, 5068, + 5069, 5070, 5071, 5072, 5073, 5054, 111, 5055, + 3371, 3373, 5056, 5057, 5058, 5059, 5060, 5061, + 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, + 5070, 5071, 5072, 5073, 5054, 112, 113, 114, + 115, 116, 117, 5055, 3371, 3373, 5056, 5057, + 5058, 5059, 5060, 5061, 5062, 5063, 5064, 5065, + 5066, 5067, 5068, 5069, 5070, 5071, 5072, 5073, + 5054, 118, 5055, 3371, 3373, 5056, 5057, 5058, + 5059, 5060, 5061, 5062, 5063, 5064, 5065, 5066, + 5067, 5068, 5069, 5070, 5071, 5072, 5073, 5054, + 120, 121, 122, 124, 5055, 3371, 3373, 5056, + 5057, 5058, 5059, 5060, 5061, 5062, 5063, 5064, + 5065, 5066, 5067, 5068, 5069, 5070, 5071, 5072, + 5073, 123, 5054, 5238, 4499, 3371, 5077, 5078, + 5079, 5080, 5081, 5082, 5083, 5084, 5085, 5086, + 5087, 5088, 5089, 5090, 5091, 5092, 5093, 5094, + 5095, 5096, 5097, 3372, 5077, 5078, 5079, 5080, + 5081, 5082, 5083, 5084, 5085, 5086, 5087, 5088, + 5089, 5090, 5091, 5092, 5093, 5094, 5095, 5096, + 5097, 3372, 5053, 4500, 122, 124, 4501, 4502, + 4503, 4504, 4505, 4506, 4507, 4508, 4509, 4510, + 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, + 4499, 3372, 153, 274, 275, 153, 1549, 5239, + 5240, 5241, 280, 281, 282, 5242, 284, 5243, + 5244, 5245, 5246, 5247, 5248, 5249, 5250, 2465, + 5251, 295, 296, 152, 5252, 3196, 5253, 5254, + 5255, 5256, 5257, 5258, 5259, 5260, 5261, 5262, + 5263, 5264, 5265, 5266, 5267, 5268, 5269, 5270, + 5271, 5272, 5273, 151, 3021, 4499, 181, 181, + 181, 571, 5274, 150, 152, 153, 4564, 4211, + 5275, 4566, 158, 5276, 160, 161, 5277, 5278, + 5279, 5280, 5281, 5282, 5283, 5284, 5285, 5286, + 5287, 5288, 5289, 5290, 5021, 5291, 5292, 5293, + 421, 148, 148, 151, 5020, 5002, 181, 181, + 181, 571, 5003, 150, 152, 153, 4564, 3196, + 5004, 4566, 158, 5005, 160, 161, 5006, 5007, + 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, + 5016, 5017, 5018, 5019, 5021, 5022, 5023, 5024, + 421, 148, 148, 1, 1, 1, 1, 151, + 5020, 5002, 181, 181, 181, 571, 5003, 150, + 152, 153, 4564, 3196, 5004, 4566, 158, 5005, + 160, 161, 5006, 5007, 5008, 5009, 5010, 5011, + 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, + 5021, 5022, 5023, 5024, 421, 148, 148, 1, + 151, 5020, 5002, 181, 181, 181, 571, 5294, + 4805, 4807, 4808, 4809, 5295, 5296, 4811, 4812, + 5297, 4814, 4815, 5298, 5299, 5300, 5301, 5302, + 5303, 5304, 5305, 5306, 5307, 5308, 5309, 5310, + 5311, 5313, 5314, 5315, 5316, 421, 148, 148, + 1, 4806, 1, 5312, 1, 5002, 148, 2984, + 148, 181, 148, 4500, 122, 124, 4501, 4502, + 4503, 4504, 4505, 4506, 4507, 4508, 4509, 4510, + 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, + 4499, 5317, 5318, 5319, 5320, 5321, 5322, 5323, + 5324, 5325, 5326, 5327, 5328, 5329, 5330, 5331, + 5332, 5333, 5334, 5335, 5336, 5337, 2984, 4499, + 181, 181, 181, 571, 1, 5003, 150, 152, + 153, 4564, 3196, 5004, 4566, 158, 5005, 160, + 161, 5006, 5007, 5008, 5009, 5010, 5011, 5012, + 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5021, + 5022, 5023, 5024, 421, 148, 148, 151, 5020, + 5002, 181, 181, 181, 571, 5294, 4805, 4807, + 4808, 4809, 5295, 5296, 4811, 4812, 5297, 4814, + 4815, 5298, 5299, 5300, 5301, 5302, 5303, 5304, + 5305, 5306, 5307, 5308, 5309, 5310, 5311, 5313, + 5314, 5315, 5316, 5002, 421, 5002, 148, 5002, + 148, 5002, 4806, 5312, 1, 4499, 4499, 4500, + 122, 124, 4501, 4502, 4503, 4504, 4505, 4506, + 4507, 4508, 4509, 4510, 4511, 4512, 4513, 4514, + 4515, 4516, 4517, 4518, 148, 4499, 148, 4499, + 2984, 4499, 4783, 4784, 4785, 4786, 4787, 4788, + 4789, 4790, 4791, 4792, 4793, 4794, 4795, 4796, + 4797, 4798, 4799, 4800, 4801, 4802, 4803, 2984, + 148, 4499, 4500, 122, 124, 4501, 4502, 4503, + 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, + 4512, 4513, 4514, 4515, 4516, 4517, 4518, 4499, + 2984, 4499, 148, 2984, 148, 181, 4500, 122, + 124, 4501, 4502, 4503, 4504, 4505, 4506, 4507, + 4508, 4509, 4510, 4511, 4512, 4513, 4514, 4515, + 4516, 4517, 4518, 2984, 2984, 572, 572, 4499, + 2984, 4500, 122, 124, 4501, 4502, 4503, 4504, + 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, + 4513, 4514, 4515, 4516, 4517, 4518, 2984, 2984, + 148, 4499, 421, 2984, 4783, 4784, 4785, 4786, + 4787, 4788, 4789, 4790, 4791, 4792, 4793, 4794, + 4795, 4796, 4797, 4798, 4799, 4800, 4801, 4802, + 4803, 148, 2984, 421, 148, 4499, 4499, 4499, + 4499, 4500, 122, 124, 4501, 4502, 4503, 4504, + 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, + 4513, 4514, 4515, 4516, 4517, 4518, 2984, 2984, + 421, 4499, 4499, 148, 148, 5317, 5318, 5319, + 5320, 5321, 5322, 5323, 5324, 5325, 5326, 5327, + 5328, 5329, 5330, 5331, 5332, 5333, 5334, 5335, + 5336, 5337, 2984, 148, 2984, 4499, 2518, 2518, + 2518, 2774, 5003, 150, 152, 153, 4564, 3196, + 5004, 4566, 158, 5005, 160, 161, 5006, 5007, + 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, + 5016, 5017, 5018, 5019, 5021, 5022, 5023, 5024, + 2646, 2008, 2008, 5002, 151, 5002, 5020, 5002, + 1, 181, 181, 181, 571, 5003, 150, 152, + 153, 4564, 3196, 5004, 4566, 158, 5005, 160, + 161, 5006, 5007, 5008, 5009, 5010, 5011, 5012, + 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5021, + 5022, 5023, 5024, 421, 148, 148, 1, 151, + 5020, 5002, 181, 181, 181, 571, 1, 5003, + 150, 152, 153, 4564, 3196, 5004, 4566, 158, + 5005, 160, 161, 5006, 5007, 5008, 5009, 5010, + 5011, 5012, 5013, 5014, 5015, 5016, 5017, 5018, + 5019, 5021, 5022, 5023, 5024, 421, 148, 148, + 1, 151, 5020, 5002, 181, 181, 181, 571, + 1, 5003, 150, 152, 153, 4564, 3196, 5004, + 4566, 158, 5005, 160, 161, 5006, 5007, 5008, + 5009, 5010, 5011, 5012, 5013, 5014, 5015, 5016, + 5017, 5018, 5019, 5021, 5022, 5023, 5024, 421, + 148, 148, 1, 1, 151, 5020, 5002, 181, + 181, 181, 571, 1, 5003, 150, 152, 153, + 4564, 3196, 5004, 4566, 158, 5005, 160, 161, + 5006, 5007, 5008, 5009, 5010, 5011, 5012, 5013, + 5014, 5015, 5016, 5017, 5018, 5019, 5021, 5022, + 5023, 5024, 421, 148, 148, 1, 1, 151, + 5020, 5002, 181, 181, 181, 571, 1, 5003, + 150, 152, 153, 4564, 3196, 5004, 4566, 158, + 5005, 160, 161, 5006, 5007, 5008, 5009, 5010, + 5011, 5012, 5013, 5014, 5015, 5016, 5017, 5018, + 5019, 5021, 5022, 5023, 5024, 421, 148, 148, + 1, 151, 5020, 5002, 181, 181, 181, 571, + 5003, 150, 152, 153, 4564, 3196, 5004, 4566, + 158, 5005, 160, 161, 5006, 5007, 5008, 5009, + 5010, 5011, 5012, 5013, 5014, 5015, 5016, 5017, + 5018, 5019, 5021, 5022, 5023, 5024, 421, 148, + 148, 1, 1, 1, 1, 151, 5020, 5002, + 181, 181, 181, 571, 1, 1, 5294, 4805, + 4807, 4808, 4809, 5295, 5296, 4811, 4812, 5297, + 4814, 4815, 5298, 5299, 5300, 5301, 5302, 5303, + 5304, 5305, 5306, 5307, 5308, 5309, 5310, 5311, + 5313, 5314, 5315, 5316, 421, 148, 148, 1, + 4806, 1, 5312, 1, 5002, 4783, 4784, 4785, + 4786, 4787, 4788, 4789, 4790, 4791, 4792, 4793, + 4794, 4795, 4796, 4797, 4798, 4799, 4800, 4801, + 4802, 4803, 4499, 148, 2984, 4500, 122, 124, + 4501, 4502, 4503, 4504, 4505, 4506, 4507, 4508, + 4509, 4510, 4511, 4512, 4513, 4514, 4515, 4516, + 4517, 4518, 2984, 4499, 148, 148, 4500, 122, + 124, 4501, 4502, 4503, 4504, 4505, 4506, 4507, + 4508, 4509, 4510, 4511, 4512, 4513, 4514, 4515, + 4516, 4517, 4518, 421, 148, 2984, 148, 4499, + 2986, 2987, 184, 2988, 2989, 2990, 2991, 2992, + 2993, 2994, 2995, 2996, 2997, 2998, 2999, 3000, + 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, + 3009, 3010, 3011, 3012, 3013, 3014, 3015, 3016, + 4500, 122, 124, 4501, 4502, 4503, 4504, 4505, + 4506, 4507, 4508, 4509, 4510, 4511, 4512, 4513, + 4514, 4515, 4516, 4517, 4518, 4499, 3017, 3018, + 3019, 217, 3020, 3022, 218, 219, 220, 221, + 3023, 223, 224, 225, 226, 227, 228, 3024, + 3025, 3026, 3027, 3028, 234, 3029, 236, 3030, + 483, 484, 3031, 3032, 3033, 3034, 3035, 3036, + 3037, 3038, 646, 3039, 151, 152, 3040, 249, + 250, 251, 252, 4500, 122, 124, 4501, 4502, + 4503, 4504, 4505, 4506, 4507, 4508, 4509, 4510, + 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, + 3021, 151, 153, 151, 4499, 3041, 3042, 255, + 3043, 257, 258, 259, 260, 261, 262, 263, + 151, 3044, 265, 3045, 267, 3046, 269, 4500, + 122, 124, 4501, 4502, 4503, 4504, 4505, 4506, + 4507, 4508, 4509, 4510, 4511, 4512, 4513, 4514, + 4515, 4516, 4517, 4518, 4499, 3047, 3048, 3049, + 3021, 3050, 3051, 3052, 4500, 122, 124, 4501, + 4502, 4503, 4504, 4505, 4506, 4507, 4508, 4509, + 4510, 4511, 4512, 4513, 4514, 4515, 4516, 4517, + 4518, 4499, 153, 274, 275, 153, 657, 3181, + 3182, 3183, 280, 281, 282, 3184, 284, 3185, + 3186, 3187, 3188, 3189, 3190, 3191, 3192, 3193, + 3194, 295, 296, 152, 3195, 3196, 5253, 5254, + 5255, 5256, 5257, 5258, 5259, 5260, 5261, 5262, + 5263, 5264, 5265, 5266, 5267, 5268, 5269, 5270, + 5271, 5272, 5273, 151, 3021, 4499, 181, 181, + 181, 571, 5003, 150, 152, 153, 4564, 3196, + 5004, 4566, 158, 5005, 160, 161, 5006, 5007, + 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, + 5016, 5017, 5018, 5019, 5021, 5022, 5023, 5024, + 421, 148, 148, 1, 151, 5020, 5002, 181, + 181, 181, 571, 5003, 150, 152, 153, 4564, + 3196, 5004, 4566, 158, 5005, 160, 161, 5006, + 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, + 5015, 5016, 5017, 5018, 5019, 5021, 5022, 5023, + 5024, 421, 148, 148, 1, 1, 1, 1, + 1, 151, 5020, 5002, 181, 181, 181, 571, + 1, 5003, 150, 152, 153, 4564, 3196, 5004, + 4566, 158, 5005, 160, 161, 5006, 5007, 5008, + 5009, 5010, 5011, 5012, 5013, 5014, 5015, 5016, + 5017, 5018, 5019, 5021, 5022, 5023, 5024, 421, + 148, 148, 1, 1, 151, 5020, 5002, 181, + 181, 181, 571, 5003, 150, 152, 153, 4564, + 3196, 5004, 4566, 158, 5005, 160, 161, 5006, + 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, + 5015, 5016, 5017, 5018, 5019, 5021, 5022, 5023, + 5024, 421, 148, 148, 1, 151, 5020, 5002, + 181, 181, 181, 571, 5003, 150, 152, 153, + 4564, 3196, 5004, 4566, 158, 5005, 160, 161, + 5006, 5007, 5008, 5009, 5010, 5011, 5012, 5013, + 5014, 5015, 5016, 5017, 5018, 5019, 5021, 5022, + 5023, 5024, 421, 148, 148, 1, 1, 151, + 5020, 5002, 181, 181, 181, 571, 5003, 150, + 152, 153, 4564, 3196, 5004, 4566, 158, 5005, + 160, 161, 5006, 5007, 5008, 5009, 5010, 5011, + 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, + 5021, 5022, 5023, 5024, 421, 148, 148, 1, + 1, 151, 5020, 5002, 181, 181, 181, 571, + 5294, 4805, 4807, 4808, 4809, 5295, 5296, 4811, + 4812, 5297, 4814, 4815, 5298, 5299, 5300, 5301, + 5302, 5303, 5304, 5305, 5306, 5307, 5308, 5309, + 5310, 5311, 5313, 5314, 5315, 5316, 421, 148, + 148, 1, 4806, 1, 5312, 1, 5002, 5253, + 5254, 5255, 5256, 5257, 5258, 5259, 5260, 5261, + 5262, 5263, 5264, 5265, 5266, 5267, 5268, 5269, + 5270, 5271, 5272, 5273, 3021, 181, 181, 181, + 571, 5003, 150, 152, 153, 4564, 3196, 5004, + 4566, 158, 5005, 160, 161, 5006, 5007, 5008, + 5009, 5010, 5011, 5012, 5013, 5014, 5015, 5016, + 5017, 5018, 5019, 5021, 5022, 5023, 5024, 421, + 148, 148, 1, 1, 151, 5020, 5002, 181, + 181, 181, 571, 5003, 150, 152, 153, 4564, + 3196, 5004, 4566, 158, 5005, 160, 161, 5006, + 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, + 5015, 5016, 5017, 5018, 5019, 5021, 5022, 5023, + 5024, 421, 148, 148, 1, 1, 151, 5020, + 5002, 181, 181, 181, 571, 5003, 150, 152, + 153, 4564, 3196, 5004, 4566, 158, 5005, 160, + 161, 5006, 5007, 5008, 5009, 5010, 5011, 5012, + 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5021, + 5022, 5023, 5024, 421, 148, 148, 1, 151, + 5020, 5002, 181, 181, 181, 571, 5003, 150, + 152, 153, 4564, 3196, 5004, 4566, 158, 5005, + 160, 161, 5006, 5007, 5008, 5009, 5010, 5011, + 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, + 5021, 5022, 5023, 5024, 421, 148, 148, 1, + 151, 5020, 5002, 181, 181, 181, 571, 1, + 5003, 150, 152, 153, 4564, 3196, 5004, 4566, + 158, 5005, 160, 161, 5006, 5007, 5008, 5009, + 5010, 5011, 5012, 5013, 5014, 5015, 5016, 5017, + 5018, 5019, 5021, 5022, 5023, 5024, 421, 148, + 148, 151, 5020, 5002, 181, 181, 181, 571, + 5003, 150, 152, 153, 4564, 3196, 5004, 4566, + 158, 5005, 160, 161, 5006, 5007, 5008, 5009, + 5010, 5011, 5012, 5013, 5014, 5015, 5016, 5017, + 5018, 5019, 5021, 5022, 5023, 5024, 421, 148, + 148, 1, 151, 5020, 5002, 181, 181, 181, + 571, 5003, 150, 152, 153, 4564, 3196, 5004, + 4566, 158, 5005, 160, 161, 5006, 5007, 5008, + 5009, 5010, 5011, 5012, 5013, 5014, 5015, 5016, + 5017, 5018, 5019, 5021, 5022, 5023, 5024, 421, + 148, 148, 1, 151, 5020, 5002, 181, 181, + 181, 571, 5003, 150, 152, 153, 4564, 3196, + 5004, 4566, 158, 5005, 160, 161, 5006, 5007, + 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, + 5016, 5017, 5018, 5019, 5021, 5022, 5023, 5024, + 421, 148, 148, 1, 151, 5020, 5002, 181, + 181, 181, 571, 5003, 150, 152, 153, 4564, + 3196, 5004, 4566, 158, 5005, 160, 161, 5006, + 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, + 5015, 5016, 5017, 5018, 5019, 5021, 5022, 5023, + 5024, 421, 148, 148, 1, 1, 151, 5020, + 5002, 181, 181, 181, 571, 5003, 150, 152, + 153, 4564, 3196, 5004, 4566, 158, 5005, 160, + 161, 5006, 5007, 5008, 5009, 5010, 5011, 5012, + 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5021, + 5022, 5023, 5024, 421, 148, 148, 1, 151, + 5020, 5002, 181, 181, 181, 571, 5003, 150, + 152, 153, 4564, 3196, 5004, 4566, 158, 5005, + 160, 161, 5006, 5007, 5008, 5009, 5010, 5011, + 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, + 5021, 5022, 5023, 5024, 421, 148, 148, 1, + 151, 5020, 5002, 181, 181, 181, 571, 1, + 1, 1, 5003, 150, 152, 153, 4564, 3196, + 5004, 4566, 158, 5005, 160, 161, 5006, 5007, + 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, + 5016, 5017, 5018, 5019, 5021, 5022, 5023, 5024, + 421, 148, 148, 1, 151, 5020, 5002, 181, + 181, 181, 571, 5294, 4805, 4807, 4808, 4809, + 5295, 5296, 4811, 4812, 5297, 4814, 4815, 5298, + 5299, 5300, 5301, 5302, 5303, 5304, 5305, 5306, + 5307, 5308, 5309, 5310, 5311, 5313, 5314, 5315, + 5316, 421, 148, 148, 1, 1, 4806, 1, + 5312, 1, 5002, 3197, 3198, 4500, 122, 124, + 4501, 4502, 4503, 4504, 4505, 4506, 4507, 4508, + 4509, 4510, 4511, 4512, 4513, 4514, 4515, 4516, + 4517, 4518, 4499, 3021, 3199, 674, 302, 303, + 304, 305, 306, 307, 3200, 932, 3201, 934, + 312, 3202, 3203, 4500, 122, 124, 4501, 4502, + 4503, 4504, 4505, 4506, 4507, 4508, 4509, 4510, + 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, + 151, 4499, 3204, 3205, 317, 318, 319, 3206, + 3207, 3208, 3209, 324, 4500, 122, 124, 4501, + 4502, 4503, 4504, 4505, 4506, 4507, 4508, 4509, + 4510, 4511, 4512, 4513, 4514, 4515, 4516, 4517, + 4518, 4499, 3245, 4500, 122, 124, 4501, 4502, + 4503, 4504, 4505, 4506, 4507, 4508, 4509, 4510, + 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, + 4499, 2518, 2518, 2518, 2774, 5003, 150, 152, + 153, 4564, 3196, 5004, 4566, 158, 5005, 160, + 161, 5006, 5007, 5008, 5009, 5010, 5011, 5012, + 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5021, + 5022, 5023, 5024, 2646, 2008, 2008, 5002, 5002, + 151, 5002, 5020, 5002, 1, 181, 181, 181, + 571, 5003, 150, 152, 153, 4564, 3196, 5004, + 4566, 158, 5005, 160, 161, 5006, 5007, 5008, + 5009, 5010, 5011, 5012, 5013, 5014, 5015, 5016, + 5017, 5018, 5019, 5021, 5022, 5023, 5024, 421, + 148, 148, 1, 151, 5020, 5002, 181, 181, + 181, 571, 5003, 150, 152, 153, 4564, 3196, + 5004, 4566, 158, 5005, 160, 161, 5006, 5007, + 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, + 5016, 5017, 5018, 5019, 5021, 5022, 5023, 5024, + 421, 148, 148, 1, 151, 5020, 5002, 181, + 181, 181, 571, 5294, 4805, 4807, 4808, 4809, + 5295, 5296, 4811, 4812, 5297, 4814, 4815, 5298, + 5299, 5300, 5301, 5302, 5303, 5304, 5305, 5306, + 5307, 5308, 5309, 5310, 5311, 5313, 5314, 5315, + 5316, 421, 148, 148, 1, 1, 4806, 1, + 5312, 1, 5002, 2518, 2518, 2518, 2774, 1, + 5003, 150, 152, 153, 4564, 3196, 5004, 4566, + 158, 5005, 160, 161, 5006, 5007, 5008, 5009, + 5010, 5011, 5012, 5013, 5014, 5015, 5016, 5017, + 5018, 5019, 5021, 5022, 5023, 5024, 1, 2646, + 1, 2008, 1, 2008, 1, 151, 5020, 5002, + 181, 181, 181, 571, 5003, 150, 152, 153, + 4564, 3196, 5004, 4566, 158, 5005, 160, 161, + 5006, 5007, 5008, 5009, 5010, 5011, 5012, 5013, + 5014, 5015, 5016, 5017, 5018, 5019, 5021, 5022, + 5023, 5024, 421, 148, 148, 1, 151, 5020, + 5002, 181, 181, 181, 571, 1, 5003, 150, + 152, 153, 4564, 3196, 5004, 4566, 158, 5005, + 160, 161, 5006, 5007, 5008, 5009, 5010, 5011, + 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, + 5021, 5022, 5023, 5024, 421, 148, 148, 1, + 1, 151, 5020, 5002, 181, 181, 181, 571, + 1, 5003, 150, 152, 153, 4564, 3196, 5004, + 4566, 158, 5005, 160, 161, 5006, 5007, 5008, + 5009, 5010, 5011, 5012, 5013, 5014, 5015, 5016, + 5017, 5018, 5019, 5021, 5022, 5023, 5024, 421, + 148, 148, 1, 1, 1, 151, 5020, 5002, + 181, 181, 181, 571, 1, 5003, 150, 152, + 153, 4564, 3196, 5004, 4566, 158, 5005, 160, + 161, 5006, 5007, 5008, 5009, 5010, 5011, 5012, + 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5021, + 5022, 5023, 5024, 421, 148, 148, 1, 1, + 151, 5020, 5002, 181, 181, 181, 571, 5003, + 150, 152, 153, 4564, 3196, 5004, 4566, 158, + 5005, 160, 161, 5006, 5007, 5008, 5009, 5010, + 5011, 5012, 5013, 5014, 5015, 5016, 5017, 5018, + 5019, 5021, 5022, 5023, 5024, 421, 148, 148, + 1, 1, 151, 5020, 5002, 181, 181, 181, + 571, 1, 5003, 150, 152, 153, 4564, 3196, + 5004, 4566, 158, 5005, 160, 161, 5006, 5007, + 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, + 5016, 5017, 5018, 5019, 5021, 5022, 5023, 5024, + 421, 148, 148, 151, 5020, 5002, 181, 181, + 181, 571, 5003, 150, 152, 153, 4564, 3196, + 5004, 4566, 158, 5005, 160, 161, 5006, 5007, + 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, + 5016, 5017, 5018, 5019, 5021, 5022, 5023, 5024, + 421, 148, 148, 1, 1, 151, 5020, 5002, + 181, 181, 181, 571, 5003, 150, 152, 153, + 4564, 3196, 5004, 4566, 158, 5005, 160, 161, + 5006, 5007, 5008, 5009, 5010, 5011, 5012, 5013, + 5014, 5015, 5016, 5017, 5018, 5019, 5021, 5022, + 5023, 5024, 421, 148, 148, 1, 151, 5020, + 5002, 181, 181, 181, 571, 84, 85, 86, + 87, 88, 5003, 150, 152, 153, 4564, 3196, + 5004, 4566, 158, 5005, 160, 161, 5006, 5007, + 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, + 5016, 5017, 5018, 5019, 5021, 5022, 5023, 5024, + 421, 148, 148, 151, 5020, 5002, 181, 181, + 181, 571, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, + 103, 100, 104, 105, 106, 5003, 150, 152, + 153, 4564, 3196, 5004, 4566, 158, 5005, 160, + 161, 5006, 5007, 5008, 5009, 5010, 5011, 5012, + 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5021, + 5022, 5023, 5024, 421, 148, 148, 151, 5020, + 5002, 181, 181, 181, 571, 107, 108, 109, + 110, 5003, 150, 152, 153, 4564, 3196, 5004, + 4566, 158, 5005, 160, 161, 5006, 5007, 5008, + 5009, 5010, 5011, 5012, 5013, 5014, 5015, 5016, + 5017, 5018, 5019, 5021, 5022, 5023, 5024, 421, + 148, 148, 151, 5020, 5002, 181, 181, 181, + 571, 111, 5003, 150, 152, 153, 4564, 3196, + 5004, 4566, 158, 5005, 160, 161, 5006, 5007, + 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, + 5016, 5017, 5018, 5019, 5021, 5022, 5023, 5024, + 421, 148, 148, 151, 5020, 5002, 181, 181, + 181, 571, 112, 113, 114, 115, 116, 117, + 5003, 150, 152, 153, 4564, 3196, 5004, 4566, + 158, 5005, 160, 161, 5006, 5007, 5008, 5009, + 5010, 5011, 5012, 5013, 5014, 5015, 5016, 5017, + 5018, 5019, 5021, 5022, 5023, 5024, 421, 148, + 148, 151, 5020, 5002, 181, 181, 181, 571, + 118, 5003, 150, 152, 153, 4564, 3196, 5004, + 4566, 158, 5005, 160, 161, 5006, 5007, 5008, + 5009, 5010, 5011, 5012, 5013, 5014, 5015, 5016, + 5017, 5018, 5019, 5021, 5022, 5023, 5024, 421, + 148, 148, 151, 5020, 5002, 181, 181, 181, + 571, 120, 121, 122, 124, 5003, 150, 152, + 153, 4564, 3196, 5004, 4566, 158, 5005, 160, + 161, 5006, 5007, 5008, 5009, 5010, 5011, 5012, + 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5021, + 5022, 5023, 5024, 421, 148, 148, 123, 151, + 5020, 5002, 2518, 2518, 2518, 2774, 5003, 150, + 152, 153, 4564, 3196, 5004, 4566, 158, 5005, + 160, 161, 5006, 5007, 5008, 5009, 5010, 5011, + 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, + 5021, 5022, 5023, 5024, 2646, 2008, 2008, 5002, + 5002, 151, 5002, 5020, 5002, 1, 181, 181, + 181, 571, 5003, 150, 152, 153, 4564, 3196, + 5004, 4566, 158, 5005, 160, 161, 5006, 5007, + 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, + 5016, 5017, 5018, 5019, 5021, 5022, 5023, 5024, + 421, 148, 148, 1, 151, 5020, 5002, 181, + 181, 181, 571, 1, 5003, 150, 152, 153, + 4564, 3196, 5004, 4566, 158, 5005, 160, 161, + 5006, 5007, 5008, 5009, 5010, 5011, 5012, 5013, + 5014, 5015, 5016, 5017, 5018, 5019, 5021, 5022, + 5023, 5024, 421, 148, 148, 151, 5020, 5002, + 181, 181, 181, 571, 5003, 150, 152, 153, + 4564, 3196, 5004, 4566, 158, 5005, 160, 161, + 5006, 5007, 5008, 5009, 5010, 5011, 5012, 5013, + 5014, 5015, 5016, 5017, 5018, 5019, 5021, 5022, + 5023, 5024, 421, 148, 148, 1, 1, 151, + 5020, 5002, 181, 181, 181, 571, 5003, 150, + 152, 153, 4564, 3196, 5004, 4566, 158, 5005, + 160, 161, 5006, 5007, 5008, 5009, 5010, 5011, + 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, + 5021, 5022, 5023, 5024, 421, 148, 148, 1, + 151, 5020, 5002, 181, 181, 181, 571, 1, + 5003, 150, 152, 153, 4564, 3196, 5004, 4566, + 158, 5005, 160, 161, 5006, 5007, 5008, 5009, + 5010, 5011, 5012, 5013, 5014, 5015, 5016, 5017, + 5018, 5019, 5021, 5022, 5023, 5024, 421, 148, + 148, 1, 1, 151, 5020, 5002, 181, 181, + 181, 571, 5003, 150, 152, 153, 4564, 3196, + 5004, 4566, 158, 5005, 160, 161, 5006, 5007, + 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, + 5016, 5017, 5018, 5019, 5021, 5022, 5023, 5024, + 421, 148, 148, 1, 151, 5020, 5002, 181, + 181, 181, 571, 5294, 4805, 4807, 4808, 4809, + 5295, 5296, 4811, 4812, 5297, 4814, 4815, 5298, + 5299, 5300, 5301, 5302, 5303, 5304, 5305, 5306, + 5307, 5308, 5309, 5310, 5311, 5313, 5314, 5315, + 5316, 421, 148, 148, 1, 1, 4806, 1, + 5312, 1, 5002, 2518, 2518, 2518, 2774, 5003, + 150, 152, 153, 4564, 3196, 5004, 4566, 158, + 5005, 160, 161, 5006, 5007, 5008, 5009, 5010, + 5011, 5012, 5013, 5014, 5015, 5016, 5017, 5018, + 5019, 5021, 5022, 5023, 5024, 2646, 2008, 2008, + 5002, 5002, 151, 5002, 5020, 5002, 1, 181, + 181, 181, 571, 5003, 150, 152, 153, 4564, + 3196, 5004, 4566, 158, 5005, 160, 161, 5006, + 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, + 5015, 5016, 5017, 5018, 5019, 5021, 5022, 5023, + 5024, 421, 148, 148, 1, 1, 151, 5020, + 5002, 181, 181, 181, 571, 5003, 150, 152, + 153, 4564, 3196, 5004, 4566, 158, 5005, 160, + 161, 5006, 5007, 5008, 5009, 5010, 5011, 5012, + 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5021, + 5022, 5023, 5024, 421, 148, 148, 1, 151, + 5020, 5002, 181, 181, 181, 571, 5003, 150, + 152, 153, 4564, 3196, 5004, 4566, 158, 5005, + 160, 161, 5006, 5007, 5008, 5009, 5010, 5011, + 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, + 5021, 5022, 5023, 5024, 421, 148, 148, 1, + 151, 5020, 5002, 181, 181, 181, 571, 1, + 5003, 150, 152, 153, 4564, 3196, 5004, 4566, + 158, 5005, 160, 161, 5006, 5007, 5008, 5009, + 5010, 5011, 5012, 5013, 5014, 5015, 5016, 5017, + 5018, 5019, 5021, 5022, 5023, 5024, 421, 148, + 148, 1, 1, 1, 1, 151, 5020, 5002, + 181, 181, 181, 571, 5003, 150, 152, 153, + 4564, 3196, 5004, 4566, 158, 5005, 160, 161, + 5006, 5007, 5008, 5009, 5010, 5011, 5012, 5013, + 5014, 5015, 5016, 5017, 5018, 5019, 5021, 5022, + 5023, 5024, 421, 148, 148, 1, 1, 151, + 5020, 5002, 2518, 2518, 2518, 2774, 5003, 150, + 152, 153, 4564, 3196, 5004, 4566, 158, 5005, + 160, 161, 5006, 5007, 5008, 5009, 5010, 5011, + 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, + 5021, 5022, 5023, 5024, 1, 2646, 1, 2008, + 1, 2008, 1, 151, 5020, 5002, 181, 181, + 181, 571, 5003, 150, 152, 153, 4564, 3196, + 5004, 4566, 158, 5005, 160, 161, 5006, 5007, + 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, + 5016, 5017, 5018, 5019, 5021, 5022, 5023, 5024, + 421, 148, 148, 1, 151, 5020, 5002, 181, + 181, 181, 571, 5003, 150, 152, 153, 4564, + 3196, 5004, 4566, 158, 5005, 160, 161, 5006, + 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, + 5015, 5016, 5017, 5018, 5019, 5021, 5022, 5023, + 5024, 421, 148, 148, 1, 151, 5020, 5002, + 181, 181, 181, 571, 3, 4, 5, 6, + 7, 9, 10, 11, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 5003, 150, + 152, 153, 4564, 3196, 5004, 4566, 158, 5005, + 160, 161, 5006, 5007, 5008, 5009, 5010, 5011, + 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, + 5021, 5022, 5023, 5024, 421, 148, 148, 8, + 12, 151, 5020, 5002, 181, 181, 181, 571, + 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 5003, 150, 152, + 153, 4564, 3196, 5004, 4566, 158, 5005, 160, + 161, 5006, 5007, 5008, 5009, 5010, 5011, 5012, + 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5021, + 5022, 5023, 5024, 421, 148, 148, 151, 5020, + 5002, 181, 181, 181, 571, 52, 53, 54, + 55, 56, 57, 5003, 150, 152, 153, 4564, + 3196, 5004, 4566, 158, 5005, 160, 161, 5006, + 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, + 5015, 5016, 5017, 5018, 5019, 5021, 5022, 5023, + 5024, 421, 148, 148, 151, 5020, 5002, 181, + 181, 181, 571, 58, 59, 5003, 150, 152, + 153, 4564, 3196, 5004, 4566, 158, 5005, 160, + 161, 5006, 5007, 5008, 5009, 5010, 5011, 5012, + 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5021, + 5022, 5023, 5024, 421, 148, 148, 151, 5020, + 5002, 181, 181, 181, 571, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 5003, 150, 152, 153, + 4564, 3196, 5004, 4566, 158, 5005, 160, 161, + 5006, 5007, 5008, 5009, 5010, 5011, 5012, 5013, + 5014, 5015, 5016, 5017, 5018, 5019, 5021, 5022, + 5023, 5024, 421, 148, 148, 151, 5020, 5002, + 181, 181, 181, 571, 75, 76, 56, 61, + 77, 5003, 150, 152, 153, 4564, 3196, 5004, + 4566, 158, 5005, 160, 161, 5006, 5007, 5008, + 5009, 5010, 5011, 5012, 5013, 5014, 5015, 5016, + 5017, 5018, 5019, 5021, 5022, 5023, 5024, 421, + 148, 148, 151, 5020, 5002, 181, 181, 181, + 571, 78, 79, 80, 81, 82, 83, 5003, + 150, 152, 153, 4564, 3196, 5004, 4566, 158, + 5005, 160, 161, 5006, 5007, 5008, 5009, 5010, + 5011, 5012, 5013, 5014, 5015, 5016, 5017, 5018, + 5019, 5021, 5022, 5023, 5024, 421, 148, 148, + 151, 5020, 5002, 181, 181, 181, 571, 119, + 5003, 150, 152, 153, 4564, 3196, 5004, 4566, + 158, 5005, 160, 161, 5006, 5007, 5008, 5009, + 5010, 5011, 5012, 5013, 5014, 5015, 5016, 5017, + 5018, 5019, 5021, 5022, 5023, 5024, 421, 148, + 148, 151, 5020, 5002, 2518, 2518, 2518, 2774, + 5002, 5294, 4805, 4807, 4808, 4809, 5295, 5296, + 4811, 4812, 5297, 4814, 4815, 5298, 5299, 5300, + 5301, 5302, 5303, 5304, 5305, 5306, 5307, 5308, + 5309, 5310, 5311, 5313, 5314, 5315, 5316, 2646, + 2008, 2008, 5002, 4806, 5312, 1, 2518, 2518, + 2518, 2774, 5002, 5003, 150, 152, 153, 4564, + 3196, 5004, 4566, 158, 5005, 160, 161, 5006, + 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, + 5015, 5016, 5017, 5018, 5019, 5021, 5022, 5023, + 5024, 2646, 2008, 2008, 5002, 5002, 151, 5002, + 5020, 5002, 1, 181, 181, 181, 571, 1, + 5294, 4805, 4807, 4808, 4809, 5295, 5296, 4811, + 4812, 5297, 4814, 4815, 5298, 5299, 5300, 5301, + 5302, 5303, 5304, 5305, 5306, 5307, 5308, 5309, + 5310, 5311, 5313, 5314, 5315, 5316, 421, 148, + 148, 1, 1, 4806, 1, 5312, 1, 5002, + 2518, 2518, 2518, 2774, 5003, 150, 152, 153, + 4564, 3196, 5004, 4566, 158, 5005, 160, 161, + 5006, 5007, 5008, 5009, 5010, 5011, 5012, 5013, + 5014, 5015, 5016, 5017, 5018, 5019, 5021, 5022, + 5023, 5024, 2646, 2008, 2008, 5002, 5002, 5002, + 5002, 5002, 151, 5002, 5020, 5002, 1, 2518, + 2518, 2518, 2774, 1, 1, 5003, 150, 152, + 153, 4564, 3196, 5004, 4566, 158, 5005, 160, + 161, 5006, 5007, 5008, 5009, 5010, 5011, 5012, + 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5021, + 5022, 5023, 5024, 1, 2646, 1, 2008, 1, + 2008, 1, 1, 1, 1, 151, 5020, 5002, + 2518, 2518, 2518, 2774, 5002, 5002, 5003, 150, + 152, 153, 4564, 3196, 5004, 4566, 158, 5005, + 160, 161, 5006, 5007, 5008, 5009, 5010, 5011, + 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, + 5021, 5022, 5023, 5024, 2646, 2008, 2008, 5002, + 5002, 151, 5002, 5020, 5002, 1, 181, 181, + 181, 571, 1, 5003, 150, 152, 153, 4564, + 3196, 5004, 4566, 158, 5005, 160, 161, 5006, + 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, + 5015, 5016, 5017, 5018, 5019, 5021, 5022, 5023, + 5024, 421, 148, 148, 1, 1, 151, 5020, + 5002, 181, 181, 181, 571, 5003, 150, 152, + 153, 4564, 3196, 5004, 4566, 158, 5005, 160, + 161, 5006, 5007, 5008, 5009, 5010, 5011, 5012, + 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5021, + 5022, 5023, 5024, 421, 148, 148, 1, 1, + 1, 1, 1, 151, 5020, 5002, 181, 181, + 181, 571, 1, 5003, 150, 152, 153, 4564, + 3196, 5004, 4566, 158, 5005, 160, 161, 5006, + 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, + 5015, 5016, 5017, 5018, 5019, 5021, 5022, 5023, + 5024, 421, 148, 148, 1, 151, 5020, 5002, + 181, 181, 181, 571, 1, 5003, 150, 152, + 153, 4564, 3196, 5004, 4566, 158, 5005, 160, + 161, 5006, 5007, 5008, 5009, 5010, 5011, 5012, + 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5021, + 5022, 5023, 5024, 421, 148, 148, 1, 1, + 1, 151, 5020, 5002, 181, 181, 181, 571, + 5294, 4805, 4807, 4808, 4809, 5295, 5296, 4811, + 4812, 5297, 4814, 4815, 5298, 5299, 5300, 5301, + 5302, 5303, 5304, 5305, 5306, 5307, 5308, 5309, + 5310, 5311, 5313, 5314, 5315, 5316, 421, 148, + 148, 1, 1, 4806, 1, 5312, 1, 5002, + 2518, 2518, 2518, 2774, 5002, 5002, 5003, 150, + 152, 153, 4564, 3196, 5004, 4566, 158, 5005, + 160, 161, 5006, 5007, 5008, 5009, 5010, 5011, + 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, + 5021, 5022, 5023, 5024, 2646, 2008, 2008, 5002, + 5002, 5002, 151, 5002, 5020, 5002, 1, 181, + 181, 181, 571, 5003, 150, 152, 153, 4564, + 3196, 5004, 4566, 158, 5005, 160, 161, 5006, + 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, + 5015, 5016, 5017, 5018, 5019, 5021, 5022, 5023, + 5024, 421, 148, 148, 1, 1, 1, 1, + 1, 151, 5020, 5002, 181, 181, 181, 571, + 5294, 4805, 4807, 4808, 4809, 5295, 5296, 4811, + 4812, 5297, 4814, 4815, 5298, 5299, 5300, 5301, + 5302, 5303, 5304, 5305, 5306, 5307, 5308, 5309, + 5310, 5311, 5313, 5314, 5315, 5316, 421, 148, + 148, 1, 1, 4806, 1, 5312, 1, 5002, + 2518, 2518, 2518, 2774, 5002, 5002, 5003, 150, + 152, 153, 4564, 3196, 5004, 4566, 158, 5005, + 160, 161, 5006, 5007, 5008, 5009, 5010, 5011, + 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, + 5021, 5022, 5023, 5024, 2646, 2008, 2008, 5002, + 5002, 5002, 151, 5002, 5020, 5002, 1, 181, + 181, 181, 571, 5003, 150, 152, 153, 4564, + 3196, 5004, 4566, 158, 5005, 160, 161, 5006, + 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, + 5015, 5016, 5017, 5018, 5019, 5021, 5022, 5023, + 5024, 421, 148, 148, 1, 151, 5020, 5002, + 181, 181, 181, 571, 1, 1, 5003, 150, + 152, 153, 4564, 3196, 5004, 4566, 158, 5005, + 160, 161, 5006, 5007, 5008, 5009, 5010, 5011, + 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, + 5021, 5022, 5023, 5024, 421, 148, 148, 1, + 1, 1, 151, 5020, 5002, 181, 181, 181, + 571, 1, 5003, 150, 152, 153, 4564, 3196, + 5004, 4566, 158, 5005, 160, 161, 5006, 5007, + 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, + 5016, 5017, 5018, 5019, 5021, 5022, 5023, 5024, + 421, 148, 148, 1, 151, 5020, 5002, 181, + 181, 181, 571, 5003, 150, 152, 153, 4564, + 3196, 5004, 4566, 158, 5005, 160, 161, 5006, + 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, + 5015, 5016, 5017, 5018, 5019, 5021, 5022, 5023, + 5024, 421, 148, 148, 1, 151, 5020, 5002, + 181, 181, 181, 571, 1, 5003, 150, 152, + 153, 4564, 3196, 5004, 4566, 158, 5005, 160, + 161, 5006, 5007, 5008, 5009, 5010, 5011, 5012, + 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5021, + 5022, 5023, 5024, 421, 148, 148, 1, 1, + 151, 5020, 5002, 181, 181, 181, 571, 5003, + 150, 152, 153, 4564, 3196, 5004, 4566, 158, + 5005, 160, 161, 5006, 5007, 5008, 5009, 5010, + 5011, 5012, 5013, 5014, 5015, 5016, 5017, 5018, + 5019, 5021, 5022, 5023, 5024, 421, 148, 148, + 1, 151, 5020, 5002, 181, 181, 181, 571, + 1, 1, 1, 5003, 150, 152, 153, 4564, + 3196, 5004, 4566, 158, 5005, 160, 161, 5006, + 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, + 5015, 5016, 5017, 5018, 5019, 5021, 5022, 5023, + 5024, 421, 148, 148, 1, 1, 151, 5020, + 5002, 181, 181, 181, 571, 5003, 150, 152, + 153, 4564, 3196, 5004, 4566, 158, 5005, 160, + 161, 5006, 5007, 5008, 5009, 5010, 5011, 5012, + 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5021, + 5022, 5023, 5024, 421, 148, 148, 1, 151, + 5020, 5002, 181, 181, 181, 571, 5003, 150, + 152, 153, 4564, 3196, 5004, 4566, 158, 5005, + 160, 161, 5006, 5007, 5008, 5009, 5010, 5011, + 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, + 5021, 5022, 5023, 5024, 421, 148, 148, 1, + 1, 1, 1, 151, 5020, 5002, 181, 181, + 181, 571, 1, 5003, 150, 152, 153, 4564, + 3196, 5004, 4566, 158, 5005, 160, 161, 5006, + 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, + 5015, 5016, 5017, 5018, 5019, 5021, 5022, 5023, + 5024, 421, 148, 148, 151, 5020, 5002, 3371, + 5338, 5339, 5340, 674, 302, 303, 304, 305, + 306, 307, 5341, 2214, 5342, 2216, 5343, 5344, + 5345, 4500, 122, 124, 4501, 4502, 4503, 4504, + 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, + 4513, 4514, 4515, 4516, 4517, 4518, 3372, 151, + 4499, 5346, 5347, 317, 318, 319, 5348, 5349, + 5350, 5351, 5352, 5353, 5355, 5356, 5357, 5358, + 4500, 122, 124, 4501, 4502, 4503, 4504, 4505, + 4506, 4507, 4508, 4509, 4510, 4511, 4512, 4513, + 4514, 4515, 4516, 4517, 4518, 5354, 4499, 5360, + 4449, 4451, 5361, 5362, 5363, 5364, 5365, 5366, + 5367, 5368, 5369, 5370, 5371, 5372, 5373, 5374, + 5375, 5376, 5377, 5378, 5359, +} + +var _s_trans_targs []int16 = []int16{ + 4862, 4863, 4862, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 43, + 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 65, 66, 67, 68, + 69, 70, 72, 73, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 91, 92, 93, 95, 101, + 120, 125, 127, 134, 96, 97, 98, 99, + 100, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 121, 122, 123, 124, 126, + 128, 129, 130, 131, 132, 133, 135, 137, + 138, 139, 1, 140, 2, 4862, 4866, 1901, + 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909, + 1910, 1911, 1912, 1913, 1914, 1943, 1966, 1973, + 1976, 1993, 1997, 2041, 4867, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 198, 238, 256, 261, + 286, 287, 290, 306, 407, 142, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 239, 240, 241, + 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 257, 258, + 259, 260, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 288, 289, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 307, 338, 362, 366, 367, + 369, 377, 380, 398, 403, 308, 309, 310, + 311, 312, 313, 314, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 325, 326, + 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 339, 340, 341, 342, 343, + 344, 345, 346, 347, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 363, 364, 365, 368, 370, 371, + 372, 373, 374, 375, 376, 378, 379, 381, + 382, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, + 399, 400, 401, 402, 404, 405, 406, 408, + 409, 410, 411, 412, 4862, 4868, 414, 415, + 416, 417, 418, 419, 420, 421, 422, 423, + 424, 425, 426, 427, 456, 481, 488, 491, + 508, 512, 557, 413, 428, 429, 430, 431, + 432, 433, 434, 435, 436, 437, 438, 439, + 440, 441, 442, 443, 444, 445, 446, 447, + 448, 449, 450, 451, 452, 453, 454, 455, + 457, 458, 459, 460, 461, 462, 463, 464, + 465, 466, 467, 468, 469, 470, 471, 472, + 473, 474, 475, 476, 477, 478, 479, 480, + 482, 483, 484, 485, 486, 487, 489, 490, + 492, 493, 494, 495, 496, 497, 498, 499, + 500, 501, 502, 503, 504, 505, 506, 507, + 509, 510, 511, 513, 519, 540, 545, 547, + 555, 514, 515, 516, 517, 518, 520, 521, + 522, 523, 524, 525, 526, 527, 528, 529, + 530, 531, 532, 533, 534, 535, 536, 537, + 538, 539, 541, 542, 543, 544, 546, 548, + 549, 550, 551, 552, 553, 554, 556, 558, + 559, 560, 561, 4869, 4870, 569, 570, 571, + 572, 573, 574, 733, 734, 735, 736, 737, + 738, 739, 740, 769, 791, 798, 801, 817, + 822, 864, 568, 4871, 589, 590, 591, 592, + 593, 594, 595, 596, 597, 598, 599, 600, + 601, 602, 603, 604, 605, 606, 607, 608, + 609, 610, 611, 612, 613, 614, 615, 616, + 617, 618, 619, 621, 622, 623, 624, 625, + 626, 627, 628, 629, 630, 631, 632, 633, + 634, 635, 636, 637, 638, 639, 640, 641, + 642, 644, 645, 646, 647, 648, 649, 651, + 652, 654, 655, 656, 657, 658, 659, 660, + 661, 662, 663, 664, 665, 666, 667, 668, + 669, 671, 672, 673, 674, 675, 676, 677, + 678, 680, 687, 708, 715, 717, 725, 681, + 682, 683, 684, 685, 686, 688, 689, 690, + 691, 692, 693, 694, 695, 696, 697, 698, + 699, 700, 701, 702, 703, 704, 705, 706, + 707, 709, 710, 711, 712, 713, 714, 716, + 718, 719, 720, 721, 722, 723, 724, 726, + 728, 729, 730, 576, 731, 732, 741, 742, + 743, 744, 745, 746, 747, 748, 749, 750, + 751, 752, 753, 754, 755, 756, 757, 758, + 759, 760, 761, 762, 763, 764, 765, 766, + 767, 768, 770, 771, 772, 773, 774, 775, + 776, 777, 778, 779, 780, 781, 782, 783, + 784, 785, 786, 787, 788, 789, 790, 792, + 793, 794, 795, 796, 797, 799, 800, 802, + 803, 804, 805, 806, 807, 808, 809, 810, + 811, 812, 813, 814, 815, 816, 818, 819, + 820, 821, 823, 829, 848, 853, 855, 862, + 824, 825, 826, 827, 828, 830, 831, 832, + 833, 834, 835, 836, 837, 838, 839, 840, + 841, 842, 843, 844, 845, 846, 847, 849, + 850, 851, 852, 854, 856, 857, 858, 859, + 860, 861, 863, 865, 866, 867, 868, 885, + 886, 887, 888, 889, 890, 891, 892, 893, + 894, 895, 896, 897, 898, 899, 900, 901, + 902, 903, 904, 905, 906, 907, 908, 909, + 910, 911, 912, 913, 914, 915, 917, 918, + 919, 920, 921, 922, 923, 924, 925, 926, + 927, 928, 929, 930, 931, 932, 933, 934, + 935, 936, 937, 939, 940, 941, 942, 943, + 944, 946, 947, 949, 950, 951, 952, 953, + 954, 955, 956, 957, 958, 959, 960, 961, + 962, 963, 965, 966, 967, 968, 969, 970, + 971, 973, 979, 998, 1003, 1005, 1012, 974, + 975, 976, 977, 978, 980, 981, 982, 983, + 984, 985, 986, 987, 988, 989, 990, 991, + 992, 993, 994, 995, 996, 997, 999, 1000, + 1001, 1002, 1004, 1006, 1007, 1008, 1009, 1010, + 1011, 1013, 1015, 1016, 1017, 871, 1018, 1019, + 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, + 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, + 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, + 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1060, + 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, + 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, + 1077, 1078, 1079, 1080, 1082, 1083, 1084, 1085, + 1086, 1087, 1089, 1240, 1164, 1165, 1166, 1091, + 1167, 4872, 1104, 1105, 1106, 1107, 1108, 1109, + 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, + 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, + 1126, 1127, 1128, 1129, 1130, 1131, 1133, 1134, + 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, + 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, + 1151, 1152, 1153, 1155, 1156, 1157, 1158, 1159, + 1160, 1162, 1163, 1169, 1170, 1171, 1172, 1173, + 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, + 1182, 1183, 1185, 1186, 1187, 1188, 1189, 1190, + 1191, 1193, 1199, 1218, 1223, 1226, 1233, 1194, + 1195, 1196, 1197, 1198, 1200, 1201, 1202, 1203, + 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, + 1212, 1213, 1214, 1215, 1216, 1217, 1219, 1220, + 1221, 1222, 1224, 1225, 1227, 1228, 1229, 1230, + 1231, 1232, 1234, 1236, 1237, 1238, 1239, 1092, + 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, + 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1258, + 1259, 1260, 1261, 1262, 1263, 1265, 1271, 1290, + 1295, 1297, 1304, 1266, 1267, 1268, 1269, 1270, + 1272, 1273, 1274, 1275, 1276, 1277, 1278, 1279, + 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, + 1288, 1289, 1291, 1292, 1293, 1294, 1296, 1298, + 1299, 1300, 1301, 1302, 1303, 1305, 1307, 1308, + 1309, 563, 1310, 1311, 1326, 1327, 1328, 1329, + 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, + 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, + 1346, 1347, 1348, 1349, 1350, 1351, 1352, 1353, + 1354, 1355, 1356, 1358, 1359, 1360, 1361, 1362, + 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1370, + 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, + 1380, 1381, 1382, 1383, 1384, 1385, 1387, 1388, + 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, + 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1406, + 1407, 1408, 1409, 1410, 1411, 1412, 1414, 1420, + 1439, 1444, 1446, 1453, 1415, 1416, 1417, 1418, + 1419, 1421, 1422, 1423, 1424, 1425, 1426, 1427, + 1428, 1429, 1430, 1431, 1432, 1433, 1434, 1435, + 1436, 1437, 1438, 1440, 1441, 1442, 1443, 1445, + 1447, 1448, 1449, 1450, 1451, 1452, 1454, 1456, + 1457, 1458, 1313, 1459, 1460, 1473, 1474, 1475, + 1476, 1477, 1478, 1479, 1480, 1481, 1482, 1483, + 1484, 1485, 1486, 1487, 1488, 1489, 1490, 1491, + 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, + 1500, 1501, 1502, 1504, 1505, 1506, 1507, 1508, + 1509, 1510, 1511, 1512, 1513, 1514, 1515, 1516, + 1517, 1518, 1519, 1520, 1521, 1522, 1524, 1525, + 1526, 1527, 1528, 1529, 1531, 1532, 1534, 1535, + 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, + 1544, 1546, 1547, 1548, 1549, 1550, 1552, 1558, + 1573, 1577, 1579, 1586, 1553, 1554, 1555, 1556, + 1557, 1559, 1560, 1561, 1562, 1563, 1564, 1565, + 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1574, + 1575, 1576, 1578, 1580, 1581, 1582, 1583, 1584, + 1585, 1587, 1589, 1590, 1591, 4873, 1606, 1607, + 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, + 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, + 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, + 1632, 1633, 1634, 1635, 1636, 1638, 1639, 1640, + 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, + 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, + 1657, 1658, 1659, 1660, 1661, 1663, 1664, 1665, + 1666, 1667, 1668, 1670, 1671, 1673, 1674, 1675, + 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, + 1684, 1685, 1686, 1687, 1688, 1690, 1691, 1692, + 1693, 1694, 1695, 1696, 1698, 1705, 1727, 1734, + 1736, 1744, 1699, 1700, 1701, 1702, 1703, 1704, + 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, + 1714, 1715, 1716, 1717, 1718, 1719, 1720, 1721, + 1722, 1723, 1724, 1725, 1726, 1728, 1729, 1730, + 1731, 1732, 1733, 1735, 1737, 1738, 1739, 1740, + 1741, 1742, 1743, 1745, 1747, 1748, 1749, 1593, + 1750, 1751, 141, 1766, 1767, 1768, 1769, 1770, + 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, + 1779, 1780, 1781, 1782, 1783, 1784, 1785, 1786, + 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, + 1795, 1796, 1798, 1799, 1800, 1801, 1802, 1803, + 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811, + 1812, 1813, 1814, 1815, 1816, 1817, 1818, 1820, + 1821, 1822, 1823, 1824, 1825, 1827, 1828, 1830, + 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, + 1839, 1840, 1841, 1842, 1843, 1844, 1846, 1847, + 1848, 1849, 1850, 1851, 1852, 1854, 1860, 1879, + 1884, 1886, 1893, 1855, 1856, 1857, 1858, 1859, + 1861, 1862, 1863, 1864, 1865, 1866, 1867, 1868, + 1869, 1870, 1871, 1872, 1873, 1874, 1875, 1876, + 1877, 1878, 1880, 1881, 1882, 1883, 1885, 1887, + 1888, 1889, 1890, 1891, 1892, 1894, 1896, 1897, + 1898, 1753, 1899, 1900, 1915, 1916, 1917, 1918, + 1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, + 1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, + 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, + 1944, 1945, 1946, 1947, 1948, 1949, 1950, 1951, + 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, + 1960, 1961, 1962, 1963, 1964, 1965, 1967, 1968, + 1969, 1970, 1971, 1972, 1974, 1975, 1977, 1978, + 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, + 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, + 1996, 1998, 2004, 2024, 2029, 2031, 2039, 1999, + 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, + 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, + 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2025, + 2026, 2027, 2028, 2030, 2032, 2033, 2034, 2035, + 2036, 2037, 2038, 2040, 2042, 2043, 2044, 2045, + 4865, 2060, 2061, 2062, 2063, 2064, 2065, 2066, + 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, + 2075, 2076, 2077, 2078, 2079, 2080, 2081, 2082, + 2083, 2084, 2085, 2086, 2087, 2088, 2089, 2090, + 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2099, + 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107, + 2108, 2109, 2110, 2111, 2112, 2114, 2115, 2116, + 2117, 2118, 2119, 2121, 2122, 2124, 2125, 2126, + 2127, 2128, 2129, 2130, 2131, 2132, 2133, 2134, + 2135, 2136, 2137, 2138, 2140, 2141, 2142, 2143, + 2144, 2146, 2152, 2171, 2176, 2178, 2185, 2147, + 2148, 2149, 2150, 2151, 2153, 2154, 2155, 2156, + 2157, 2158, 2159, 2160, 2161, 2162, 2163, 2164, + 2165, 2166, 2167, 2168, 2169, 2170, 2172, 2173, + 2174, 2175, 2177, 2179, 2180, 2181, 2182, 2183, + 2184, 2186, 2188, 2189, 2190, 2047, 2191, 2192, + 4874, 2207, 2208, 2209, 2210, 2211, 2212, 2213, + 2214, 2215, 2216, 2217, 2218, 2219, 2220, 2221, + 2222, 2223, 2224, 2225, 2226, 2227, 2228, 2229, + 2230, 2231, 2232, 2233, 2234, 2235, 2236, 2237, + 2239, 2240, 2241, 2242, 2243, 2244, 2245, 2246, + 2247, 2248, 2249, 2250, 2251, 2252, 2253, 2254, + 2255, 2256, 2257, 2258, 2259, 2261, 2262, 2263, + 2264, 2265, 2266, 2268, 2269, 2271, 2272, 2273, + 2274, 2275, 2276, 2277, 2278, 2279, 2280, 2281, + 2282, 2283, 2284, 2285, 2287, 2288, 2289, 2290, + 2291, 2293, 2299, 2318, 2323, 2325, 2332, 2294, + 2295, 2296, 2297, 2298, 2300, 2301, 2302, 2303, + 2304, 2305, 2306, 2307, 2308, 2309, 2310, 2311, + 2312, 2313, 2314, 2315, 2316, 2317, 2319, 2320, + 2321, 2322, 2324, 2326, 2327, 2328, 2329, 2330, + 2331, 2333, 2335, 2336, 2337, 2194, 2338, 2339, + 4876, 2354, 2355, 2356, 2357, 2358, 2359, 2360, + 2361, 2362, 2363, 2364, 2365, 2366, 2367, 2368, + 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, + 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2384, + 2386, 2387, 2388, 2389, 2390, 2391, 2392, 2393, + 2394, 2395, 2396, 2397, 2398, 2399, 2400, 2401, + 2402, 2403, 2404, 2405, 2406, 2408, 2409, 2410, + 2411, 2412, 2413, 2415, 2416, 2418, 2419, 2420, + 2421, 2422, 2423, 2424, 2425, 2426, 2427, 2428, + 2429, 2430, 2431, 2432, 2434, 2435, 2436, 2437, + 2438, 2439, 2440, 2442, 2448, 2467, 2472, 2474, + 2481, 2443, 2444, 2445, 2446, 2447, 2449, 2450, + 2451, 2452, 2453, 2454, 2455, 2456, 2457, 2458, + 2459, 2460, 2461, 2462, 2463, 2464, 2465, 2466, + 2468, 2469, 2470, 2471, 2473, 2475, 2476, 2477, + 2478, 2479, 2480, 2482, 2484, 2485, 2486, 2341, + 2487, 2488, 4875, 2503, 2504, 2505, 2506, 2507, + 2508, 2509, 2510, 2511, 2512, 2513, 2514, 2515, + 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2523, + 2524, 2525, 2526, 2527, 2528, 2529, 2530, 2531, + 2532, 2533, 2535, 2536, 2537, 2538, 2539, 2540, + 2541, 2542, 2543, 2544, 2545, 2546, 2547, 2548, + 2549, 2550, 2551, 2552, 2553, 2554, 2555, 2557, + 2558, 2559, 2560, 2561, 2562, 2564, 2565, 2567, + 2568, 2569, 2570, 2571, 2572, 2573, 2574, 2575, + 2576, 2577, 2578, 2579, 2580, 2581, 2583, 2584, + 2585, 2586, 2587, 2589, 2595, 2614, 2619, 2621, + 2628, 2590, 2591, 2592, 2593, 2594, 2596, 2597, + 2598, 2599, 2600, 2601, 2602, 2603, 2604, 2605, + 2606, 2607, 2608, 2609, 2610, 2611, 2612, 2613, + 2615, 2616, 2617, 2618, 2620, 2622, 2623, 2624, + 2625, 2626, 2627, 2629, 2631, 2632, 2633, 2490, + 2634, 2635, 4862, 4878, 2650, 2651, 2652, 2653, + 2654, 2655, 2656, 2657, 2658, 2659, 2660, 2661, + 2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, + 2670, 2671, 2672, 2673, 2674, 2675, 2676, 2677, + 2679, 2680, 2681, 2682, 2683, 2684, 2685, 2686, + 2687, 2688, 2689, 2690, 2691, 2692, 2693, 2694, + 2695, 2696, 2697, 2698, 2699, 2701, 2702, 2703, + 2704, 2705, 2706, 2708, 2709, 2711, 2712, 2713, + 2714, 2715, 2716, 2717, 2718, 2719, 2720, 2721, + 2722, 2723, 2724, 2725, 2727, 2728, 2729, 2731, + 2737, 2756, 2761, 2763, 2770, 2732, 2733, 2734, + 2735, 2736, 2738, 2739, 2740, 2741, 2742, 2743, + 2744, 2745, 2746, 2747, 2748, 2749, 2750, 2751, + 2752, 2753, 2754, 2755, 2757, 2758, 2759, 2760, + 2762, 2764, 2765, 2766, 2767, 2768, 2769, 2771, + 2773, 2774, 2775, 2637, 2776, 2638, 4885, 2791, + 2792, 2793, 2794, 2795, 2796, 2797, 2798, 2799, + 2800, 2801, 2802, 2803, 2804, 2805, 2806, 2807, + 2808, 2809, 2810, 2811, 2812, 2813, 2814, 2815, + 2816, 2817, 2818, 2819, 2820, 2821, 2823, 2824, + 2825, 2826, 2827, 2828, 2829, 2830, 2831, 2832, + 2833, 2834, 2835, 2836, 2837, 2838, 2839, 2840, + 2841, 2842, 2843, 2845, 2846, 2847, 2848, 2849, + 2850, 2852, 2853, 2855, 2856, 2857, 2858, 2859, + 2860, 2861, 2862, 2863, 2864, 2865, 2866, 2867, + 2868, 2869, 2871, 2872, 2873, 2874, 2875, 2877, + 2883, 2902, 2907, 2909, 2916, 2878, 2879, 2880, + 2881, 2882, 2884, 2885, 2886, 2887, 2888, 2889, + 2890, 2891, 2892, 2893, 2894, 2895, 2896, 2897, + 2898, 2899, 2900, 2901, 2903, 2904, 2905, 2906, + 2908, 2910, 2911, 2912, 2913, 2914, 2915, 2917, + 2919, 2920, 2921, 2778, 2922, 2923, 4886, 2938, + 2939, 2940, 2941, 2942, 2943, 2944, 2945, 2946, + 2947, 2948, 2949, 2950, 2951, 2952, 2953, 2954, + 2955, 2956, 2957, 2958, 2959, 2960, 2961, 2962, + 2963, 2964, 2965, 2966, 2967, 2968, 2970, 2971, + 2972, 2973, 2974, 2975, 2976, 2977, 2978, 2979, + 2980, 2981, 2982, 2983, 2984, 2985, 2986, 2987, + 2988, 2989, 2990, 2992, 2993, 2994, 2995, 2996, + 2997, 2999, 3000, 3002, 3003, 3004, 3005, 3006, + 3007, 3008, 3009, 3010, 3011, 3012, 3013, 3014, + 3015, 3016, 3018, 3019, 3020, 3021, 3022, 3024, + 3030, 3049, 3054, 3056, 3063, 3025, 3026, 3027, + 3028, 3029, 3031, 3032, 3033, 3034, 3035, 3036, + 3037, 3038, 3039, 3040, 3041, 3042, 3043, 3044, + 3045, 3046, 3047, 3048, 3050, 3051, 3052, 3053, + 3055, 3057, 3058, 3059, 3060, 3061, 3062, 3064, + 3066, 3067, 3068, 2925, 3069, 3070, 4887, 3085, + 3086, 3087, 3088, 3089, 3090, 3091, 3092, 3093, + 3094, 3095, 3096, 3097, 3098, 3099, 3100, 3101, + 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109, + 3110, 3111, 3112, 3113, 3114, 3115, 3117, 3118, + 3119, 3120, 3121, 3122, 3123, 3124, 3125, 3126, + 3127, 3128, 3129, 3130, 3131, 3132, 3133, 3134, + 3135, 3136, 3137, 3139, 3140, 3141, 3142, 3143, + 3144, 3146, 3147, 3149, 3150, 3151, 3152, 3153, + 3154, 3155, 3156, 3157, 3158, 3159, 3160, 3161, + 3162, 3163, 3165, 3166, 3167, 3168, 3169, 3171, + 3177, 3196, 3201, 3203, 3210, 3172, 3173, 3174, + 3175, 3176, 3178, 3179, 3180, 3181, 3182, 3183, + 3184, 3185, 3186, 3187, 3188, 3189, 3190, 3191, + 3192, 3193, 3194, 3195, 3197, 3198, 3199, 3200, + 3202, 3204, 3205, 3206, 3207, 3208, 3209, 3211, + 3213, 3214, 3215, 3072, 3216, 3217, 4929, 4930, + 4931, 4991, 4992, 4993, 4994, 4995, 4996, 4997, + 4998, 4999, 5000, 5001, 5002, 5003, 5004, 5005, + 5006, 5007, 5008, 5009, 5010, 5011, 5012, 5013, + 5014, 5015, 4933, 4934, 4935, 4936, 4937, 4938, + 4939, 4944, 4945, 4946, 4947, 4948, 4949, 4950, + 4951, 4952, 4953, 4954, 4955, 4956, 4957, 4958, + 4959, 4960, 4961, 4962, 4963, 4964, 4965, 4966, + 4967, 4968, 4969, 4970, 4971, 4972, 4973, 4974, + 4975, 4976, 4977, 4978, 4979, 4980, 4981, 4982, + 4983, 4984, 4985, 4986, 4987, 4988, 4989, 4990, + 5073, 4862, 3283, 3284, 3285, 3286, 3287, 3288, + 3289, 3290, 3291, 3292, 3293, 3294, 3295, 3296, + 3297, 3298, 3299, 3300, 3301, 3302, 3303, 3304, + 3305, 3306, 3307, 3308, 3309, 3310, 3311, 3312, + 3313, 3315, 3316, 3317, 3268, 3318, 3319, 3320, + 3321, 3322, 3323, 3324, 3325, 3326, 3327, 3328, + 3329, 3330, 3331, 3332, 3333, 3334, 3335, 3336, + 3337, 3339, 3340, 3341, 3342, 3343, 3344, 3346, + 3347, 3348, 3349, 3350, 3429, 5074, 3365, 3366, + 3367, 3368, 3369, 3370, 3371, 3372, 3373, 3374, + 3375, 3376, 3377, 3378, 3379, 3380, 3381, 3382, + 3383, 3384, 3385, 3386, 3387, 3388, 3389, 3390, + 3391, 3392, 3394, 3395, 3396, 3352, 3397, 3398, + 3399, 3400, 3401, 3402, 3403, 3404, 3405, 3406, + 3407, 3408, 3409, 3410, 3411, 3412, 3413, 3414, + 3415, 3416, 3418, 3419, 3420, 3421, 3422, 3423, + 3425, 3426, 3427, 3428, 3431, 3432, 3433, 3434, + 3435, 3436, 3437, 3438, 3439, 3440, 3441, 3442, + 3443, 3444, 3445, 3448, 3449, 3451, 3452, 3453, + 3454, 3456, 3462, 3481, 3486, 3488, 3495, 3457, + 3458, 3459, 3460, 3461, 3463, 3464, 3465, 3466, + 3467, 3468, 3469, 3470, 3471, 3472, 3473, 3474, + 3475, 3476, 3477, 3478, 3479, 3480, 3482, 3483, + 3484, 3485, 3487, 3489, 3490, 3491, 3492, 3493, + 3494, 3496, 3498, 3499, 3353, 3501, 3502, 3503, + 3504, 3505, 3506, 3507, 3508, 3509, 3510, 3511, + 3512, 3513, 3514, 3515, 3270, 3518, 3519, 3521, + 3522, 3523, 3524, 3525, 3527, 3533, 3552, 3557, + 3559, 3566, 3528, 3529, 3530, 3531, 3532, 3534, + 3535, 3536, 3537, 3538, 3539, 3540, 3541, 3542, + 3543, 3544, 3545, 3546, 3547, 3548, 3549, 3550, + 3551, 3553, 3554, 3555, 3556, 3558, 3560, 3561, + 3562, 3563, 3564, 3565, 3567, 3569, 3570, 3571, + 3572, 4862, 5076, 4862, 3608, 3609, 3610, 3611, + 3612, 3613, 3614, 3615, 3616, 3617, 3618, 3619, + 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, + 3628, 3629, 3630, 3631, 3632, 3633, 3634, 3635, + 3637, 3638, 3639, 3640, 3641, 3642, 3643, 3644, + 3645, 3646, 3647, 3648, 3649, 3650, 3651, 3652, + 3653, 3654, 3655, 3656, 3657, 3659, 3660, 3661, + 3662, 3663, 3664, 3666, 3667, 3669, 3670, 3671, + 3672, 3673, 3674, 3675, 3676, 3677, 3678, 3679, + 3680, 3681, 3682, 3683, 3685, 3686, 3687, 3689, + 3695, 3714, 3719, 3721, 3728, 3690, 3691, 3692, + 3693, 3694, 3696, 3697, 3698, 3699, 3700, 3701, + 3702, 3703, 3704, 3705, 3706, 3707, 3708, 3709, + 3710, 3711, 3712, 3713, 3715, 3716, 3717, 3718, + 3720, 3722, 3723, 3724, 3725, 3726, 3727, 3729, + 3731, 3732, 3733, 3595, 3734, 3596, 5078, 5079, + 5080, 3752, 3753, 3754, 3755, 3756, 3757, 3758, + 3759, 3760, 3761, 3762, 3763, 3764, 3765, 3766, + 3767, 3768, 3769, 3770, 3771, 3772, 3773, 3774, + 3775, 3776, 3777, 3778, 3779, 3780, 3781, 3782, + 3784, 3785, 3786, 3787, 3788, 3789, 3790, 3791, + 3792, 3793, 3794, 3795, 3796, 3797, 3798, 3799, + 3800, 3801, 3802, 3803, 3804, 3806, 3807, 3808, + 3809, 3810, 3811, 3813, 3814, 3816, 3817, 3818, + 3819, 3820, 3821, 3822, 3823, 3824, 3825, 3826, + 3827, 3828, 3829, 3830, 3832, 3833, 3834, 3835, + 3836, 3838, 3844, 3863, 3868, 3870, 3877, 3839, + 3840, 3841, 3842, 3843, 3845, 3846, 3847, 3848, + 3849, 3850, 3851, 3852, 3853, 3854, 3855, 3856, + 3857, 3858, 3859, 3860, 3861, 3862, 3864, 3865, + 3866, 3867, 3869, 3871, 3872, 3873, 3874, 3875, + 3876, 3878, 3880, 3881, 3882, 3739, 3883, 3884, + 3899, 3900, 3901, 3902, 3903, 3904, 3905, 3906, + 3907, 3908, 3909, 3910, 3911, 3912, 3913, 3914, + 3915, 3916, 3917, 3918, 3919, 3920, 3921, 3922, + 3923, 3924, 3925, 3926, 3928, 3929, 3930, 3931, + 3932, 3933, 3934, 3935, 3936, 3937, 3938, 3939, + 3940, 3941, 3942, 3943, 3944, 3945, 3946, 3947, + 3948, 3950, 3951, 3952, 3953, 3954, 3955, 3957, + 3958, 3960, 3961, 3962, 3963, 3964, 3965, 3966, + 3967, 3968, 3969, 3970, 3971, 3972, 3973, 3974, + 3976, 3977, 3978, 3979, 3981, 3987, 4006, 4011, + 4013, 4020, 3982, 3983, 3984, 3985, 3986, 3988, + 3989, 3990, 3991, 3992, 3993, 3994, 3995, 3996, + 3997, 3998, 3999, 4000, 4001, 4002, 4003, 4004, + 4005, 4007, 4008, 4009, 4010, 4012, 4014, 4015, + 4016, 4017, 4018, 4019, 4021, 4023, 4024, 4025, + 3886, 4026, 3887, 4862, 4041, 4042, 4043, 4044, + 4045, 4046, 4047, 4048, 4049, 4050, 4051, 4052, + 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, + 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, + 4070, 4071, 4072, 4073, 4074, 4075, 4076, 4077, + 4078, 4079, 4080, 4081, 4082, 4083, 4084, 4085, + 4086, 4087, 4088, 4089, 4090, 4092, 4093, 4094, + 4095, 4096, 4097, 4099, 4100, 4101, 4102, 4103, + 4028, 4104, 4106, 4107, 4108, 4109, 4110, 4111, + 4112, 4113, 4114, 4115, 4116, 4117, 4118, 4119, + 4120, 4122, 4123, 4124, 4125, 4126, 4128, 4134, + 4153, 4158, 4161, 4168, 4129, 4130, 4131, 4132, + 4133, 4135, 4136, 4137, 4138, 4139, 4140, 4141, + 4142, 4143, 4144, 4145, 4146, 4147, 4148, 4149, + 4150, 4151, 4152, 4154, 4155, 4156, 4157, 4159, + 4160, 4162, 4163, 4164, 4165, 4166, 4167, 4169, + 4171, 4172, 4173, 4174, 4029, 5081, 4862, 4190, + 4191, 4192, 4193, 4194, 4195, 4196, 4197, 4198, + 4199, 4200, 4201, 4202, 4203, 4204, 4205, 4206, + 4207, 4208, 4209, 4210, 4211, 4212, 4213, 4214, + 4215, 4216, 4217, 4219, 4220, 4221, 4222, 4223, + 4224, 4225, 4226, 4227, 4228, 4229, 4230, 4231, + 4232, 4233, 4234, 4235, 4236, 4237, 4238, 4239, + 4241, 4242, 4243, 4244, 4245, 4246, 4248, 4249, + 4251, 4252, 4253, 4254, 4255, 4256, 4257, 4258, + 4259, 4260, 4261, 4262, 4263, 4264, 4265, 4267, + 4268, 4269, 4271, 4277, 4296, 4301, 4303, 4310, + 4272, 4273, 4274, 4275, 4276, 4278, 4279, 4280, + 4281, 4282, 4283, 4284, 4285, 4286, 4287, 4288, + 4289, 4290, 4291, 4292, 4293, 4294, 4295, 4297, + 4298, 4299, 4300, 4302, 4304, 4305, 4306, 4307, + 4308, 4309, 4311, 4313, 4314, 4315, 4177, 4316, + 4178, 5082, 4333, 4334, 4335, 4336, 4337, 4338, + 4339, 4340, 4341, 4342, 4343, 4344, 4345, 4346, + 4347, 4348, 4349, 4350, 4351, 4352, 4353, 4354, + 4355, 4356, 4357, 4358, 4359, 4360, 4362, 4363, + 4364, 4365, 4366, 4367, 4368, 4369, 4370, 4371, + 4372, 4373, 4374, 4375, 4376, 4377, 4378, 4379, + 4380, 4381, 4382, 4384, 4385, 4386, 4387, 4388, + 4389, 4391, 4392, 4394, 4395, 4396, 4397, 4398, + 4399, 4400, 4401, 4402, 4403, 4404, 4405, 4406, + 4407, 4408, 4410, 4411, 4412, 4414, 4420, 4439, + 4444, 4446, 4453, 4415, 4416, 4417, 4418, 4419, + 4421, 4422, 4423, 4424, 4425, 4426, 4427, 4428, + 4429, 4430, 4431, 4432, 4433, 4434, 4435, 4436, + 4437, 4438, 4440, 4441, 4442, 4443, 4445, 4447, + 4448, 4449, 4450, 4451, 4452, 4454, 4456, 4457, + 4458, 4320, 4459, 4321, 5083, 5084, 5085, 5128, + 5129, 5130, 5131, 5132, 5133, 5134, 5135, 5136, + 5137, 5138, 5139, 5140, 5141, 5142, 5143, 5144, + 5145, 5146, 5147, 5148, 5149, 5150, 5151, 5152, + 5153, 5154, 5155, 5156, 5157, 5158, 5159, 5160, + 5161, 5162, 5163, 5164, 5165, 5166, 5167, 5168, + 5169, 5170, 5171, 5172, 5173, 5174, 5175, 5176, + 5177, 5178, 5179, 5180, 5181, 5182, 5183, 5184, + 5185, 5186, 5187, 5188, 5189, 5190, 5191, 5192, + 5193, 5194, 5195, 5196, 5197, 5198, 5199, 5200, + 5201, 5202, 5203, 5204, 5205, 5206, 5211, 4510, + 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, + 4519, 4520, 4521, 4522, 4523, 4524, 4525, 4526, + 4527, 4528, 4529, 4530, 4531, 4532, 4533, 4534, + 4535, 4536, 4537, 4538, 4539, 4540, 4542, 4543, + 4544, 4545, 4546, 4547, 4548, 4549, 4550, 4551, + 4552, 4553, 4554, 4555, 4556, 4557, 4558, 4559, + 4560, 4561, 4562, 4564, 4565, 4566, 4567, 4568, + 4569, 4571, 4572, 4574, 4575, 4576, 4577, 4578, + 4579, 4580, 4581, 4582, 4583, 4584, 4585, 4586, + 4587, 4588, 4590, 4591, 4592, 4593, 4594, 4596, + 4602, 4621, 4626, 4628, 4635, 4597, 4598, 4599, + 4600, 4601, 4603, 4604, 4605, 4606, 4607, 4608, + 4609, 4610, 4611, 4612, 4613, 4614, 4615, 4616, + 4617, 4618, 4619, 4620, 4622, 4623, 4624, 4625, + 4627, 4629, 4630, 4631, 4632, 4633, 4634, 4636, + 4638, 4639, 4640, 4497, 4641, 4642, 5212, 5213, + 5214, 5313, 5314, 5315, 5316, 5317, 5318, 5319, + 5320, 5321, 5322, 5323, 5324, 5325, 5326, 5327, + 5328, 5329, 5330, 5331, 5332, 5333, 5334, 5335, + 5336, 5337, 5243, 5244, 5245, 5246, 5247, 5248, + 5249, 5288, 5289, 5290, 5291, 5292, 5293, 5294, + 5295, 5296, 5297, 5298, 5299, 5300, 5301, 5251, + 5252, 5253, 5254, 5255, 5256, 5257, 5258, 5259, + 5260, 5261, 5262, 5263, 5268, 5269, 5270, 5271, + 5272, 5273, 5274, 5275, 5276, 5277, 5278, 5279, + 5280, 5281, 5282, 5283, 5284, 5285, 5286, 5287, + 4672, 4673, 4674, 4675, 4677, 4678, 4679, 4680, + 4681, 4682, 4683, 4684, 4685, 4686, 4687, 4688, + 4689, 4690, 4691, 4692, 4693, 4694, 4696, 4697, + 4698, 4699, 4701, 4702, 4705, 4707, 4850, 5340, + 4862, 4722, 4723, 4724, 4725, 4726, 4727, 4728, + 4729, 4730, 4731, 4732, 4733, 4734, 4735, 4736, + 4737, 4738, 4739, 4740, 4741, 4742, 4743, 4744, + 4745, 4746, 4747, 4748, 4749, 4751, 4752, 4753, + 4754, 4755, 4756, 4757, 4758, 4759, 4760, 4761, + 4762, 4763, 4764, 4765, 4766, 4767, 4768, 4769, + 4770, 4771, 4773, 4774, 4775, 4776, 4777, 4778, + 4780, 4781, 4783, 4784, 4785, 4786, 4787, 4788, + 4789, 4790, 4791, 4792, 4793, 4794, 4795, 4796, + 4797, 4799, 4800, 4801, 4803, 4809, 4828, 4833, + 4835, 4842, 4844, 4804, 4805, 4806, 4807, 4808, + 4810, 4811, 4812, 4813, 4814, 4815, 4816, 4817, + 4818, 4819, 4820, 4821, 4822, 4823, 4824, 4825, + 4826, 4827, 4829, 4830, 4831, 4832, 4834, 4836, + 4837, 4838, 4839, 4840, 4841, 4843, 4846, 4847, + 4848, 4709, 4849, 4710, 4854, 4856, 4857, 4859, + 4861, 4863, 4862, 4862, 4864, 4865, 4874, 4875, + 4877, 4879, 4883, 4895, 4896, 5016, 5017, 5059, + 5060, 4911, 5061, 4913, 4914, 5062, 5063, 5064, + 5065, 5066, 5067, 5068, 5069, 5070, 5071, 5072, + 5075, 5077, 5207, 5208, 5209, 5210, 5250, 5264, + 5338, 5339, 5047, 4862, 0, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, + 42, 64, 71, 74, 90, 94, 136, 4862, + 4862, 4862, 2046, 2048, 2049, 2050, 2051, 2052, + 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2091, + 2113, 2120, 2123, 2139, 2145, 2187, 1752, 1754, + 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, + 1763, 1764, 1765, 1797, 1819, 1826, 1829, 1845, + 1853, 1895, 4862, 1461, 870, 1462, 873, 1463, + 1464, 1465, 1466, 1467, 1468, 1469, 1470, 1471, + 1472, 1503, 1523, 1530, 1533, 1545, 1551, 1588, + 1312, 1314, 1315, 1316, 1317, 1318, 1319, 1320, + 1321, 1322, 1323, 1324, 1325, 1357, 1379, 1386, + 1389, 1405, 1413, 1455, 562, 564, 565, 566, + 567, 1020, 1021, 1022, 1023, 1024, 1025, 1026, + 1027, 1059, 1081, 1088, 1241, 1257, 1264, 1306, + 869, 872, 874, 875, 876, 877, 878, 879, + 880, 881, 882, 883, 884, 916, 938, 945, + 948, 964, 972, 1014, 575, 577, 578, 579, + 580, 581, 582, 583, 584, 585, 586, 587, + 588, 620, 643, 650, 653, 670, 679, 727, + 1090, 1093, 1094, 1095, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1132, 1154, 1161, 1168, + 1184, 1192, 1235, 1592, 1594, 1595, 1596, 1597, + 1598, 1599, 1600, 1601, 1602, 1603, 1604, 1605, + 1637, 1662, 1669, 1672, 1689, 1697, 1746, 2193, + 2195, 2196, 2197, 2198, 2199, 2200, 2201, 2202, + 2203, 2204, 2205, 2206, 2238, 2260, 2267, 2270, + 2286, 2292, 2334, 2489, 2491, 2492, 2493, 2494, + 2495, 2496, 2497, 2498, 2499, 2500, 2501, 2502, + 2534, 2556, 2563, 2566, 2582, 2588, 2630, 2340, + 2342, 2343, 2344, 2345, 2346, 2347, 2348, 2349, + 2350, 2351, 2352, 2353, 2385, 2407, 2414, 2417, + 2433, 2441, 2483, 4862, 2636, 2639, 2640, 2641, + 2642, 2643, 2644, 2645, 2646, 2647, 2648, 2649, + 2678, 2700, 2707, 2710, 2726, 2730, 2772, 4880, + 4881, 4884, 4888, 4889, 4890, 4891, 4892, 4893, + 4894, 4897, 4898, 4899, 4900, 4901, 4902, 4903, + 4904, 4905, 4906, 4907, 4882, 4879, 4883, 4895, + 4896, 4908, 4909, 4910, 4911, 4912, 4913, 4914, + 4915, 4916, 4917, 4918, 4919, 4920, 4921, 4922, + 4923, 4924, 4925, 4926, 4927, 4928, 4932, 4940, + 4941, 4942, 4943, 2777, 2779, 2780, 2781, 2782, + 2783, 2784, 2785, 2786, 2787, 2788, 2789, 2790, + 2822, 2844, 2851, 2854, 2870, 2876, 2918, 2924, + 2926, 2927, 2928, 2929, 2930, 2931, 2932, 2933, + 2934, 2935, 2936, 2937, 2969, 2991, 2998, 3001, + 3017, 3023, 3065, 3071, 3073, 3074, 3075, 3076, + 3077, 3078, 3079, 3080, 3081, 3082, 3083, 3084, + 3116, 3138, 3145, 3148, 3164, 3170, 3212, 3218, + 3219, 3220, 3221, 3222, 3223, 3224, 3225, 3226, + 3227, 3228, 3229, 3230, 3231, 3232, 3233, 3234, + 3235, 3236, 3237, 3238, 5018, 5019, 5029, 5030, + 5031, 5032, 5033, 5034, 5035, 5036, 5048, 5049, + 5050, 5051, 5052, 5053, 5054, 5055, 5056, 5057, + 5058, 5020, 5017, 5021, 5022, 5023, 5024, 5025, + 5026, 5027, 5028, 5037, 5038, 5039, 5040, 5041, + 5042, 5043, 5044, 5045, 5046, 5047, 3239, 3240, + 3241, 3242, 3243, 3244, 3245, 3246, 3247, 3248, + 3249, 3250, 3251, 3252, 3253, 3254, 3255, 3256, + 3257, 3258, 3259, 3260, 3261, 3262, 3263, 3264, + 3265, 3266, 3267, 3573, 3574, 3575, 3576, 3577, + 3578, 3579, 3580, 3581, 3582, 3583, 3584, 3585, + 3586, 3587, 4862, 3269, 3271, 3272, 3273, 3274, + 3275, 3276, 3277, 3278, 3279, 3280, 3281, 3282, + 3314, 3338, 3345, 3500, 3516, 3517, 3520, 3526, + 3568, 3351, 3354, 3355, 3356, 3357, 3358, 3359, + 3360, 3361, 3362, 3363, 3364, 3393, 3417, 3424, + 3430, 3446, 3447, 3450, 3455, 3497, 3588, 3589, + 3590, 3591, 3592, 3593, 3735, 3736, 4862, 3594, + 3597, 3598, 3599, 3600, 3601, 3602, 3603, 3604, + 3605, 3606, 3607, 3636, 3658, 3665, 3668, 3684, + 3688, 3730, 3737, 4175, 4317, 4318, 4460, 4461, + 4462, 4463, 4464, 4465, 4466, 4467, 4468, 4469, + 4470, 4471, 4472, 4473, 4474, 4475, 4476, 4477, + 4478, 4479, 3738, 3740, 3741, 3742, 3743, 3744, + 3745, 3746, 3747, 3748, 3749, 3750, 3751, 3783, + 3805, 3812, 3815, 3831, 3837, 3879, 3885, 3888, + 3889, 3890, 3891, 3892, 3893, 3894, 3895, 3896, + 3897, 3898, 3927, 3949, 3956, 3959, 3975, 3980, + 4022, 4862, 4027, 4030, 4031, 4032, 4033, 4034, + 4035, 4036, 4037, 4038, 4039, 4040, 4069, 4091, + 4098, 4105, 4121, 4127, 4170, 4862, 4176, 4179, + 4180, 4181, 4182, 4183, 4184, 4185, 4186, 4187, + 4188, 4189, 4218, 4240, 4247, 4250, 4266, 4270, + 4312, 4319, 4322, 4323, 4324, 4325, 4326, 4327, + 4328, 4329, 4330, 4331, 4332, 4361, 4383, 4390, + 4393, 4409, 4413, 4455, 5086, 5087, 5090, 5091, + 5092, 5093, 5094, 5095, 5096, 5097, 5106, 5107, + 5108, 5109, 5110, 5111, 5112, 5113, 5114, 5115, + 5116, 5088, 5089, 5098, 5099, 5100, 5101, 5102, + 5103, 5104, 5105, 5117, 5118, 5119, 5120, 5121, + 5122, 5123, 5124, 5125, 5126, 5127, 4480, 4481, + 4482, 4483, 4484, 4485, 4486, 4487, 4488, 4489, + 4490, 4491, 4492, 4493, 4494, 4495, 4643, 4644, + 4645, 4646, 4647, 4648, 4649, 4650, 4651, 4652, + 4653, 4654, 4655, 4656, 4657, 4658, 4659, 4660, + 4661, 4662, 4496, 4498, 4499, 4500, 4501, 4502, + 4503, 4504, 4505, 4506, 4507, 4508, 4509, 4541, + 4563, 4570, 4573, 4589, 4595, 4637, 5215, 5216, + 5219, 5220, 5221, 5222, 5223, 5224, 5225, 5226, + 5235, 5236, 5237, 5238, 5239, 5240, 5241, 5242, + 5250, 5264, 5265, 5266, 5267, 5217, 5218, 5227, + 5228, 5229, 5230, 5231, 5232, 5233, 5234, 5302, + 5303, 5304, 5305, 5306, 5307, 5308, 5309, 5310, + 5311, 5312, 4663, 4664, 4665, 4666, 4667, 4668, + 4669, 4670, 4671, 4676, 4695, 4700, 4703, 4704, + 4706, 4851, 4852, 4853, 4855, 4858, 4860, 4862, + 4708, 4711, 4712, 4713, 4714, 4715, 4716, 4717, + 4718, 4719, 4720, 4721, 4750, 4772, 4779, 4782, + 4798, 4802, 4845, +} + +var _s_trans_actions []byte = []byte{ + 1, 2, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 6, + 6, 10, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 11, 12, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 11, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 13, 14, 15, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 11, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 17, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 18, 19, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 18, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 14, 14, 10, 10, + 14, 10, 14, 14, 14, 14, 14, 14, + 14, 10, 14, 14, 10, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 10, 14, + 14, 14, 14, 14, 14, 14, 10, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 10, 14, 14, 14, 10, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 11, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 11, 11, + 11, 10, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 20, + 21, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 25, 26, 27, 28, 29, 30, 30, + 25, 28, 28, 25, 28, 25, 28, 25, + 28, 28, 28, 28, 28, 25, 25, 25, + 28, 25, 28, 28, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 31, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 32, + 33, 34, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 35, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 36, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 2, 10, 10, 2, + 10, 2, 2, 2, 10, 10, 10, 10, + 2, 2, 2, 10, 2, 10, 10, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 10, 9, 9, + 9, 9, 9, 9, 9, 10, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 2, 10, 2, 2, 2, 2, 2, + 2, 2, 10, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 37, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 38, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 39, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 40, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 10, 2, 2, + 2, 2, 2, 2, 2, 10, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 14, 10, 14, 14, 14, 14, 14, + 14, 14, 10, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 10, + 2, 10, 2, 2, 2, 10, 2, 10, + 10, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 41, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, +} + +var _s_to_state_actions []byte = []byte{ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 22, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, +} + +var _s_from_state_actions []byte = []byte{ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 23, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, +} + +var _s_eof_actions []byte = []byte{ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, +} + +var _s_eof_trans []uint16 = []uint16{ + 1, 3, 3, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 1, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 1, 3, 3, 3, 3, 3, 3, 1, + 3, 3, 1, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 1, 3, 3, 3, 1, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 1, 3, 3, 3, 3, 126, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 3, 3, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 3, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 3, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 3, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 3, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 3, 421, 421, 421, + 421, 421, 421, 3, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 3, 421, 3, 421, 421, + 3, 421, 421, 421, 421, 421, 421, 421, + 421, 3, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 3, 421, + 421, 3, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 3, + 421, 3, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 3, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 3, 3, 3, 3, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 3, 3, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 3, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 3, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 421, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 421, 3, 3, 3, 3, + 3, 3, 421, 3, 3, 421, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 421, 3, 3, 3, 3, 3, 421, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 421, 3, 3, 3, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 3, 3, 126, 126, 126, 126, 126, + 126, 126, 126, 3, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 3, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 3, 126, + 126, 126, 126, 126, 126, 3, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 3, 126, 3, 126, + 3, 126, 126, 3, 126, 126, 126, 126, + 126, 126, 126, 126, 3, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 3, 421, 3, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 2395, 3, 3, 2395, + 2395, 2395, 2395, 2395, 2395, 2395, 2395, 2395, + 2395, 2395, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 2395, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 2395, 3, 3, 3, + 3, 3, 3, 2395, 3, 3, 2395, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 2395, 3, + 3, 3, 2395, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 2395, 3, 3, 3, + 3, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 2986, 3, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 2986, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 2986, 3, 3, 3, 3, 3, + 3, 2986, 3, 3, 3, 3, 3, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 3, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 2986, 2986, 3, 3, + 2986, 3, 3, 3, 3, 3, 2986, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 2986, 3, 3, 3, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 3252, 3, 3, 3252, 3252, 3252, + 3252, 3252, 3252, 3252, 3252, 3252, 3252, 3252, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3252, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3252, 3, 3, 3, 3, 3, + 3, 3252, 3, 3, 3252, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3252, 3, 3, 3, + 3252, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3252, 3, 3, 3, 3, 1, + 1, 1, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 3628, 3, 3628, 3628, 3628, + 3628, 3628, 3628, 3628, 3628, 3628, 3628, 3628, + 3628, 3628, 3628, 3628, 3628, 3628, 3628, 3628, + 3628, 3628, 3628, 3628, 3628, 3628, 3628, 3628, + 3628, 3628, 3628, 3628, 3628, 3628, 3628, 3628, + 3628, 3628, 3628, 3628, 3628, 3628, 3628, 3628, + 3628, 3628, 3628, 3628, 3628, 3628, 3628, 3628, + 3628, 3628, 3628, 3628, 3628, 3628, 3628, 3628, + 3628, 3628, 3628, 3628, 3628, 3628, 3628, 3628, + 3628, 3628, 3628, 3628, 3628, 3, 3, 3, + 3, 3628, 3628, 3628, 3628, 3628, 3628, 3628, + 3628, 3628, 3628, 3628, 3628, 3628, 3628, 3628, + 3628, 3628, 3628, 3628, 3628, 3628, 3628, 3628, + 3628, 3628, 3628, 3628, 3628, 3628, 3628, 3628, + 3628, 3628, 3628, 3628, 3628, 3628, 3628, 3628, + 3628, 3628, 3628, 3628, 3628, 3628, 3628, 3628, + 3628, 3628, 3628, 3628, 3628, 3628, 3628, 3628, + 3628, 3628, 3628, 3628, 3628, 3628, 3628, 3628, + 3628, 3628, 3628, 3628, 3628, 3628, 3628, 1, + 3759, 3759, 3759, 3759, 3759, 3759, 3759, 3759, + 3759, 3759, 3759, 3759, 3759, 3759, 3759, 3759, + 3759, 3759, 3759, 3759, 3759, 3759, 3759, 3759, + 3759, 3759, 3759, 3759, 3759, 3759, 3759, 3759, + 3759, 3759, 3759, 3759, 3759, 3759, 3759, 3759, + 3759, 3759, 3759, 3759, 3759, 3759, 3759, 3759, + 3759, 3759, 3759, 3759, 3759, 3759, 3759, 3759, + 3759, 3759, 3759, 3759, 3759, 3759, 3759, 3759, + 3759, 3759, 3759, 3759, 3759, 3759, 3759, 3759, + 3759, 3759, 3759, 3759, 3759, 3759, 3759, 3759, + 3759, 3759, 3759, 3759, 3759, 3759, 3759, 3759, + 3759, 3759, 3759, 3759, 3759, 3759, 3759, 3759, + 3759, 3759, 3759, 3759, 3759, 3759, 3759, 3759, + 3759, 3759, 3759, 3759, 3759, 3759, 3759, 3759, + 3759, 3759, 3759, 3759, 3759, 3759, 3759, 3759, + 3759, 3759, 3759, 3759, 3759, 3759, 3759, 3759, + 3759, 3759, 3759, 3759, 3759, 3759, 3759, 3759, + 3759, 3759, 3759, 3759, 3759, 1, 1, 3252, + 3252, 3252, 3252, 3252, 3252, 3252, 3252, 3252, + 3252, 3252, 3252, 3252, 3252, 3252, 3252, 3252, + 3252, 3252, 3252, 3252, 3252, 3252, 3252, 3252, + 3252, 3252, 3252, 3252, 3252, 3252, 3252, 3252, + 3252, 3252, 3252, 3252, 3252, 3252, 3252, 3252, + 3252, 3252, 3252, 3252, 3252, 3252, 3252, 3252, + 3252, 3252, 3252, 3252, 3252, 3252, 3252, 3252, + 3252, 3252, 3252, 3252, 3252, 3252, 3252, 3252, + 3252, 3252, 3252, 3252, 3252, 3252, 3252, 3252, + 3252, 3252, 3252, 3252, 3252, 3252, 3252, 3252, + 3252, 3252, 3252, 3252, 3252, 3252, 3252, 3252, + 3252, 3252, 3252, 3252, 3252, 3252, 3252, 3252, + 3252, 3252, 3252, 3252, 3252, 3252, 3252, 3252, + 3252, 3252, 3252, 3252, 3252, 3252, 3252, 3252, + 3252, 3252, 3252, 3252, 3252, 3252, 3252, 3252, + 3252, 3252, 3252, 3252, 3252, 3252, 3252, 3252, + 3252, 3252, 3252, 3252, 3252, 3252, 3252, 3252, + 3252, 3252, 3252, 3252, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2986, + 2986, 2986, 2986, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 3, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 4500, + 4520, 4522, 4522, 4563, 4563, 4563, 4563, 4563, + 4563, 4522, 4563, 4563, 4563, 4500, 4764, 4500, + 4563, 4563, 4500, 4500, 4563, 4500, 4563, 4563, + 4563, 4563, 4563, 4563, 4563, 4563, 4563, 4500, + 4500, 4563, 4563, 4563, 4563, 4563, 4563, 4563, + 4563, 4563, 4563, 4563, 4500, 4500, 4500, 4500, + 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, + 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, + 4500, 4563, 4563, 4563, 4500, 4563, 4563, 4563, + 4563, 4563, 4563, 4563, 4500, 4500, 4500, 4500, + 4563, 4563, 4563, 4563, 4563, 4563, 4563, 4563, + 4563, 4563, 4563, 4563, 4563, 4563, 4563, 4563, + 4563, 4563, 4563, 4563, 4563, 4563, 4563, 4563, + 4563, 4563, 4563, 4563, 4563, 4563, 4563, 4563, + 4563, 4563, 4563, 4563, 4563, 4563, 4563, 4563, + 4563, 4563, 4563, 4563, 4563, 4563, 4563, 4563, + 4563, 4563, 4563, 4563, 4563, 4563, 4563, 4563, + 4563, 4563, 4563, 4563, 4563, 4563, 4563, 4563, + 4563, 4563, 4563, 4563, 4563, 4563, 4563, 4563, + 4500, 4500, 4764, 4764, 4500, 4500, 4500, 4500, + 4500, 4500, 4500, 4500, 4500, 4764, 4764, 4764, + 4764, 4764, 4764, 4764, 4764, 4500, 4500, 4500, + 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, + 4764, 4764, 4764, 4764, 4764, 4764, 4764, 4764, + 4764, 4764, 4764, 4500, 4500, 4500, 4500, 4500, + 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, + 4500, 5003, 5003, 4500, 5055, 4500, 4563, 5003, + 5138, 5158, 5055, 5055, 5055, 5055, 4500, 4500, + 5055, 5055, 4500, 4500, 4500, 4500, 4500, 4500, + 4500, 4500, 5055, 5055, 5055, 5055, 5055, 5055, + 5055, 5055, 4500, 4500, 4500, 4500, 4500, 4500, + 4500, 4500, 4500, 4500, 4500, 5055, 5055, 5055, + 5055, 5055, 5055, 5055, 5055, 5055, 5055, 5055, + 5055, 5055, 5055, 5055, 5055, 5055, 5055, 5055, + 5055, 5055, 5055, 5055, 5055, 5055, 5055, 5055, + 5055, 5055, 5055, 5055, 5055, 5055, 5055, 5055, + 5055, 5055, 5055, 5055, 5055, 5055, 5055, 5055, + 5055, 5055, 5055, 5055, 5055, 5055, 5055, 5055, + 5055, 5055, 5055, 5055, 5055, 5055, 5055, 5055, + 5055, 5055, 5055, 5055, 5055, 5055, 5055, 5055, + 5055, 5055, 5055, 5055, 5055, 5055, 5055, 5055, + 5055, 5055, 5055, 5055, 5055, 5055, 5055, 5055, + 5055, 5055, 5055, 5055, 5055, 5055, 5055, 4500, + 4500, 4500, 4500, 5003, 5003, 5003, 5003, 4500, + 4500, 5003, 5003, 4500, 4500, 4500, 4500, 4500, + 4500, 4500, 4500, 5003, 5003, 5003, 5003, 5003, + 5003, 5003, 5003, 4500, 4500, 4500, 4500, 4500, + 4500, 4500, 4500, 5003, 5003, 5003, 5003, 5003, + 5003, 5003, 4500, 5003, 5003, 5003, 5003, 5003, + 5003, 5003, 5003, 5003, 5003, 5003, 5003, 5003, + 4500, 4500, 4500, 4500, 5003, 5003, 5003, 5003, + 5003, 5003, 5003, 5003, 5003, 5003, 5003, 5003, + 5003, 5003, 5003, 5003, 5003, 5003, 5003, 5003, + 5003, 5003, 5003, 5003, 5003, 5003, 5003, 5003, + 5003, 5003, 5003, 5003, 5003, 5003, 5003, 5003, + 5003, 5003, 5003, 5003, 5003, 5003, 5003, 5003, + 5003, 5003, 5003, 5003, 5003, 5003, 5003, 5003, + 5003, 5003, 5003, 5003, 5003, 5003, 5003, 5003, + 5003, 5003, 5003, 5003, 5003, 5003, 5003, 5003, + 5003, 5003, 4500, 4500, 5360, +} + +const s_start int = 4862 +const s_first_final int = 4862 +const s_error int = -1 + +const s_en_main int = 4862 + + +//line segment_words.rl:35 + + +func segmentWords(data []byte, maxTokens int, atEOF bool, val [][]byte, types []int) ([][]byte, []int, int, error) { + cs, p, pe := 0, 0, len(data) + cap := maxTokens + if cap < 0 { + cap = 1000 + } + if val == nil { + val = make([][]byte, 0, cap) + } + if types == nil { + types = make([]int, 0, cap) + } + + // added for scanner + ts := 0 + te := 0 + act := 0 + eof := pe + _ = ts // compiler not happy + _ = te + _ = act + + // our state + startPos := 0 + endPos := 0 + totalConsumed := 0 + +//line segment_words.go:18574 + { + cs = s_start + ts = 0 + te = 0 + act = 0 + } + +//line segment_words.go:18582 + { + var _klen int + var _keys int + var _trans int + + if p == pe { + goto _test_eof + } +_resume: + switch _s_from_state_actions[cs] { + case 23: +//line NONE:1 +ts = p + + +//line segment_words.go:18598 + } + + _keys = int(_s_key_offsets[cs]) + _trans = int(_s_index_offsets[cs]) + + _klen = int(_s_single_lengths[cs]) + if _klen > 0 { + _lower := int(_keys) + var _mid int + _upper := int(_keys + _klen - 1) + for { + if _upper < _lower { + break + } + + _mid = _lower + ((_upper - _lower) >> 1) + switch { + case data[p] < _s_trans_keys[_mid]: + _upper = _mid - 1 + case data[p] > _s_trans_keys[_mid]: + _lower = _mid + 1 + default: + _trans += int(_mid - int(_keys)) + goto _match + } + } + _keys += _klen + _trans += _klen + } + + _klen = int(_s_range_lengths[cs]) + if _klen > 0 { + _lower := int(_keys) + var _mid int + _upper := int(_keys + (_klen << 1) - 2) + for { + if _upper < _lower { + break + } + + _mid = _lower + (((_upper - _lower) >> 1) & ^1) + switch { + case data[p] < _s_trans_keys[_mid]: + _upper = _mid - 2 + case data[p] > _s_trans_keys[_mid + 1]: + _lower = _mid + 2 + default: + _trans += int((_mid - int(_keys)) >> 1) + goto _match + } + } + _trans += _klen + } + +_match: + _trans = int(_s_indicies[_trans]) +_eof_trans: + cs = int(_s_trans_targs[_trans]) + + if _s_trans_actions[_trans] == 0 { + goto _again + } + + switch _s_trans_actions[_trans] { + case 10: +//line segment_words.rl:72 + + endPos = p + + + case 34: +//line segment_words.rl:76 +te = p +p-- +{ + if !atEOF { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Number) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 37: +//line segment_words.rl:89 +te = p +p-- +{ + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Letter) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 39: +//line segment_words.rl:104 +te = p +p-- +{ + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 35: +//line segment_words.rl:119 +te = p +p-- +{ + if !atEOF { + return val, types, totalConsumed, nil + } + val = append(val, data[startPos:endPos+1]) + types = append(types, Letter) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 38: +//line segment_words.rl:131 +te = p +p-- +{ + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 40: +//line segment_words.rl:146 +te = p +p-- +{ + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 41: +//line segment_words.rl:161 +te = p +p-- +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 32: +//line segment_words.rl:161 +te = p +p-- +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 36: +//line segment_words.rl:161 +te = p +p-- +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 31: +//line segment_words.rl:161 +te = p +p-- +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 4: +//line segment_words.rl:76 +p = (te) - 1 +{ + if !atEOF { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Number) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 12: +//line segment_words.rl:89 +p = (te) - 1 +{ + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Letter) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 17: +//line segment_words.rl:104 +p = (te) - 1 +{ + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 7: +//line segment_words.rl:119 +p = (te) - 1 +{ + if !atEOF { + return val, types, totalConsumed, nil + } + val = append(val, data[startPos:endPos+1]) + types = append(types, Letter) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 15: +//line segment_words.rl:131 +p = (te) - 1 +{ + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 19: +//line segment_words.rl:146 +p = (te) - 1 +{ + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 21: +//line segment_words.rl:161 +p = (te) - 1 +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 8: +//line segment_words.rl:161 +p = (te) - 1 +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 1: +//line segment_words.rl:161 +p = (te) - 1 +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 3: +//line NONE:1 + switch act { + case 1: + {p = (te) - 1 + + if !atEOF { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Number) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + case 2: + {p = (te) - 1 + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Letter) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + case 3: + {p = (te) - 1 + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + case 4: + {p = (te) - 1 + + if !atEOF { + return val, types, totalConsumed, nil + } + val = append(val, data[startPos:endPos+1]) + types = append(types, Letter) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + case 5: + {p = (te) - 1 + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + case 7: + {p = (te) - 1 + + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + case 12: + {p = (te) - 1 + + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + case 13: + {p = (te) - 1 + + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + } + + + case 28: +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + + + case 33: +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +te = p+1 +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 13: +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +te = p+1 +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 18: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + + + case 26: +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +te = p+1 +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 27: +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +te = p+1 +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + case 5: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:76 +act = 1; + + case 11: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + + case 16: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:104 +act = 3; + + case 6: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + + case 14: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + + case 20: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 7; + + case 9: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + + case 2: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + + case 29: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:76 +act = 1; + + case 30: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + + case 25: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + +//line segment_words.go:19500 + } + +_again: + switch _s_to_state_actions[cs] { + case 22: +//line NONE:1 +ts = 0 + + +//line segment_words.go:19510 + } + + if p++; p != pe { + goto _resume + } + _test_eof: {} + if p == eof { + if _s_eof_trans[cs] > 0 { + _trans = int(_s_eof_trans[cs] - 1) + goto _eof_trans + } + switch _s_eof_actions[cs] { + case 24: +//line segment_words.rl:68 + + startPos = p + + +//line segment_words.go:19529 + } + } + + } + +//line segment_words.rl:278 + + + if cs < s_first_final { + return val, types, totalConsumed, ParseError + } + + return val, types, totalConsumed, nil +} diff --git a/backend/vendor/github.com/blevesearch/segment/segment_words.rl b/backend/vendor/github.com/blevesearch/segment/segment_words.rl new file mode 100644 index 0000000000..e69af8b214 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/segment/segment_words.rl @@ -0,0 +1,285 @@ +// Copyright (c) 2015 Couchbase, Inc. +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software distributed under the +// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. + +// +build BUILDTAGS + +package segment + +import ( + "fmt" + "unicode/utf8" +) + +var RagelFlags = "RAGELFLAGS" + +var ParseError = fmt.Errorf("unicode word segmentation parse error") + +// Word Types +const ( + None = iota + Number + Letter + Kana + Ideo +) + +%%{ + machine s; + write data; +}%% + +func segmentWords(data []byte, maxTokens int, atEOF bool, val [][]byte, types []int) ([][]byte, []int, int, error) { + cs, p, pe := 0, 0, len(data) + cap := maxTokens + if cap < 0 { + cap = 1000 + } + if val == nil { + val = make([][]byte, 0, cap) + } + if types == nil { + types = make([]int, 0, cap) + } + + // added for scanner + ts := 0 + te := 0 + act := 0 + eof := pe + _ = ts // compiler not happy + _ = te + _ = act + + // our state + startPos := 0 + endPos := 0 + totalConsumed := 0 + %%{ + + include SCRIPTS "ragel/uscript.rl"; + include WB "ragel/uwb.rl"; + + action startToken { + startPos = p + } + + action endToken { + endPos = p + } + + action finishNumericToken { + if !atEOF { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Number) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + action finishHangulToken { + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Letter) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + action finishKatakanaToken { + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + action finishWordToken { + if !atEOF { + return val, types, totalConsumed, nil + } + val = append(val, data[startPos:endPos+1]) + types = append(types, Letter) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + action finishHanToken { + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + action finishHiraganaToken { + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + action finishNoneToken { + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + + HangulEx = Hangul ( Extend | Format )*; + HebrewOrALetterEx = ( Hebrew_Letter | ALetter ) ( Extend | Format )*; + NumericEx = Numeric ( Extend | Format )*; + KatakanaEx = Katakana ( Extend | Format )*; + MidLetterEx = ( MidLetter | MidNumLet | Single_Quote ) ( Extend | Format )*; + MidNumericEx = ( MidNum | MidNumLet | Single_Quote ) ( Extend | Format )*; + ExtendNumLetEx = ExtendNumLet ( Extend | Format )*; + HanEx = Han ( Extend | Format )*; + HiraganaEx = Hiragana ( Extend | Format )*; + SingleQuoteEx = Single_Quote ( Extend | Format )*; + DoubleQuoteEx = Double_Quote ( Extend | Format )*; + HebrewLetterEx = Hebrew_Letter ( Extend | Format )*; + RegionalIndicatorEx = Regional_Indicator ( Extend | Format )*; + NLCRLF = Newline | CR | LF; + OtherEx = ^(NLCRLF) ( Extend | Format )* ; + + # UAX#29 WB8. Numeric × Numeric + # WB11. Numeric (MidNum | MidNumLet | Single_Quote) × Numeric + # WB12. Numeric × (MidNum | MidNumLet | Single_Quote) Numeric + # WB13a. (ALetter | Hebrew_Letter | Numeric | Katakana | ExtendNumLet) × ExtendNumLet + # WB13b. ExtendNumLet × (ALetter | Hebrew_Letter | Numeric | Katakana) + # + WordNumeric = ( ( ExtendNumLetEx )* NumericEx ( ( ( ExtendNumLetEx )* | MidNumericEx ) NumericEx )* ( ExtendNumLetEx )* ) >startToken @endToken; + + # subset of the below for typing purposes only! + WordHangul = ( HangulEx )+ >startToken @endToken; + WordKatakana = ( KatakanaEx )+ >startToken @endToken; + + # UAX#29 WB5. (ALetter | Hebrew_Letter) × (ALetter | Hebrew_Letter) + # WB6. (ALetter | Hebrew_Letter) × (MidLetter | MidNumLet | Single_Quote) (ALetter | Hebrew_Letter) + # WB7. (ALetter | Hebrew_Letter) (MidLetter | MidNumLet | Single_Quote) × (ALetter | Hebrew_Letter) + # WB7a. Hebrew_Letter × Single_Quote + # WB7b. Hebrew_Letter × Double_Quote Hebrew_Letter + # WB7c. Hebrew_Letter Double_Quote × Hebrew_Letter + # WB9. (ALetter | Hebrew_Letter) × Numeric + # WB10. Numeric × (ALetter | Hebrew_Letter) + # WB13. Katakana × Katakana + # WB13a. (ALetter | Hebrew_Letter | Numeric | Katakana | ExtendNumLet) × ExtendNumLet + # WB13b. ExtendNumLet × (ALetter | Hebrew_Letter | Numeric | Katakana) + # + # Marty -deviated here to allow for (ExtendNumLetEx x ExtendNumLetEx) part of 13a + # + Word = ( ( ExtendNumLetEx )* ( KatakanaEx ( ( ExtendNumLetEx )* KatakanaEx )* + | ( HebrewLetterEx ( SingleQuoteEx | DoubleQuoteEx HebrewLetterEx ) + | NumericEx ( ( ( ExtendNumLetEx )* | MidNumericEx ) NumericEx )* + | HebrewOrALetterEx ( ( ( ExtendNumLetEx )* | MidLetterEx ) HebrewOrALetterEx )* + |ExtendNumLetEx + )+ + ) + ( + ( ExtendNumLetEx )+ ( KatakanaEx ( ( ExtendNumLetEx )* KatakanaEx )* + | ( HebrewLetterEx ( SingleQuoteEx | DoubleQuoteEx HebrewLetterEx ) + | NumericEx ( ( ( ExtendNumLetEx )* | MidNumericEx ) NumericEx )* + | HebrewOrALetterEx ( ( ( ExtendNumLetEx )* | MidLetterEx ) HebrewOrALetterEx )* + )+ + ) + )* ExtendNumLetEx*) >startToken @endToken; + + # UAX#29 WB14. Any ÷ Any + WordHan = HanEx >startToken @endToken; + WordHiragana = HiraganaEx >startToken @endToken; + + WordExt = ( ( Extend | Format )* ) >startToken @endToken; # maybe plus not star + + WordCRLF = (CR LF) >startToken @endToken; + + WordCR = CR >startToken @endToken; + + WordLF = LF >startToken @endToken; + + WordNL = Newline >startToken @endToken; + + WordRegional = (RegionalIndicatorEx+) >startToken @endToken; + + Other = OtherEx >startToken @endToken; + + main := |* + WordNumeric => finishNumericToken; + WordHangul => finishHangulToken; + WordKatakana => finishKatakanaToken; + Word => finishWordToken; + WordHan => finishHanToken; + WordHiragana => finishHiraganaToken; + WordRegional =>finishNoneToken; + WordCRLF => finishNoneToken; + WordCR => finishNoneToken; + WordLF => finishNoneToken; + WordNL => finishNoneToken; + WordExt => finishNoneToken; + Other => finishNoneToken; + *|; + + write init; + write exec; + }%% + + if cs < s_first_final { + return val, types, totalConsumed, ParseError + } + + return val, types, totalConsumed, nil +} diff --git a/backend/vendor/github.com/blevesearch/segment/segment_words_prod.go b/backend/vendor/github.com/blevesearch/segment/segment_words_prod.go new file mode 100644 index 0000000000..93b3b6e8ac --- /dev/null +++ b/backend/vendor/github.com/blevesearch/segment/segment_words_prod.go @@ -0,0 +1,173643 @@ + +//line segment_words.rl:1 +// Copyright (c) 2015 Couchbase, Inc. +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software distributed under the +// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. + +// +build prod + +package segment + +import ( + "fmt" + "unicode/utf8" +) + +var RagelFlags = "-G2" + +var ParseError = fmt.Errorf("unicode word segmentation parse error") + +// Word Types +const ( + None = iota + Number + Letter + Kana + Ideo +) + + +//line segment_words_prod.go:36 +const s_start int = 4862 +const s_first_final int = 4862 +const s_error int = -1 + +const s_en_main int = 4862 + + +//line segment_words.rl:35 + + +func segmentWords(data []byte, maxTokens int, atEOF bool, val [][]byte, types []int) ([][]byte, []int, int, error) { + cs, p, pe := 0, 0, len(data) + cap := maxTokens + if cap < 0 { + cap = 1000 + } + if val == nil { + val = make([][]byte, 0, cap) + } + if types == nil { + types = make([]int, 0, cap) + } + + // added for scanner + ts := 0 + te := 0 + act := 0 + eof := pe + _ = ts // compiler not happy + _ = te + _ = act + + // our state + startPos := 0 + endPos := 0 + totalConsumed := 0 + +//line segment_words_prod.go:74 + { + cs = s_start + ts = 0 + te = 0 + act = 0 + } + +//line segment_words_prod.go:82 + { + if p == pe { + goto _test_eof + } + switch cs { + case 4862: + goto st_case_4862 + case 4863: + goto st_case_4863 + case 0: + goto st_case_0 + case 1: + goto st_case_1 + case 2: + goto st_case_2 + case 3: + goto st_case_3 + case 4: + goto st_case_4 + case 5: + goto st_case_5 + case 6: + goto st_case_6 + case 7: + goto st_case_7 + case 8: + goto st_case_8 + case 9: + goto st_case_9 + case 10: + goto st_case_10 + case 11: + goto st_case_11 + case 12: + goto st_case_12 + case 13: + goto st_case_13 + case 14: + goto st_case_14 + case 15: + goto st_case_15 + case 16: + goto st_case_16 + case 17: + goto st_case_17 + case 18: + goto st_case_18 + case 19: + goto st_case_19 + case 20: + goto st_case_20 + case 21: + goto st_case_21 + case 22: + goto st_case_22 + case 23: + goto st_case_23 + case 24: + goto st_case_24 + case 25: + goto st_case_25 + case 26: + goto st_case_26 + case 27: + goto st_case_27 + case 28: + goto st_case_28 + case 29: + goto st_case_29 + case 30: + goto st_case_30 + case 31: + goto st_case_31 + case 32: + goto st_case_32 + case 33: + goto st_case_33 + case 34: + goto st_case_34 + case 35: + goto st_case_35 + case 36: + goto st_case_36 + case 37: + goto st_case_37 + case 38: + goto st_case_38 + case 39: + goto st_case_39 + case 40: + goto st_case_40 + case 41: + goto st_case_41 + case 42: + goto st_case_42 + case 43: + goto st_case_43 + case 44: + goto st_case_44 + case 45: + goto st_case_45 + case 46: + goto st_case_46 + case 47: + goto st_case_47 + case 48: + goto st_case_48 + case 49: + goto st_case_49 + case 50: + goto st_case_50 + case 51: + goto st_case_51 + case 52: + goto st_case_52 + case 53: + goto st_case_53 + case 54: + goto st_case_54 + case 55: + goto st_case_55 + case 56: + goto st_case_56 + case 57: + goto st_case_57 + case 58: + goto st_case_58 + case 59: + goto st_case_59 + case 60: + goto st_case_60 + case 61: + goto st_case_61 + case 62: + goto st_case_62 + case 63: + goto st_case_63 + case 64: + goto st_case_64 + case 65: + goto st_case_65 + case 66: + goto st_case_66 + case 67: + goto st_case_67 + case 68: + goto st_case_68 + case 69: + goto st_case_69 + case 70: + goto st_case_70 + case 71: + goto st_case_71 + case 72: + goto st_case_72 + case 73: + goto st_case_73 + case 74: + goto st_case_74 + case 75: + goto st_case_75 + case 76: + goto st_case_76 + case 77: + goto st_case_77 + case 78: + goto st_case_78 + case 79: + goto st_case_79 + case 80: + goto st_case_80 + case 81: + goto st_case_81 + case 82: + goto st_case_82 + case 83: + goto st_case_83 + case 84: + goto st_case_84 + case 85: + goto st_case_85 + case 86: + goto st_case_86 + case 87: + goto st_case_87 + case 88: + goto st_case_88 + case 89: + goto st_case_89 + case 90: + goto st_case_90 + case 91: + goto st_case_91 + case 92: + goto st_case_92 + case 93: + goto st_case_93 + case 94: + goto st_case_94 + case 95: + goto st_case_95 + case 96: + goto st_case_96 + case 97: + goto st_case_97 + case 98: + goto st_case_98 + case 99: + goto st_case_99 + case 100: + goto st_case_100 + case 101: + goto st_case_101 + case 102: + goto st_case_102 + case 103: + goto st_case_103 + case 104: + goto st_case_104 + case 105: + goto st_case_105 + case 106: + goto st_case_106 + case 107: + goto st_case_107 + case 108: + goto st_case_108 + case 109: + goto st_case_109 + case 110: + goto st_case_110 + case 111: + goto st_case_111 + case 112: + goto st_case_112 + case 113: + goto st_case_113 + case 114: + goto st_case_114 + case 115: + goto st_case_115 + case 116: + goto st_case_116 + case 117: + goto st_case_117 + case 118: + goto st_case_118 + case 119: + goto st_case_119 + case 120: + goto st_case_120 + case 121: + goto st_case_121 + case 122: + goto st_case_122 + case 123: + goto st_case_123 + case 124: + goto st_case_124 + case 125: + goto st_case_125 + case 126: + goto st_case_126 + case 127: + goto st_case_127 + case 128: + goto st_case_128 + case 129: + goto st_case_129 + case 130: + goto st_case_130 + case 131: + goto st_case_131 + case 132: + goto st_case_132 + case 133: + goto st_case_133 + case 134: + goto st_case_134 + case 135: + goto st_case_135 + case 136: + goto st_case_136 + case 137: + goto st_case_137 + case 138: + goto st_case_138 + case 139: + goto st_case_139 + case 140: + goto st_case_140 + case 4864: + goto st_case_4864 + case 4865: + goto st_case_4865 + case 141: + goto st_case_141 + case 4866: + goto st_case_4866 + case 4867: + goto st_case_4867 + case 142: + goto st_case_142 + case 143: + goto st_case_143 + case 144: + goto st_case_144 + case 145: + goto st_case_145 + case 146: + goto st_case_146 + case 147: + goto st_case_147 + case 148: + goto st_case_148 + case 149: + goto st_case_149 + case 150: + goto st_case_150 + case 151: + goto st_case_151 + case 152: + goto st_case_152 + case 153: + goto st_case_153 + case 154: + goto st_case_154 + case 155: + goto st_case_155 + case 156: + goto st_case_156 + case 157: + goto st_case_157 + case 158: + goto st_case_158 + case 159: + goto st_case_159 + case 160: + goto st_case_160 + case 161: + goto st_case_161 + case 162: + goto st_case_162 + case 163: + goto st_case_163 + case 164: + goto st_case_164 + case 165: + goto st_case_165 + case 166: + goto st_case_166 + case 167: + goto st_case_167 + case 168: + goto st_case_168 + case 169: + goto st_case_169 + case 170: + goto st_case_170 + case 171: + goto st_case_171 + case 172: + goto st_case_172 + case 173: + goto st_case_173 + case 174: + goto st_case_174 + case 175: + goto st_case_175 + case 176: + goto st_case_176 + case 177: + goto st_case_177 + case 178: + goto st_case_178 + case 179: + goto st_case_179 + case 180: + goto st_case_180 + case 181: + goto st_case_181 + case 182: + goto st_case_182 + case 183: + goto st_case_183 + case 184: + goto st_case_184 + case 185: + goto st_case_185 + case 186: + goto st_case_186 + case 187: + goto st_case_187 + case 188: + goto st_case_188 + case 189: + goto st_case_189 + case 190: + goto st_case_190 + case 191: + goto st_case_191 + case 192: + goto st_case_192 + case 193: + goto st_case_193 + case 194: + goto st_case_194 + case 195: + goto st_case_195 + case 196: + goto st_case_196 + case 197: + goto st_case_197 + case 198: + goto st_case_198 + case 199: + goto st_case_199 + case 200: + goto st_case_200 + case 201: + goto st_case_201 + case 202: + goto st_case_202 + case 203: + goto st_case_203 + case 204: + goto st_case_204 + case 205: + goto st_case_205 + case 206: + goto st_case_206 + case 207: + goto st_case_207 + case 208: + goto st_case_208 + case 209: + goto st_case_209 + case 210: + goto st_case_210 + case 211: + goto st_case_211 + case 212: + goto st_case_212 + case 213: + goto st_case_213 + case 214: + goto st_case_214 + case 215: + goto st_case_215 + case 216: + goto st_case_216 + case 217: + goto st_case_217 + case 218: + goto st_case_218 + case 219: + goto st_case_219 + case 220: + goto st_case_220 + case 221: + goto st_case_221 + case 222: + goto st_case_222 + case 223: + goto st_case_223 + case 224: + goto st_case_224 + case 225: + goto st_case_225 + case 226: + goto st_case_226 + case 227: + goto st_case_227 + case 228: + goto st_case_228 + case 229: + goto st_case_229 + case 230: + goto st_case_230 + case 231: + goto st_case_231 + case 232: + goto st_case_232 + case 233: + goto st_case_233 + case 234: + goto st_case_234 + case 235: + goto st_case_235 + case 236: + goto st_case_236 + case 237: + goto st_case_237 + case 238: + goto st_case_238 + case 239: + goto st_case_239 + case 240: + goto st_case_240 + case 241: + goto st_case_241 + case 242: + goto st_case_242 + case 243: + goto st_case_243 + case 244: + goto st_case_244 + case 245: + goto st_case_245 + case 246: + goto st_case_246 + case 247: + goto st_case_247 + case 248: + goto st_case_248 + case 249: + goto st_case_249 + case 250: + goto st_case_250 + case 251: + goto st_case_251 + case 252: + goto st_case_252 + case 253: + goto st_case_253 + case 254: + goto st_case_254 + case 255: + goto st_case_255 + case 256: + goto st_case_256 + case 257: + goto st_case_257 + case 258: + goto st_case_258 + case 259: + goto st_case_259 + case 260: + goto st_case_260 + case 261: + goto st_case_261 + case 262: + goto st_case_262 + case 263: + goto st_case_263 + case 264: + goto st_case_264 + case 265: + goto st_case_265 + case 266: + goto st_case_266 + case 267: + goto st_case_267 + case 268: + goto st_case_268 + case 269: + goto st_case_269 + case 270: + goto st_case_270 + case 271: + goto st_case_271 + case 272: + goto st_case_272 + case 273: + goto st_case_273 + case 274: + goto st_case_274 + case 275: + goto st_case_275 + case 276: + goto st_case_276 + case 277: + goto st_case_277 + case 278: + goto st_case_278 + case 279: + goto st_case_279 + case 280: + goto st_case_280 + case 281: + goto st_case_281 + case 282: + goto st_case_282 + case 283: + goto st_case_283 + case 284: + goto st_case_284 + case 285: + goto st_case_285 + case 286: + goto st_case_286 + case 287: + goto st_case_287 + case 288: + goto st_case_288 + case 289: + goto st_case_289 + case 290: + goto st_case_290 + case 291: + goto st_case_291 + case 292: + goto st_case_292 + case 293: + goto st_case_293 + case 294: + goto st_case_294 + case 295: + goto st_case_295 + case 296: + goto st_case_296 + case 297: + goto st_case_297 + case 298: + goto st_case_298 + case 299: + goto st_case_299 + case 300: + goto st_case_300 + case 301: + goto st_case_301 + case 302: + goto st_case_302 + case 303: + goto st_case_303 + case 304: + goto st_case_304 + case 305: + goto st_case_305 + case 306: + goto st_case_306 + case 307: + goto st_case_307 + case 308: + goto st_case_308 + case 309: + goto st_case_309 + case 310: + goto st_case_310 + case 311: + goto st_case_311 + case 312: + goto st_case_312 + case 313: + goto st_case_313 + case 314: + goto st_case_314 + case 315: + goto st_case_315 + case 316: + goto st_case_316 + case 317: + goto st_case_317 + case 318: + goto st_case_318 + case 319: + goto st_case_319 + case 320: + goto st_case_320 + case 321: + goto st_case_321 + case 322: + goto st_case_322 + case 323: + goto st_case_323 + case 324: + goto st_case_324 + case 325: + goto st_case_325 + case 326: + goto st_case_326 + case 327: + goto st_case_327 + case 328: + goto st_case_328 + case 329: + goto st_case_329 + case 330: + goto st_case_330 + case 331: + goto st_case_331 + case 332: + goto st_case_332 + case 333: + goto st_case_333 + case 334: + goto st_case_334 + case 335: + goto st_case_335 + case 336: + goto st_case_336 + case 337: + goto st_case_337 + case 338: + goto st_case_338 + case 339: + goto st_case_339 + case 340: + goto st_case_340 + case 341: + goto st_case_341 + case 342: + goto st_case_342 + case 343: + goto st_case_343 + case 344: + goto st_case_344 + case 345: + goto st_case_345 + case 346: + goto st_case_346 + case 347: + goto st_case_347 + case 348: + goto st_case_348 + case 349: + goto st_case_349 + case 350: + goto st_case_350 + case 351: + goto st_case_351 + case 352: + goto st_case_352 + case 353: + goto st_case_353 + case 354: + goto st_case_354 + case 355: + goto st_case_355 + case 356: + goto st_case_356 + case 357: + goto st_case_357 + case 358: + goto st_case_358 + case 359: + goto st_case_359 + case 360: + goto st_case_360 + case 361: + goto st_case_361 + case 362: + goto st_case_362 + case 363: + goto st_case_363 + case 364: + goto st_case_364 + case 365: + goto st_case_365 + case 366: + goto st_case_366 + case 367: + goto st_case_367 + case 368: + goto st_case_368 + case 369: + goto st_case_369 + case 370: + goto st_case_370 + case 371: + goto st_case_371 + case 372: + goto st_case_372 + case 373: + goto st_case_373 + case 374: + goto st_case_374 + case 375: + goto st_case_375 + case 376: + goto st_case_376 + case 377: + goto st_case_377 + case 378: + goto st_case_378 + case 379: + goto st_case_379 + case 380: + goto st_case_380 + case 381: + goto st_case_381 + case 382: + goto st_case_382 + case 383: + goto st_case_383 + case 384: + goto st_case_384 + case 385: + goto st_case_385 + case 386: + goto st_case_386 + case 387: + goto st_case_387 + case 388: + goto st_case_388 + case 389: + goto st_case_389 + case 390: + goto st_case_390 + case 391: + goto st_case_391 + case 392: + goto st_case_392 + case 393: + goto st_case_393 + case 394: + goto st_case_394 + case 395: + goto st_case_395 + case 396: + goto st_case_396 + case 397: + goto st_case_397 + case 398: + goto st_case_398 + case 399: + goto st_case_399 + case 400: + goto st_case_400 + case 401: + goto st_case_401 + case 402: + goto st_case_402 + case 403: + goto st_case_403 + case 404: + goto st_case_404 + case 405: + goto st_case_405 + case 406: + goto st_case_406 + case 407: + goto st_case_407 + case 408: + goto st_case_408 + case 409: + goto st_case_409 + case 410: + goto st_case_410 + case 411: + goto st_case_411 + case 412: + goto st_case_412 + case 4868: + goto st_case_4868 + case 413: + goto st_case_413 + case 414: + goto st_case_414 + case 415: + goto st_case_415 + case 416: + goto st_case_416 + case 417: + goto st_case_417 + case 418: + goto st_case_418 + case 419: + goto st_case_419 + case 420: + goto st_case_420 + case 421: + goto st_case_421 + case 422: + goto st_case_422 + case 423: + goto st_case_423 + case 424: + goto st_case_424 + case 425: + goto st_case_425 + case 426: + goto st_case_426 + case 427: + goto st_case_427 + case 428: + goto st_case_428 + case 429: + goto st_case_429 + case 430: + goto st_case_430 + case 431: + goto st_case_431 + case 432: + goto st_case_432 + case 433: + goto st_case_433 + case 434: + goto st_case_434 + case 435: + goto st_case_435 + case 436: + goto st_case_436 + case 437: + goto st_case_437 + case 438: + goto st_case_438 + case 439: + goto st_case_439 + case 440: + goto st_case_440 + case 441: + goto st_case_441 + case 442: + goto st_case_442 + case 443: + goto st_case_443 + case 444: + goto st_case_444 + case 445: + goto st_case_445 + case 446: + goto st_case_446 + case 447: + goto st_case_447 + case 448: + goto st_case_448 + case 449: + goto st_case_449 + case 450: + goto st_case_450 + case 451: + goto st_case_451 + case 452: + goto st_case_452 + case 453: + goto st_case_453 + case 454: + goto st_case_454 + case 455: + goto st_case_455 + case 456: + goto st_case_456 + case 457: + goto st_case_457 + case 458: + goto st_case_458 + case 459: + goto st_case_459 + case 460: + goto st_case_460 + case 461: + goto st_case_461 + case 462: + goto st_case_462 + case 463: + goto st_case_463 + case 464: + goto st_case_464 + case 465: + goto st_case_465 + case 466: + goto st_case_466 + case 467: + goto st_case_467 + case 468: + goto st_case_468 + case 469: + goto st_case_469 + case 470: + goto st_case_470 + case 471: + goto st_case_471 + case 472: + goto st_case_472 + case 473: + goto st_case_473 + case 474: + goto st_case_474 + case 475: + goto st_case_475 + case 476: + goto st_case_476 + case 477: + goto st_case_477 + case 478: + goto st_case_478 + case 479: + goto st_case_479 + case 480: + goto st_case_480 + case 481: + goto st_case_481 + case 482: + goto st_case_482 + case 483: + goto st_case_483 + case 484: + goto st_case_484 + case 485: + goto st_case_485 + case 486: + goto st_case_486 + case 487: + goto st_case_487 + case 488: + goto st_case_488 + case 489: + goto st_case_489 + case 490: + goto st_case_490 + case 491: + goto st_case_491 + case 492: + goto st_case_492 + case 493: + goto st_case_493 + case 494: + goto st_case_494 + case 495: + goto st_case_495 + case 496: + goto st_case_496 + case 497: + goto st_case_497 + case 498: + goto st_case_498 + case 499: + goto st_case_499 + case 500: + goto st_case_500 + case 501: + goto st_case_501 + case 502: + goto st_case_502 + case 503: + goto st_case_503 + case 504: + goto st_case_504 + case 505: + goto st_case_505 + case 506: + goto st_case_506 + case 507: + goto st_case_507 + case 508: + goto st_case_508 + case 509: + goto st_case_509 + case 510: + goto st_case_510 + case 511: + goto st_case_511 + case 512: + goto st_case_512 + case 513: + goto st_case_513 + case 514: + goto st_case_514 + case 515: + goto st_case_515 + case 516: + goto st_case_516 + case 517: + goto st_case_517 + case 518: + goto st_case_518 + case 519: + goto st_case_519 + case 520: + goto st_case_520 + case 521: + goto st_case_521 + case 522: + goto st_case_522 + case 523: + goto st_case_523 + case 524: + goto st_case_524 + case 525: + goto st_case_525 + case 526: + goto st_case_526 + case 527: + goto st_case_527 + case 528: + goto st_case_528 + case 529: + goto st_case_529 + case 530: + goto st_case_530 + case 531: + goto st_case_531 + case 532: + goto st_case_532 + case 533: + goto st_case_533 + case 534: + goto st_case_534 + case 535: + goto st_case_535 + case 536: + goto st_case_536 + case 537: + goto st_case_537 + case 538: + goto st_case_538 + case 539: + goto st_case_539 + case 540: + goto st_case_540 + case 541: + goto st_case_541 + case 542: + goto st_case_542 + case 543: + goto st_case_543 + case 544: + goto st_case_544 + case 545: + goto st_case_545 + case 546: + goto st_case_546 + case 547: + goto st_case_547 + case 548: + goto st_case_548 + case 549: + goto st_case_549 + case 550: + goto st_case_550 + case 551: + goto st_case_551 + case 552: + goto st_case_552 + case 553: + goto st_case_553 + case 554: + goto st_case_554 + case 555: + goto st_case_555 + case 556: + goto st_case_556 + case 557: + goto st_case_557 + case 558: + goto st_case_558 + case 559: + goto st_case_559 + case 560: + goto st_case_560 + case 561: + goto st_case_561 + case 4869: + goto st_case_4869 + case 562: + goto st_case_562 + case 563: + goto st_case_563 + case 564: + goto st_case_564 + case 565: + goto st_case_565 + case 566: + goto st_case_566 + case 567: + goto st_case_567 + case 4870: + goto st_case_4870 + case 568: + goto st_case_568 + case 569: + goto st_case_569 + case 570: + goto st_case_570 + case 571: + goto st_case_571 + case 572: + goto st_case_572 + case 573: + goto st_case_573 + case 574: + goto st_case_574 + case 4871: + goto st_case_4871 + case 575: + goto st_case_575 + case 576: + goto st_case_576 + case 577: + goto st_case_577 + case 578: + goto st_case_578 + case 579: + goto st_case_579 + case 580: + goto st_case_580 + case 581: + goto st_case_581 + case 582: + goto st_case_582 + case 583: + goto st_case_583 + case 584: + goto st_case_584 + case 585: + goto st_case_585 + case 586: + goto st_case_586 + case 587: + goto st_case_587 + case 588: + goto st_case_588 + case 589: + goto st_case_589 + case 590: + goto st_case_590 + case 591: + goto st_case_591 + case 592: + goto st_case_592 + case 593: + goto st_case_593 + case 594: + goto st_case_594 + case 595: + goto st_case_595 + case 596: + goto st_case_596 + case 597: + goto st_case_597 + case 598: + goto st_case_598 + case 599: + goto st_case_599 + case 600: + goto st_case_600 + case 601: + goto st_case_601 + case 602: + goto st_case_602 + case 603: + goto st_case_603 + case 604: + goto st_case_604 + case 605: + goto st_case_605 + case 606: + goto st_case_606 + case 607: + goto st_case_607 + case 608: + goto st_case_608 + case 609: + goto st_case_609 + case 610: + goto st_case_610 + case 611: + goto st_case_611 + case 612: + goto st_case_612 + case 613: + goto st_case_613 + case 614: + goto st_case_614 + case 615: + goto st_case_615 + case 616: + goto st_case_616 + case 617: + goto st_case_617 + case 618: + goto st_case_618 + case 619: + goto st_case_619 + case 620: + goto st_case_620 + case 621: + goto st_case_621 + case 622: + goto st_case_622 + case 623: + goto st_case_623 + case 624: + goto st_case_624 + case 625: + goto st_case_625 + case 626: + goto st_case_626 + case 627: + goto st_case_627 + case 628: + goto st_case_628 + case 629: + goto st_case_629 + case 630: + goto st_case_630 + case 631: + goto st_case_631 + case 632: + goto st_case_632 + case 633: + goto st_case_633 + case 634: + goto st_case_634 + case 635: + goto st_case_635 + case 636: + goto st_case_636 + case 637: + goto st_case_637 + case 638: + goto st_case_638 + case 639: + goto st_case_639 + case 640: + goto st_case_640 + case 641: + goto st_case_641 + case 642: + goto st_case_642 + case 643: + goto st_case_643 + case 644: + goto st_case_644 + case 645: + goto st_case_645 + case 646: + goto st_case_646 + case 647: + goto st_case_647 + case 648: + goto st_case_648 + case 649: + goto st_case_649 + case 650: + goto st_case_650 + case 651: + goto st_case_651 + case 652: + goto st_case_652 + case 653: + goto st_case_653 + case 654: + goto st_case_654 + case 655: + goto st_case_655 + case 656: + goto st_case_656 + case 657: + goto st_case_657 + case 658: + goto st_case_658 + case 659: + goto st_case_659 + case 660: + goto st_case_660 + case 661: + goto st_case_661 + case 662: + goto st_case_662 + case 663: + goto st_case_663 + case 664: + goto st_case_664 + case 665: + goto st_case_665 + case 666: + goto st_case_666 + case 667: + goto st_case_667 + case 668: + goto st_case_668 + case 669: + goto st_case_669 + case 670: + goto st_case_670 + case 671: + goto st_case_671 + case 672: + goto st_case_672 + case 673: + goto st_case_673 + case 674: + goto st_case_674 + case 675: + goto st_case_675 + case 676: + goto st_case_676 + case 677: + goto st_case_677 + case 678: + goto st_case_678 + case 679: + goto st_case_679 + case 680: + goto st_case_680 + case 681: + goto st_case_681 + case 682: + goto st_case_682 + case 683: + goto st_case_683 + case 684: + goto st_case_684 + case 685: + goto st_case_685 + case 686: + goto st_case_686 + case 687: + goto st_case_687 + case 688: + goto st_case_688 + case 689: + goto st_case_689 + case 690: + goto st_case_690 + case 691: + goto st_case_691 + case 692: + goto st_case_692 + case 693: + goto st_case_693 + case 694: + goto st_case_694 + case 695: + goto st_case_695 + case 696: + goto st_case_696 + case 697: + goto st_case_697 + case 698: + goto st_case_698 + case 699: + goto st_case_699 + case 700: + goto st_case_700 + case 701: + goto st_case_701 + case 702: + goto st_case_702 + case 703: + goto st_case_703 + case 704: + goto st_case_704 + case 705: + goto st_case_705 + case 706: + goto st_case_706 + case 707: + goto st_case_707 + case 708: + goto st_case_708 + case 709: + goto st_case_709 + case 710: + goto st_case_710 + case 711: + goto st_case_711 + case 712: + goto st_case_712 + case 713: + goto st_case_713 + case 714: + goto st_case_714 + case 715: + goto st_case_715 + case 716: + goto st_case_716 + case 717: + goto st_case_717 + case 718: + goto st_case_718 + case 719: + goto st_case_719 + case 720: + goto st_case_720 + case 721: + goto st_case_721 + case 722: + goto st_case_722 + case 723: + goto st_case_723 + case 724: + goto st_case_724 + case 725: + goto st_case_725 + case 726: + goto st_case_726 + case 727: + goto st_case_727 + case 728: + goto st_case_728 + case 729: + goto st_case_729 + case 730: + goto st_case_730 + case 731: + goto st_case_731 + case 732: + goto st_case_732 + case 733: + goto st_case_733 + case 734: + goto st_case_734 + case 735: + goto st_case_735 + case 736: + goto st_case_736 + case 737: + goto st_case_737 + case 738: + goto st_case_738 + case 739: + goto st_case_739 + case 740: + goto st_case_740 + case 741: + goto st_case_741 + case 742: + goto st_case_742 + case 743: + goto st_case_743 + case 744: + goto st_case_744 + case 745: + goto st_case_745 + case 746: + goto st_case_746 + case 747: + goto st_case_747 + case 748: + goto st_case_748 + case 749: + goto st_case_749 + case 750: + goto st_case_750 + case 751: + goto st_case_751 + case 752: + goto st_case_752 + case 753: + goto st_case_753 + case 754: + goto st_case_754 + case 755: + goto st_case_755 + case 756: + goto st_case_756 + case 757: + goto st_case_757 + case 758: + goto st_case_758 + case 759: + goto st_case_759 + case 760: + goto st_case_760 + case 761: + goto st_case_761 + case 762: + goto st_case_762 + case 763: + goto st_case_763 + case 764: + goto st_case_764 + case 765: + goto st_case_765 + case 766: + goto st_case_766 + case 767: + goto st_case_767 + case 768: + goto st_case_768 + case 769: + goto st_case_769 + case 770: + goto st_case_770 + case 771: + goto st_case_771 + case 772: + goto st_case_772 + case 773: + goto st_case_773 + case 774: + goto st_case_774 + case 775: + goto st_case_775 + case 776: + goto st_case_776 + case 777: + goto st_case_777 + case 778: + goto st_case_778 + case 779: + goto st_case_779 + case 780: + goto st_case_780 + case 781: + goto st_case_781 + case 782: + goto st_case_782 + case 783: + goto st_case_783 + case 784: + goto st_case_784 + case 785: + goto st_case_785 + case 786: + goto st_case_786 + case 787: + goto st_case_787 + case 788: + goto st_case_788 + case 789: + goto st_case_789 + case 790: + goto st_case_790 + case 791: + goto st_case_791 + case 792: + goto st_case_792 + case 793: + goto st_case_793 + case 794: + goto st_case_794 + case 795: + goto st_case_795 + case 796: + goto st_case_796 + case 797: + goto st_case_797 + case 798: + goto st_case_798 + case 799: + goto st_case_799 + case 800: + goto st_case_800 + case 801: + goto st_case_801 + case 802: + goto st_case_802 + case 803: + goto st_case_803 + case 804: + goto st_case_804 + case 805: + goto st_case_805 + case 806: + goto st_case_806 + case 807: + goto st_case_807 + case 808: + goto st_case_808 + case 809: + goto st_case_809 + case 810: + goto st_case_810 + case 811: + goto st_case_811 + case 812: + goto st_case_812 + case 813: + goto st_case_813 + case 814: + goto st_case_814 + case 815: + goto st_case_815 + case 816: + goto st_case_816 + case 817: + goto st_case_817 + case 818: + goto st_case_818 + case 819: + goto st_case_819 + case 820: + goto st_case_820 + case 821: + goto st_case_821 + case 822: + goto st_case_822 + case 823: + goto st_case_823 + case 824: + goto st_case_824 + case 825: + goto st_case_825 + case 826: + goto st_case_826 + case 827: + goto st_case_827 + case 828: + goto st_case_828 + case 829: + goto st_case_829 + case 830: + goto st_case_830 + case 831: + goto st_case_831 + case 832: + goto st_case_832 + case 833: + goto st_case_833 + case 834: + goto st_case_834 + case 835: + goto st_case_835 + case 836: + goto st_case_836 + case 837: + goto st_case_837 + case 838: + goto st_case_838 + case 839: + goto st_case_839 + case 840: + goto st_case_840 + case 841: + goto st_case_841 + case 842: + goto st_case_842 + case 843: + goto st_case_843 + case 844: + goto st_case_844 + case 845: + goto st_case_845 + case 846: + goto st_case_846 + case 847: + goto st_case_847 + case 848: + goto st_case_848 + case 849: + goto st_case_849 + case 850: + goto st_case_850 + case 851: + goto st_case_851 + case 852: + goto st_case_852 + case 853: + goto st_case_853 + case 854: + goto st_case_854 + case 855: + goto st_case_855 + case 856: + goto st_case_856 + case 857: + goto st_case_857 + case 858: + goto st_case_858 + case 859: + goto st_case_859 + case 860: + goto st_case_860 + case 861: + goto st_case_861 + case 862: + goto st_case_862 + case 863: + goto st_case_863 + case 864: + goto st_case_864 + case 865: + goto st_case_865 + case 866: + goto st_case_866 + case 867: + goto st_case_867 + case 868: + goto st_case_868 + case 869: + goto st_case_869 + case 870: + goto st_case_870 + case 871: + goto st_case_871 + case 872: + goto st_case_872 + case 873: + goto st_case_873 + case 874: + goto st_case_874 + case 875: + goto st_case_875 + case 876: + goto st_case_876 + case 877: + goto st_case_877 + case 878: + goto st_case_878 + case 879: + goto st_case_879 + case 880: + goto st_case_880 + case 881: + goto st_case_881 + case 882: + goto st_case_882 + case 883: + goto st_case_883 + case 884: + goto st_case_884 + case 885: + goto st_case_885 + case 886: + goto st_case_886 + case 887: + goto st_case_887 + case 888: + goto st_case_888 + case 889: + goto st_case_889 + case 890: + goto st_case_890 + case 891: + goto st_case_891 + case 892: + goto st_case_892 + case 893: + goto st_case_893 + case 894: + goto st_case_894 + case 895: + goto st_case_895 + case 896: + goto st_case_896 + case 897: + goto st_case_897 + case 898: + goto st_case_898 + case 899: + goto st_case_899 + case 900: + goto st_case_900 + case 901: + goto st_case_901 + case 902: + goto st_case_902 + case 903: + goto st_case_903 + case 904: + goto st_case_904 + case 905: + goto st_case_905 + case 906: + goto st_case_906 + case 907: + goto st_case_907 + case 908: + goto st_case_908 + case 909: + goto st_case_909 + case 910: + goto st_case_910 + case 911: + goto st_case_911 + case 912: + goto st_case_912 + case 913: + goto st_case_913 + case 914: + goto st_case_914 + case 915: + goto st_case_915 + case 916: + goto st_case_916 + case 917: + goto st_case_917 + case 918: + goto st_case_918 + case 919: + goto st_case_919 + case 920: + goto st_case_920 + case 921: + goto st_case_921 + case 922: + goto st_case_922 + case 923: + goto st_case_923 + case 924: + goto st_case_924 + case 925: + goto st_case_925 + case 926: + goto st_case_926 + case 927: + goto st_case_927 + case 928: + goto st_case_928 + case 929: + goto st_case_929 + case 930: + goto st_case_930 + case 931: + goto st_case_931 + case 932: + goto st_case_932 + case 933: + goto st_case_933 + case 934: + goto st_case_934 + case 935: + goto st_case_935 + case 936: + goto st_case_936 + case 937: + goto st_case_937 + case 938: + goto st_case_938 + case 939: + goto st_case_939 + case 940: + goto st_case_940 + case 941: + goto st_case_941 + case 942: + goto st_case_942 + case 943: + goto st_case_943 + case 944: + goto st_case_944 + case 945: + goto st_case_945 + case 946: + goto st_case_946 + case 947: + goto st_case_947 + case 948: + goto st_case_948 + case 949: + goto st_case_949 + case 950: + goto st_case_950 + case 951: + goto st_case_951 + case 952: + goto st_case_952 + case 953: + goto st_case_953 + case 954: + goto st_case_954 + case 955: + goto st_case_955 + case 956: + goto st_case_956 + case 957: + goto st_case_957 + case 958: + goto st_case_958 + case 959: + goto st_case_959 + case 960: + goto st_case_960 + case 961: + goto st_case_961 + case 962: + goto st_case_962 + case 963: + goto st_case_963 + case 964: + goto st_case_964 + case 965: + goto st_case_965 + case 966: + goto st_case_966 + case 967: + goto st_case_967 + case 968: + goto st_case_968 + case 969: + goto st_case_969 + case 970: + goto st_case_970 + case 971: + goto st_case_971 + case 972: + goto st_case_972 + case 973: + goto st_case_973 + case 974: + goto st_case_974 + case 975: + goto st_case_975 + case 976: + goto st_case_976 + case 977: + goto st_case_977 + case 978: + goto st_case_978 + case 979: + goto st_case_979 + case 980: + goto st_case_980 + case 981: + goto st_case_981 + case 982: + goto st_case_982 + case 983: + goto st_case_983 + case 984: + goto st_case_984 + case 985: + goto st_case_985 + case 986: + goto st_case_986 + case 987: + goto st_case_987 + case 988: + goto st_case_988 + case 989: + goto st_case_989 + case 990: + goto st_case_990 + case 991: + goto st_case_991 + case 992: + goto st_case_992 + case 993: + goto st_case_993 + case 994: + goto st_case_994 + case 995: + goto st_case_995 + case 996: + goto st_case_996 + case 997: + goto st_case_997 + case 998: + goto st_case_998 + case 999: + goto st_case_999 + case 1000: + goto st_case_1000 + case 1001: + goto st_case_1001 + case 1002: + goto st_case_1002 + case 1003: + goto st_case_1003 + case 1004: + goto st_case_1004 + case 1005: + goto st_case_1005 + case 1006: + goto st_case_1006 + case 1007: + goto st_case_1007 + case 1008: + goto st_case_1008 + case 1009: + goto st_case_1009 + case 1010: + goto st_case_1010 + case 1011: + goto st_case_1011 + case 1012: + goto st_case_1012 + case 1013: + goto st_case_1013 + case 1014: + goto st_case_1014 + case 1015: + goto st_case_1015 + case 1016: + goto st_case_1016 + case 1017: + goto st_case_1017 + case 1018: + goto st_case_1018 + case 1019: + goto st_case_1019 + case 1020: + goto st_case_1020 + case 1021: + goto st_case_1021 + case 1022: + goto st_case_1022 + case 1023: + goto st_case_1023 + case 1024: + goto st_case_1024 + case 1025: + goto st_case_1025 + case 1026: + goto st_case_1026 + case 1027: + goto st_case_1027 + case 1028: + goto st_case_1028 + case 1029: + goto st_case_1029 + case 1030: + goto st_case_1030 + case 1031: + goto st_case_1031 + case 1032: + goto st_case_1032 + case 1033: + goto st_case_1033 + case 1034: + goto st_case_1034 + case 1035: + goto st_case_1035 + case 1036: + goto st_case_1036 + case 1037: + goto st_case_1037 + case 1038: + goto st_case_1038 + case 1039: + goto st_case_1039 + case 1040: + goto st_case_1040 + case 1041: + goto st_case_1041 + case 1042: + goto st_case_1042 + case 1043: + goto st_case_1043 + case 1044: + goto st_case_1044 + case 1045: + goto st_case_1045 + case 1046: + goto st_case_1046 + case 1047: + goto st_case_1047 + case 1048: + goto st_case_1048 + case 1049: + goto st_case_1049 + case 1050: + goto st_case_1050 + case 1051: + goto st_case_1051 + case 1052: + goto st_case_1052 + case 1053: + goto st_case_1053 + case 1054: + goto st_case_1054 + case 1055: + goto st_case_1055 + case 1056: + goto st_case_1056 + case 1057: + goto st_case_1057 + case 1058: + goto st_case_1058 + case 1059: + goto st_case_1059 + case 1060: + goto st_case_1060 + case 1061: + goto st_case_1061 + case 1062: + goto st_case_1062 + case 1063: + goto st_case_1063 + case 1064: + goto st_case_1064 + case 1065: + goto st_case_1065 + case 1066: + goto st_case_1066 + case 1067: + goto st_case_1067 + case 1068: + goto st_case_1068 + case 1069: + goto st_case_1069 + case 1070: + goto st_case_1070 + case 1071: + goto st_case_1071 + case 1072: + goto st_case_1072 + case 1073: + goto st_case_1073 + case 1074: + goto st_case_1074 + case 1075: + goto st_case_1075 + case 1076: + goto st_case_1076 + case 1077: + goto st_case_1077 + case 1078: + goto st_case_1078 + case 1079: + goto st_case_1079 + case 1080: + goto st_case_1080 + case 1081: + goto st_case_1081 + case 1082: + goto st_case_1082 + case 1083: + goto st_case_1083 + case 1084: + goto st_case_1084 + case 1085: + goto st_case_1085 + case 1086: + goto st_case_1086 + case 1087: + goto st_case_1087 + case 1088: + goto st_case_1088 + case 1089: + goto st_case_1089 + case 4872: + goto st_case_4872 + case 1090: + goto st_case_1090 + case 1091: + goto st_case_1091 + case 1092: + goto st_case_1092 + case 1093: + goto st_case_1093 + case 1094: + goto st_case_1094 + case 1095: + goto st_case_1095 + case 1096: + goto st_case_1096 + case 1097: + goto st_case_1097 + case 1098: + goto st_case_1098 + case 1099: + goto st_case_1099 + case 1100: + goto st_case_1100 + case 1101: + goto st_case_1101 + case 1102: + goto st_case_1102 + case 1103: + goto st_case_1103 + case 1104: + goto st_case_1104 + case 1105: + goto st_case_1105 + case 1106: + goto st_case_1106 + case 1107: + goto st_case_1107 + case 1108: + goto st_case_1108 + case 1109: + goto st_case_1109 + case 1110: + goto st_case_1110 + case 1111: + goto st_case_1111 + case 1112: + goto st_case_1112 + case 1113: + goto st_case_1113 + case 1114: + goto st_case_1114 + case 1115: + goto st_case_1115 + case 1116: + goto st_case_1116 + case 1117: + goto st_case_1117 + case 1118: + goto st_case_1118 + case 1119: + goto st_case_1119 + case 1120: + goto st_case_1120 + case 1121: + goto st_case_1121 + case 1122: + goto st_case_1122 + case 1123: + goto st_case_1123 + case 1124: + goto st_case_1124 + case 1125: + goto st_case_1125 + case 1126: + goto st_case_1126 + case 1127: + goto st_case_1127 + case 1128: + goto st_case_1128 + case 1129: + goto st_case_1129 + case 1130: + goto st_case_1130 + case 1131: + goto st_case_1131 + case 1132: + goto st_case_1132 + case 1133: + goto st_case_1133 + case 1134: + goto st_case_1134 + case 1135: + goto st_case_1135 + case 1136: + goto st_case_1136 + case 1137: + goto st_case_1137 + case 1138: + goto st_case_1138 + case 1139: + goto st_case_1139 + case 1140: + goto st_case_1140 + case 1141: + goto st_case_1141 + case 1142: + goto st_case_1142 + case 1143: + goto st_case_1143 + case 1144: + goto st_case_1144 + case 1145: + goto st_case_1145 + case 1146: + goto st_case_1146 + case 1147: + goto st_case_1147 + case 1148: + goto st_case_1148 + case 1149: + goto st_case_1149 + case 1150: + goto st_case_1150 + case 1151: + goto st_case_1151 + case 1152: + goto st_case_1152 + case 1153: + goto st_case_1153 + case 1154: + goto st_case_1154 + case 1155: + goto st_case_1155 + case 1156: + goto st_case_1156 + case 1157: + goto st_case_1157 + case 1158: + goto st_case_1158 + case 1159: + goto st_case_1159 + case 1160: + goto st_case_1160 + case 1161: + goto st_case_1161 + case 1162: + goto st_case_1162 + case 1163: + goto st_case_1163 + case 1164: + goto st_case_1164 + case 1165: + goto st_case_1165 + case 1166: + goto st_case_1166 + case 1167: + goto st_case_1167 + case 1168: + goto st_case_1168 + case 1169: + goto st_case_1169 + case 1170: + goto st_case_1170 + case 1171: + goto st_case_1171 + case 1172: + goto st_case_1172 + case 1173: + goto st_case_1173 + case 1174: + goto st_case_1174 + case 1175: + goto st_case_1175 + case 1176: + goto st_case_1176 + case 1177: + goto st_case_1177 + case 1178: + goto st_case_1178 + case 1179: + goto st_case_1179 + case 1180: + goto st_case_1180 + case 1181: + goto st_case_1181 + case 1182: + goto st_case_1182 + case 1183: + goto st_case_1183 + case 1184: + goto st_case_1184 + case 1185: + goto st_case_1185 + case 1186: + goto st_case_1186 + case 1187: + goto st_case_1187 + case 1188: + goto st_case_1188 + case 1189: + goto st_case_1189 + case 1190: + goto st_case_1190 + case 1191: + goto st_case_1191 + case 1192: + goto st_case_1192 + case 1193: + goto st_case_1193 + case 1194: + goto st_case_1194 + case 1195: + goto st_case_1195 + case 1196: + goto st_case_1196 + case 1197: + goto st_case_1197 + case 1198: + goto st_case_1198 + case 1199: + goto st_case_1199 + case 1200: + goto st_case_1200 + case 1201: + goto st_case_1201 + case 1202: + goto st_case_1202 + case 1203: + goto st_case_1203 + case 1204: + goto st_case_1204 + case 1205: + goto st_case_1205 + case 1206: + goto st_case_1206 + case 1207: + goto st_case_1207 + case 1208: + goto st_case_1208 + case 1209: + goto st_case_1209 + case 1210: + goto st_case_1210 + case 1211: + goto st_case_1211 + case 1212: + goto st_case_1212 + case 1213: + goto st_case_1213 + case 1214: + goto st_case_1214 + case 1215: + goto st_case_1215 + case 1216: + goto st_case_1216 + case 1217: + goto st_case_1217 + case 1218: + goto st_case_1218 + case 1219: + goto st_case_1219 + case 1220: + goto st_case_1220 + case 1221: + goto st_case_1221 + case 1222: + goto st_case_1222 + case 1223: + goto st_case_1223 + case 1224: + goto st_case_1224 + case 1225: + goto st_case_1225 + case 1226: + goto st_case_1226 + case 1227: + goto st_case_1227 + case 1228: + goto st_case_1228 + case 1229: + goto st_case_1229 + case 1230: + goto st_case_1230 + case 1231: + goto st_case_1231 + case 1232: + goto st_case_1232 + case 1233: + goto st_case_1233 + case 1234: + goto st_case_1234 + case 1235: + goto st_case_1235 + case 1236: + goto st_case_1236 + case 1237: + goto st_case_1237 + case 1238: + goto st_case_1238 + case 1239: + goto st_case_1239 + case 1240: + goto st_case_1240 + case 1241: + goto st_case_1241 + case 1242: + goto st_case_1242 + case 1243: + goto st_case_1243 + case 1244: + goto st_case_1244 + case 1245: + goto st_case_1245 + case 1246: + goto st_case_1246 + case 1247: + goto st_case_1247 + case 1248: + goto st_case_1248 + case 1249: + goto st_case_1249 + case 1250: + goto st_case_1250 + case 1251: + goto st_case_1251 + case 1252: + goto st_case_1252 + case 1253: + goto st_case_1253 + case 1254: + goto st_case_1254 + case 1255: + goto st_case_1255 + case 1256: + goto st_case_1256 + case 1257: + goto st_case_1257 + case 1258: + goto st_case_1258 + case 1259: + goto st_case_1259 + case 1260: + goto st_case_1260 + case 1261: + goto st_case_1261 + case 1262: + goto st_case_1262 + case 1263: + goto st_case_1263 + case 1264: + goto st_case_1264 + case 1265: + goto st_case_1265 + case 1266: + goto st_case_1266 + case 1267: + goto st_case_1267 + case 1268: + goto st_case_1268 + case 1269: + goto st_case_1269 + case 1270: + goto st_case_1270 + case 1271: + goto st_case_1271 + case 1272: + goto st_case_1272 + case 1273: + goto st_case_1273 + case 1274: + goto st_case_1274 + case 1275: + goto st_case_1275 + case 1276: + goto st_case_1276 + case 1277: + goto st_case_1277 + case 1278: + goto st_case_1278 + case 1279: + goto st_case_1279 + case 1280: + goto st_case_1280 + case 1281: + goto st_case_1281 + case 1282: + goto st_case_1282 + case 1283: + goto st_case_1283 + case 1284: + goto st_case_1284 + case 1285: + goto st_case_1285 + case 1286: + goto st_case_1286 + case 1287: + goto st_case_1287 + case 1288: + goto st_case_1288 + case 1289: + goto st_case_1289 + case 1290: + goto st_case_1290 + case 1291: + goto st_case_1291 + case 1292: + goto st_case_1292 + case 1293: + goto st_case_1293 + case 1294: + goto st_case_1294 + case 1295: + goto st_case_1295 + case 1296: + goto st_case_1296 + case 1297: + goto st_case_1297 + case 1298: + goto st_case_1298 + case 1299: + goto st_case_1299 + case 1300: + goto st_case_1300 + case 1301: + goto st_case_1301 + case 1302: + goto st_case_1302 + case 1303: + goto st_case_1303 + case 1304: + goto st_case_1304 + case 1305: + goto st_case_1305 + case 1306: + goto st_case_1306 + case 1307: + goto st_case_1307 + case 1308: + goto st_case_1308 + case 1309: + goto st_case_1309 + case 1310: + goto st_case_1310 + case 1311: + goto st_case_1311 + case 1312: + goto st_case_1312 + case 1313: + goto st_case_1313 + case 1314: + goto st_case_1314 + case 1315: + goto st_case_1315 + case 1316: + goto st_case_1316 + case 1317: + goto st_case_1317 + case 1318: + goto st_case_1318 + case 1319: + goto st_case_1319 + case 1320: + goto st_case_1320 + case 1321: + goto st_case_1321 + case 1322: + goto st_case_1322 + case 1323: + goto st_case_1323 + case 1324: + goto st_case_1324 + case 1325: + goto st_case_1325 + case 1326: + goto st_case_1326 + case 1327: + goto st_case_1327 + case 1328: + goto st_case_1328 + case 1329: + goto st_case_1329 + case 1330: + goto st_case_1330 + case 1331: + goto st_case_1331 + case 1332: + goto st_case_1332 + case 1333: + goto st_case_1333 + case 1334: + goto st_case_1334 + case 1335: + goto st_case_1335 + case 1336: + goto st_case_1336 + case 1337: + goto st_case_1337 + case 1338: + goto st_case_1338 + case 1339: + goto st_case_1339 + case 1340: + goto st_case_1340 + case 1341: + goto st_case_1341 + case 1342: + goto st_case_1342 + case 1343: + goto st_case_1343 + case 1344: + goto st_case_1344 + case 1345: + goto st_case_1345 + case 1346: + goto st_case_1346 + case 1347: + goto st_case_1347 + case 1348: + goto st_case_1348 + case 1349: + goto st_case_1349 + case 1350: + goto st_case_1350 + case 1351: + goto st_case_1351 + case 1352: + goto st_case_1352 + case 1353: + goto st_case_1353 + case 1354: + goto st_case_1354 + case 1355: + goto st_case_1355 + case 1356: + goto st_case_1356 + case 1357: + goto st_case_1357 + case 1358: + goto st_case_1358 + case 1359: + goto st_case_1359 + case 1360: + goto st_case_1360 + case 1361: + goto st_case_1361 + case 1362: + goto st_case_1362 + case 1363: + goto st_case_1363 + case 1364: + goto st_case_1364 + case 1365: + goto st_case_1365 + case 1366: + goto st_case_1366 + case 1367: + goto st_case_1367 + case 1368: + goto st_case_1368 + case 1369: + goto st_case_1369 + case 1370: + goto st_case_1370 + case 1371: + goto st_case_1371 + case 1372: + goto st_case_1372 + case 1373: + goto st_case_1373 + case 1374: + goto st_case_1374 + case 1375: + goto st_case_1375 + case 1376: + goto st_case_1376 + case 1377: + goto st_case_1377 + case 1378: + goto st_case_1378 + case 1379: + goto st_case_1379 + case 1380: + goto st_case_1380 + case 1381: + goto st_case_1381 + case 1382: + goto st_case_1382 + case 1383: + goto st_case_1383 + case 1384: + goto st_case_1384 + case 1385: + goto st_case_1385 + case 1386: + goto st_case_1386 + case 1387: + goto st_case_1387 + case 1388: + goto st_case_1388 + case 1389: + goto st_case_1389 + case 1390: + goto st_case_1390 + case 1391: + goto st_case_1391 + case 1392: + goto st_case_1392 + case 1393: + goto st_case_1393 + case 1394: + goto st_case_1394 + case 1395: + goto st_case_1395 + case 1396: + goto st_case_1396 + case 1397: + goto st_case_1397 + case 1398: + goto st_case_1398 + case 1399: + goto st_case_1399 + case 1400: + goto st_case_1400 + case 1401: + goto st_case_1401 + case 1402: + goto st_case_1402 + case 1403: + goto st_case_1403 + case 1404: + goto st_case_1404 + case 1405: + goto st_case_1405 + case 1406: + goto st_case_1406 + case 1407: + goto st_case_1407 + case 1408: + goto st_case_1408 + case 1409: + goto st_case_1409 + case 1410: + goto st_case_1410 + case 1411: + goto st_case_1411 + case 1412: + goto st_case_1412 + case 1413: + goto st_case_1413 + case 1414: + goto st_case_1414 + case 1415: + goto st_case_1415 + case 1416: + goto st_case_1416 + case 1417: + goto st_case_1417 + case 1418: + goto st_case_1418 + case 1419: + goto st_case_1419 + case 1420: + goto st_case_1420 + case 1421: + goto st_case_1421 + case 1422: + goto st_case_1422 + case 1423: + goto st_case_1423 + case 1424: + goto st_case_1424 + case 1425: + goto st_case_1425 + case 1426: + goto st_case_1426 + case 1427: + goto st_case_1427 + case 1428: + goto st_case_1428 + case 1429: + goto st_case_1429 + case 1430: + goto st_case_1430 + case 1431: + goto st_case_1431 + case 1432: + goto st_case_1432 + case 1433: + goto st_case_1433 + case 1434: + goto st_case_1434 + case 1435: + goto st_case_1435 + case 1436: + goto st_case_1436 + case 1437: + goto st_case_1437 + case 1438: + goto st_case_1438 + case 1439: + goto st_case_1439 + case 1440: + goto st_case_1440 + case 1441: + goto st_case_1441 + case 1442: + goto st_case_1442 + case 1443: + goto st_case_1443 + case 1444: + goto st_case_1444 + case 1445: + goto st_case_1445 + case 1446: + goto st_case_1446 + case 1447: + goto st_case_1447 + case 1448: + goto st_case_1448 + case 1449: + goto st_case_1449 + case 1450: + goto st_case_1450 + case 1451: + goto st_case_1451 + case 1452: + goto st_case_1452 + case 1453: + goto st_case_1453 + case 1454: + goto st_case_1454 + case 1455: + goto st_case_1455 + case 1456: + goto st_case_1456 + case 1457: + goto st_case_1457 + case 1458: + goto st_case_1458 + case 1459: + goto st_case_1459 + case 1460: + goto st_case_1460 + case 1461: + goto st_case_1461 + case 1462: + goto st_case_1462 + case 1463: + goto st_case_1463 + case 1464: + goto st_case_1464 + case 1465: + goto st_case_1465 + case 1466: + goto st_case_1466 + case 1467: + goto st_case_1467 + case 1468: + goto st_case_1468 + case 1469: + goto st_case_1469 + case 1470: + goto st_case_1470 + case 1471: + goto st_case_1471 + case 1472: + goto st_case_1472 + case 1473: + goto st_case_1473 + case 1474: + goto st_case_1474 + case 1475: + goto st_case_1475 + case 1476: + goto st_case_1476 + case 1477: + goto st_case_1477 + case 1478: + goto st_case_1478 + case 1479: + goto st_case_1479 + case 1480: + goto st_case_1480 + case 1481: + goto st_case_1481 + case 1482: + goto st_case_1482 + case 1483: + goto st_case_1483 + case 1484: + goto st_case_1484 + case 1485: + goto st_case_1485 + case 1486: + goto st_case_1486 + case 1487: + goto st_case_1487 + case 1488: + goto st_case_1488 + case 1489: + goto st_case_1489 + case 1490: + goto st_case_1490 + case 1491: + goto st_case_1491 + case 1492: + goto st_case_1492 + case 1493: + goto st_case_1493 + case 1494: + goto st_case_1494 + case 1495: + goto st_case_1495 + case 1496: + goto st_case_1496 + case 1497: + goto st_case_1497 + case 1498: + goto st_case_1498 + case 1499: + goto st_case_1499 + case 1500: + goto st_case_1500 + case 1501: + goto st_case_1501 + case 1502: + goto st_case_1502 + case 1503: + goto st_case_1503 + case 1504: + goto st_case_1504 + case 1505: + goto st_case_1505 + case 1506: + goto st_case_1506 + case 1507: + goto st_case_1507 + case 1508: + goto st_case_1508 + case 1509: + goto st_case_1509 + case 1510: + goto st_case_1510 + case 1511: + goto st_case_1511 + case 1512: + goto st_case_1512 + case 1513: + goto st_case_1513 + case 1514: + goto st_case_1514 + case 1515: + goto st_case_1515 + case 1516: + goto st_case_1516 + case 1517: + goto st_case_1517 + case 1518: + goto st_case_1518 + case 1519: + goto st_case_1519 + case 1520: + goto st_case_1520 + case 1521: + goto st_case_1521 + case 1522: + goto st_case_1522 + case 1523: + goto st_case_1523 + case 1524: + goto st_case_1524 + case 1525: + goto st_case_1525 + case 1526: + goto st_case_1526 + case 1527: + goto st_case_1527 + case 1528: + goto st_case_1528 + case 1529: + goto st_case_1529 + case 1530: + goto st_case_1530 + case 1531: + goto st_case_1531 + case 1532: + goto st_case_1532 + case 1533: + goto st_case_1533 + case 1534: + goto st_case_1534 + case 1535: + goto st_case_1535 + case 1536: + goto st_case_1536 + case 1537: + goto st_case_1537 + case 1538: + goto st_case_1538 + case 1539: + goto st_case_1539 + case 1540: + goto st_case_1540 + case 1541: + goto st_case_1541 + case 1542: + goto st_case_1542 + case 1543: + goto st_case_1543 + case 1544: + goto st_case_1544 + case 1545: + goto st_case_1545 + case 1546: + goto st_case_1546 + case 1547: + goto st_case_1547 + case 1548: + goto st_case_1548 + case 1549: + goto st_case_1549 + case 1550: + goto st_case_1550 + case 1551: + goto st_case_1551 + case 1552: + goto st_case_1552 + case 1553: + goto st_case_1553 + case 1554: + goto st_case_1554 + case 1555: + goto st_case_1555 + case 1556: + goto st_case_1556 + case 1557: + goto st_case_1557 + case 1558: + goto st_case_1558 + case 1559: + goto st_case_1559 + case 1560: + goto st_case_1560 + case 1561: + goto st_case_1561 + case 1562: + goto st_case_1562 + case 1563: + goto st_case_1563 + case 1564: + goto st_case_1564 + case 1565: + goto st_case_1565 + case 1566: + goto st_case_1566 + case 1567: + goto st_case_1567 + case 1568: + goto st_case_1568 + case 1569: + goto st_case_1569 + case 1570: + goto st_case_1570 + case 1571: + goto st_case_1571 + case 1572: + goto st_case_1572 + case 1573: + goto st_case_1573 + case 1574: + goto st_case_1574 + case 1575: + goto st_case_1575 + case 1576: + goto st_case_1576 + case 1577: + goto st_case_1577 + case 1578: + goto st_case_1578 + case 1579: + goto st_case_1579 + case 1580: + goto st_case_1580 + case 1581: + goto st_case_1581 + case 1582: + goto st_case_1582 + case 1583: + goto st_case_1583 + case 1584: + goto st_case_1584 + case 1585: + goto st_case_1585 + case 1586: + goto st_case_1586 + case 1587: + goto st_case_1587 + case 1588: + goto st_case_1588 + case 1589: + goto st_case_1589 + case 1590: + goto st_case_1590 + case 1591: + goto st_case_1591 + case 4873: + goto st_case_4873 + case 1592: + goto st_case_1592 + case 1593: + goto st_case_1593 + case 1594: + goto st_case_1594 + case 1595: + goto st_case_1595 + case 1596: + goto st_case_1596 + case 1597: + goto st_case_1597 + case 1598: + goto st_case_1598 + case 1599: + goto st_case_1599 + case 1600: + goto st_case_1600 + case 1601: + goto st_case_1601 + case 1602: + goto st_case_1602 + case 1603: + goto st_case_1603 + case 1604: + goto st_case_1604 + case 1605: + goto st_case_1605 + case 1606: + goto st_case_1606 + case 1607: + goto st_case_1607 + case 1608: + goto st_case_1608 + case 1609: + goto st_case_1609 + case 1610: + goto st_case_1610 + case 1611: + goto st_case_1611 + case 1612: + goto st_case_1612 + case 1613: + goto st_case_1613 + case 1614: + goto st_case_1614 + case 1615: + goto st_case_1615 + case 1616: + goto st_case_1616 + case 1617: + goto st_case_1617 + case 1618: + goto st_case_1618 + case 1619: + goto st_case_1619 + case 1620: + goto st_case_1620 + case 1621: + goto st_case_1621 + case 1622: + goto st_case_1622 + case 1623: + goto st_case_1623 + case 1624: + goto st_case_1624 + case 1625: + goto st_case_1625 + case 1626: + goto st_case_1626 + case 1627: + goto st_case_1627 + case 1628: + goto st_case_1628 + case 1629: + goto st_case_1629 + case 1630: + goto st_case_1630 + case 1631: + goto st_case_1631 + case 1632: + goto st_case_1632 + case 1633: + goto st_case_1633 + case 1634: + goto st_case_1634 + case 1635: + goto st_case_1635 + case 1636: + goto st_case_1636 + case 1637: + goto st_case_1637 + case 1638: + goto st_case_1638 + case 1639: + goto st_case_1639 + case 1640: + goto st_case_1640 + case 1641: + goto st_case_1641 + case 1642: + goto st_case_1642 + case 1643: + goto st_case_1643 + case 1644: + goto st_case_1644 + case 1645: + goto st_case_1645 + case 1646: + goto st_case_1646 + case 1647: + goto st_case_1647 + case 1648: + goto st_case_1648 + case 1649: + goto st_case_1649 + case 1650: + goto st_case_1650 + case 1651: + goto st_case_1651 + case 1652: + goto st_case_1652 + case 1653: + goto st_case_1653 + case 1654: + goto st_case_1654 + case 1655: + goto st_case_1655 + case 1656: + goto st_case_1656 + case 1657: + goto st_case_1657 + case 1658: + goto st_case_1658 + case 1659: + goto st_case_1659 + case 1660: + goto st_case_1660 + case 1661: + goto st_case_1661 + case 1662: + goto st_case_1662 + case 1663: + goto st_case_1663 + case 1664: + goto st_case_1664 + case 1665: + goto st_case_1665 + case 1666: + goto st_case_1666 + case 1667: + goto st_case_1667 + case 1668: + goto st_case_1668 + case 1669: + goto st_case_1669 + case 1670: + goto st_case_1670 + case 1671: + goto st_case_1671 + case 1672: + goto st_case_1672 + case 1673: + goto st_case_1673 + case 1674: + goto st_case_1674 + case 1675: + goto st_case_1675 + case 1676: + goto st_case_1676 + case 1677: + goto st_case_1677 + case 1678: + goto st_case_1678 + case 1679: + goto st_case_1679 + case 1680: + goto st_case_1680 + case 1681: + goto st_case_1681 + case 1682: + goto st_case_1682 + case 1683: + goto st_case_1683 + case 1684: + goto st_case_1684 + case 1685: + goto st_case_1685 + case 1686: + goto st_case_1686 + case 1687: + goto st_case_1687 + case 1688: + goto st_case_1688 + case 1689: + goto st_case_1689 + case 1690: + goto st_case_1690 + case 1691: + goto st_case_1691 + case 1692: + goto st_case_1692 + case 1693: + goto st_case_1693 + case 1694: + goto st_case_1694 + case 1695: + goto st_case_1695 + case 1696: + goto st_case_1696 + case 1697: + goto st_case_1697 + case 1698: + goto st_case_1698 + case 1699: + goto st_case_1699 + case 1700: + goto st_case_1700 + case 1701: + goto st_case_1701 + case 1702: + goto st_case_1702 + case 1703: + goto st_case_1703 + case 1704: + goto st_case_1704 + case 1705: + goto st_case_1705 + case 1706: + goto st_case_1706 + case 1707: + goto st_case_1707 + case 1708: + goto st_case_1708 + case 1709: + goto st_case_1709 + case 1710: + goto st_case_1710 + case 1711: + goto st_case_1711 + case 1712: + goto st_case_1712 + case 1713: + goto st_case_1713 + case 1714: + goto st_case_1714 + case 1715: + goto st_case_1715 + case 1716: + goto st_case_1716 + case 1717: + goto st_case_1717 + case 1718: + goto st_case_1718 + case 1719: + goto st_case_1719 + case 1720: + goto st_case_1720 + case 1721: + goto st_case_1721 + case 1722: + goto st_case_1722 + case 1723: + goto st_case_1723 + case 1724: + goto st_case_1724 + case 1725: + goto st_case_1725 + case 1726: + goto st_case_1726 + case 1727: + goto st_case_1727 + case 1728: + goto st_case_1728 + case 1729: + goto st_case_1729 + case 1730: + goto st_case_1730 + case 1731: + goto st_case_1731 + case 1732: + goto st_case_1732 + case 1733: + goto st_case_1733 + case 1734: + goto st_case_1734 + case 1735: + goto st_case_1735 + case 1736: + goto st_case_1736 + case 1737: + goto st_case_1737 + case 1738: + goto st_case_1738 + case 1739: + goto st_case_1739 + case 1740: + goto st_case_1740 + case 1741: + goto st_case_1741 + case 1742: + goto st_case_1742 + case 1743: + goto st_case_1743 + case 1744: + goto st_case_1744 + case 1745: + goto st_case_1745 + case 1746: + goto st_case_1746 + case 1747: + goto st_case_1747 + case 1748: + goto st_case_1748 + case 1749: + goto st_case_1749 + case 1750: + goto st_case_1750 + case 1751: + goto st_case_1751 + case 1752: + goto st_case_1752 + case 1753: + goto st_case_1753 + case 1754: + goto st_case_1754 + case 1755: + goto st_case_1755 + case 1756: + goto st_case_1756 + case 1757: + goto st_case_1757 + case 1758: + goto st_case_1758 + case 1759: + goto st_case_1759 + case 1760: + goto st_case_1760 + case 1761: + goto st_case_1761 + case 1762: + goto st_case_1762 + case 1763: + goto st_case_1763 + case 1764: + goto st_case_1764 + case 1765: + goto st_case_1765 + case 1766: + goto st_case_1766 + case 1767: + goto st_case_1767 + case 1768: + goto st_case_1768 + case 1769: + goto st_case_1769 + case 1770: + goto st_case_1770 + case 1771: + goto st_case_1771 + case 1772: + goto st_case_1772 + case 1773: + goto st_case_1773 + case 1774: + goto st_case_1774 + case 1775: + goto st_case_1775 + case 1776: + goto st_case_1776 + case 1777: + goto st_case_1777 + case 1778: + goto st_case_1778 + case 1779: + goto st_case_1779 + case 1780: + goto st_case_1780 + case 1781: + goto st_case_1781 + case 1782: + goto st_case_1782 + case 1783: + goto st_case_1783 + case 1784: + goto st_case_1784 + case 1785: + goto st_case_1785 + case 1786: + goto st_case_1786 + case 1787: + goto st_case_1787 + case 1788: + goto st_case_1788 + case 1789: + goto st_case_1789 + case 1790: + goto st_case_1790 + case 1791: + goto st_case_1791 + case 1792: + goto st_case_1792 + case 1793: + goto st_case_1793 + case 1794: + goto st_case_1794 + case 1795: + goto st_case_1795 + case 1796: + goto st_case_1796 + case 1797: + goto st_case_1797 + case 1798: + goto st_case_1798 + case 1799: + goto st_case_1799 + case 1800: + goto st_case_1800 + case 1801: + goto st_case_1801 + case 1802: + goto st_case_1802 + case 1803: + goto st_case_1803 + case 1804: + goto st_case_1804 + case 1805: + goto st_case_1805 + case 1806: + goto st_case_1806 + case 1807: + goto st_case_1807 + case 1808: + goto st_case_1808 + case 1809: + goto st_case_1809 + case 1810: + goto st_case_1810 + case 1811: + goto st_case_1811 + case 1812: + goto st_case_1812 + case 1813: + goto st_case_1813 + case 1814: + goto st_case_1814 + case 1815: + goto st_case_1815 + case 1816: + goto st_case_1816 + case 1817: + goto st_case_1817 + case 1818: + goto st_case_1818 + case 1819: + goto st_case_1819 + case 1820: + goto st_case_1820 + case 1821: + goto st_case_1821 + case 1822: + goto st_case_1822 + case 1823: + goto st_case_1823 + case 1824: + goto st_case_1824 + case 1825: + goto st_case_1825 + case 1826: + goto st_case_1826 + case 1827: + goto st_case_1827 + case 1828: + goto st_case_1828 + case 1829: + goto st_case_1829 + case 1830: + goto st_case_1830 + case 1831: + goto st_case_1831 + case 1832: + goto st_case_1832 + case 1833: + goto st_case_1833 + case 1834: + goto st_case_1834 + case 1835: + goto st_case_1835 + case 1836: + goto st_case_1836 + case 1837: + goto st_case_1837 + case 1838: + goto st_case_1838 + case 1839: + goto st_case_1839 + case 1840: + goto st_case_1840 + case 1841: + goto st_case_1841 + case 1842: + goto st_case_1842 + case 1843: + goto st_case_1843 + case 1844: + goto st_case_1844 + case 1845: + goto st_case_1845 + case 1846: + goto st_case_1846 + case 1847: + goto st_case_1847 + case 1848: + goto st_case_1848 + case 1849: + goto st_case_1849 + case 1850: + goto st_case_1850 + case 1851: + goto st_case_1851 + case 1852: + goto st_case_1852 + case 1853: + goto st_case_1853 + case 1854: + goto st_case_1854 + case 1855: + goto st_case_1855 + case 1856: + goto st_case_1856 + case 1857: + goto st_case_1857 + case 1858: + goto st_case_1858 + case 1859: + goto st_case_1859 + case 1860: + goto st_case_1860 + case 1861: + goto st_case_1861 + case 1862: + goto st_case_1862 + case 1863: + goto st_case_1863 + case 1864: + goto st_case_1864 + case 1865: + goto st_case_1865 + case 1866: + goto st_case_1866 + case 1867: + goto st_case_1867 + case 1868: + goto st_case_1868 + case 1869: + goto st_case_1869 + case 1870: + goto st_case_1870 + case 1871: + goto st_case_1871 + case 1872: + goto st_case_1872 + case 1873: + goto st_case_1873 + case 1874: + goto st_case_1874 + case 1875: + goto st_case_1875 + case 1876: + goto st_case_1876 + case 1877: + goto st_case_1877 + case 1878: + goto st_case_1878 + case 1879: + goto st_case_1879 + case 1880: + goto st_case_1880 + case 1881: + goto st_case_1881 + case 1882: + goto st_case_1882 + case 1883: + goto st_case_1883 + case 1884: + goto st_case_1884 + case 1885: + goto st_case_1885 + case 1886: + goto st_case_1886 + case 1887: + goto st_case_1887 + case 1888: + goto st_case_1888 + case 1889: + goto st_case_1889 + case 1890: + goto st_case_1890 + case 1891: + goto st_case_1891 + case 1892: + goto st_case_1892 + case 1893: + goto st_case_1893 + case 1894: + goto st_case_1894 + case 1895: + goto st_case_1895 + case 1896: + goto st_case_1896 + case 1897: + goto st_case_1897 + case 1898: + goto st_case_1898 + case 1899: + goto st_case_1899 + case 1900: + goto st_case_1900 + case 1901: + goto st_case_1901 + case 1902: + goto st_case_1902 + case 1903: + goto st_case_1903 + case 1904: + goto st_case_1904 + case 1905: + goto st_case_1905 + case 1906: + goto st_case_1906 + case 1907: + goto st_case_1907 + case 1908: + goto st_case_1908 + case 1909: + goto st_case_1909 + case 1910: + goto st_case_1910 + case 1911: + goto st_case_1911 + case 1912: + goto st_case_1912 + case 1913: + goto st_case_1913 + case 1914: + goto st_case_1914 + case 1915: + goto st_case_1915 + case 1916: + goto st_case_1916 + case 1917: + goto st_case_1917 + case 1918: + goto st_case_1918 + case 1919: + goto st_case_1919 + case 1920: + goto st_case_1920 + case 1921: + goto st_case_1921 + case 1922: + goto st_case_1922 + case 1923: + goto st_case_1923 + case 1924: + goto st_case_1924 + case 1925: + goto st_case_1925 + case 1926: + goto st_case_1926 + case 1927: + goto st_case_1927 + case 1928: + goto st_case_1928 + case 1929: + goto st_case_1929 + case 1930: + goto st_case_1930 + case 1931: + goto st_case_1931 + case 1932: + goto st_case_1932 + case 1933: + goto st_case_1933 + case 1934: + goto st_case_1934 + case 1935: + goto st_case_1935 + case 1936: + goto st_case_1936 + case 1937: + goto st_case_1937 + case 1938: + goto st_case_1938 + case 1939: + goto st_case_1939 + case 1940: + goto st_case_1940 + case 1941: + goto st_case_1941 + case 1942: + goto st_case_1942 + case 1943: + goto st_case_1943 + case 1944: + goto st_case_1944 + case 1945: + goto st_case_1945 + case 1946: + goto st_case_1946 + case 1947: + goto st_case_1947 + case 1948: + goto st_case_1948 + case 1949: + goto st_case_1949 + case 1950: + goto st_case_1950 + case 1951: + goto st_case_1951 + case 1952: + goto st_case_1952 + case 1953: + goto st_case_1953 + case 1954: + goto st_case_1954 + case 1955: + goto st_case_1955 + case 1956: + goto st_case_1956 + case 1957: + goto st_case_1957 + case 1958: + goto st_case_1958 + case 1959: + goto st_case_1959 + case 1960: + goto st_case_1960 + case 1961: + goto st_case_1961 + case 1962: + goto st_case_1962 + case 1963: + goto st_case_1963 + case 1964: + goto st_case_1964 + case 1965: + goto st_case_1965 + case 1966: + goto st_case_1966 + case 1967: + goto st_case_1967 + case 1968: + goto st_case_1968 + case 1969: + goto st_case_1969 + case 1970: + goto st_case_1970 + case 1971: + goto st_case_1971 + case 1972: + goto st_case_1972 + case 1973: + goto st_case_1973 + case 1974: + goto st_case_1974 + case 1975: + goto st_case_1975 + case 1976: + goto st_case_1976 + case 1977: + goto st_case_1977 + case 1978: + goto st_case_1978 + case 1979: + goto st_case_1979 + case 1980: + goto st_case_1980 + case 1981: + goto st_case_1981 + case 1982: + goto st_case_1982 + case 1983: + goto st_case_1983 + case 1984: + goto st_case_1984 + case 1985: + goto st_case_1985 + case 1986: + goto st_case_1986 + case 1987: + goto st_case_1987 + case 1988: + goto st_case_1988 + case 1989: + goto st_case_1989 + case 1990: + goto st_case_1990 + case 1991: + goto st_case_1991 + case 1992: + goto st_case_1992 + case 1993: + goto st_case_1993 + case 1994: + goto st_case_1994 + case 1995: + goto st_case_1995 + case 1996: + goto st_case_1996 + case 1997: + goto st_case_1997 + case 1998: + goto st_case_1998 + case 1999: + goto st_case_1999 + case 2000: + goto st_case_2000 + case 2001: + goto st_case_2001 + case 2002: + goto st_case_2002 + case 2003: + goto st_case_2003 + case 2004: + goto st_case_2004 + case 2005: + goto st_case_2005 + case 2006: + goto st_case_2006 + case 2007: + goto st_case_2007 + case 2008: + goto st_case_2008 + case 2009: + goto st_case_2009 + case 2010: + goto st_case_2010 + case 2011: + goto st_case_2011 + case 2012: + goto st_case_2012 + case 2013: + goto st_case_2013 + case 2014: + goto st_case_2014 + case 2015: + goto st_case_2015 + case 2016: + goto st_case_2016 + case 2017: + goto st_case_2017 + case 2018: + goto st_case_2018 + case 2019: + goto st_case_2019 + case 2020: + goto st_case_2020 + case 2021: + goto st_case_2021 + case 2022: + goto st_case_2022 + case 2023: + goto st_case_2023 + case 2024: + goto st_case_2024 + case 2025: + goto st_case_2025 + case 2026: + goto st_case_2026 + case 2027: + goto st_case_2027 + case 2028: + goto st_case_2028 + case 2029: + goto st_case_2029 + case 2030: + goto st_case_2030 + case 2031: + goto st_case_2031 + case 2032: + goto st_case_2032 + case 2033: + goto st_case_2033 + case 2034: + goto st_case_2034 + case 2035: + goto st_case_2035 + case 2036: + goto st_case_2036 + case 2037: + goto st_case_2037 + case 2038: + goto st_case_2038 + case 2039: + goto st_case_2039 + case 2040: + goto st_case_2040 + case 2041: + goto st_case_2041 + case 2042: + goto st_case_2042 + case 2043: + goto st_case_2043 + case 2044: + goto st_case_2044 + case 2045: + goto st_case_2045 + case 2046: + goto st_case_2046 + case 2047: + goto st_case_2047 + case 2048: + goto st_case_2048 + case 2049: + goto st_case_2049 + case 2050: + goto st_case_2050 + case 2051: + goto st_case_2051 + case 2052: + goto st_case_2052 + case 2053: + goto st_case_2053 + case 2054: + goto st_case_2054 + case 2055: + goto st_case_2055 + case 2056: + goto st_case_2056 + case 2057: + goto st_case_2057 + case 2058: + goto st_case_2058 + case 2059: + goto st_case_2059 + case 2060: + goto st_case_2060 + case 2061: + goto st_case_2061 + case 2062: + goto st_case_2062 + case 2063: + goto st_case_2063 + case 2064: + goto st_case_2064 + case 2065: + goto st_case_2065 + case 2066: + goto st_case_2066 + case 2067: + goto st_case_2067 + case 2068: + goto st_case_2068 + case 2069: + goto st_case_2069 + case 2070: + goto st_case_2070 + case 2071: + goto st_case_2071 + case 2072: + goto st_case_2072 + case 2073: + goto st_case_2073 + case 2074: + goto st_case_2074 + case 2075: + goto st_case_2075 + case 2076: + goto st_case_2076 + case 2077: + goto st_case_2077 + case 2078: + goto st_case_2078 + case 2079: + goto st_case_2079 + case 2080: + goto st_case_2080 + case 2081: + goto st_case_2081 + case 2082: + goto st_case_2082 + case 2083: + goto st_case_2083 + case 2084: + goto st_case_2084 + case 2085: + goto st_case_2085 + case 2086: + goto st_case_2086 + case 2087: + goto st_case_2087 + case 2088: + goto st_case_2088 + case 2089: + goto st_case_2089 + case 2090: + goto st_case_2090 + case 2091: + goto st_case_2091 + case 2092: + goto st_case_2092 + case 2093: + goto st_case_2093 + case 2094: + goto st_case_2094 + case 2095: + goto st_case_2095 + case 2096: + goto st_case_2096 + case 2097: + goto st_case_2097 + case 2098: + goto st_case_2098 + case 2099: + goto st_case_2099 + case 2100: + goto st_case_2100 + case 2101: + goto st_case_2101 + case 2102: + goto st_case_2102 + case 2103: + goto st_case_2103 + case 2104: + goto st_case_2104 + case 2105: + goto st_case_2105 + case 2106: + goto st_case_2106 + case 2107: + goto st_case_2107 + case 2108: + goto st_case_2108 + case 2109: + goto st_case_2109 + case 2110: + goto st_case_2110 + case 2111: + goto st_case_2111 + case 2112: + goto st_case_2112 + case 2113: + goto st_case_2113 + case 2114: + goto st_case_2114 + case 2115: + goto st_case_2115 + case 2116: + goto st_case_2116 + case 2117: + goto st_case_2117 + case 2118: + goto st_case_2118 + case 2119: + goto st_case_2119 + case 2120: + goto st_case_2120 + case 2121: + goto st_case_2121 + case 2122: + goto st_case_2122 + case 2123: + goto st_case_2123 + case 2124: + goto st_case_2124 + case 2125: + goto st_case_2125 + case 2126: + goto st_case_2126 + case 2127: + goto st_case_2127 + case 2128: + goto st_case_2128 + case 2129: + goto st_case_2129 + case 2130: + goto st_case_2130 + case 2131: + goto st_case_2131 + case 2132: + goto st_case_2132 + case 2133: + goto st_case_2133 + case 2134: + goto st_case_2134 + case 2135: + goto st_case_2135 + case 2136: + goto st_case_2136 + case 2137: + goto st_case_2137 + case 2138: + goto st_case_2138 + case 2139: + goto st_case_2139 + case 2140: + goto st_case_2140 + case 2141: + goto st_case_2141 + case 2142: + goto st_case_2142 + case 2143: + goto st_case_2143 + case 2144: + goto st_case_2144 + case 2145: + goto st_case_2145 + case 2146: + goto st_case_2146 + case 2147: + goto st_case_2147 + case 2148: + goto st_case_2148 + case 2149: + goto st_case_2149 + case 2150: + goto st_case_2150 + case 2151: + goto st_case_2151 + case 2152: + goto st_case_2152 + case 2153: + goto st_case_2153 + case 2154: + goto st_case_2154 + case 2155: + goto st_case_2155 + case 2156: + goto st_case_2156 + case 2157: + goto st_case_2157 + case 2158: + goto st_case_2158 + case 2159: + goto st_case_2159 + case 2160: + goto st_case_2160 + case 2161: + goto st_case_2161 + case 2162: + goto st_case_2162 + case 2163: + goto st_case_2163 + case 2164: + goto st_case_2164 + case 2165: + goto st_case_2165 + case 2166: + goto st_case_2166 + case 2167: + goto st_case_2167 + case 2168: + goto st_case_2168 + case 2169: + goto st_case_2169 + case 2170: + goto st_case_2170 + case 2171: + goto st_case_2171 + case 2172: + goto st_case_2172 + case 2173: + goto st_case_2173 + case 2174: + goto st_case_2174 + case 2175: + goto st_case_2175 + case 2176: + goto st_case_2176 + case 2177: + goto st_case_2177 + case 2178: + goto st_case_2178 + case 2179: + goto st_case_2179 + case 2180: + goto st_case_2180 + case 2181: + goto st_case_2181 + case 2182: + goto st_case_2182 + case 2183: + goto st_case_2183 + case 2184: + goto st_case_2184 + case 2185: + goto st_case_2185 + case 2186: + goto st_case_2186 + case 2187: + goto st_case_2187 + case 2188: + goto st_case_2188 + case 2189: + goto st_case_2189 + case 2190: + goto st_case_2190 + case 2191: + goto st_case_2191 + case 2192: + goto st_case_2192 + case 4874: + goto st_case_4874 + case 2193: + goto st_case_2193 + case 2194: + goto st_case_2194 + case 2195: + goto st_case_2195 + case 2196: + goto st_case_2196 + case 2197: + goto st_case_2197 + case 2198: + goto st_case_2198 + case 2199: + goto st_case_2199 + case 2200: + goto st_case_2200 + case 2201: + goto st_case_2201 + case 2202: + goto st_case_2202 + case 2203: + goto st_case_2203 + case 2204: + goto st_case_2204 + case 2205: + goto st_case_2205 + case 2206: + goto st_case_2206 + case 2207: + goto st_case_2207 + case 2208: + goto st_case_2208 + case 2209: + goto st_case_2209 + case 2210: + goto st_case_2210 + case 2211: + goto st_case_2211 + case 2212: + goto st_case_2212 + case 2213: + goto st_case_2213 + case 2214: + goto st_case_2214 + case 2215: + goto st_case_2215 + case 2216: + goto st_case_2216 + case 2217: + goto st_case_2217 + case 2218: + goto st_case_2218 + case 2219: + goto st_case_2219 + case 2220: + goto st_case_2220 + case 2221: + goto st_case_2221 + case 2222: + goto st_case_2222 + case 2223: + goto st_case_2223 + case 2224: + goto st_case_2224 + case 2225: + goto st_case_2225 + case 2226: + goto st_case_2226 + case 2227: + goto st_case_2227 + case 2228: + goto st_case_2228 + case 2229: + goto st_case_2229 + case 2230: + goto st_case_2230 + case 2231: + goto st_case_2231 + case 2232: + goto st_case_2232 + case 2233: + goto st_case_2233 + case 2234: + goto st_case_2234 + case 2235: + goto st_case_2235 + case 2236: + goto st_case_2236 + case 2237: + goto st_case_2237 + case 2238: + goto st_case_2238 + case 2239: + goto st_case_2239 + case 2240: + goto st_case_2240 + case 2241: + goto st_case_2241 + case 2242: + goto st_case_2242 + case 2243: + goto st_case_2243 + case 2244: + goto st_case_2244 + case 2245: + goto st_case_2245 + case 2246: + goto st_case_2246 + case 2247: + goto st_case_2247 + case 2248: + goto st_case_2248 + case 2249: + goto st_case_2249 + case 2250: + goto st_case_2250 + case 2251: + goto st_case_2251 + case 2252: + goto st_case_2252 + case 2253: + goto st_case_2253 + case 2254: + goto st_case_2254 + case 2255: + goto st_case_2255 + case 2256: + goto st_case_2256 + case 2257: + goto st_case_2257 + case 2258: + goto st_case_2258 + case 2259: + goto st_case_2259 + case 2260: + goto st_case_2260 + case 2261: + goto st_case_2261 + case 2262: + goto st_case_2262 + case 2263: + goto st_case_2263 + case 2264: + goto st_case_2264 + case 2265: + goto st_case_2265 + case 2266: + goto st_case_2266 + case 2267: + goto st_case_2267 + case 2268: + goto st_case_2268 + case 2269: + goto st_case_2269 + case 2270: + goto st_case_2270 + case 2271: + goto st_case_2271 + case 2272: + goto st_case_2272 + case 2273: + goto st_case_2273 + case 2274: + goto st_case_2274 + case 2275: + goto st_case_2275 + case 2276: + goto st_case_2276 + case 2277: + goto st_case_2277 + case 2278: + goto st_case_2278 + case 2279: + goto st_case_2279 + case 2280: + goto st_case_2280 + case 2281: + goto st_case_2281 + case 2282: + goto st_case_2282 + case 2283: + goto st_case_2283 + case 2284: + goto st_case_2284 + case 2285: + goto st_case_2285 + case 2286: + goto st_case_2286 + case 2287: + goto st_case_2287 + case 2288: + goto st_case_2288 + case 2289: + goto st_case_2289 + case 2290: + goto st_case_2290 + case 2291: + goto st_case_2291 + case 2292: + goto st_case_2292 + case 2293: + goto st_case_2293 + case 2294: + goto st_case_2294 + case 2295: + goto st_case_2295 + case 2296: + goto st_case_2296 + case 2297: + goto st_case_2297 + case 2298: + goto st_case_2298 + case 2299: + goto st_case_2299 + case 2300: + goto st_case_2300 + case 2301: + goto st_case_2301 + case 2302: + goto st_case_2302 + case 2303: + goto st_case_2303 + case 2304: + goto st_case_2304 + case 2305: + goto st_case_2305 + case 2306: + goto st_case_2306 + case 2307: + goto st_case_2307 + case 2308: + goto st_case_2308 + case 2309: + goto st_case_2309 + case 2310: + goto st_case_2310 + case 2311: + goto st_case_2311 + case 2312: + goto st_case_2312 + case 2313: + goto st_case_2313 + case 2314: + goto st_case_2314 + case 2315: + goto st_case_2315 + case 2316: + goto st_case_2316 + case 2317: + goto st_case_2317 + case 2318: + goto st_case_2318 + case 2319: + goto st_case_2319 + case 2320: + goto st_case_2320 + case 2321: + goto st_case_2321 + case 2322: + goto st_case_2322 + case 2323: + goto st_case_2323 + case 2324: + goto st_case_2324 + case 2325: + goto st_case_2325 + case 2326: + goto st_case_2326 + case 2327: + goto st_case_2327 + case 2328: + goto st_case_2328 + case 2329: + goto st_case_2329 + case 2330: + goto st_case_2330 + case 2331: + goto st_case_2331 + case 2332: + goto st_case_2332 + case 2333: + goto st_case_2333 + case 2334: + goto st_case_2334 + case 2335: + goto st_case_2335 + case 2336: + goto st_case_2336 + case 2337: + goto st_case_2337 + case 2338: + goto st_case_2338 + case 2339: + goto st_case_2339 + case 4875: + goto st_case_4875 + case 4876: + goto st_case_4876 + case 2340: + goto st_case_2340 + case 2341: + goto st_case_2341 + case 2342: + goto st_case_2342 + case 2343: + goto st_case_2343 + case 2344: + goto st_case_2344 + case 2345: + goto st_case_2345 + case 2346: + goto st_case_2346 + case 2347: + goto st_case_2347 + case 2348: + goto st_case_2348 + case 2349: + goto st_case_2349 + case 2350: + goto st_case_2350 + case 2351: + goto st_case_2351 + case 2352: + goto st_case_2352 + case 2353: + goto st_case_2353 + case 2354: + goto st_case_2354 + case 2355: + goto st_case_2355 + case 2356: + goto st_case_2356 + case 2357: + goto st_case_2357 + case 2358: + goto st_case_2358 + case 2359: + goto st_case_2359 + case 2360: + goto st_case_2360 + case 2361: + goto st_case_2361 + case 2362: + goto st_case_2362 + case 2363: + goto st_case_2363 + case 2364: + goto st_case_2364 + case 2365: + goto st_case_2365 + case 2366: + goto st_case_2366 + case 2367: + goto st_case_2367 + case 2368: + goto st_case_2368 + case 2369: + goto st_case_2369 + case 2370: + goto st_case_2370 + case 2371: + goto st_case_2371 + case 2372: + goto st_case_2372 + case 2373: + goto st_case_2373 + case 2374: + goto st_case_2374 + case 2375: + goto st_case_2375 + case 2376: + goto st_case_2376 + case 2377: + goto st_case_2377 + case 2378: + goto st_case_2378 + case 2379: + goto st_case_2379 + case 2380: + goto st_case_2380 + case 2381: + goto st_case_2381 + case 2382: + goto st_case_2382 + case 2383: + goto st_case_2383 + case 2384: + goto st_case_2384 + case 2385: + goto st_case_2385 + case 2386: + goto st_case_2386 + case 2387: + goto st_case_2387 + case 2388: + goto st_case_2388 + case 2389: + goto st_case_2389 + case 2390: + goto st_case_2390 + case 2391: + goto st_case_2391 + case 2392: + goto st_case_2392 + case 2393: + goto st_case_2393 + case 2394: + goto st_case_2394 + case 2395: + goto st_case_2395 + case 2396: + goto st_case_2396 + case 2397: + goto st_case_2397 + case 2398: + goto st_case_2398 + case 2399: + goto st_case_2399 + case 2400: + goto st_case_2400 + case 2401: + goto st_case_2401 + case 2402: + goto st_case_2402 + case 2403: + goto st_case_2403 + case 2404: + goto st_case_2404 + case 2405: + goto st_case_2405 + case 2406: + goto st_case_2406 + case 2407: + goto st_case_2407 + case 2408: + goto st_case_2408 + case 2409: + goto st_case_2409 + case 2410: + goto st_case_2410 + case 2411: + goto st_case_2411 + case 2412: + goto st_case_2412 + case 2413: + goto st_case_2413 + case 2414: + goto st_case_2414 + case 2415: + goto st_case_2415 + case 2416: + goto st_case_2416 + case 2417: + goto st_case_2417 + case 2418: + goto st_case_2418 + case 2419: + goto st_case_2419 + case 2420: + goto st_case_2420 + case 2421: + goto st_case_2421 + case 2422: + goto st_case_2422 + case 2423: + goto st_case_2423 + case 2424: + goto st_case_2424 + case 2425: + goto st_case_2425 + case 2426: + goto st_case_2426 + case 2427: + goto st_case_2427 + case 2428: + goto st_case_2428 + case 2429: + goto st_case_2429 + case 2430: + goto st_case_2430 + case 2431: + goto st_case_2431 + case 2432: + goto st_case_2432 + case 2433: + goto st_case_2433 + case 2434: + goto st_case_2434 + case 2435: + goto st_case_2435 + case 2436: + goto st_case_2436 + case 2437: + goto st_case_2437 + case 2438: + goto st_case_2438 + case 2439: + goto st_case_2439 + case 2440: + goto st_case_2440 + case 2441: + goto st_case_2441 + case 2442: + goto st_case_2442 + case 2443: + goto st_case_2443 + case 2444: + goto st_case_2444 + case 2445: + goto st_case_2445 + case 2446: + goto st_case_2446 + case 2447: + goto st_case_2447 + case 2448: + goto st_case_2448 + case 2449: + goto st_case_2449 + case 2450: + goto st_case_2450 + case 2451: + goto st_case_2451 + case 2452: + goto st_case_2452 + case 2453: + goto st_case_2453 + case 2454: + goto st_case_2454 + case 2455: + goto st_case_2455 + case 2456: + goto st_case_2456 + case 2457: + goto st_case_2457 + case 2458: + goto st_case_2458 + case 2459: + goto st_case_2459 + case 2460: + goto st_case_2460 + case 2461: + goto st_case_2461 + case 2462: + goto st_case_2462 + case 2463: + goto st_case_2463 + case 2464: + goto st_case_2464 + case 2465: + goto st_case_2465 + case 2466: + goto st_case_2466 + case 2467: + goto st_case_2467 + case 2468: + goto st_case_2468 + case 2469: + goto st_case_2469 + case 2470: + goto st_case_2470 + case 2471: + goto st_case_2471 + case 2472: + goto st_case_2472 + case 2473: + goto st_case_2473 + case 2474: + goto st_case_2474 + case 2475: + goto st_case_2475 + case 2476: + goto st_case_2476 + case 2477: + goto st_case_2477 + case 2478: + goto st_case_2478 + case 2479: + goto st_case_2479 + case 2480: + goto st_case_2480 + case 2481: + goto st_case_2481 + case 2482: + goto st_case_2482 + case 2483: + goto st_case_2483 + case 2484: + goto st_case_2484 + case 2485: + goto st_case_2485 + case 2486: + goto st_case_2486 + case 2487: + goto st_case_2487 + case 2488: + goto st_case_2488 + case 2489: + goto st_case_2489 + case 2490: + goto st_case_2490 + case 2491: + goto st_case_2491 + case 2492: + goto st_case_2492 + case 2493: + goto st_case_2493 + case 2494: + goto st_case_2494 + case 2495: + goto st_case_2495 + case 2496: + goto st_case_2496 + case 2497: + goto st_case_2497 + case 2498: + goto st_case_2498 + case 2499: + goto st_case_2499 + case 2500: + goto st_case_2500 + case 2501: + goto st_case_2501 + case 2502: + goto st_case_2502 + case 2503: + goto st_case_2503 + case 2504: + goto st_case_2504 + case 2505: + goto st_case_2505 + case 2506: + goto st_case_2506 + case 2507: + goto st_case_2507 + case 2508: + goto st_case_2508 + case 2509: + goto st_case_2509 + case 2510: + goto st_case_2510 + case 2511: + goto st_case_2511 + case 2512: + goto st_case_2512 + case 2513: + goto st_case_2513 + case 2514: + goto st_case_2514 + case 2515: + goto st_case_2515 + case 2516: + goto st_case_2516 + case 2517: + goto st_case_2517 + case 2518: + goto st_case_2518 + case 2519: + goto st_case_2519 + case 2520: + goto st_case_2520 + case 2521: + goto st_case_2521 + case 2522: + goto st_case_2522 + case 2523: + goto st_case_2523 + case 2524: + goto st_case_2524 + case 2525: + goto st_case_2525 + case 2526: + goto st_case_2526 + case 2527: + goto st_case_2527 + case 2528: + goto st_case_2528 + case 2529: + goto st_case_2529 + case 2530: + goto st_case_2530 + case 2531: + goto st_case_2531 + case 2532: + goto st_case_2532 + case 2533: + goto st_case_2533 + case 2534: + goto st_case_2534 + case 2535: + goto st_case_2535 + case 2536: + goto st_case_2536 + case 2537: + goto st_case_2537 + case 2538: + goto st_case_2538 + case 2539: + goto st_case_2539 + case 2540: + goto st_case_2540 + case 2541: + goto st_case_2541 + case 2542: + goto st_case_2542 + case 2543: + goto st_case_2543 + case 2544: + goto st_case_2544 + case 2545: + goto st_case_2545 + case 2546: + goto st_case_2546 + case 2547: + goto st_case_2547 + case 2548: + goto st_case_2548 + case 2549: + goto st_case_2549 + case 2550: + goto st_case_2550 + case 2551: + goto st_case_2551 + case 2552: + goto st_case_2552 + case 2553: + goto st_case_2553 + case 2554: + goto st_case_2554 + case 2555: + goto st_case_2555 + case 2556: + goto st_case_2556 + case 2557: + goto st_case_2557 + case 2558: + goto st_case_2558 + case 2559: + goto st_case_2559 + case 2560: + goto st_case_2560 + case 2561: + goto st_case_2561 + case 2562: + goto st_case_2562 + case 2563: + goto st_case_2563 + case 2564: + goto st_case_2564 + case 2565: + goto st_case_2565 + case 2566: + goto st_case_2566 + case 2567: + goto st_case_2567 + case 2568: + goto st_case_2568 + case 2569: + goto st_case_2569 + case 2570: + goto st_case_2570 + case 2571: + goto st_case_2571 + case 2572: + goto st_case_2572 + case 2573: + goto st_case_2573 + case 2574: + goto st_case_2574 + case 2575: + goto st_case_2575 + case 2576: + goto st_case_2576 + case 2577: + goto st_case_2577 + case 2578: + goto st_case_2578 + case 2579: + goto st_case_2579 + case 2580: + goto st_case_2580 + case 2581: + goto st_case_2581 + case 2582: + goto st_case_2582 + case 2583: + goto st_case_2583 + case 2584: + goto st_case_2584 + case 2585: + goto st_case_2585 + case 2586: + goto st_case_2586 + case 2587: + goto st_case_2587 + case 2588: + goto st_case_2588 + case 2589: + goto st_case_2589 + case 2590: + goto st_case_2590 + case 2591: + goto st_case_2591 + case 2592: + goto st_case_2592 + case 2593: + goto st_case_2593 + case 2594: + goto st_case_2594 + case 2595: + goto st_case_2595 + case 2596: + goto st_case_2596 + case 2597: + goto st_case_2597 + case 2598: + goto st_case_2598 + case 2599: + goto st_case_2599 + case 2600: + goto st_case_2600 + case 2601: + goto st_case_2601 + case 2602: + goto st_case_2602 + case 2603: + goto st_case_2603 + case 2604: + goto st_case_2604 + case 2605: + goto st_case_2605 + case 2606: + goto st_case_2606 + case 2607: + goto st_case_2607 + case 2608: + goto st_case_2608 + case 2609: + goto st_case_2609 + case 2610: + goto st_case_2610 + case 2611: + goto st_case_2611 + case 2612: + goto st_case_2612 + case 2613: + goto st_case_2613 + case 2614: + goto st_case_2614 + case 2615: + goto st_case_2615 + case 2616: + goto st_case_2616 + case 2617: + goto st_case_2617 + case 2618: + goto st_case_2618 + case 2619: + goto st_case_2619 + case 2620: + goto st_case_2620 + case 2621: + goto st_case_2621 + case 2622: + goto st_case_2622 + case 2623: + goto st_case_2623 + case 2624: + goto st_case_2624 + case 2625: + goto st_case_2625 + case 2626: + goto st_case_2626 + case 2627: + goto st_case_2627 + case 2628: + goto st_case_2628 + case 2629: + goto st_case_2629 + case 2630: + goto st_case_2630 + case 2631: + goto st_case_2631 + case 2632: + goto st_case_2632 + case 2633: + goto st_case_2633 + case 2634: + goto st_case_2634 + case 2635: + goto st_case_2635 + case 4877: + goto st_case_4877 + case 4878: + goto st_case_4878 + case 2636: + goto st_case_2636 + case 2637: + goto st_case_2637 + case 2638: + goto st_case_2638 + case 2639: + goto st_case_2639 + case 2640: + goto st_case_2640 + case 2641: + goto st_case_2641 + case 2642: + goto st_case_2642 + case 2643: + goto st_case_2643 + case 2644: + goto st_case_2644 + case 2645: + goto st_case_2645 + case 2646: + goto st_case_2646 + case 2647: + goto st_case_2647 + case 2648: + goto st_case_2648 + case 2649: + goto st_case_2649 + case 2650: + goto st_case_2650 + case 2651: + goto st_case_2651 + case 2652: + goto st_case_2652 + case 2653: + goto st_case_2653 + case 2654: + goto st_case_2654 + case 2655: + goto st_case_2655 + case 2656: + goto st_case_2656 + case 2657: + goto st_case_2657 + case 2658: + goto st_case_2658 + case 2659: + goto st_case_2659 + case 2660: + goto st_case_2660 + case 2661: + goto st_case_2661 + case 2662: + goto st_case_2662 + case 2663: + goto st_case_2663 + case 2664: + goto st_case_2664 + case 2665: + goto st_case_2665 + case 2666: + goto st_case_2666 + case 2667: + goto st_case_2667 + case 2668: + goto st_case_2668 + case 2669: + goto st_case_2669 + case 2670: + goto st_case_2670 + case 2671: + goto st_case_2671 + case 2672: + goto st_case_2672 + case 2673: + goto st_case_2673 + case 2674: + goto st_case_2674 + case 2675: + goto st_case_2675 + case 2676: + goto st_case_2676 + case 2677: + goto st_case_2677 + case 2678: + goto st_case_2678 + case 2679: + goto st_case_2679 + case 2680: + goto st_case_2680 + case 2681: + goto st_case_2681 + case 2682: + goto st_case_2682 + case 2683: + goto st_case_2683 + case 2684: + goto st_case_2684 + case 2685: + goto st_case_2685 + case 2686: + goto st_case_2686 + case 2687: + goto st_case_2687 + case 2688: + goto st_case_2688 + case 2689: + goto st_case_2689 + case 2690: + goto st_case_2690 + case 2691: + goto st_case_2691 + case 2692: + goto st_case_2692 + case 2693: + goto st_case_2693 + case 2694: + goto st_case_2694 + case 2695: + goto st_case_2695 + case 2696: + goto st_case_2696 + case 2697: + goto st_case_2697 + case 2698: + goto st_case_2698 + case 2699: + goto st_case_2699 + case 2700: + goto st_case_2700 + case 2701: + goto st_case_2701 + case 2702: + goto st_case_2702 + case 2703: + goto st_case_2703 + case 2704: + goto st_case_2704 + case 2705: + goto st_case_2705 + case 2706: + goto st_case_2706 + case 2707: + goto st_case_2707 + case 2708: + goto st_case_2708 + case 2709: + goto st_case_2709 + case 2710: + goto st_case_2710 + case 2711: + goto st_case_2711 + case 2712: + goto st_case_2712 + case 2713: + goto st_case_2713 + case 2714: + goto st_case_2714 + case 2715: + goto st_case_2715 + case 2716: + goto st_case_2716 + case 2717: + goto st_case_2717 + case 2718: + goto st_case_2718 + case 2719: + goto st_case_2719 + case 2720: + goto st_case_2720 + case 2721: + goto st_case_2721 + case 2722: + goto st_case_2722 + case 2723: + goto st_case_2723 + case 2724: + goto st_case_2724 + case 2725: + goto st_case_2725 + case 2726: + goto st_case_2726 + case 2727: + goto st_case_2727 + case 2728: + goto st_case_2728 + case 2729: + goto st_case_2729 + case 2730: + goto st_case_2730 + case 2731: + goto st_case_2731 + case 2732: + goto st_case_2732 + case 2733: + goto st_case_2733 + case 2734: + goto st_case_2734 + case 2735: + goto st_case_2735 + case 2736: + goto st_case_2736 + case 2737: + goto st_case_2737 + case 2738: + goto st_case_2738 + case 2739: + goto st_case_2739 + case 2740: + goto st_case_2740 + case 2741: + goto st_case_2741 + case 2742: + goto st_case_2742 + case 2743: + goto st_case_2743 + case 2744: + goto st_case_2744 + case 2745: + goto st_case_2745 + case 2746: + goto st_case_2746 + case 2747: + goto st_case_2747 + case 2748: + goto st_case_2748 + case 2749: + goto st_case_2749 + case 2750: + goto st_case_2750 + case 2751: + goto st_case_2751 + case 2752: + goto st_case_2752 + case 2753: + goto st_case_2753 + case 2754: + goto st_case_2754 + case 2755: + goto st_case_2755 + case 2756: + goto st_case_2756 + case 2757: + goto st_case_2757 + case 2758: + goto st_case_2758 + case 2759: + goto st_case_2759 + case 2760: + goto st_case_2760 + case 2761: + goto st_case_2761 + case 2762: + goto st_case_2762 + case 2763: + goto st_case_2763 + case 2764: + goto st_case_2764 + case 2765: + goto st_case_2765 + case 2766: + goto st_case_2766 + case 2767: + goto st_case_2767 + case 2768: + goto st_case_2768 + case 2769: + goto st_case_2769 + case 2770: + goto st_case_2770 + case 2771: + goto st_case_2771 + case 2772: + goto st_case_2772 + case 2773: + goto st_case_2773 + case 2774: + goto st_case_2774 + case 2775: + goto st_case_2775 + case 2776: + goto st_case_2776 + case 4879: + goto st_case_4879 + case 4880: + goto st_case_4880 + case 4881: + goto st_case_4881 + case 4882: + goto st_case_4882 + case 4883: + goto st_case_4883 + case 4884: + goto st_case_4884 + case 4885: + goto st_case_4885 + case 2777: + goto st_case_2777 + case 2778: + goto st_case_2778 + case 2779: + goto st_case_2779 + case 2780: + goto st_case_2780 + case 2781: + goto st_case_2781 + case 2782: + goto st_case_2782 + case 2783: + goto st_case_2783 + case 2784: + goto st_case_2784 + case 2785: + goto st_case_2785 + case 2786: + goto st_case_2786 + case 2787: + goto st_case_2787 + case 2788: + goto st_case_2788 + case 2789: + goto st_case_2789 + case 2790: + goto st_case_2790 + case 2791: + goto st_case_2791 + case 2792: + goto st_case_2792 + case 2793: + goto st_case_2793 + case 2794: + goto st_case_2794 + case 2795: + goto st_case_2795 + case 2796: + goto st_case_2796 + case 2797: + goto st_case_2797 + case 2798: + goto st_case_2798 + case 2799: + goto st_case_2799 + case 2800: + goto st_case_2800 + case 2801: + goto st_case_2801 + case 2802: + goto st_case_2802 + case 2803: + goto st_case_2803 + case 2804: + goto st_case_2804 + case 2805: + goto st_case_2805 + case 2806: + goto st_case_2806 + case 2807: + goto st_case_2807 + case 2808: + goto st_case_2808 + case 2809: + goto st_case_2809 + case 2810: + goto st_case_2810 + case 2811: + goto st_case_2811 + case 2812: + goto st_case_2812 + case 2813: + goto st_case_2813 + case 2814: + goto st_case_2814 + case 2815: + goto st_case_2815 + case 2816: + goto st_case_2816 + case 2817: + goto st_case_2817 + case 2818: + goto st_case_2818 + case 2819: + goto st_case_2819 + case 2820: + goto st_case_2820 + case 2821: + goto st_case_2821 + case 2822: + goto st_case_2822 + case 2823: + goto st_case_2823 + case 2824: + goto st_case_2824 + case 2825: + goto st_case_2825 + case 2826: + goto st_case_2826 + case 2827: + goto st_case_2827 + case 2828: + goto st_case_2828 + case 2829: + goto st_case_2829 + case 2830: + goto st_case_2830 + case 2831: + goto st_case_2831 + case 2832: + goto st_case_2832 + case 2833: + goto st_case_2833 + case 2834: + goto st_case_2834 + case 2835: + goto st_case_2835 + case 2836: + goto st_case_2836 + case 2837: + goto st_case_2837 + case 2838: + goto st_case_2838 + case 2839: + goto st_case_2839 + case 2840: + goto st_case_2840 + case 2841: + goto st_case_2841 + case 2842: + goto st_case_2842 + case 2843: + goto st_case_2843 + case 2844: + goto st_case_2844 + case 2845: + goto st_case_2845 + case 2846: + goto st_case_2846 + case 2847: + goto st_case_2847 + case 2848: + goto st_case_2848 + case 2849: + goto st_case_2849 + case 2850: + goto st_case_2850 + case 2851: + goto st_case_2851 + case 2852: + goto st_case_2852 + case 2853: + goto st_case_2853 + case 2854: + goto st_case_2854 + case 2855: + goto st_case_2855 + case 2856: + goto st_case_2856 + case 2857: + goto st_case_2857 + case 2858: + goto st_case_2858 + case 2859: + goto st_case_2859 + case 2860: + goto st_case_2860 + case 2861: + goto st_case_2861 + case 2862: + goto st_case_2862 + case 2863: + goto st_case_2863 + case 2864: + goto st_case_2864 + case 2865: + goto st_case_2865 + case 2866: + goto st_case_2866 + case 2867: + goto st_case_2867 + case 2868: + goto st_case_2868 + case 2869: + goto st_case_2869 + case 2870: + goto st_case_2870 + case 2871: + goto st_case_2871 + case 2872: + goto st_case_2872 + case 2873: + goto st_case_2873 + case 2874: + goto st_case_2874 + case 2875: + goto st_case_2875 + case 2876: + goto st_case_2876 + case 2877: + goto st_case_2877 + case 2878: + goto st_case_2878 + case 2879: + goto st_case_2879 + case 2880: + goto st_case_2880 + case 2881: + goto st_case_2881 + case 2882: + goto st_case_2882 + case 2883: + goto st_case_2883 + case 2884: + goto st_case_2884 + case 2885: + goto st_case_2885 + case 2886: + goto st_case_2886 + case 2887: + goto st_case_2887 + case 2888: + goto st_case_2888 + case 2889: + goto st_case_2889 + case 2890: + goto st_case_2890 + case 2891: + goto st_case_2891 + case 2892: + goto st_case_2892 + case 2893: + goto st_case_2893 + case 2894: + goto st_case_2894 + case 2895: + goto st_case_2895 + case 2896: + goto st_case_2896 + case 2897: + goto st_case_2897 + case 2898: + goto st_case_2898 + case 2899: + goto st_case_2899 + case 2900: + goto st_case_2900 + case 2901: + goto st_case_2901 + case 2902: + goto st_case_2902 + case 2903: + goto st_case_2903 + case 2904: + goto st_case_2904 + case 2905: + goto st_case_2905 + case 2906: + goto st_case_2906 + case 2907: + goto st_case_2907 + case 2908: + goto st_case_2908 + case 2909: + goto st_case_2909 + case 2910: + goto st_case_2910 + case 2911: + goto st_case_2911 + case 2912: + goto st_case_2912 + case 2913: + goto st_case_2913 + case 2914: + goto st_case_2914 + case 2915: + goto st_case_2915 + case 2916: + goto st_case_2916 + case 2917: + goto st_case_2917 + case 2918: + goto st_case_2918 + case 2919: + goto st_case_2919 + case 2920: + goto st_case_2920 + case 2921: + goto st_case_2921 + case 2922: + goto st_case_2922 + case 2923: + goto st_case_2923 + case 4886: + goto st_case_4886 + case 2924: + goto st_case_2924 + case 2925: + goto st_case_2925 + case 2926: + goto st_case_2926 + case 2927: + goto st_case_2927 + case 2928: + goto st_case_2928 + case 2929: + goto st_case_2929 + case 2930: + goto st_case_2930 + case 2931: + goto st_case_2931 + case 2932: + goto st_case_2932 + case 2933: + goto st_case_2933 + case 2934: + goto st_case_2934 + case 2935: + goto st_case_2935 + case 2936: + goto st_case_2936 + case 2937: + goto st_case_2937 + case 2938: + goto st_case_2938 + case 2939: + goto st_case_2939 + case 2940: + goto st_case_2940 + case 2941: + goto st_case_2941 + case 2942: + goto st_case_2942 + case 2943: + goto st_case_2943 + case 2944: + goto st_case_2944 + case 2945: + goto st_case_2945 + case 2946: + goto st_case_2946 + case 2947: + goto st_case_2947 + case 2948: + goto st_case_2948 + case 2949: + goto st_case_2949 + case 2950: + goto st_case_2950 + case 2951: + goto st_case_2951 + case 2952: + goto st_case_2952 + case 2953: + goto st_case_2953 + case 2954: + goto st_case_2954 + case 2955: + goto st_case_2955 + case 2956: + goto st_case_2956 + case 2957: + goto st_case_2957 + case 2958: + goto st_case_2958 + case 2959: + goto st_case_2959 + case 2960: + goto st_case_2960 + case 2961: + goto st_case_2961 + case 2962: + goto st_case_2962 + case 2963: + goto st_case_2963 + case 2964: + goto st_case_2964 + case 2965: + goto st_case_2965 + case 2966: + goto st_case_2966 + case 2967: + goto st_case_2967 + case 2968: + goto st_case_2968 + case 2969: + goto st_case_2969 + case 2970: + goto st_case_2970 + case 2971: + goto st_case_2971 + case 2972: + goto st_case_2972 + case 2973: + goto st_case_2973 + case 2974: + goto st_case_2974 + case 2975: + goto st_case_2975 + case 2976: + goto st_case_2976 + case 2977: + goto st_case_2977 + case 2978: + goto st_case_2978 + case 2979: + goto st_case_2979 + case 2980: + goto st_case_2980 + case 2981: + goto st_case_2981 + case 2982: + goto st_case_2982 + case 2983: + goto st_case_2983 + case 2984: + goto st_case_2984 + case 2985: + goto st_case_2985 + case 2986: + goto st_case_2986 + case 2987: + goto st_case_2987 + case 2988: + goto st_case_2988 + case 2989: + goto st_case_2989 + case 2990: + goto st_case_2990 + case 2991: + goto st_case_2991 + case 2992: + goto st_case_2992 + case 2993: + goto st_case_2993 + case 2994: + goto st_case_2994 + case 2995: + goto st_case_2995 + case 2996: + goto st_case_2996 + case 2997: + goto st_case_2997 + case 2998: + goto st_case_2998 + case 2999: + goto st_case_2999 + case 3000: + goto st_case_3000 + case 3001: + goto st_case_3001 + case 3002: + goto st_case_3002 + case 3003: + goto st_case_3003 + case 3004: + goto st_case_3004 + case 3005: + goto st_case_3005 + case 3006: + goto st_case_3006 + case 3007: + goto st_case_3007 + case 3008: + goto st_case_3008 + case 3009: + goto st_case_3009 + case 3010: + goto st_case_3010 + case 3011: + goto st_case_3011 + case 3012: + goto st_case_3012 + case 3013: + goto st_case_3013 + case 3014: + goto st_case_3014 + case 3015: + goto st_case_3015 + case 3016: + goto st_case_3016 + case 3017: + goto st_case_3017 + case 3018: + goto st_case_3018 + case 3019: + goto st_case_3019 + case 3020: + goto st_case_3020 + case 3021: + goto st_case_3021 + case 3022: + goto st_case_3022 + case 3023: + goto st_case_3023 + case 3024: + goto st_case_3024 + case 3025: + goto st_case_3025 + case 3026: + goto st_case_3026 + case 3027: + goto st_case_3027 + case 3028: + goto st_case_3028 + case 3029: + goto st_case_3029 + case 3030: + goto st_case_3030 + case 3031: + goto st_case_3031 + case 3032: + goto st_case_3032 + case 3033: + goto st_case_3033 + case 3034: + goto st_case_3034 + case 3035: + goto st_case_3035 + case 3036: + goto st_case_3036 + case 3037: + goto st_case_3037 + case 3038: + goto st_case_3038 + case 3039: + goto st_case_3039 + case 3040: + goto st_case_3040 + case 3041: + goto st_case_3041 + case 3042: + goto st_case_3042 + case 3043: + goto st_case_3043 + case 3044: + goto st_case_3044 + case 3045: + goto st_case_3045 + case 3046: + goto st_case_3046 + case 3047: + goto st_case_3047 + case 3048: + goto st_case_3048 + case 3049: + goto st_case_3049 + case 3050: + goto st_case_3050 + case 3051: + goto st_case_3051 + case 3052: + goto st_case_3052 + case 3053: + goto st_case_3053 + case 3054: + goto st_case_3054 + case 3055: + goto st_case_3055 + case 3056: + goto st_case_3056 + case 3057: + goto st_case_3057 + case 3058: + goto st_case_3058 + case 3059: + goto st_case_3059 + case 3060: + goto st_case_3060 + case 3061: + goto st_case_3061 + case 3062: + goto st_case_3062 + case 3063: + goto st_case_3063 + case 3064: + goto st_case_3064 + case 3065: + goto st_case_3065 + case 3066: + goto st_case_3066 + case 3067: + goto st_case_3067 + case 3068: + goto st_case_3068 + case 3069: + goto st_case_3069 + case 3070: + goto st_case_3070 + case 4887: + goto st_case_4887 + case 3071: + goto st_case_3071 + case 3072: + goto st_case_3072 + case 3073: + goto st_case_3073 + case 3074: + goto st_case_3074 + case 3075: + goto st_case_3075 + case 3076: + goto st_case_3076 + case 3077: + goto st_case_3077 + case 3078: + goto st_case_3078 + case 3079: + goto st_case_3079 + case 3080: + goto st_case_3080 + case 3081: + goto st_case_3081 + case 3082: + goto st_case_3082 + case 3083: + goto st_case_3083 + case 3084: + goto st_case_3084 + case 3085: + goto st_case_3085 + case 3086: + goto st_case_3086 + case 3087: + goto st_case_3087 + case 3088: + goto st_case_3088 + case 3089: + goto st_case_3089 + case 3090: + goto st_case_3090 + case 3091: + goto st_case_3091 + case 3092: + goto st_case_3092 + case 3093: + goto st_case_3093 + case 3094: + goto st_case_3094 + case 3095: + goto st_case_3095 + case 3096: + goto st_case_3096 + case 3097: + goto st_case_3097 + case 3098: + goto st_case_3098 + case 3099: + goto st_case_3099 + case 3100: + goto st_case_3100 + case 3101: + goto st_case_3101 + case 3102: + goto st_case_3102 + case 3103: + goto st_case_3103 + case 3104: + goto st_case_3104 + case 3105: + goto st_case_3105 + case 3106: + goto st_case_3106 + case 3107: + goto st_case_3107 + case 3108: + goto st_case_3108 + case 3109: + goto st_case_3109 + case 3110: + goto st_case_3110 + case 3111: + goto st_case_3111 + case 3112: + goto st_case_3112 + case 3113: + goto st_case_3113 + case 3114: + goto st_case_3114 + case 3115: + goto st_case_3115 + case 3116: + goto st_case_3116 + case 3117: + goto st_case_3117 + case 3118: + goto st_case_3118 + case 3119: + goto st_case_3119 + case 3120: + goto st_case_3120 + case 3121: + goto st_case_3121 + case 3122: + goto st_case_3122 + case 3123: + goto st_case_3123 + case 3124: + goto st_case_3124 + case 3125: + goto st_case_3125 + case 3126: + goto st_case_3126 + case 3127: + goto st_case_3127 + case 3128: + goto st_case_3128 + case 3129: + goto st_case_3129 + case 3130: + goto st_case_3130 + case 3131: + goto st_case_3131 + case 3132: + goto st_case_3132 + case 3133: + goto st_case_3133 + case 3134: + goto st_case_3134 + case 3135: + goto st_case_3135 + case 3136: + goto st_case_3136 + case 3137: + goto st_case_3137 + case 3138: + goto st_case_3138 + case 3139: + goto st_case_3139 + case 3140: + goto st_case_3140 + case 3141: + goto st_case_3141 + case 3142: + goto st_case_3142 + case 3143: + goto st_case_3143 + case 3144: + goto st_case_3144 + case 3145: + goto st_case_3145 + case 3146: + goto st_case_3146 + case 3147: + goto st_case_3147 + case 3148: + goto st_case_3148 + case 3149: + goto st_case_3149 + case 3150: + goto st_case_3150 + case 3151: + goto st_case_3151 + case 3152: + goto st_case_3152 + case 3153: + goto st_case_3153 + case 3154: + goto st_case_3154 + case 3155: + goto st_case_3155 + case 3156: + goto st_case_3156 + case 3157: + goto st_case_3157 + case 3158: + goto st_case_3158 + case 3159: + goto st_case_3159 + case 3160: + goto st_case_3160 + case 3161: + goto st_case_3161 + case 3162: + goto st_case_3162 + case 3163: + goto st_case_3163 + case 3164: + goto st_case_3164 + case 3165: + goto st_case_3165 + case 3166: + goto st_case_3166 + case 3167: + goto st_case_3167 + case 3168: + goto st_case_3168 + case 3169: + goto st_case_3169 + case 3170: + goto st_case_3170 + case 3171: + goto st_case_3171 + case 3172: + goto st_case_3172 + case 3173: + goto st_case_3173 + case 3174: + goto st_case_3174 + case 3175: + goto st_case_3175 + case 3176: + goto st_case_3176 + case 3177: + goto st_case_3177 + case 3178: + goto st_case_3178 + case 3179: + goto st_case_3179 + case 3180: + goto st_case_3180 + case 3181: + goto st_case_3181 + case 3182: + goto st_case_3182 + case 3183: + goto st_case_3183 + case 3184: + goto st_case_3184 + case 3185: + goto st_case_3185 + case 3186: + goto st_case_3186 + case 3187: + goto st_case_3187 + case 3188: + goto st_case_3188 + case 3189: + goto st_case_3189 + case 3190: + goto st_case_3190 + case 3191: + goto st_case_3191 + case 3192: + goto st_case_3192 + case 3193: + goto st_case_3193 + case 3194: + goto st_case_3194 + case 3195: + goto st_case_3195 + case 3196: + goto st_case_3196 + case 3197: + goto st_case_3197 + case 3198: + goto st_case_3198 + case 3199: + goto st_case_3199 + case 3200: + goto st_case_3200 + case 3201: + goto st_case_3201 + case 3202: + goto st_case_3202 + case 3203: + goto st_case_3203 + case 3204: + goto st_case_3204 + case 3205: + goto st_case_3205 + case 3206: + goto st_case_3206 + case 3207: + goto st_case_3207 + case 3208: + goto st_case_3208 + case 3209: + goto st_case_3209 + case 3210: + goto st_case_3210 + case 3211: + goto st_case_3211 + case 3212: + goto st_case_3212 + case 3213: + goto st_case_3213 + case 3214: + goto st_case_3214 + case 3215: + goto st_case_3215 + case 3216: + goto st_case_3216 + case 3217: + goto st_case_3217 + case 4888: + goto st_case_4888 + case 4889: + goto st_case_4889 + case 4890: + goto st_case_4890 + case 4891: + goto st_case_4891 + case 4892: + goto st_case_4892 + case 4893: + goto st_case_4893 + case 4894: + goto st_case_4894 + case 4895: + goto st_case_4895 + case 4896: + goto st_case_4896 + case 4897: + goto st_case_4897 + case 4898: + goto st_case_4898 + case 4899: + goto st_case_4899 + case 4900: + goto st_case_4900 + case 4901: + goto st_case_4901 + case 4902: + goto st_case_4902 + case 4903: + goto st_case_4903 + case 4904: + goto st_case_4904 + case 4905: + goto st_case_4905 + case 4906: + goto st_case_4906 + case 4907: + goto st_case_4907 + case 4908: + goto st_case_4908 + case 4909: + goto st_case_4909 + case 4910: + goto st_case_4910 + case 4911: + goto st_case_4911 + case 4912: + goto st_case_4912 + case 4913: + goto st_case_4913 + case 4914: + goto st_case_4914 + case 4915: + goto st_case_4915 + case 4916: + goto st_case_4916 + case 4917: + goto st_case_4917 + case 4918: + goto st_case_4918 + case 4919: + goto st_case_4919 + case 4920: + goto st_case_4920 + case 4921: + goto st_case_4921 + case 4922: + goto st_case_4922 + case 4923: + goto st_case_4923 + case 4924: + goto st_case_4924 + case 4925: + goto st_case_4925 + case 4926: + goto st_case_4926 + case 4927: + goto st_case_4927 + case 4928: + goto st_case_4928 + case 3218: + goto st_case_3218 + case 3219: + goto st_case_3219 + case 3220: + goto st_case_3220 + case 3221: + goto st_case_3221 + case 3222: + goto st_case_3222 + case 3223: + goto st_case_3223 + case 3224: + goto st_case_3224 + case 3225: + goto st_case_3225 + case 3226: + goto st_case_3226 + case 3227: + goto st_case_3227 + case 3228: + goto st_case_3228 + case 3229: + goto st_case_3229 + case 3230: + goto st_case_3230 + case 3231: + goto st_case_3231 + case 4929: + goto st_case_4929 + case 4930: + goto st_case_4930 + case 4931: + goto st_case_4931 + case 4932: + goto st_case_4932 + case 3232: + goto st_case_3232 + case 4933: + goto st_case_4933 + case 4934: + goto st_case_4934 + case 4935: + goto st_case_4935 + case 4936: + goto st_case_4936 + case 4937: + goto st_case_4937 + case 4938: + goto st_case_4938 + case 4939: + goto st_case_4939 + case 4940: + goto st_case_4940 + case 4941: + goto st_case_4941 + case 4942: + goto st_case_4942 + case 4943: + goto st_case_4943 + case 4944: + goto st_case_4944 + case 4945: + goto st_case_4945 + case 4946: + goto st_case_4946 + case 4947: + goto st_case_4947 + case 4948: + goto st_case_4948 + case 4949: + goto st_case_4949 + case 4950: + goto st_case_4950 + case 4951: + goto st_case_4951 + case 4952: + goto st_case_4952 + case 4953: + goto st_case_4953 + case 4954: + goto st_case_4954 + case 4955: + goto st_case_4955 + case 4956: + goto st_case_4956 + case 4957: + goto st_case_4957 + case 3233: + goto st_case_3233 + case 4958: + goto st_case_4958 + case 4959: + goto st_case_4959 + case 4960: + goto st_case_4960 + case 4961: + goto st_case_4961 + case 4962: + goto st_case_4962 + case 4963: + goto st_case_4963 + case 3234: + goto st_case_3234 + case 4964: + goto st_case_4964 + case 4965: + goto st_case_4965 + case 3235: + goto st_case_3235 + case 4966: + goto st_case_4966 + case 4967: + goto st_case_4967 + case 4968: + goto st_case_4968 + case 4969: + goto st_case_4969 + case 4970: + goto st_case_4970 + case 4971: + goto st_case_4971 + case 4972: + goto st_case_4972 + case 4973: + goto st_case_4973 + case 4974: + goto st_case_4974 + case 4975: + goto st_case_4975 + case 4976: + goto st_case_4976 + case 4977: + goto st_case_4977 + case 4978: + goto st_case_4978 + case 4979: + goto st_case_4979 + case 4980: + goto st_case_4980 + case 3236: + goto st_case_3236 + case 4981: + goto st_case_4981 + case 4982: + goto st_case_4982 + case 4983: + goto st_case_4983 + case 3237: + goto st_case_3237 + case 4984: + goto st_case_4984 + case 4985: + goto st_case_4985 + case 4986: + goto st_case_4986 + case 4987: + goto st_case_4987 + case 4988: + goto st_case_4988 + case 4989: + goto st_case_4989 + case 3238: + goto st_case_3238 + case 4990: + goto st_case_4990 + case 4991: + goto st_case_4991 + case 4992: + goto st_case_4992 + case 4993: + goto st_case_4993 + case 4994: + goto st_case_4994 + case 4995: + goto st_case_4995 + case 4996: + goto st_case_4996 + case 4997: + goto st_case_4997 + case 4998: + goto st_case_4998 + case 4999: + goto st_case_4999 + case 5000: + goto st_case_5000 + case 5001: + goto st_case_5001 + case 5002: + goto st_case_5002 + case 5003: + goto st_case_5003 + case 5004: + goto st_case_5004 + case 5005: + goto st_case_5005 + case 5006: + goto st_case_5006 + case 5007: + goto st_case_5007 + case 5008: + goto st_case_5008 + case 5009: + goto st_case_5009 + case 5010: + goto st_case_5010 + case 5011: + goto st_case_5011 + case 5012: + goto st_case_5012 + case 5013: + goto st_case_5013 + case 5014: + goto st_case_5014 + case 5015: + goto st_case_5015 + case 5016: + goto st_case_5016 + case 5017: + goto st_case_5017 + case 5018: + goto st_case_5018 + case 5019: + goto st_case_5019 + case 5020: + goto st_case_5020 + case 5021: + goto st_case_5021 + case 5022: + goto st_case_5022 + case 5023: + goto st_case_5023 + case 5024: + goto st_case_5024 + case 5025: + goto st_case_5025 + case 5026: + goto st_case_5026 + case 5027: + goto st_case_5027 + case 5028: + goto st_case_5028 + case 5029: + goto st_case_5029 + case 5030: + goto st_case_5030 + case 5031: + goto st_case_5031 + case 5032: + goto st_case_5032 + case 5033: + goto st_case_5033 + case 5034: + goto st_case_5034 + case 5035: + goto st_case_5035 + case 5036: + goto st_case_5036 + case 5037: + goto st_case_5037 + case 5038: + goto st_case_5038 + case 5039: + goto st_case_5039 + case 5040: + goto st_case_5040 + case 5041: + goto st_case_5041 + case 5042: + goto st_case_5042 + case 5043: + goto st_case_5043 + case 5044: + goto st_case_5044 + case 5045: + goto st_case_5045 + case 5046: + goto st_case_5046 + case 5047: + goto st_case_5047 + case 5048: + goto st_case_5048 + case 5049: + goto st_case_5049 + case 5050: + goto st_case_5050 + case 5051: + goto st_case_5051 + case 5052: + goto st_case_5052 + case 5053: + goto st_case_5053 + case 5054: + goto st_case_5054 + case 5055: + goto st_case_5055 + case 5056: + goto st_case_5056 + case 5057: + goto st_case_5057 + case 5058: + goto st_case_5058 + case 5059: + goto st_case_5059 + case 5060: + goto st_case_5060 + case 5061: + goto st_case_5061 + case 5062: + goto st_case_5062 + case 5063: + goto st_case_5063 + case 5064: + goto st_case_5064 + case 5065: + goto st_case_5065 + case 5066: + goto st_case_5066 + case 5067: + goto st_case_5067 + case 5068: + goto st_case_5068 + case 5069: + goto st_case_5069 + case 5070: + goto st_case_5070 + case 5071: + goto st_case_5071 + case 3239: + goto st_case_3239 + case 3240: + goto st_case_3240 + case 3241: + goto st_case_3241 + case 3242: + goto st_case_3242 + case 3243: + goto st_case_3243 + case 3244: + goto st_case_3244 + case 3245: + goto st_case_3245 + case 3246: + goto st_case_3246 + case 3247: + goto st_case_3247 + case 3248: + goto st_case_3248 + case 3249: + goto st_case_3249 + case 3250: + goto st_case_3250 + case 3251: + goto st_case_3251 + case 3252: + goto st_case_3252 + case 3253: + goto st_case_3253 + case 3254: + goto st_case_3254 + case 3255: + goto st_case_3255 + case 3256: + goto st_case_3256 + case 3257: + goto st_case_3257 + case 3258: + goto st_case_3258 + case 3259: + goto st_case_3259 + case 3260: + goto st_case_3260 + case 3261: + goto st_case_3261 + case 3262: + goto st_case_3262 + case 3263: + goto st_case_3263 + case 3264: + goto st_case_3264 + case 3265: + goto st_case_3265 + case 5072: + goto st_case_5072 + case 3266: + goto st_case_3266 + case 3267: + goto st_case_3267 + case 3268: + goto st_case_3268 + case 5073: + goto st_case_5073 + case 3269: + goto st_case_3269 + case 3270: + goto st_case_3270 + case 3271: + goto st_case_3271 + case 3272: + goto st_case_3272 + case 3273: + goto st_case_3273 + case 3274: + goto st_case_3274 + case 3275: + goto st_case_3275 + case 3276: + goto st_case_3276 + case 3277: + goto st_case_3277 + case 3278: + goto st_case_3278 + case 3279: + goto st_case_3279 + case 3280: + goto st_case_3280 + case 3281: + goto st_case_3281 + case 3282: + goto st_case_3282 + case 3283: + goto st_case_3283 + case 3284: + goto st_case_3284 + case 3285: + goto st_case_3285 + case 3286: + goto st_case_3286 + case 3287: + goto st_case_3287 + case 3288: + goto st_case_3288 + case 3289: + goto st_case_3289 + case 3290: + goto st_case_3290 + case 3291: + goto st_case_3291 + case 3292: + goto st_case_3292 + case 3293: + goto st_case_3293 + case 3294: + goto st_case_3294 + case 3295: + goto st_case_3295 + case 3296: + goto st_case_3296 + case 3297: + goto st_case_3297 + case 3298: + goto st_case_3298 + case 3299: + goto st_case_3299 + case 3300: + goto st_case_3300 + case 3301: + goto st_case_3301 + case 3302: + goto st_case_3302 + case 3303: + goto st_case_3303 + case 3304: + goto st_case_3304 + case 3305: + goto st_case_3305 + case 3306: + goto st_case_3306 + case 3307: + goto st_case_3307 + case 3308: + goto st_case_3308 + case 3309: + goto st_case_3309 + case 3310: + goto st_case_3310 + case 3311: + goto st_case_3311 + case 3312: + goto st_case_3312 + case 3313: + goto st_case_3313 + case 3314: + goto st_case_3314 + case 3315: + goto st_case_3315 + case 3316: + goto st_case_3316 + case 3317: + goto st_case_3317 + case 3318: + goto st_case_3318 + case 3319: + goto st_case_3319 + case 3320: + goto st_case_3320 + case 3321: + goto st_case_3321 + case 3322: + goto st_case_3322 + case 3323: + goto st_case_3323 + case 3324: + goto st_case_3324 + case 3325: + goto st_case_3325 + case 3326: + goto st_case_3326 + case 3327: + goto st_case_3327 + case 3328: + goto st_case_3328 + case 3329: + goto st_case_3329 + case 3330: + goto st_case_3330 + case 3331: + goto st_case_3331 + case 3332: + goto st_case_3332 + case 3333: + goto st_case_3333 + case 3334: + goto st_case_3334 + case 3335: + goto st_case_3335 + case 3336: + goto st_case_3336 + case 3337: + goto st_case_3337 + case 3338: + goto st_case_3338 + case 3339: + goto st_case_3339 + case 3340: + goto st_case_3340 + case 3341: + goto st_case_3341 + case 3342: + goto st_case_3342 + case 3343: + goto st_case_3343 + case 3344: + goto st_case_3344 + case 3345: + goto st_case_3345 + case 3346: + goto st_case_3346 + case 3347: + goto st_case_3347 + case 3348: + goto st_case_3348 + case 3349: + goto st_case_3349 + case 3350: + goto st_case_3350 + case 5074: + goto st_case_5074 + case 3351: + goto st_case_3351 + case 3352: + goto st_case_3352 + case 3353: + goto st_case_3353 + case 3354: + goto st_case_3354 + case 3355: + goto st_case_3355 + case 3356: + goto st_case_3356 + case 3357: + goto st_case_3357 + case 3358: + goto st_case_3358 + case 3359: + goto st_case_3359 + case 3360: + goto st_case_3360 + case 3361: + goto st_case_3361 + case 3362: + goto st_case_3362 + case 3363: + goto st_case_3363 + case 3364: + goto st_case_3364 + case 3365: + goto st_case_3365 + case 3366: + goto st_case_3366 + case 3367: + goto st_case_3367 + case 3368: + goto st_case_3368 + case 3369: + goto st_case_3369 + case 3370: + goto st_case_3370 + case 3371: + goto st_case_3371 + case 3372: + goto st_case_3372 + case 3373: + goto st_case_3373 + case 3374: + goto st_case_3374 + case 3375: + goto st_case_3375 + case 3376: + goto st_case_3376 + case 3377: + goto st_case_3377 + case 3378: + goto st_case_3378 + case 3379: + goto st_case_3379 + case 3380: + goto st_case_3380 + case 3381: + goto st_case_3381 + case 3382: + goto st_case_3382 + case 3383: + goto st_case_3383 + case 3384: + goto st_case_3384 + case 3385: + goto st_case_3385 + case 3386: + goto st_case_3386 + case 3387: + goto st_case_3387 + case 3388: + goto st_case_3388 + case 3389: + goto st_case_3389 + case 3390: + goto st_case_3390 + case 3391: + goto st_case_3391 + case 3392: + goto st_case_3392 + case 3393: + goto st_case_3393 + case 3394: + goto st_case_3394 + case 3395: + goto st_case_3395 + case 3396: + goto st_case_3396 + case 3397: + goto st_case_3397 + case 3398: + goto st_case_3398 + case 3399: + goto st_case_3399 + case 3400: + goto st_case_3400 + case 3401: + goto st_case_3401 + case 3402: + goto st_case_3402 + case 3403: + goto st_case_3403 + case 3404: + goto st_case_3404 + case 3405: + goto st_case_3405 + case 3406: + goto st_case_3406 + case 3407: + goto st_case_3407 + case 3408: + goto st_case_3408 + case 3409: + goto st_case_3409 + case 3410: + goto st_case_3410 + case 3411: + goto st_case_3411 + case 3412: + goto st_case_3412 + case 3413: + goto st_case_3413 + case 3414: + goto st_case_3414 + case 3415: + goto st_case_3415 + case 3416: + goto st_case_3416 + case 3417: + goto st_case_3417 + case 3418: + goto st_case_3418 + case 3419: + goto st_case_3419 + case 3420: + goto st_case_3420 + case 3421: + goto st_case_3421 + case 3422: + goto st_case_3422 + case 3423: + goto st_case_3423 + case 3424: + goto st_case_3424 + case 3425: + goto st_case_3425 + case 3426: + goto st_case_3426 + case 3427: + goto st_case_3427 + case 3428: + goto st_case_3428 + case 3429: + goto st_case_3429 + case 3430: + goto st_case_3430 + case 3431: + goto st_case_3431 + case 3432: + goto st_case_3432 + case 3433: + goto st_case_3433 + case 3434: + goto st_case_3434 + case 3435: + goto st_case_3435 + case 3436: + goto st_case_3436 + case 3437: + goto st_case_3437 + case 3438: + goto st_case_3438 + case 3439: + goto st_case_3439 + case 3440: + goto st_case_3440 + case 3441: + goto st_case_3441 + case 3442: + goto st_case_3442 + case 3443: + goto st_case_3443 + case 3444: + goto st_case_3444 + case 3445: + goto st_case_3445 + case 3446: + goto st_case_3446 + case 3447: + goto st_case_3447 + case 3448: + goto st_case_3448 + case 3449: + goto st_case_3449 + case 3450: + goto st_case_3450 + case 3451: + goto st_case_3451 + case 3452: + goto st_case_3452 + case 3453: + goto st_case_3453 + case 3454: + goto st_case_3454 + case 3455: + goto st_case_3455 + case 3456: + goto st_case_3456 + case 3457: + goto st_case_3457 + case 3458: + goto st_case_3458 + case 3459: + goto st_case_3459 + case 3460: + goto st_case_3460 + case 3461: + goto st_case_3461 + case 3462: + goto st_case_3462 + case 3463: + goto st_case_3463 + case 3464: + goto st_case_3464 + case 3465: + goto st_case_3465 + case 3466: + goto st_case_3466 + case 3467: + goto st_case_3467 + case 3468: + goto st_case_3468 + case 3469: + goto st_case_3469 + case 3470: + goto st_case_3470 + case 3471: + goto st_case_3471 + case 3472: + goto st_case_3472 + case 3473: + goto st_case_3473 + case 3474: + goto st_case_3474 + case 3475: + goto st_case_3475 + case 3476: + goto st_case_3476 + case 3477: + goto st_case_3477 + case 3478: + goto st_case_3478 + case 3479: + goto st_case_3479 + case 3480: + goto st_case_3480 + case 3481: + goto st_case_3481 + case 3482: + goto st_case_3482 + case 3483: + goto st_case_3483 + case 3484: + goto st_case_3484 + case 3485: + goto st_case_3485 + case 3486: + goto st_case_3486 + case 3487: + goto st_case_3487 + case 3488: + goto st_case_3488 + case 3489: + goto st_case_3489 + case 3490: + goto st_case_3490 + case 3491: + goto st_case_3491 + case 3492: + goto st_case_3492 + case 3493: + goto st_case_3493 + case 3494: + goto st_case_3494 + case 3495: + goto st_case_3495 + case 3496: + goto st_case_3496 + case 3497: + goto st_case_3497 + case 3498: + goto st_case_3498 + case 3499: + goto st_case_3499 + case 3500: + goto st_case_3500 + case 3501: + goto st_case_3501 + case 3502: + goto st_case_3502 + case 3503: + goto st_case_3503 + case 3504: + goto st_case_3504 + case 3505: + goto st_case_3505 + case 3506: + goto st_case_3506 + case 3507: + goto st_case_3507 + case 3508: + goto st_case_3508 + case 3509: + goto st_case_3509 + case 3510: + goto st_case_3510 + case 3511: + goto st_case_3511 + case 3512: + goto st_case_3512 + case 3513: + goto st_case_3513 + case 3514: + goto st_case_3514 + case 3515: + goto st_case_3515 + case 3516: + goto st_case_3516 + case 3517: + goto st_case_3517 + case 3518: + goto st_case_3518 + case 3519: + goto st_case_3519 + case 3520: + goto st_case_3520 + case 3521: + goto st_case_3521 + case 3522: + goto st_case_3522 + case 3523: + goto st_case_3523 + case 3524: + goto st_case_3524 + case 3525: + goto st_case_3525 + case 3526: + goto st_case_3526 + case 3527: + goto st_case_3527 + case 3528: + goto st_case_3528 + case 3529: + goto st_case_3529 + case 3530: + goto st_case_3530 + case 3531: + goto st_case_3531 + case 3532: + goto st_case_3532 + case 3533: + goto st_case_3533 + case 3534: + goto st_case_3534 + case 3535: + goto st_case_3535 + case 3536: + goto st_case_3536 + case 3537: + goto st_case_3537 + case 3538: + goto st_case_3538 + case 3539: + goto st_case_3539 + case 3540: + goto st_case_3540 + case 3541: + goto st_case_3541 + case 3542: + goto st_case_3542 + case 3543: + goto st_case_3543 + case 3544: + goto st_case_3544 + case 3545: + goto st_case_3545 + case 3546: + goto st_case_3546 + case 3547: + goto st_case_3547 + case 3548: + goto st_case_3548 + case 3549: + goto st_case_3549 + case 3550: + goto st_case_3550 + case 3551: + goto st_case_3551 + case 3552: + goto st_case_3552 + case 3553: + goto st_case_3553 + case 3554: + goto st_case_3554 + case 3555: + goto st_case_3555 + case 3556: + goto st_case_3556 + case 3557: + goto st_case_3557 + case 3558: + goto st_case_3558 + case 3559: + goto st_case_3559 + case 3560: + goto st_case_3560 + case 3561: + goto st_case_3561 + case 3562: + goto st_case_3562 + case 3563: + goto st_case_3563 + case 3564: + goto st_case_3564 + case 3565: + goto st_case_3565 + case 3566: + goto st_case_3566 + case 3567: + goto st_case_3567 + case 3568: + goto st_case_3568 + case 3569: + goto st_case_3569 + case 3570: + goto st_case_3570 + case 3571: + goto st_case_3571 + case 3572: + goto st_case_3572 + case 3573: + goto st_case_3573 + case 3574: + goto st_case_3574 + case 3575: + goto st_case_3575 + case 3576: + goto st_case_3576 + case 3577: + goto st_case_3577 + case 3578: + goto st_case_3578 + case 3579: + goto st_case_3579 + case 3580: + goto st_case_3580 + case 3581: + goto st_case_3581 + case 3582: + goto st_case_3582 + case 3583: + goto st_case_3583 + case 3584: + goto st_case_3584 + case 3585: + goto st_case_3585 + case 3586: + goto st_case_3586 + case 3587: + goto st_case_3587 + case 5075: + goto st_case_5075 + case 3588: + goto st_case_3588 + case 3589: + goto st_case_3589 + case 3590: + goto st_case_3590 + case 3591: + goto st_case_3591 + case 3592: + goto st_case_3592 + case 3593: + goto st_case_3593 + case 5076: + goto st_case_5076 + case 3594: + goto st_case_3594 + case 3595: + goto st_case_3595 + case 3596: + goto st_case_3596 + case 3597: + goto st_case_3597 + case 3598: + goto st_case_3598 + case 3599: + goto st_case_3599 + case 3600: + goto st_case_3600 + case 3601: + goto st_case_3601 + case 3602: + goto st_case_3602 + case 3603: + goto st_case_3603 + case 3604: + goto st_case_3604 + case 3605: + goto st_case_3605 + case 3606: + goto st_case_3606 + case 3607: + goto st_case_3607 + case 3608: + goto st_case_3608 + case 3609: + goto st_case_3609 + case 3610: + goto st_case_3610 + case 3611: + goto st_case_3611 + case 3612: + goto st_case_3612 + case 3613: + goto st_case_3613 + case 3614: + goto st_case_3614 + case 3615: + goto st_case_3615 + case 3616: + goto st_case_3616 + case 3617: + goto st_case_3617 + case 3618: + goto st_case_3618 + case 3619: + goto st_case_3619 + case 3620: + goto st_case_3620 + case 3621: + goto st_case_3621 + case 3622: + goto st_case_3622 + case 3623: + goto st_case_3623 + case 3624: + goto st_case_3624 + case 3625: + goto st_case_3625 + case 3626: + goto st_case_3626 + case 3627: + goto st_case_3627 + case 3628: + goto st_case_3628 + case 3629: + goto st_case_3629 + case 3630: + goto st_case_3630 + case 3631: + goto st_case_3631 + case 3632: + goto st_case_3632 + case 3633: + goto st_case_3633 + case 3634: + goto st_case_3634 + case 3635: + goto st_case_3635 + case 3636: + goto st_case_3636 + case 3637: + goto st_case_3637 + case 3638: + goto st_case_3638 + case 3639: + goto st_case_3639 + case 3640: + goto st_case_3640 + case 3641: + goto st_case_3641 + case 3642: + goto st_case_3642 + case 3643: + goto st_case_3643 + case 3644: + goto st_case_3644 + case 3645: + goto st_case_3645 + case 3646: + goto st_case_3646 + case 3647: + goto st_case_3647 + case 3648: + goto st_case_3648 + case 3649: + goto st_case_3649 + case 3650: + goto st_case_3650 + case 3651: + goto st_case_3651 + case 3652: + goto st_case_3652 + case 3653: + goto st_case_3653 + case 3654: + goto st_case_3654 + case 3655: + goto st_case_3655 + case 3656: + goto st_case_3656 + case 3657: + goto st_case_3657 + case 3658: + goto st_case_3658 + case 3659: + goto st_case_3659 + case 3660: + goto st_case_3660 + case 3661: + goto st_case_3661 + case 3662: + goto st_case_3662 + case 3663: + goto st_case_3663 + case 3664: + goto st_case_3664 + case 3665: + goto st_case_3665 + case 3666: + goto st_case_3666 + case 3667: + goto st_case_3667 + case 3668: + goto st_case_3668 + case 3669: + goto st_case_3669 + case 3670: + goto st_case_3670 + case 3671: + goto st_case_3671 + case 3672: + goto st_case_3672 + case 3673: + goto st_case_3673 + case 3674: + goto st_case_3674 + case 3675: + goto st_case_3675 + case 3676: + goto st_case_3676 + case 3677: + goto st_case_3677 + case 3678: + goto st_case_3678 + case 3679: + goto st_case_3679 + case 3680: + goto st_case_3680 + case 3681: + goto st_case_3681 + case 3682: + goto st_case_3682 + case 3683: + goto st_case_3683 + case 3684: + goto st_case_3684 + case 3685: + goto st_case_3685 + case 3686: + goto st_case_3686 + case 3687: + goto st_case_3687 + case 3688: + goto st_case_3688 + case 3689: + goto st_case_3689 + case 3690: + goto st_case_3690 + case 3691: + goto st_case_3691 + case 3692: + goto st_case_3692 + case 3693: + goto st_case_3693 + case 3694: + goto st_case_3694 + case 3695: + goto st_case_3695 + case 3696: + goto st_case_3696 + case 3697: + goto st_case_3697 + case 3698: + goto st_case_3698 + case 3699: + goto st_case_3699 + case 3700: + goto st_case_3700 + case 3701: + goto st_case_3701 + case 3702: + goto st_case_3702 + case 3703: + goto st_case_3703 + case 3704: + goto st_case_3704 + case 3705: + goto st_case_3705 + case 3706: + goto st_case_3706 + case 3707: + goto st_case_3707 + case 3708: + goto st_case_3708 + case 3709: + goto st_case_3709 + case 3710: + goto st_case_3710 + case 3711: + goto st_case_3711 + case 3712: + goto st_case_3712 + case 3713: + goto st_case_3713 + case 3714: + goto st_case_3714 + case 3715: + goto st_case_3715 + case 3716: + goto st_case_3716 + case 3717: + goto st_case_3717 + case 3718: + goto st_case_3718 + case 3719: + goto st_case_3719 + case 3720: + goto st_case_3720 + case 3721: + goto st_case_3721 + case 3722: + goto st_case_3722 + case 3723: + goto st_case_3723 + case 3724: + goto st_case_3724 + case 3725: + goto st_case_3725 + case 3726: + goto st_case_3726 + case 3727: + goto st_case_3727 + case 3728: + goto st_case_3728 + case 3729: + goto st_case_3729 + case 3730: + goto st_case_3730 + case 3731: + goto st_case_3731 + case 3732: + goto st_case_3732 + case 3733: + goto st_case_3733 + case 3734: + goto st_case_3734 + case 3735: + goto st_case_3735 + case 3736: + goto st_case_3736 + case 5077: + goto st_case_5077 + case 3737: + goto st_case_3737 + case 5078: + goto st_case_5078 + case 3738: + goto st_case_3738 + case 3739: + goto st_case_3739 + case 3740: + goto st_case_3740 + case 3741: + goto st_case_3741 + case 3742: + goto st_case_3742 + case 3743: + goto st_case_3743 + case 3744: + goto st_case_3744 + case 3745: + goto st_case_3745 + case 3746: + goto st_case_3746 + case 3747: + goto st_case_3747 + case 3748: + goto st_case_3748 + case 3749: + goto st_case_3749 + case 3750: + goto st_case_3750 + case 3751: + goto st_case_3751 + case 3752: + goto st_case_3752 + case 3753: + goto st_case_3753 + case 3754: + goto st_case_3754 + case 3755: + goto st_case_3755 + case 3756: + goto st_case_3756 + case 3757: + goto st_case_3757 + case 3758: + goto st_case_3758 + case 3759: + goto st_case_3759 + case 3760: + goto st_case_3760 + case 3761: + goto st_case_3761 + case 3762: + goto st_case_3762 + case 3763: + goto st_case_3763 + case 3764: + goto st_case_3764 + case 3765: + goto st_case_3765 + case 3766: + goto st_case_3766 + case 3767: + goto st_case_3767 + case 3768: + goto st_case_3768 + case 3769: + goto st_case_3769 + case 3770: + goto st_case_3770 + case 3771: + goto st_case_3771 + case 3772: + goto st_case_3772 + case 3773: + goto st_case_3773 + case 3774: + goto st_case_3774 + case 3775: + goto st_case_3775 + case 3776: + goto st_case_3776 + case 3777: + goto st_case_3777 + case 3778: + goto st_case_3778 + case 3779: + goto st_case_3779 + case 3780: + goto st_case_3780 + case 3781: + goto st_case_3781 + case 3782: + goto st_case_3782 + case 3783: + goto st_case_3783 + case 3784: + goto st_case_3784 + case 3785: + goto st_case_3785 + case 3786: + goto st_case_3786 + case 3787: + goto st_case_3787 + case 3788: + goto st_case_3788 + case 3789: + goto st_case_3789 + case 3790: + goto st_case_3790 + case 3791: + goto st_case_3791 + case 3792: + goto st_case_3792 + case 3793: + goto st_case_3793 + case 3794: + goto st_case_3794 + case 3795: + goto st_case_3795 + case 3796: + goto st_case_3796 + case 3797: + goto st_case_3797 + case 3798: + goto st_case_3798 + case 3799: + goto st_case_3799 + case 3800: + goto st_case_3800 + case 3801: + goto st_case_3801 + case 3802: + goto st_case_3802 + case 3803: + goto st_case_3803 + case 3804: + goto st_case_3804 + case 3805: + goto st_case_3805 + case 3806: + goto st_case_3806 + case 3807: + goto st_case_3807 + case 3808: + goto st_case_3808 + case 3809: + goto st_case_3809 + case 3810: + goto st_case_3810 + case 3811: + goto st_case_3811 + case 3812: + goto st_case_3812 + case 3813: + goto st_case_3813 + case 3814: + goto st_case_3814 + case 3815: + goto st_case_3815 + case 3816: + goto st_case_3816 + case 3817: + goto st_case_3817 + case 3818: + goto st_case_3818 + case 3819: + goto st_case_3819 + case 3820: + goto st_case_3820 + case 3821: + goto st_case_3821 + case 3822: + goto st_case_3822 + case 3823: + goto st_case_3823 + case 3824: + goto st_case_3824 + case 3825: + goto st_case_3825 + case 3826: + goto st_case_3826 + case 3827: + goto st_case_3827 + case 3828: + goto st_case_3828 + case 3829: + goto st_case_3829 + case 3830: + goto st_case_3830 + case 3831: + goto st_case_3831 + case 3832: + goto st_case_3832 + case 3833: + goto st_case_3833 + case 3834: + goto st_case_3834 + case 3835: + goto st_case_3835 + case 3836: + goto st_case_3836 + case 3837: + goto st_case_3837 + case 3838: + goto st_case_3838 + case 3839: + goto st_case_3839 + case 3840: + goto st_case_3840 + case 3841: + goto st_case_3841 + case 3842: + goto st_case_3842 + case 3843: + goto st_case_3843 + case 3844: + goto st_case_3844 + case 3845: + goto st_case_3845 + case 3846: + goto st_case_3846 + case 3847: + goto st_case_3847 + case 3848: + goto st_case_3848 + case 3849: + goto st_case_3849 + case 3850: + goto st_case_3850 + case 3851: + goto st_case_3851 + case 3852: + goto st_case_3852 + case 3853: + goto st_case_3853 + case 3854: + goto st_case_3854 + case 3855: + goto st_case_3855 + case 3856: + goto st_case_3856 + case 3857: + goto st_case_3857 + case 3858: + goto st_case_3858 + case 3859: + goto st_case_3859 + case 3860: + goto st_case_3860 + case 3861: + goto st_case_3861 + case 3862: + goto st_case_3862 + case 3863: + goto st_case_3863 + case 3864: + goto st_case_3864 + case 3865: + goto st_case_3865 + case 3866: + goto st_case_3866 + case 3867: + goto st_case_3867 + case 3868: + goto st_case_3868 + case 3869: + goto st_case_3869 + case 3870: + goto st_case_3870 + case 3871: + goto st_case_3871 + case 3872: + goto st_case_3872 + case 3873: + goto st_case_3873 + case 3874: + goto st_case_3874 + case 3875: + goto st_case_3875 + case 3876: + goto st_case_3876 + case 3877: + goto st_case_3877 + case 3878: + goto st_case_3878 + case 3879: + goto st_case_3879 + case 3880: + goto st_case_3880 + case 3881: + goto st_case_3881 + case 3882: + goto st_case_3882 + case 3883: + goto st_case_3883 + case 3884: + goto st_case_3884 + case 5079: + goto st_case_5079 + case 3885: + goto st_case_3885 + case 3886: + goto st_case_3886 + case 3887: + goto st_case_3887 + case 3888: + goto st_case_3888 + case 3889: + goto st_case_3889 + case 3890: + goto st_case_3890 + case 3891: + goto st_case_3891 + case 3892: + goto st_case_3892 + case 3893: + goto st_case_3893 + case 3894: + goto st_case_3894 + case 3895: + goto st_case_3895 + case 3896: + goto st_case_3896 + case 3897: + goto st_case_3897 + case 3898: + goto st_case_3898 + case 3899: + goto st_case_3899 + case 3900: + goto st_case_3900 + case 3901: + goto st_case_3901 + case 3902: + goto st_case_3902 + case 3903: + goto st_case_3903 + case 3904: + goto st_case_3904 + case 3905: + goto st_case_3905 + case 3906: + goto st_case_3906 + case 3907: + goto st_case_3907 + case 3908: + goto st_case_3908 + case 3909: + goto st_case_3909 + case 3910: + goto st_case_3910 + case 3911: + goto st_case_3911 + case 3912: + goto st_case_3912 + case 3913: + goto st_case_3913 + case 3914: + goto st_case_3914 + case 3915: + goto st_case_3915 + case 3916: + goto st_case_3916 + case 3917: + goto st_case_3917 + case 3918: + goto st_case_3918 + case 3919: + goto st_case_3919 + case 3920: + goto st_case_3920 + case 3921: + goto st_case_3921 + case 3922: + goto st_case_3922 + case 3923: + goto st_case_3923 + case 3924: + goto st_case_3924 + case 3925: + goto st_case_3925 + case 3926: + goto st_case_3926 + case 3927: + goto st_case_3927 + case 3928: + goto st_case_3928 + case 3929: + goto st_case_3929 + case 3930: + goto st_case_3930 + case 3931: + goto st_case_3931 + case 3932: + goto st_case_3932 + case 3933: + goto st_case_3933 + case 3934: + goto st_case_3934 + case 3935: + goto st_case_3935 + case 3936: + goto st_case_3936 + case 3937: + goto st_case_3937 + case 3938: + goto st_case_3938 + case 3939: + goto st_case_3939 + case 3940: + goto st_case_3940 + case 3941: + goto st_case_3941 + case 3942: + goto st_case_3942 + case 3943: + goto st_case_3943 + case 3944: + goto st_case_3944 + case 3945: + goto st_case_3945 + case 3946: + goto st_case_3946 + case 3947: + goto st_case_3947 + case 3948: + goto st_case_3948 + case 3949: + goto st_case_3949 + case 3950: + goto st_case_3950 + case 3951: + goto st_case_3951 + case 3952: + goto st_case_3952 + case 3953: + goto st_case_3953 + case 3954: + goto st_case_3954 + case 3955: + goto st_case_3955 + case 3956: + goto st_case_3956 + case 3957: + goto st_case_3957 + case 3958: + goto st_case_3958 + case 3959: + goto st_case_3959 + case 3960: + goto st_case_3960 + case 3961: + goto st_case_3961 + case 3962: + goto st_case_3962 + case 3963: + goto st_case_3963 + case 3964: + goto st_case_3964 + case 3965: + goto st_case_3965 + case 3966: + goto st_case_3966 + case 3967: + goto st_case_3967 + case 3968: + goto st_case_3968 + case 3969: + goto st_case_3969 + case 3970: + goto st_case_3970 + case 3971: + goto st_case_3971 + case 3972: + goto st_case_3972 + case 3973: + goto st_case_3973 + case 3974: + goto st_case_3974 + case 3975: + goto st_case_3975 + case 3976: + goto st_case_3976 + case 3977: + goto st_case_3977 + case 3978: + goto st_case_3978 + case 3979: + goto st_case_3979 + case 3980: + goto st_case_3980 + case 3981: + goto st_case_3981 + case 3982: + goto st_case_3982 + case 3983: + goto st_case_3983 + case 3984: + goto st_case_3984 + case 3985: + goto st_case_3985 + case 3986: + goto st_case_3986 + case 3987: + goto st_case_3987 + case 3988: + goto st_case_3988 + case 3989: + goto st_case_3989 + case 3990: + goto st_case_3990 + case 3991: + goto st_case_3991 + case 3992: + goto st_case_3992 + case 3993: + goto st_case_3993 + case 3994: + goto st_case_3994 + case 3995: + goto st_case_3995 + case 3996: + goto st_case_3996 + case 3997: + goto st_case_3997 + case 3998: + goto st_case_3998 + case 3999: + goto st_case_3999 + case 4000: + goto st_case_4000 + case 4001: + goto st_case_4001 + case 4002: + goto st_case_4002 + case 4003: + goto st_case_4003 + case 4004: + goto st_case_4004 + case 4005: + goto st_case_4005 + case 4006: + goto st_case_4006 + case 4007: + goto st_case_4007 + case 4008: + goto st_case_4008 + case 4009: + goto st_case_4009 + case 4010: + goto st_case_4010 + case 4011: + goto st_case_4011 + case 4012: + goto st_case_4012 + case 4013: + goto st_case_4013 + case 4014: + goto st_case_4014 + case 4015: + goto st_case_4015 + case 4016: + goto st_case_4016 + case 4017: + goto st_case_4017 + case 4018: + goto st_case_4018 + case 4019: + goto st_case_4019 + case 4020: + goto st_case_4020 + case 4021: + goto st_case_4021 + case 4022: + goto st_case_4022 + case 4023: + goto st_case_4023 + case 4024: + goto st_case_4024 + case 4025: + goto st_case_4025 + case 4026: + goto st_case_4026 + case 5080: + goto st_case_5080 + case 4027: + goto st_case_4027 + case 4028: + goto st_case_4028 + case 4029: + goto st_case_4029 + case 4030: + goto st_case_4030 + case 4031: + goto st_case_4031 + case 4032: + goto st_case_4032 + case 4033: + goto st_case_4033 + case 4034: + goto st_case_4034 + case 4035: + goto st_case_4035 + case 4036: + goto st_case_4036 + case 4037: + goto st_case_4037 + case 4038: + goto st_case_4038 + case 4039: + goto st_case_4039 + case 4040: + goto st_case_4040 + case 4041: + goto st_case_4041 + case 4042: + goto st_case_4042 + case 4043: + goto st_case_4043 + case 4044: + goto st_case_4044 + case 4045: + goto st_case_4045 + case 4046: + goto st_case_4046 + case 4047: + goto st_case_4047 + case 4048: + goto st_case_4048 + case 4049: + goto st_case_4049 + case 4050: + goto st_case_4050 + case 4051: + goto st_case_4051 + case 4052: + goto st_case_4052 + case 4053: + goto st_case_4053 + case 4054: + goto st_case_4054 + case 4055: + goto st_case_4055 + case 4056: + goto st_case_4056 + case 4057: + goto st_case_4057 + case 4058: + goto st_case_4058 + case 4059: + goto st_case_4059 + case 4060: + goto st_case_4060 + case 4061: + goto st_case_4061 + case 4062: + goto st_case_4062 + case 4063: + goto st_case_4063 + case 4064: + goto st_case_4064 + case 4065: + goto st_case_4065 + case 4066: + goto st_case_4066 + case 4067: + goto st_case_4067 + case 4068: + goto st_case_4068 + case 4069: + goto st_case_4069 + case 4070: + goto st_case_4070 + case 4071: + goto st_case_4071 + case 4072: + goto st_case_4072 + case 4073: + goto st_case_4073 + case 4074: + goto st_case_4074 + case 4075: + goto st_case_4075 + case 4076: + goto st_case_4076 + case 4077: + goto st_case_4077 + case 4078: + goto st_case_4078 + case 4079: + goto st_case_4079 + case 4080: + goto st_case_4080 + case 4081: + goto st_case_4081 + case 4082: + goto st_case_4082 + case 4083: + goto st_case_4083 + case 4084: + goto st_case_4084 + case 4085: + goto st_case_4085 + case 4086: + goto st_case_4086 + case 4087: + goto st_case_4087 + case 4088: + goto st_case_4088 + case 4089: + goto st_case_4089 + case 4090: + goto st_case_4090 + case 4091: + goto st_case_4091 + case 4092: + goto st_case_4092 + case 4093: + goto st_case_4093 + case 4094: + goto st_case_4094 + case 4095: + goto st_case_4095 + case 4096: + goto st_case_4096 + case 4097: + goto st_case_4097 + case 4098: + goto st_case_4098 + case 4099: + goto st_case_4099 + case 4100: + goto st_case_4100 + case 4101: + goto st_case_4101 + case 4102: + goto st_case_4102 + case 4103: + goto st_case_4103 + case 4104: + goto st_case_4104 + case 4105: + goto st_case_4105 + case 4106: + goto st_case_4106 + case 4107: + goto st_case_4107 + case 4108: + goto st_case_4108 + case 4109: + goto st_case_4109 + case 4110: + goto st_case_4110 + case 4111: + goto st_case_4111 + case 4112: + goto st_case_4112 + case 4113: + goto st_case_4113 + case 4114: + goto st_case_4114 + case 4115: + goto st_case_4115 + case 4116: + goto st_case_4116 + case 4117: + goto st_case_4117 + case 4118: + goto st_case_4118 + case 4119: + goto st_case_4119 + case 4120: + goto st_case_4120 + case 4121: + goto st_case_4121 + case 4122: + goto st_case_4122 + case 4123: + goto st_case_4123 + case 4124: + goto st_case_4124 + case 4125: + goto st_case_4125 + case 4126: + goto st_case_4126 + case 4127: + goto st_case_4127 + case 4128: + goto st_case_4128 + case 4129: + goto st_case_4129 + case 4130: + goto st_case_4130 + case 4131: + goto st_case_4131 + case 4132: + goto st_case_4132 + case 4133: + goto st_case_4133 + case 4134: + goto st_case_4134 + case 4135: + goto st_case_4135 + case 4136: + goto st_case_4136 + case 4137: + goto st_case_4137 + case 4138: + goto st_case_4138 + case 4139: + goto st_case_4139 + case 4140: + goto st_case_4140 + case 4141: + goto st_case_4141 + case 4142: + goto st_case_4142 + case 4143: + goto st_case_4143 + case 4144: + goto st_case_4144 + case 4145: + goto st_case_4145 + case 4146: + goto st_case_4146 + case 4147: + goto st_case_4147 + case 4148: + goto st_case_4148 + case 4149: + goto st_case_4149 + case 4150: + goto st_case_4150 + case 4151: + goto st_case_4151 + case 4152: + goto st_case_4152 + case 4153: + goto st_case_4153 + case 4154: + goto st_case_4154 + case 4155: + goto st_case_4155 + case 4156: + goto st_case_4156 + case 4157: + goto st_case_4157 + case 4158: + goto st_case_4158 + case 4159: + goto st_case_4159 + case 4160: + goto st_case_4160 + case 4161: + goto st_case_4161 + case 4162: + goto st_case_4162 + case 4163: + goto st_case_4163 + case 4164: + goto st_case_4164 + case 4165: + goto st_case_4165 + case 4166: + goto st_case_4166 + case 4167: + goto st_case_4167 + case 4168: + goto st_case_4168 + case 4169: + goto st_case_4169 + case 4170: + goto st_case_4170 + case 4171: + goto st_case_4171 + case 4172: + goto st_case_4172 + case 4173: + goto st_case_4173 + case 4174: + goto st_case_4174 + case 4175: + goto st_case_4175 + case 5081: + goto st_case_5081 + case 4176: + goto st_case_4176 + case 4177: + goto st_case_4177 + case 4178: + goto st_case_4178 + case 4179: + goto st_case_4179 + case 4180: + goto st_case_4180 + case 4181: + goto st_case_4181 + case 4182: + goto st_case_4182 + case 4183: + goto st_case_4183 + case 4184: + goto st_case_4184 + case 4185: + goto st_case_4185 + case 4186: + goto st_case_4186 + case 4187: + goto st_case_4187 + case 4188: + goto st_case_4188 + case 4189: + goto st_case_4189 + case 4190: + goto st_case_4190 + case 4191: + goto st_case_4191 + case 4192: + goto st_case_4192 + case 4193: + goto st_case_4193 + case 4194: + goto st_case_4194 + case 4195: + goto st_case_4195 + case 4196: + goto st_case_4196 + case 4197: + goto st_case_4197 + case 4198: + goto st_case_4198 + case 4199: + goto st_case_4199 + case 4200: + goto st_case_4200 + case 4201: + goto st_case_4201 + case 4202: + goto st_case_4202 + case 4203: + goto st_case_4203 + case 4204: + goto st_case_4204 + case 4205: + goto st_case_4205 + case 4206: + goto st_case_4206 + case 4207: + goto st_case_4207 + case 4208: + goto st_case_4208 + case 4209: + goto st_case_4209 + case 4210: + goto st_case_4210 + case 4211: + goto st_case_4211 + case 4212: + goto st_case_4212 + case 4213: + goto st_case_4213 + case 4214: + goto st_case_4214 + case 4215: + goto st_case_4215 + case 4216: + goto st_case_4216 + case 4217: + goto st_case_4217 + case 4218: + goto st_case_4218 + case 4219: + goto st_case_4219 + case 4220: + goto st_case_4220 + case 4221: + goto st_case_4221 + case 4222: + goto st_case_4222 + case 4223: + goto st_case_4223 + case 4224: + goto st_case_4224 + case 4225: + goto st_case_4225 + case 4226: + goto st_case_4226 + case 4227: + goto st_case_4227 + case 4228: + goto st_case_4228 + case 4229: + goto st_case_4229 + case 4230: + goto st_case_4230 + case 4231: + goto st_case_4231 + case 4232: + goto st_case_4232 + case 4233: + goto st_case_4233 + case 4234: + goto st_case_4234 + case 4235: + goto st_case_4235 + case 4236: + goto st_case_4236 + case 4237: + goto st_case_4237 + case 4238: + goto st_case_4238 + case 4239: + goto st_case_4239 + case 4240: + goto st_case_4240 + case 4241: + goto st_case_4241 + case 4242: + goto st_case_4242 + case 4243: + goto st_case_4243 + case 4244: + goto st_case_4244 + case 4245: + goto st_case_4245 + case 4246: + goto st_case_4246 + case 4247: + goto st_case_4247 + case 4248: + goto st_case_4248 + case 4249: + goto st_case_4249 + case 4250: + goto st_case_4250 + case 4251: + goto st_case_4251 + case 4252: + goto st_case_4252 + case 4253: + goto st_case_4253 + case 4254: + goto st_case_4254 + case 4255: + goto st_case_4255 + case 4256: + goto st_case_4256 + case 4257: + goto st_case_4257 + case 4258: + goto st_case_4258 + case 4259: + goto st_case_4259 + case 4260: + goto st_case_4260 + case 4261: + goto st_case_4261 + case 4262: + goto st_case_4262 + case 4263: + goto st_case_4263 + case 4264: + goto st_case_4264 + case 4265: + goto st_case_4265 + case 4266: + goto st_case_4266 + case 4267: + goto st_case_4267 + case 4268: + goto st_case_4268 + case 4269: + goto st_case_4269 + case 4270: + goto st_case_4270 + case 4271: + goto st_case_4271 + case 4272: + goto st_case_4272 + case 4273: + goto st_case_4273 + case 4274: + goto st_case_4274 + case 4275: + goto st_case_4275 + case 4276: + goto st_case_4276 + case 4277: + goto st_case_4277 + case 4278: + goto st_case_4278 + case 4279: + goto st_case_4279 + case 4280: + goto st_case_4280 + case 4281: + goto st_case_4281 + case 4282: + goto st_case_4282 + case 4283: + goto st_case_4283 + case 4284: + goto st_case_4284 + case 4285: + goto st_case_4285 + case 4286: + goto st_case_4286 + case 4287: + goto st_case_4287 + case 4288: + goto st_case_4288 + case 4289: + goto st_case_4289 + case 4290: + goto st_case_4290 + case 4291: + goto st_case_4291 + case 4292: + goto st_case_4292 + case 4293: + goto st_case_4293 + case 4294: + goto st_case_4294 + case 4295: + goto st_case_4295 + case 4296: + goto st_case_4296 + case 4297: + goto st_case_4297 + case 4298: + goto st_case_4298 + case 4299: + goto st_case_4299 + case 4300: + goto st_case_4300 + case 4301: + goto st_case_4301 + case 4302: + goto st_case_4302 + case 4303: + goto st_case_4303 + case 4304: + goto st_case_4304 + case 4305: + goto st_case_4305 + case 4306: + goto st_case_4306 + case 4307: + goto st_case_4307 + case 4308: + goto st_case_4308 + case 4309: + goto st_case_4309 + case 4310: + goto st_case_4310 + case 4311: + goto st_case_4311 + case 4312: + goto st_case_4312 + case 4313: + goto st_case_4313 + case 4314: + goto st_case_4314 + case 4315: + goto st_case_4315 + case 4316: + goto st_case_4316 + case 4317: + goto st_case_4317 + case 4318: + goto st_case_4318 + case 5082: + goto st_case_5082 + case 4319: + goto st_case_4319 + case 4320: + goto st_case_4320 + case 4321: + goto st_case_4321 + case 4322: + goto st_case_4322 + case 4323: + goto st_case_4323 + case 4324: + goto st_case_4324 + case 4325: + goto st_case_4325 + case 4326: + goto st_case_4326 + case 4327: + goto st_case_4327 + case 4328: + goto st_case_4328 + case 4329: + goto st_case_4329 + case 4330: + goto st_case_4330 + case 4331: + goto st_case_4331 + case 4332: + goto st_case_4332 + case 4333: + goto st_case_4333 + case 4334: + goto st_case_4334 + case 4335: + goto st_case_4335 + case 4336: + goto st_case_4336 + case 4337: + goto st_case_4337 + case 4338: + goto st_case_4338 + case 4339: + goto st_case_4339 + case 4340: + goto st_case_4340 + case 4341: + goto st_case_4341 + case 4342: + goto st_case_4342 + case 4343: + goto st_case_4343 + case 4344: + goto st_case_4344 + case 4345: + goto st_case_4345 + case 4346: + goto st_case_4346 + case 4347: + goto st_case_4347 + case 4348: + goto st_case_4348 + case 4349: + goto st_case_4349 + case 4350: + goto st_case_4350 + case 4351: + goto st_case_4351 + case 4352: + goto st_case_4352 + case 4353: + goto st_case_4353 + case 4354: + goto st_case_4354 + case 4355: + goto st_case_4355 + case 4356: + goto st_case_4356 + case 4357: + goto st_case_4357 + case 4358: + goto st_case_4358 + case 4359: + goto st_case_4359 + case 4360: + goto st_case_4360 + case 4361: + goto st_case_4361 + case 4362: + goto st_case_4362 + case 4363: + goto st_case_4363 + case 4364: + goto st_case_4364 + case 4365: + goto st_case_4365 + case 4366: + goto st_case_4366 + case 4367: + goto st_case_4367 + case 4368: + goto st_case_4368 + case 4369: + goto st_case_4369 + case 4370: + goto st_case_4370 + case 4371: + goto st_case_4371 + case 4372: + goto st_case_4372 + case 4373: + goto st_case_4373 + case 4374: + goto st_case_4374 + case 4375: + goto st_case_4375 + case 4376: + goto st_case_4376 + case 4377: + goto st_case_4377 + case 4378: + goto st_case_4378 + case 4379: + goto st_case_4379 + case 4380: + goto st_case_4380 + case 4381: + goto st_case_4381 + case 4382: + goto st_case_4382 + case 4383: + goto st_case_4383 + case 4384: + goto st_case_4384 + case 4385: + goto st_case_4385 + case 4386: + goto st_case_4386 + case 4387: + goto st_case_4387 + case 4388: + goto st_case_4388 + case 4389: + goto st_case_4389 + case 4390: + goto st_case_4390 + case 4391: + goto st_case_4391 + case 4392: + goto st_case_4392 + case 4393: + goto st_case_4393 + case 4394: + goto st_case_4394 + case 4395: + goto st_case_4395 + case 4396: + goto st_case_4396 + case 4397: + goto st_case_4397 + case 4398: + goto st_case_4398 + case 4399: + goto st_case_4399 + case 4400: + goto st_case_4400 + case 4401: + goto st_case_4401 + case 4402: + goto st_case_4402 + case 4403: + goto st_case_4403 + case 4404: + goto st_case_4404 + case 4405: + goto st_case_4405 + case 4406: + goto st_case_4406 + case 4407: + goto st_case_4407 + case 4408: + goto st_case_4408 + case 4409: + goto st_case_4409 + case 4410: + goto st_case_4410 + case 4411: + goto st_case_4411 + case 4412: + goto st_case_4412 + case 4413: + goto st_case_4413 + case 4414: + goto st_case_4414 + case 4415: + goto st_case_4415 + case 4416: + goto st_case_4416 + case 4417: + goto st_case_4417 + case 4418: + goto st_case_4418 + case 4419: + goto st_case_4419 + case 4420: + goto st_case_4420 + case 4421: + goto st_case_4421 + case 4422: + goto st_case_4422 + case 4423: + goto st_case_4423 + case 4424: + goto st_case_4424 + case 4425: + goto st_case_4425 + case 4426: + goto st_case_4426 + case 4427: + goto st_case_4427 + case 4428: + goto st_case_4428 + case 4429: + goto st_case_4429 + case 4430: + goto st_case_4430 + case 4431: + goto st_case_4431 + case 4432: + goto st_case_4432 + case 4433: + goto st_case_4433 + case 4434: + goto st_case_4434 + case 4435: + goto st_case_4435 + case 4436: + goto st_case_4436 + case 4437: + goto st_case_4437 + case 4438: + goto st_case_4438 + case 4439: + goto st_case_4439 + case 4440: + goto st_case_4440 + case 4441: + goto st_case_4441 + case 4442: + goto st_case_4442 + case 4443: + goto st_case_4443 + case 4444: + goto st_case_4444 + case 4445: + goto st_case_4445 + case 4446: + goto st_case_4446 + case 4447: + goto st_case_4447 + case 4448: + goto st_case_4448 + case 4449: + goto st_case_4449 + case 4450: + goto st_case_4450 + case 4451: + goto st_case_4451 + case 4452: + goto st_case_4452 + case 4453: + goto st_case_4453 + case 4454: + goto st_case_4454 + case 4455: + goto st_case_4455 + case 4456: + goto st_case_4456 + case 4457: + goto st_case_4457 + case 4458: + goto st_case_4458 + case 4459: + goto st_case_4459 + case 4460: + goto st_case_4460 + case 4461: + goto st_case_4461 + case 4462: + goto st_case_4462 + case 4463: + goto st_case_4463 + case 4464: + goto st_case_4464 + case 4465: + goto st_case_4465 + case 4466: + goto st_case_4466 + case 4467: + goto st_case_4467 + case 4468: + goto st_case_4468 + case 4469: + goto st_case_4469 + case 4470: + goto st_case_4470 + case 4471: + goto st_case_4471 + case 4472: + goto st_case_4472 + case 5083: + goto st_case_5083 + case 5084: + goto st_case_5084 + case 5085: + goto st_case_5085 + case 5086: + goto st_case_5086 + case 5087: + goto st_case_5087 + case 5088: + goto st_case_5088 + case 5089: + goto st_case_5089 + case 5090: + goto st_case_5090 + case 5091: + goto st_case_5091 + case 5092: + goto st_case_5092 + case 5093: + goto st_case_5093 + case 5094: + goto st_case_5094 + case 5095: + goto st_case_5095 + case 5096: + goto st_case_5096 + case 5097: + goto st_case_5097 + case 5098: + goto st_case_5098 + case 5099: + goto st_case_5099 + case 5100: + goto st_case_5100 + case 5101: + goto st_case_5101 + case 5102: + goto st_case_5102 + case 5103: + goto st_case_5103 + case 5104: + goto st_case_5104 + case 5105: + goto st_case_5105 + case 5106: + goto st_case_5106 + case 5107: + goto st_case_5107 + case 5108: + goto st_case_5108 + case 5109: + goto st_case_5109 + case 5110: + goto st_case_5110 + case 5111: + goto st_case_5111 + case 5112: + goto st_case_5112 + case 5113: + goto st_case_5113 + case 5114: + goto st_case_5114 + case 5115: + goto st_case_5115 + case 5116: + goto st_case_5116 + case 5117: + goto st_case_5117 + case 5118: + goto st_case_5118 + case 5119: + goto st_case_5119 + case 5120: + goto st_case_5120 + case 5121: + goto st_case_5121 + case 5122: + goto st_case_5122 + case 5123: + goto st_case_5123 + case 5124: + goto st_case_5124 + case 5125: + goto st_case_5125 + case 5126: + goto st_case_5126 + case 5127: + goto st_case_5127 + case 5128: + goto st_case_5128 + case 5129: + goto st_case_5129 + case 5130: + goto st_case_5130 + case 5131: + goto st_case_5131 + case 5132: + goto st_case_5132 + case 5133: + goto st_case_5133 + case 5134: + goto st_case_5134 + case 5135: + goto st_case_5135 + case 5136: + goto st_case_5136 + case 5137: + goto st_case_5137 + case 5138: + goto st_case_5138 + case 5139: + goto st_case_5139 + case 5140: + goto st_case_5140 + case 5141: + goto st_case_5141 + case 5142: + goto st_case_5142 + case 5143: + goto st_case_5143 + case 5144: + goto st_case_5144 + case 5145: + goto st_case_5145 + case 5146: + goto st_case_5146 + case 5147: + goto st_case_5147 + case 5148: + goto st_case_5148 + case 5149: + goto st_case_5149 + case 5150: + goto st_case_5150 + case 5151: + goto st_case_5151 + case 5152: + goto st_case_5152 + case 4473: + goto st_case_4473 + case 5153: + goto st_case_5153 + case 5154: + goto st_case_5154 + case 5155: + goto st_case_5155 + case 5156: + goto st_case_5156 + case 5157: + goto st_case_5157 + case 5158: + goto st_case_5158 + case 5159: + goto st_case_5159 + case 5160: + goto st_case_5160 + case 5161: + goto st_case_5161 + case 5162: + goto st_case_5162 + case 5163: + goto st_case_5163 + case 5164: + goto st_case_5164 + case 5165: + goto st_case_5165 + case 5166: + goto st_case_5166 + case 5167: + goto st_case_5167 + case 5168: + goto st_case_5168 + case 5169: + goto st_case_5169 + case 5170: + goto st_case_5170 + case 5171: + goto st_case_5171 + case 5172: + goto st_case_5172 + case 5173: + goto st_case_5173 + case 4474: + goto st_case_4474 + case 5174: + goto st_case_5174 + case 5175: + goto st_case_5175 + case 5176: + goto st_case_5176 + case 5177: + goto st_case_5177 + case 5178: + goto st_case_5178 + case 5179: + goto st_case_5179 + case 4475: + goto st_case_4475 + case 5180: + goto st_case_5180 + case 5181: + goto st_case_5181 + case 4476: + goto st_case_4476 + case 5182: + goto st_case_5182 + case 5183: + goto st_case_5183 + case 5184: + goto st_case_5184 + case 5185: + goto st_case_5185 + case 5186: + goto st_case_5186 + case 5187: + goto st_case_5187 + case 5188: + goto st_case_5188 + case 5189: + goto st_case_5189 + case 5190: + goto st_case_5190 + case 5191: + goto st_case_5191 + case 5192: + goto st_case_5192 + case 5193: + goto st_case_5193 + case 5194: + goto st_case_5194 + case 5195: + goto st_case_5195 + case 5196: + goto st_case_5196 + case 4477: + goto st_case_4477 + case 5197: + goto st_case_5197 + case 5198: + goto st_case_5198 + case 5199: + goto st_case_5199 + case 4478: + goto st_case_4478 + case 5200: + goto st_case_5200 + case 5201: + goto st_case_5201 + case 5202: + goto st_case_5202 + case 5203: + goto st_case_5203 + case 5204: + goto st_case_5204 + case 5205: + goto st_case_5205 + case 4479: + goto st_case_4479 + case 5206: + goto st_case_5206 + case 5207: + goto st_case_5207 + case 4480: + goto st_case_4480 + case 5208: + goto st_case_5208 + case 5209: + goto st_case_5209 + case 5210: + goto st_case_5210 + case 4481: + goto st_case_4481 + case 4482: + goto st_case_4482 + case 4483: + goto st_case_4483 + case 4484: + goto st_case_4484 + case 4485: + goto st_case_4485 + case 4486: + goto st_case_4486 + case 4487: + goto st_case_4487 + case 4488: + goto st_case_4488 + case 4489: + goto st_case_4489 + case 4490: + goto st_case_4490 + case 4491: + goto st_case_4491 + case 4492: + goto st_case_4492 + case 4493: + goto st_case_4493 + case 4494: + goto st_case_4494 + case 4495: + goto st_case_4495 + case 5211: + goto st_case_5211 + case 4496: + goto st_case_4496 + case 4497: + goto st_case_4497 + case 4498: + goto st_case_4498 + case 4499: + goto st_case_4499 + case 4500: + goto st_case_4500 + case 4501: + goto st_case_4501 + case 4502: + goto st_case_4502 + case 4503: + goto st_case_4503 + case 4504: + goto st_case_4504 + case 4505: + goto st_case_4505 + case 4506: + goto st_case_4506 + case 4507: + goto st_case_4507 + case 4508: + goto st_case_4508 + case 4509: + goto st_case_4509 + case 4510: + goto st_case_4510 + case 4511: + goto st_case_4511 + case 4512: + goto st_case_4512 + case 4513: + goto st_case_4513 + case 4514: + goto st_case_4514 + case 4515: + goto st_case_4515 + case 4516: + goto st_case_4516 + case 4517: + goto st_case_4517 + case 4518: + goto st_case_4518 + case 4519: + goto st_case_4519 + case 4520: + goto st_case_4520 + case 4521: + goto st_case_4521 + case 4522: + goto st_case_4522 + case 4523: + goto st_case_4523 + case 4524: + goto st_case_4524 + case 4525: + goto st_case_4525 + case 4526: + goto st_case_4526 + case 4527: + goto st_case_4527 + case 4528: + goto st_case_4528 + case 4529: + goto st_case_4529 + case 4530: + goto st_case_4530 + case 4531: + goto st_case_4531 + case 4532: + goto st_case_4532 + case 4533: + goto st_case_4533 + case 4534: + goto st_case_4534 + case 4535: + goto st_case_4535 + case 4536: + goto st_case_4536 + case 4537: + goto st_case_4537 + case 4538: + goto st_case_4538 + case 4539: + goto st_case_4539 + case 4540: + goto st_case_4540 + case 4541: + goto st_case_4541 + case 4542: + goto st_case_4542 + case 4543: + goto st_case_4543 + case 4544: + goto st_case_4544 + case 4545: + goto st_case_4545 + case 4546: + goto st_case_4546 + case 4547: + goto st_case_4547 + case 4548: + goto st_case_4548 + case 4549: + goto st_case_4549 + case 4550: + goto st_case_4550 + case 4551: + goto st_case_4551 + case 4552: + goto st_case_4552 + case 4553: + goto st_case_4553 + case 4554: + goto st_case_4554 + case 4555: + goto st_case_4555 + case 4556: + goto st_case_4556 + case 4557: + goto st_case_4557 + case 4558: + goto st_case_4558 + case 4559: + goto st_case_4559 + case 4560: + goto st_case_4560 + case 4561: + goto st_case_4561 + case 4562: + goto st_case_4562 + case 4563: + goto st_case_4563 + case 4564: + goto st_case_4564 + case 4565: + goto st_case_4565 + case 4566: + goto st_case_4566 + case 4567: + goto st_case_4567 + case 4568: + goto st_case_4568 + case 4569: + goto st_case_4569 + case 4570: + goto st_case_4570 + case 4571: + goto st_case_4571 + case 4572: + goto st_case_4572 + case 4573: + goto st_case_4573 + case 4574: + goto st_case_4574 + case 4575: + goto st_case_4575 + case 4576: + goto st_case_4576 + case 4577: + goto st_case_4577 + case 4578: + goto st_case_4578 + case 4579: + goto st_case_4579 + case 4580: + goto st_case_4580 + case 4581: + goto st_case_4581 + case 4582: + goto st_case_4582 + case 4583: + goto st_case_4583 + case 4584: + goto st_case_4584 + case 4585: + goto st_case_4585 + case 4586: + goto st_case_4586 + case 4587: + goto st_case_4587 + case 4588: + goto st_case_4588 + case 4589: + goto st_case_4589 + case 4590: + goto st_case_4590 + case 4591: + goto st_case_4591 + case 4592: + goto st_case_4592 + case 4593: + goto st_case_4593 + case 4594: + goto st_case_4594 + case 4595: + goto st_case_4595 + case 4596: + goto st_case_4596 + case 4597: + goto st_case_4597 + case 4598: + goto st_case_4598 + case 4599: + goto st_case_4599 + case 4600: + goto st_case_4600 + case 4601: + goto st_case_4601 + case 4602: + goto st_case_4602 + case 4603: + goto st_case_4603 + case 4604: + goto st_case_4604 + case 4605: + goto st_case_4605 + case 4606: + goto st_case_4606 + case 4607: + goto st_case_4607 + case 4608: + goto st_case_4608 + case 4609: + goto st_case_4609 + case 4610: + goto st_case_4610 + case 4611: + goto st_case_4611 + case 4612: + goto st_case_4612 + case 4613: + goto st_case_4613 + case 4614: + goto st_case_4614 + case 4615: + goto st_case_4615 + case 4616: + goto st_case_4616 + case 4617: + goto st_case_4617 + case 4618: + goto st_case_4618 + case 4619: + goto st_case_4619 + case 4620: + goto st_case_4620 + case 4621: + goto st_case_4621 + case 4622: + goto st_case_4622 + case 4623: + goto st_case_4623 + case 4624: + goto st_case_4624 + case 4625: + goto st_case_4625 + case 4626: + goto st_case_4626 + case 4627: + goto st_case_4627 + case 4628: + goto st_case_4628 + case 4629: + goto st_case_4629 + case 4630: + goto st_case_4630 + case 4631: + goto st_case_4631 + case 4632: + goto st_case_4632 + case 4633: + goto st_case_4633 + case 4634: + goto st_case_4634 + case 4635: + goto st_case_4635 + case 4636: + goto st_case_4636 + case 4637: + goto st_case_4637 + case 4638: + goto st_case_4638 + case 4639: + goto st_case_4639 + case 4640: + goto st_case_4640 + case 4641: + goto st_case_4641 + case 4642: + goto st_case_4642 + case 4643: + goto st_case_4643 + case 4644: + goto st_case_4644 + case 4645: + goto st_case_4645 + case 4646: + goto st_case_4646 + case 4647: + goto st_case_4647 + case 4648: + goto st_case_4648 + case 4649: + goto st_case_4649 + case 4650: + goto st_case_4650 + case 4651: + goto st_case_4651 + case 4652: + goto st_case_4652 + case 4653: + goto st_case_4653 + case 4654: + goto st_case_4654 + case 4655: + goto st_case_4655 + case 5212: + goto st_case_5212 + case 5213: + goto st_case_5213 + case 5214: + goto st_case_5214 + case 5215: + goto st_case_5215 + case 5216: + goto st_case_5216 + case 5217: + goto st_case_5217 + case 5218: + goto st_case_5218 + case 5219: + goto st_case_5219 + case 5220: + goto st_case_5220 + case 5221: + goto st_case_5221 + case 5222: + goto st_case_5222 + case 5223: + goto st_case_5223 + case 5224: + goto st_case_5224 + case 5225: + goto st_case_5225 + case 5226: + goto st_case_5226 + case 5227: + goto st_case_5227 + case 5228: + goto st_case_5228 + case 5229: + goto st_case_5229 + case 5230: + goto st_case_5230 + case 5231: + goto st_case_5231 + case 5232: + goto st_case_5232 + case 5233: + goto st_case_5233 + case 5234: + goto st_case_5234 + case 5235: + goto st_case_5235 + case 5236: + goto st_case_5236 + case 5237: + goto st_case_5237 + case 5238: + goto st_case_5238 + case 5239: + goto st_case_5239 + case 5240: + goto st_case_5240 + case 5241: + goto st_case_5241 + case 5242: + goto st_case_5242 + case 4656: + goto st_case_4656 + case 5243: + goto st_case_5243 + case 5244: + goto st_case_5244 + case 5245: + goto st_case_5245 + case 5246: + goto st_case_5246 + case 5247: + goto st_case_5247 + case 5248: + goto st_case_5248 + case 5249: + goto st_case_5249 + case 5250: + goto st_case_5250 + case 4657: + goto st_case_4657 + case 5251: + goto st_case_5251 + case 5252: + goto st_case_5252 + case 5253: + goto st_case_5253 + case 5254: + goto st_case_5254 + case 5255: + goto st_case_5255 + case 5256: + goto st_case_5256 + case 4658: + goto st_case_4658 + case 5257: + goto st_case_5257 + case 5258: + goto st_case_5258 + case 4659: + goto st_case_4659 + case 5259: + goto st_case_5259 + case 5260: + goto st_case_5260 + case 5261: + goto st_case_5261 + case 5262: + goto st_case_5262 + case 5263: + goto st_case_5263 + case 5264: + goto st_case_5264 + case 5265: + goto st_case_5265 + case 5266: + goto st_case_5266 + case 5267: + goto st_case_5267 + case 5268: + goto st_case_5268 + case 5269: + goto st_case_5269 + case 5270: + goto st_case_5270 + case 5271: + goto st_case_5271 + case 5272: + goto st_case_5272 + case 5273: + goto st_case_5273 + case 5274: + goto st_case_5274 + case 5275: + goto st_case_5275 + case 5276: + goto st_case_5276 + case 5277: + goto st_case_5277 + case 4660: + goto st_case_4660 + case 5278: + goto st_case_5278 + case 5279: + goto st_case_5279 + case 5280: + goto st_case_5280 + case 4661: + goto st_case_4661 + case 5281: + goto st_case_5281 + case 5282: + goto st_case_5282 + case 5283: + goto st_case_5283 + case 5284: + goto st_case_5284 + case 5285: + goto st_case_5285 + case 5286: + goto st_case_5286 + case 4662: + goto st_case_4662 + case 5287: + goto st_case_5287 + case 5288: + goto st_case_5288 + case 5289: + goto st_case_5289 + case 5290: + goto st_case_5290 + case 5291: + goto st_case_5291 + case 5292: + goto st_case_5292 + case 5293: + goto st_case_5293 + case 5294: + goto st_case_5294 + case 5295: + goto st_case_5295 + case 5296: + goto st_case_5296 + case 5297: + goto st_case_5297 + case 5298: + goto st_case_5298 + case 5299: + goto st_case_5299 + case 5300: + goto st_case_5300 + case 5301: + goto st_case_5301 + case 5302: + goto st_case_5302 + case 5303: + goto st_case_5303 + case 5304: + goto st_case_5304 + case 5305: + goto st_case_5305 + case 5306: + goto st_case_5306 + case 5307: + goto st_case_5307 + case 5308: + goto st_case_5308 + case 5309: + goto st_case_5309 + case 5310: + goto st_case_5310 + case 5311: + goto st_case_5311 + case 5312: + goto st_case_5312 + case 5313: + goto st_case_5313 + case 5314: + goto st_case_5314 + case 5315: + goto st_case_5315 + case 5316: + goto st_case_5316 + case 5317: + goto st_case_5317 + case 5318: + goto st_case_5318 + case 5319: + goto st_case_5319 + case 5320: + goto st_case_5320 + case 5321: + goto st_case_5321 + case 5322: + goto st_case_5322 + case 5323: + goto st_case_5323 + case 5324: + goto st_case_5324 + case 5325: + goto st_case_5325 + case 5326: + goto st_case_5326 + case 5327: + goto st_case_5327 + case 5328: + goto st_case_5328 + case 5329: + goto st_case_5329 + case 5330: + goto st_case_5330 + case 5331: + goto st_case_5331 + case 5332: + goto st_case_5332 + case 5333: + goto st_case_5333 + case 5334: + goto st_case_5334 + case 5335: + goto st_case_5335 + case 5336: + goto st_case_5336 + case 5337: + goto st_case_5337 + case 5338: + goto st_case_5338 + case 4663: + goto st_case_4663 + case 4664: + goto st_case_4664 + case 4665: + goto st_case_4665 + case 4666: + goto st_case_4666 + case 4667: + goto st_case_4667 + case 4668: + goto st_case_4668 + case 4669: + goto st_case_4669 + case 4670: + goto st_case_4670 + case 5339: + goto st_case_5339 + case 4671: + goto st_case_4671 + case 4672: + goto st_case_4672 + case 4673: + goto st_case_4673 + case 4674: + goto st_case_4674 + case 4675: + goto st_case_4675 + case 4676: + goto st_case_4676 + case 4677: + goto st_case_4677 + case 4678: + goto st_case_4678 + case 4679: + goto st_case_4679 + case 4680: + goto st_case_4680 + case 4681: + goto st_case_4681 + case 4682: + goto st_case_4682 + case 4683: + goto st_case_4683 + case 4684: + goto st_case_4684 + case 4685: + goto st_case_4685 + case 4686: + goto st_case_4686 + case 4687: + goto st_case_4687 + case 4688: + goto st_case_4688 + case 4689: + goto st_case_4689 + case 4690: + goto st_case_4690 + case 4691: + goto st_case_4691 + case 4692: + goto st_case_4692 + case 4693: + goto st_case_4693 + case 4694: + goto st_case_4694 + case 4695: + goto st_case_4695 + case 4696: + goto st_case_4696 + case 4697: + goto st_case_4697 + case 4698: + goto st_case_4698 + case 4699: + goto st_case_4699 + case 4700: + goto st_case_4700 + case 4701: + goto st_case_4701 + case 4702: + goto st_case_4702 + case 4703: + goto st_case_4703 + case 4704: + goto st_case_4704 + case 4705: + goto st_case_4705 + case 4706: + goto st_case_4706 + case 4707: + goto st_case_4707 + case 5340: + goto st_case_5340 + case 4708: + goto st_case_4708 + case 4709: + goto st_case_4709 + case 4710: + goto st_case_4710 + case 4711: + goto st_case_4711 + case 4712: + goto st_case_4712 + case 4713: + goto st_case_4713 + case 4714: + goto st_case_4714 + case 4715: + goto st_case_4715 + case 4716: + goto st_case_4716 + case 4717: + goto st_case_4717 + case 4718: + goto st_case_4718 + case 4719: + goto st_case_4719 + case 4720: + goto st_case_4720 + case 4721: + goto st_case_4721 + case 4722: + goto st_case_4722 + case 4723: + goto st_case_4723 + case 4724: + goto st_case_4724 + case 4725: + goto st_case_4725 + case 4726: + goto st_case_4726 + case 4727: + goto st_case_4727 + case 4728: + goto st_case_4728 + case 4729: + goto st_case_4729 + case 4730: + goto st_case_4730 + case 4731: + goto st_case_4731 + case 4732: + goto st_case_4732 + case 4733: + goto st_case_4733 + case 4734: + goto st_case_4734 + case 4735: + goto st_case_4735 + case 4736: + goto st_case_4736 + case 4737: + goto st_case_4737 + case 4738: + goto st_case_4738 + case 4739: + goto st_case_4739 + case 4740: + goto st_case_4740 + case 4741: + goto st_case_4741 + case 4742: + goto st_case_4742 + case 4743: + goto st_case_4743 + case 4744: + goto st_case_4744 + case 4745: + goto st_case_4745 + case 4746: + goto st_case_4746 + case 4747: + goto st_case_4747 + case 4748: + goto st_case_4748 + case 4749: + goto st_case_4749 + case 4750: + goto st_case_4750 + case 4751: + goto st_case_4751 + case 4752: + goto st_case_4752 + case 4753: + goto st_case_4753 + case 4754: + goto st_case_4754 + case 4755: + goto st_case_4755 + case 4756: + goto st_case_4756 + case 4757: + goto st_case_4757 + case 4758: + goto st_case_4758 + case 4759: + goto st_case_4759 + case 4760: + goto st_case_4760 + case 4761: + goto st_case_4761 + case 4762: + goto st_case_4762 + case 4763: + goto st_case_4763 + case 4764: + goto st_case_4764 + case 4765: + goto st_case_4765 + case 4766: + goto st_case_4766 + case 4767: + goto st_case_4767 + case 4768: + goto st_case_4768 + case 4769: + goto st_case_4769 + case 4770: + goto st_case_4770 + case 4771: + goto st_case_4771 + case 4772: + goto st_case_4772 + case 4773: + goto st_case_4773 + case 4774: + goto st_case_4774 + case 4775: + goto st_case_4775 + case 4776: + goto st_case_4776 + case 4777: + goto st_case_4777 + case 4778: + goto st_case_4778 + case 4779: + goto st_case_4779 + case 4780: + goto st_case_4780 + case 4781: + goto st_case_4781 + case 4782: + goto st_case_4782 + case 4783: + goto st_case_4783 + case 4784: + goto st_case_4784 + case 4785: + goto st_case_4785 + case 4786: + goto st_case_4786 + case 4787: + goto st_case_4787 + case 4788: + goto st_case_4788 + case 4789: + goto st_case_4789 + case 4790: + goto st_case_4790 + case 4791: + goto st_case_4791 + case 4792: + goto st_case_4792 + case 4793: + goto st_case_4793 + case 4794: + goto st_case_4794 + case 4795: + goto st_case_4795 + case 4796: + goto st_case_4796 + case 4797: + goto st_case_4797 + case 4798: + goto st_case_4798 + case 4799: + goto st_case_4799 + case 4800: + goto st_case_4800 + case 4801: + goto st_case_4801 + case 4802: + goto st_case_4802 + case 4803: + goto st_case_4803 + case 4804: + goto st_case_4804 + case 4805: + goto st_case_4805 + case 4806: + goto st_case_4806 + case 4807: + goto st_case_4807 + case 4808: + goto st_case_4808 + case 4809: + goto st_case_4809 + case 4810: + goto st_case_4810 + case 4811: + goto st_case_4811 + case 4812: + goto st_case_4812 + case 4813: + goto st_case_4813 + case 4814: + goto st_case_4814 + case 4815: + goto st_case_4815 + case 4816: + goto st_case_4816 + case 4817: + goto st_case_4817 + case 4818: + goto st_case_4818 + case 4819: + goto st_case_4819 + case 4820: + goto st_case_4820 + case 4821: + goto st_case_4821 + case 4822: + goto st_case_4822 + case 4823: + goto st_case_4823 + case 4824: + goto st_case_4824 + case 4825: + goto st_case_4825 + case 4826: + goto st_case_4826 + case 4827: + goto st_case_4827 + case 4828: + goto st_case_4828 + case 4829: + goto st_case_4829 + case 4830: + goto st_case_4830 + case 4831: + goto st_case_4831 + case 4832: + goto st_case_4832 + case 4833: + goto st_case_4833 + case 4834: + goto st_case_4834 + case 4835: + goto st_case_4835 + case 4836: + goto st_case_4836 + case 4837: + goto st_case_4837 + case 4838: + goto st_case_4838 + case 4839: + goto st_case_4839 + case 4840: + goto st_case_4840 + case 4841: + goto st_case_4841 + case 4842: + goto st_case_4842 + case 4843: + goto st_case_4843 + case 4844: + goto st_case_4844 + case 4845: + goto st_case_4845 + case 4846: + goto st_case_4846 + case 4847: + goto st_case_4847 + case 4848: + goto st_case_4848 + case 4849: + goto st_case_4849 + case 4850: + goto st_case_4850 + case 4851: + goto st_case_4851 + case 4852: + goto st_case_4852 + case 4853: + goto st_case_4853 + case 4854: + goto st_case_4854 + case 4855: + goto st_case_4855 + case 4856: + goto st_case_4856 + case 4857: + goto st_case_4857 + case 4858: + goto st_case_4858 + case 4859: + goto st_case_4859 + case 4860: + goto st_case_4860 + case 4861: + goto st_case_4861 + } + goto st_out +tr0: +//line segment_words.rl:161 +p = (te) - 1 +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr2: +//line NONE:1 + switch act { + case 1: + {p = (te) - 1 + + if !atEOF { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Number) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + case 2: + {p = (te) - 1 + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Letter) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + case 3: + {p = (te) - 1 + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + case 4: + {p = (te) - 1 + + if !atEOF { + return val, types, totalConsumed, nil + } + val = append(val, data[startPos:endPos+1]) + types = append(types, Letter) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + case 5: + {p = (te) - 1 + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + case 7: + {p = (te) - 1 + + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + case 12: + {p = (te) - 1 + + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + case 13: + {p = (te) - 1 + + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + } + + goto st4862 +tr125: +//line segment_words.rl:76 +p = (te) - 1 +{ + if !atEOF { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Number) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr420: +//line segment_words.rl:119 +p = (te) - 1 +{ + if !atEOF { + return val, types, totalConsumed, nil + } + val = append(val, data[startPos:endPos+1]) + types = append(types, Letter) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr2394: +//line segment_words.rl:161 +p = (te) - 1 +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr2985: +//line segment_words.rl:89 +p = (te) - 1 +{ + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Letter) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr3249: +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +te = p+1 +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr3251: +//line segment_words.rl:131 +p = (te) - 1 +{ + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr3627: +//line segment_words.rl:104 +p = (te) - 1 +{ + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr3758: +//line segment_words.rl:146 +p = (te) - 1 +{ + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr4328: +//line segment_words.rl:161 +p = (te) - 1 +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr4458: +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +te = p+1 +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr4459: +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +te = p+1 +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr4499: +//line segment_words.rl:161 +te = p +p-- +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr4519: +//line segment_words.rl:161 +te = p +p-- +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr4520: +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +te = p+1 +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr4521: +//line segment_words.rl:76 +te = p +p-- +{ + if !atEOF { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Number) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr4562: +//line segment_words.rl:119 +te = p +p-- +{ + if !atEOF { + return val, types, totalConsumed, nil + } + val = append(val, data[startPos:endPos+1]) + types = append(types, Letter) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr4763: +//line segment_words.rl:161 +te = p +p-- +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr5002: +//line segment_words.rl:89 +te = p +p-- +{ + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Letter) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr5054: +//line segment_words.rl:131 +te = p +p-- +{ + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr5137: +//line segment_words.rl:104 +te = p +p-- +{ + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr5157: +//line segment_words.rl:146 +te = p +p-- +{ + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + + val = append(val, data[startPos:endPos+1]) + types = append(types, Ideo) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 +tr5359: +//line segment_words.rl:161 +te = p +p-- +{ + lastPos := startPos + for lastPos <= endPos { + _, size := utf8.DecodeRune(data[lastPos:]) + lastPos += size + } + endPos = lastPos -1 + p = endPos + + if endPos+1 == pe && !atEOF { + return val, types, totalConsumed, nil + } else if dr, size := utf8.DecodeRune(data[endPos+1:]); dr == utf8.RuneError && size == 1 { + return val, types, totalConsumed, nil + } + // otherwise, consume this as well + val = append(val, data[startPos:endPos+1]) + types = append(types, None) + totalConsumed = endPos+1 + if maxTokens > 0 && len(val) >= maxTokens { + return val, types, totalConsumed, nil + } + } + goto st4862 + st4862: +//line NONE:1 +ts = 0 + + if p++; p == pe { + goto _test_eof4862 + } + st_case_4862: +//line NONE:1 +ts = p + +//line segment_words_prod.go:11462 + switch data[p] { + case 10: + goto tr4458 + case 13: + goto tr4460 + case 95: + goto tr4463 + case 194: + goto tr4464 + case 195: + goto tr4465 + case 198: + goto tr4467 + case 199: + goto tr4468 + case 203: + goto tr4469 + case 204: + goto tr4470 + case 205: + goto tr4471 + case 206: + goto tr4472 + case 207: + goto tr4473 + case 210: + goto tr4474 + case 212: + goto tr4475 + case 213: + goto tr4476 + case 214: + goto tr4477 + case 215: + goto tr4478 + case 216: + goto tr4479 + case 217: + goto tr4480 + case 219: + goto tr4481 + case 220: + goto tr4482 + case 221: + goto tr4483 + case 222: + goto tr4484 + case 223: + goto tr4485 + case 224: + goto tr4486 + case 225: + goto tr4487 + case 226: + goto tr4488 + case 227: + goto tr4489 + case 228: + goto tr4490 + case 233: + goto tr4492 + case 234: + goto tr4493 + case 237: + goto tr4495 + case 239: + goto tr4496 + case 240: + goto tr4497 + case 243: + goto tr4498 + } + switch { + case data[p] < 97: + switch { + case data[p] < 48: + if 11 <= data[p] && data[p] <= 12 { + goto tr4459 + } + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr4462 + } + default: + goto tr4461 + } + case data[p] > 122: + switch { + case data[p] < 229: + if 196 <= data[p] && data[p] <= 218 { + goto tr4466 + } + case data[p] > 232: + if 235 <= data[p] && data[p] <= 236 { + goto tr4494 + } + default: + goto tr4491 + } + default: + goto tr4462 + } + goto tr4457 +tr1: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4863 +tr4457: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4863 + st4863: + if p++; p == pe { + goto _test_eof4863 + } + st_case_4863: +//line segment_words_prod.go:11597 + switch data[p] { + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 + st0: + if p++; p == pe { + goto _test_eof0 + } + st_case_0: + if data[p] == 173 { + goto tr1 + } + goto tr0 + st1: + if p++; p == pe { + goto _test_eof1 + } + st_case_1: + if data[p] <= 127 { + goto tr2 + } + goto tr1 + st2: + if p++; p == pe { + goto _test_eof2 + } + st_case_2: + if 176 <= data[p] { + goto tr2 + } + goto tr1 + st3: + if p++; p == pe { + goto _test_eof3 + } + st_case_3: + if 131 <= data[p] && data[p] <= 137 { + goto tr1 + } + goto tr0 + st4: + if p++; p == pe { + goto _test_eof4 + } + st_case_4: + if data[p] == 191 { + goto tr1 + } + if 145 <= data[p] && data[p] <= 189 { + goto tr1 + } + goto tr0 + st5: + if p++; p == pe { + goto _test_eof5 + } + st_case_5: + if data[p] == 135 { + goto tr1 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto tr1 + } + case data[p] >= 129: + goto tr1 + } + goto tr0 + st6: + if p++; p == pe { + goto _test_eof6 + } + st_case_6: + if data[p] == 156 { + goto tr1 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr0 + st7: + if p++; p == pe { + goto _test_eof7 + } + st_case_7: + if data[p] == 176 { + goto tr1 + } + if 139 <= data[p] && data[p] <= 159 { + goto tr1 + } + goto tr0 + st8: + if p++; p == pe { + goto _test_eof8 + } + st_case_8: + switch { + case data[p] < 159: + if 150 <= data[p] && data[p] <= 157 { + goto tr1 + } + case data[p] > 164: + switch { + case data[p] > 168: + if 170 <= data[p] && data[p] <= 173 { + goto tr1 + } + case data[p] >= 167: + goto tr1 + } + default: + goto tr1 + } + goto tr0 + st9: + if p++; p == pe { + goto _test_eof9 + } + st_case_9: + switch data[p] { + case 143: + goto tr1 + case 145: + goto tr1 + } + if 176 <= data[p] { + goto tr1 + } + goto tr0 + st10: + if p++; p == pe { + goto _test_eof10 + } + st_case_10: + if 139 <= data[p] { + goto tr0 + } + goto tr1 + st11: + if p++; p == pe { + goto _test_eof11 + } + st_case_11: + if 166 <= data[p] && data[p] <= 176 { + goto tr1 + } + goto tr0 + st12: + if p++; p == pe { + goto _test_eof12 + } + st_case_12: + if 171 <= data[p] && data[p] <= 179 { + goto tr1 + } + goto tr0 + st13: + if p++; p == pe { + goto _test_eof13 + } + st_case_13: + switch data[p] { + case 160: + goto st14 + case 161: + goto st15 + case 163: + goto st16 + case 164: + goto st17 + case 165: + goto st18 + case 167: + goto st20 + case 169: + goto st21 + case 171: + goto st22 + case 173: + goto st24 + case 174: + goto st25 + case 175: + goto st26 + case 176: + goto st27 + case 177: + goto st28 + case 179: + goto st29 + case 180: + goto st30 + case 181: + goto st31 + case 182: + goto st32 + case 183: + goto st33 + case 184: + goto st34 + case 185: + goto st35 + case 186: + goto st36 + case 187: + goto st37 + case 188: + goto st38 + case 189: + goto st39 + case 190: + goto st40 + case 191: + goto st41 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto st23 + } + case data[p] >= 166: + goto st19 + } + goto tr0 + st14: + if p++; p == pe { + goto _test_eof14 + } + st_case_14: + switch { + case data[p] < 155: + if 150 <= data[p] && data[p] <= 153 { + goto tr1 + } + case data[p] > 163: + switch { + case data[p] > 167: + if 169 <= data[p] && data[p] <= 173 { + goto tr1 + } + case data[p] >= 165: + goto tr1 + } + default: + goto tr1 + } + goto tr2 + st15: + if p++; p == pe { + goto _test_eof15 + } + st_case_15: + if 153 <= data[p] && data[p] <= 155 { + goto tr1 + } + goto tr2 + st16: + if p++; p == pe { + goto _test_eof16 + } + st_case_16: + if 163 <= data[p] { + goto tr1 + } + goto tr2 + st17: + if p++; p == pe { + goto _test_eof17 + } + st_case_17: + if data[p] == 189 { + goto tr2 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr2 + } + goto tr1 + st18: + if p++; p == pe { + goto _test_eof18 + } + st_case_18: + if data[p] == 144 { + goto tr2 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr2 + } + case data[p] >= 152: + goto tr2 + } + goto tr1 + st19: + if p++; p == pe { + goto _test_eof19 + } + st_case_19: + if data[p] == 188 { + goto tr1 + } + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr1 + } + case data[p] >= 129: + goto tr1 + } + goto tr2 + st20: + if p++; p == pe { + goto _test_eof20 + } + st_case_20: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr2 + } + case data[p] >= 133: + goto tr2 + } + case data[p] > 150: + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr2 + } + case data[p] >= 152: + goto tr2 + } + default: + goto tr2 + } + goto tr1 + st21: + if p++; p == pe { + goto _test_eof21 + } + st_case_21: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr2 + } + case data[p] >= 131: + goto tr2 + } + case data[p] > 144: + switch { + case data[p] < 178: + if 146 <= data[p] && data[p] <= 175 { + goto tr2 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + default: + goto tr2 + } + goto tr1 + st22: + if p++; p == pe { + goto _test_eof22 + } + st_case_22: + switch data[p] { + case 134: + goto tr2 + case 138: + goto tr2 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr2 + } + case data[p] >= 142: + goto tr2 + } + goto tr1 + st23: + if p++; p == pe { + goto _test_eof23 + } + st_case_23: + if data[p] == 188 { + goto tr1 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] >= 129: + goto tr1 + } + goto tr2 + st24: + if p++; p == pe { + goto _test_eof24 + } + st_case_24: + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + case data[p] > 141: + switch { + case data[p] > 151: + if 162 <= data[p] && data[p] <= 163 { + goto tr1 + } + case data[p] >= 150: + goto tr1 + } + default: + goto tr1 + } + goto tr2 + st25: + if p++; p == pe { + goto _test_eof25 + } + st_case_25: + if data[p] == 130 { + goto tr1 + } + if 190 <= data[p] && data[p] <= 191 { + goto tr1 + } + goto tr2 + st26: + if p++; p == pe { + goto _test_eof26 + } + st_case_26: + if data[p] == 151 { + goto tr1 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr1 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr1 + } + default: + goto tr1 + } + goto tr2 + st27: + if p++; p == pe { + goto _test_eof27 + } + st_case_27: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr2 + st28: + if p++; p == pe { + goto _test_eof28 + } + st_case_28: + switch data[p] { + case 133: + goto tr2 + case 137: + goto tr2 + } + switch { + case data[p] < 151: + if 142 <= data[p] && data[p] <= 148 { + goto tr2 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr1 + st29: + if p++; p == pe { + goto _test_eof29 + } + st_case_29: + switch { + case data[p] < 138: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 136 { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + case data[p] > 141: + switch { + case data[p] > 150: + if 162 <= data[p] && data[p] <= 163 { + goto tr1 + } + case data[p] >= 149: + goto tr1 + } + default: + goto tr1 + } + goto tr2 + st30: + if p++; p == pe { + goto _test_eof30 + } + st_case_30: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr1 + } + case data[p] >= 129: + goto tr1 + } + goto tr2 + st31: + if p++; p == pe { + goto _test_eof31 + } + st_case_31: + switch data[p] { + case 133: + goto tr2 + case 137: + goto tr2 + } + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 150 { + goto tr2 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr1 + st32: + if p++; p == pe { + goto _test_eof32 + } + st_case_32: + if 130 <= data[p] && data[p] <= 131 { + goto tr1 + } + goto tr2 + st33: + if p++; p == pe { + goto _test_eof33 + } + st_case_33: + switch data[p] { + case 138: + goto tr1 + case 150: + goto tr1 + } + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 148 { + goto tr1 + } + case data[p] > 159: + if 178 <= data[p] && data[p] <= 179 { + goto tr1 + } + default: + goto tr1 + } + goto tr2 + st34: + if p++; p == pe { + goto _test_eof34 + } + st_case_34: + if data[p] == 177 { + goto tr1 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr1 + } + goto tr2 + st35: + if p++; p == pe { + goto _test_eof35 + } + st_case_35: + if 135 <= data[p] && data[p] <= 142 { + goto tr1 + } + goto tr2 + st36: + if p++; p == pe { + goto _test_eof36 + } + st_case_36: + if data[p] == 177 { + goto tr1 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr1 + } + case data[p] >= 180: + goto tr1 + } + goto tr2 + st37: + if p++; p == pe { + goto _test_eof37 + } + st_case_37: + if 136 <= data[p] && data[p] <= 141 { + goto tr1 + } + goto tr2 + st38: + if p++; p == pe { + goto _test_eof38 + } + st_case_38: + switch data[p] { + case 181: + goto tr1 + case 183: + goto tr1 + case 185: + goto tr1 + } + switch { + case data[p] > 153: + if 190 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] >= 152: + goto tr1 + } + goto tr2 + st39: + if p++; p == pe { + goto _test_eof39 + } + st_case_39: + if 177 <= data[p] && data[p] <= 191 { + goto tr1 + } + goto tr2 + st40: + if p++; p == pe { + goto _test_eof40 + } + st_case_40: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr1 + } + case data[p] > 135: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr1 + } + case data[p] >= 141: + goto tr1 + } + default: + goto tr1 + } + goto tr2 + st41: + if p++; p == pe { + goto _test_eof41 + } + st_case_41: + if data[p] == 134 { + goto tr1 + } + goto tr2 + st42: + if p++; p == pe { + goto _test_eof42 + } + st_case_42: + switch data[p] { + case 128: + goto st43 + case 129: + goto st44 + case 130: + goto st45 + case 141: + goto st46 + case 156: + goto st47 + case 157: + goto st48 + case 158: + goto st49 + case 159: + goto st50 + case 160: + goto st51 + case 162: + goto st52 + case 164: + goto st53 + case 168: + goto st54 + case 169: + goto st55 + case 170: + goto st56 + case 172: + goto st57 + case 173: + goto st58 + case 174: + goto st59 + case 175: + goto st60 + case 176: + goto st61 + case 179: + goto st62 + case 183: + goto st63 + } + goto tr0 + st43: + if p++; p == pe { + goto _test_eof43 + } + st_case_43: + if 171 <= data[p] && data[p] <= 190 { + goto tr1 + } + goto tr2 + st44: + if p++; p == pe { + goto _test_eof44 + } + st_case_44: + switch { + case data[p] < 162: + switch { + case data[p] > 153: + if 158 <= data[p] && data[p] <= 160 { + goto tr1 + } + case data[p] >= 150: + goto tr1 + } + case data[p] > 164: + switch { + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr1 + } + case data[p] >= 167: + goto tr1 + } + default: + goto tr1 + } + goto tr2 + st45: + if p++; p == pe { + goto _test_eof45 + } + st_case_45: + if data[p] == 143 { + goto tr1 + } + switch { + case data[p] > 141: + if 154 <= data[p] && data[p] <= 157 { + goto tr1 + } + case data[p] >= 130: + goto tr1 + } + goto tr2 + st46: + if p++; p == pe { + goto _test_eof46 + } + st_case_46: + if 157 <= data[p] && data[p] <= 159 { + goto tr1 + } + goto tr2 + st47: + if p++; p == pe { + goto _test_eof47 + } + st_case_47: + switch { + case data[p] > 148: + if 178 <= data[p] && data[p] <= 180 { + goto tr1 + } + case data[p] >= 146: + goto tr1 + } + goto tr2 + st48: + if p++; p == pe { + goto _test_eof48 + } + st_case_48: + switch { + case data[p] > 147: + if 178 <= data[p] && data[p] <= 179 { + goto tr1 + } + case data[p] >= 146: + goto tr1 + } + goto tr2 + st49: + if p++; p == pe { + goto _test_eof49 + } + st_case_49: + if 180 <= data[p] { + goto tr1 + } + goto tr2 + st50: + if p++; p == pe { + goto _test_eof50 + } + st_case_50: + switch { + case data[p] > 156: + if 158 <= data[p] { + goto tr2 + } + case data[p] >= 148: + goto tr2 + } + goto tr1 + st51: + if p++; p == pe { + goto _test_eof51 + } + st_case_51: + if 139 <= data[p] && data[p] <= 142 { + goto tr1 + } + goto tr2 + st52: + if p++; p == pe { + goto _test_eof52 + } + st_case_52: + if data[p] == 169 { + goto tr1 + } + goto tr2 + st53: + if p++; p == pe { + goto _test_eof53 + } + st_case_53: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr1 + } + case data[p] >= 160: + goto tr1 + } + goto tr2 + st54: + if p++; p == pe { + goto _test_eof54 + } + st_case_54: + if 151 <= data[p] && data[p] <= 155 { + goto tr1 + } + goto tr2 + st55: + if p++; p == pe { + goto _test_eof55 + } + st_case_55: + if data[p] == 191 { + goto tr1 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr1 + } + case data[p] >= 149: + goto tr1 + } + goto tr2 + st56: + if p++; p == pe { + goto _test_eof56 + } + st_case_56: + if 176 <= data[p] && data[p] <= 190 { + goto tr1 + } + goto tr2 + st57: + if p++; p == pe { + goto _test_eof57 + } + st_case_57: + switch { + case data[p] > 132: + if 180 <= data[p] { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr2 + st58: + if p++; p == pe { + goto _test_eof58 + } + st_case_58: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr2 + } + case data[p] >= 133: + goto tr2 + } + goto tr1 + st59: + if p++; p == pe { + goto _test_eof59 + } + st_case_59: + switch { + case data[p] > 130: + if 161 <= data[p] && data[p] <= 173 { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr2 + st60: + if p++; p == pe { + goto _test_eof60 + } + st_case_60: + if 166 <= data[p] && data[p] <= 179 { + goto tr1 + } + goto tr2 + st61: + if p++; p == pe { + goto _test_eof61 + } + st_case_61: + if 164 <= data[p] && data[p] <= 183 { + goto tr1 + } + goto tr2 + st62: + if p++; p == pe { + goto _test_eof62 + } + st_case_62: + if data[p] == 173 { + goto tr1 + } + switch { + case data[p] < 148: + if 144 <= data[p] && data[p] <= 146 { + goto tr1 + } + case data[p] > 168: + switch { + case data[p] > 180: + if 184 <= data[p] && data[p] <= 185 { + goto tr1 + } + case data[p] >= 178: + goto tr1 + } + default: + goto tr1 + } + goto tr2 + st63: + if p++; p == pe { + goto _test_eof63 + } + st_case_63: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr2 + st64: + if p++; p == pe { + goto _test_eof64 + } + st_case_64: + switch data[p] { + case 128: + goto st65 + case 129: + goto st66 + case 131: + goto st67 + case 179: + goto st68 + case 181: + goto st69 + case 183: + goto st70 + } + goto tr0 + st65: + if p++; p == pe { + goto _test_eof65 + } + st_case_65: + switch { + case data[p] > 143: + if 170 <= data[p] && data[p] <= 174 { + goto tr1 + } + case data[p] >= 140: + goto tr1 + } + goto tr2 + st66: + if p++; p == pe { + goto _test_eof66 + } + st_case_66: + switch { + case data[p] > 164: + if 166 <= data[p] && data[p] <= 175 { + goto tr1 + } + case data[p] >= 160: + goto tr1 + } + goto tr2 + st67: + if p++; p == pe { + goto _test_eof67 + } + st_case_67: + if 144 <= data[p] && data[p] <= 176 { + goto tr1 + } + goto tr2 + st68: + if p++; p == pe { + goto _test_eof68 + } + st_case_68: + if 175 <= data[p] && data[p] <= 177 { + goto tr1 + } + goto tr2 + st69: + if p++; p == pe { + goto _test_eof69 + } + st_case_69: + if data[p] == 191 { + goto tr1 + } + goto tr2 + st70: + if p++; p == pe { + goto _test_eof70 + } + st_case_70: + if 160 <= data[p] && data[p] <= 191 { + goto tr1 + } + goto tr2 + st71: + if p++; p == pe { + goto _test_eof71 + } + st_case_71: + switch data[p] { + case 128: + goto st72 + case 130: + goto st73 + } + goto tr0 + st72: + if p++; p == pe { + goto _test_eof72 + } + st_case_72: + if 170 <= data[p] && data[p] <= 175 { + goto tr1 + } + goto tr2 + st73: + if p++; p == pe { + goto _test_eof73 + } + st_case_73: + if 153 <= data[p] && data[p] <= 154 { + goto tr1 + } + goto tr2 + st74: + if p++; p == pe { + goto _test_eof74 + } + st_case_74: + switch data[p] { + case 153: + goto st75 + case 154: + goto st76 + case 155: + goto st77 + case 160: + goto st78 + case 162: + goto st79 + case 163: + goto st80 + case 164: + goto st81 + case 165: + goto st82 + case 166: + goto st83 + case 167: + goto st84 + case 168: + goto st85 + case 169: + goto st86 + case 170: + goto st87 + case 171: + goto st88 + case 175: + goto st89 + } + goto tr0 + st75: + if p++; p == pe { + goto _test_eof75 + } + st_case_75: + switch { + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr1 + } + case data[p] >= 175: + goto tr1 + } + goto tr2 + st76: + if p++; p == pe { + goto _test_eof76 + } + st_case_76: + if 158 <= data[p] && data[p] <= 159 { + goto tr1 + } + goto tr2 + st77: + if p++; p == pe { + goto _test_eof77 + } + st_case_77: + if 176 <= data[p] && data[p] <= 177 { + goto tr1 + } + goto tr2 + st78: + if p++; p == pe { + goto _test_eof78 + } + st_case_78: + switch data[p] { + case 130: + goto tr1 + case 134: + goto tr1 + case 139: + goto tr1 + } + if 163 <= data[p] && data[p] <= 167 { + goto tr1 + } + goto tr2 + st79: + if p++; p == pe { + goto _test_eof79 + } + st_case_79: + switch { + case data[p] > 129: + if 180 <= data[p] { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr2 + st80: + if p++; p == pe { + goto _test_eof80 + } + st_case_80: + switch { + case data[p] > 159: + if 178 <= data[p] { + goto tr2 + } + case data[p] >= 133: + goto tr2 + } + goto tr1 + st81: + if p++; p == pe { + goto _test_eof81 + } + st_case_81: + if 166 <= data[p] && data[p] <= 173 { + goto tr1 + } + goto tr2 + st82: + if p++; p == pe { + goto _test_eof82 + } + st_case_82: + if 135 <= data[p] && data[p] <= 147 { + goto tr1 + } + goto tr2 + st83: + if p++; p == pe { + goto _test_eof83 + } + st_case_83: + switch { + case data[p] > 131: + if 179 <= data[p] { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr2 + st84: + if p++; p == pe { + goto _test_eof84 + } + st_case_84: + switch { + case data[p] > 164: + if 166 <= data[p] { + goto tr2 + } + case data[p] >= 129: + goto tr2 + } + goto tr1 + st85: + if p++; p == pe { + goto _test_eof85 + } + st_case_85: + if 169 <= data[p] && data[p] <= 182 { + goto tr1 + } + goto tr2 + st86: + if p++; p == pe { + goto _test_eof86 + } + st_case_86: + if data[p] == 131 { + goto tr1 + } + switch { + case data[p] > 141: + if 187 <= data[p] && data[p] <= 189 { + goto tr1 + } + case data[p] >= 140: + goto tr1 + } + goto tr2 + st87: + if p++; p == pe { + goto _test_eof87 + } + st_case_87: + if data[p] == 176 { + goto tr1 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr1 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr1 + } + default: + goto tr1 + } + goto tr2 + st88: + if p++; p == pe { + goto _test_eof88 + } + st_case_88: + if data[p] == 129 { + goto tr1 + } + switch { + case data[p] > 175: + if 181 <= data[p] && data[p] <= 182 { + goto tr1 + } + case data[p] >= 171: + goto tr1 + } + goto tr2 + st89: + if p++; p == pe { + goto _test_eof89 + } + st_case_89: + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 173 { + goto tr1 + } + case data[p] >= 163: + goto tr1 + } + goto tr2 + st90: + if p++; p == pe { + goto _test_eof90 + } + st_case_90: + switch data[p] { + case 172: + goto st91 + case 184: + goto st92 + case 187: + goto st69 + case 190: + goto st76 + case 191: + goto st93 + } + goto tr0 + st91: + if p++; p == pe { + goto _test_eof91 + } + st_case_91: + if data[p] == 158 { + goto tr1 + } + goto tr2 + st92: + if p++; p == pe { + goto _test_eof92 + } + st_case_92: + switch { + case data[p] > 143: + if 160 <= data[p] && data[p] <= 175 { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr2 + st93: + if p++; p == pe { + goto _test_eof93 + } + st_case_93: + if 185 <= data[p] && data[p] <= 187 { + goto tr1 + } + goto tr2 + st94: + if p++; p == pe { + goto _test_eof94 + } + st_case_94: + switch data[p] { + case 144: + goto st95 + case 145: + goto st101 + case 150: + goto st120 + case 155: + goto st125 + case 157: + goto st127 + case 158: + goto st134 + } + goto tr0 + st95: + if p++; p == pe { + goto _test_eof95 + } + st_case_95: + switch data[p] { + case 135: + goto st96 + case 139: + goto st97 + case 141: + goto st98 + case 168: + goto st99 + case 171: + goto st100 + } + goto tr2 + st96: + if p++; p == pe { + goto _test_eof96 + } + st_case_96: + if data[p] == 189 { + goto tr1 + } + goto tr2 + st97: + if p++; p == pe { + goto _test_eof97 + } + st_case_97: + if data[p] == 160 { + goto tr1 + } + goto tr2 + st98: + if p++; p == pe { + goto _test_eof98 + } + st_case_98: + if 182 <= data[p] && data[p] <= 186 { + goto tr1 + } + goto tr2 + st99: + if p++; p == pe { + goto _test_eof99 + } + st_case_99: + if data[p] == 191 { + goto tr1 + } + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr1 + } + case data[p] > 134: + switch { + case data[p] > 143: + if 184 <= data[p] && data[p] <= 186 { + goto tr1 + } + case data[p] >= 140: + goto tr1 + } + default: + goto tr1 + } + goto tr2 + st100: + if p++; p == pe { + goto _test_eof100 + } + st_case_100: + if 165 <= data[p] && data[p] <= 166 { + goto tr1 + } + goto tr2 + st101: + if p++; p == pe { + goto _test_eof101 + } + st_case_101: + switch data[p] { + case 128: + goto st102 + case 129: + goto st103 + case 130: + goto st104 + case 132: + goto st105 + case 133: + goto st106 + case 134: + goto st107 + case 135: + goto st108 + case 136: + goto st109 + case 139: + goto st110 + case 140: + goto st111 + case 141: + goto st112 + case 146: + goto st113 + case 147: + goto st114 + case 150: + goto st115 + case 151: + goto st116 + case 152: + goto st113 + case 153: + goto st117 + case 154: + goto st118 + case 156: + goto st119 + } + goto tr2 + st102: + if p++; p == pe { + goto _test_eof102 + } + st_case_102: + switch { + case data[p] > 130: + if 184 <= data[p] { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr2 + st103: + if p++; p == pe { + goto _test_eof103 + } + st_case_103: + if 135 <= data[p] && data[p] <= 190 { + goto tr2 + } + goto tr1 + st104: + if p++; p == pe { + goto _test_eof104 + } + st_case_104: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr2 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr1 + st105: + if p++; p == pe { + goto _test_eof105 + } + st_case_105: + switch { + case data[p] > 130: + if 167 <= data[p] && data[p] <= 180 { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr2 + st106: + if p++; p == pe { + goto _test_eof106 + } + st_case_106: + if data[p] == 179 { + goto tr1 + } + goto tr2 + st107: + if p++; p == pe { + goto _test_eof107 + } + st_case_107: + switch { + case data[p] > 130: + if 179 <= data[p] { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr2 + st108: + if p++; p == pe { + goto _test_eof108 + } + st_case_108: + switch { + case data[p] > 137: + if 141 <= data[p] { + goto tr2 + } + case data[p] >= 129: + goto tr2 + } + goto tr1 + st109: + if p++; p == pe { + goto _test_eof109 + } + st_case_109: + if 172 <= data[p] && data[p] <= 183 { + goto tr1 + } + goto tr2 + st110: + if p++; p == pe { + goto _test_eof110 + } + st_case_110: + if 159 <= data[p] && data[p] <= 170 { + goto tr1 + } + goto tr2 + st111: + if p++; p == pe { + goto _test_eof111 + } + st_case_111: + if data[p] == 188 { + goto tr1 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr2 + st112: + if p++; p == pe { + goto _test_eof112 + } + st_case_112: + if data[p] == 151 { + goto tr1 + } + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + case data[p] > 141: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr1 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr1 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr2 + st113: + if p++; p == pe { + goto _test_eof113 + } + st_case_113: + if 176 <= data[p] { + goto tr1 + } + goto tr2 + st114: + if p++; p == pe { + goto _test_eof114 + } + st_case_114: + if 132 <= data[p] { + goto tr2 + } + goto tr1 + st115: + if p++; p == pe { + goto _test_eof115 + } + st_case_115: + switch { + case data[p] > 181: + if 184 <= data[p] { + goto tr1 + } + case data[p] >= 175: + goto tr1 + } + goto tr2 + st116: + if p++; p == pe { + goto _test_eof116 + } + st_case_116: + switch { + case data[p] > 155: + if 158 <= data[p] { + goto tr2 + } + case data[p] >= 129: + goto tr2 + } + goto tr1 + st117: + if p++; p == pe { + goto _test_eof117 + } + st_case_117: + if 129 <= data[p] { + goto tr2 + } + goto tr1 + st118: + if p++; p == pe { + goto _test_eof118 + } + st_case_118: + if 171 <= data[p] && data[p] <= 183 { + goto tr1 + } + goto tr2 + st119: + if p++; p == pe { + goto _test_eof119 + } + st_case_119: + if 157 <= data[p] && data[p] <= 171 { + goto tr1 + } + goto tr2 + st120: + if p++; p == pe { + goto _test_eof120 + } + st_case_120: + switch data[p] { + case 171: + goto st121 + case 172: + goto st122 + case 189: + goto st123 + case 190: + goto st124 + } + goto tr2 + st121: + if p++; p == pe { + goto _test_eof121 + } + st_case_121: + if 176 <= data[p] && data[p] <= 180 { + goto tr1 + } + goto tr2 + st122: + if p++; p == pe { + goto _test_eof122 + } + st_case_122: + if 176 <= data[p] && data[p] <= 182 { + goto tr1 + } + goto tr2 + st123: + if p++; p == pe { + goto _test_eof123 + } + st_case_123: + if 145 <= data[p] && data[p] <= 190 { + goto tr1 + } + goto tr2 + st124: + if p++; p == pe { + goto _test_eof124 + } + st_case_124: + if 143 <= data[p] && data[p] <= 146 { + goto tr1 + } + goto tr2 + st125: + if p++; p == pe { + goto _test_eof125 + } + st_case_125: + if data[p] == 178 { + goto st126 + } + goto tr2 + st126: + if p++; p == pe { + goto _test_eof126 + } + st_case_126: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr1 + } + case data[p] >= 157: + goto tr1 + } + goto tr2 + st127: + if p++; p == pe { + goto _test_eof127 + } + st_case_127: + switch data[p] { + case 133: + goto st128 + case 134: + goto st129 + case 137: + goto st130 + case 168: + goto st131 + case 169: + goto st132 + case 170: + goto st133 + } + goto tr2 + st128: + if p++; p == pe { + goto _test_eof128 + } + st_case_128: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr1 + } + case data[p] >= 165: + goto tr1 + } + goto tr2 + st129: + if p++; p == pe { + goto _test_eof129 + } + st_case_129: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr2 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr1 + st130: + if p++; p == pe { + goto _test_eof130 + } + st_case_130: + if 130 <= data[p] && data[p] <= 132 { + goto tr1 + } + goto tr2 + st131: + if p++; p == pe { + goto _test_eof131 + } + st_case_131: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr2 + st132: + if p++; p == pe { + goto _test_eof132 + } + st_case_132: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr2 + } + case data[p] >= 173: + goto tr2 + } + goto tr1 + st133: + if p++; p == pe { + goto _test_eof133 + } + st_case_133: + if data[p] == 132 { + goto tr1 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr1 + } + case data[p] >= 155: + goto tr1 + } + goto tr2 + st134: + if p++; p == pe { + goto _test_eof134 + } + st_case_134: + if data[p] == 163 { + goto st135 + } + goto tr2 + st135: + if p++; p == pe { + goto _test_eof135 + } + st_case_135: + if 144 <= data[p] && data[p] <= 150 { + goto tr1 + } + goto tr2 + st136: + if p++; p == pe { + goto _test_eof136 + } + st_case_136: + if data[p] == 160 { + goto st137 + } + goto tr0 + st137: + if p++; p == pe { + goto _test_eof137 + } + st_case_137: + switch data[p] { + case 128: + goto st138 + case 129: + goto st139 + case 132: + goto st1 + case 135: + goto st2 + } + if 133 <= data[p] && data[p] <= 134 { + goto st140 + } + goto tr2 + st138: + if p++; p == pe { + goto _test_eof138 + } + st_case_138: + if data[p] == 129 { + goto tr1 + } + if 160 <= data[p] { + goto tr1 + } + goto tr2 + st139: + if p++; p == pe { + goto _test_eof139 + } + st_case_139: + if 192 <= data[p] { + goto tr2 + } + goto tr1 + st140: + if p++; p == pe { + goto _test_eof140 + } + st_case_140: + goto tr1 +tr4460: +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + + goto st4864 + st4864: + if p++; p == pe { + goto _test_eof4864 + } + st_case_4864: +//line segment_words_prod.go:13746 + if data[p] == 10 { + goto tr4520 + } + goto tr4519 +tr1880: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:76 +act = 1; + goto st4865 +tr4461: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:76 +act = 1; + goto st4865 + st4865: + if p++; p == pe { + goto _test_eof4865 + } + st_case_4865: +//line segment_words_prod.go:13782 + switch data[p] { + case 39: + goto st141 + case 44: + goto st141 + case 46: + goto st141 + case 59: + goto st141 + case 95: + goto tr1485 + case 194: + goto st2046 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st148 + case 204: + goto st2047 + case 205: + goto st2048 + case 206: + goto st151 + case 207: + goto st152 + case 210: + goto st2049 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st2050 + case 215: + goto st2051 + case 216: + goto st2052 + case 217: + goto st2053 + case 219: + goto st2054 + case 220: + goto st2055 + case 221: + goto st2056 + case 222: + goto st2057 + case 223: + goto st2058 + case 224: + goto st2059 + case 225: + goto st2091 + case 226: + goto st2113 + case 227: + goto st2120 + case 234: + goto st2123 + case 237: + goto st287 + case 239: + goto st2139 + case 240: + goto st2145 + case 243: + goto st2187 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr126 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4521 + st141: + if p++; p == pe { + goto _test_eof141 + } + st_case_141: + switch data[p] { + case 194: + goto st1901 + case 204: + goto st1902 + case 205: + goto st1903 + case 210: + goto st1904 + case 214: + goto st1905 + case 215: + goto st1906 + case 216: + goto st1907 + case 217: + goto st1908 + case 219: + goto st1909 + case 220: + goto st1910 + case 221: + goto st1911 + case 222: + goto st1912 + case 223: + goto st1913 + case 224: + goto st1914 + case 225: + goto st1943 + case 226: + goto st1966 + case 227: + goto st1973 + case 234: + goto st1976 + case 239: + goto st1993 + case 240: + goto st1997 + case 243: + goto st2041 + } + if 48 <= data[p] && data[p] <= 57 { + goto tr126 + } + goto tr125 +tr126: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:76 +act = 1; + goto st4866 + st4866: + if p++; p == pe { + goto _test_eof4866 + } + st_case_4866: +//line segment_words_prod.go:13947 + switch data[p] { + case 39: + goto st141 + case 44: + goto st141 + case 46: + goto st141 + case 59: + goto st141 + case 95: + goto tr1485 + case 194: + goto st1752 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st148 + case 204: + goto st1753 + case 205: + goto st1754 + case 206: + goto st151 + case 207: + goto st152 + case 210: + goto st1755 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1756 + case 215: + goto st1757 + case 216: + goto st1758 + case 217: + goto st1759 + case 219: + goto st1760 + case 220: + goto st1761 + case 221: + goto st1762 + case 222: + goto st1763 + case 223: + goto st1764 + case 224: + goto st1765 + case 225: + goto st1797 + case 226: + goto st1819 + case 227: + goto st1826 + case 234: + goto st1829 + case 237: + goto st287 + case 239: + goto st1845 + case 240: + goto st1853 + case 243: + goto st1895 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr126 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4521 +tr148: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4867 + st4867: + if p++; p == pe { + goto _test_eof4867 + } + st_case_4867: +//line segment_words_prod.go:14059 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 + st142: + if p++; p == pe { + goto _test_eof142 + } + st_case_142: + switch data[p] { + case 194: + goto st143 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st148 + case 204: + goto st149 + case 205: + goto st150 + case 206: + goto st151 + case 207: + goto st152 + case 210: + goto st153 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st156 + case 215: + goto st157 + case 216: + goto st158 + case 217: + goto st159 + case 219: + goto st160 + case 220: + goto st161 + case 221: + goto st162 + case 222: + goto st163 + case 223: + goto st164 + case 224: + goto st165 + case 225: + goto st198 + case 226: + goto st238 + case 227: + goto st256 + case 234: + goto st261 + case 237: + goto st287 + case 239: + goto st290 + case 240: + goto st306 + case 243: + goto st407 + } + switch { + case data[p] < 97: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr2 + st143: + if p++; p == pe { + goto _test_eof143 + } + st_case_143: + switch data[p] { + case 170: + goto tr148 + case 173: + goto st142 + case 181: + goto tr148 + case 186: + goto tr148 + } + goto tr2 + st144: + if p++; p == pe { + goto _test_eof144 + } + st_case_144: + switch { + case data[p] < 152: + if 128 <= data[p] && data[p] <= 150 { + goto tr148 + } + case data[p] > 182: + if 184 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st145: + if p++; p == pe { + goto _test_eof145 + } + st_case_145: + goto tr148 + st146: + if p++; p == pe { + goto _test_eof146 + } + st_case_146: + if 192 <= data[p] { + goto tr2 + } + goto tr148 + st147: + if p++; p == pe { + goto _test_eof147 + } + st_case_147: + if data[p] <= 127 { + goto tr2 + } + goto tr148 + st148: + if p++; p == pe { + goto _test_eof148 + } + st_case_148: + if data[p] == 173 { + goto tr2 + } + switch { + case data[p] < 146: + if 130 <= data[p] && data[p] <= 133 { + goto tr2 + } + case data[p] > 159: + switch { + case data[p] > 171: + if 175 <= data[p] { + goto tr2 + } + case data[p] >= 165: + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st149: + if p++; p == pe { + goto _test_eof149 + } + st_case_149: + if 128 <= data[p] { + goto st142 + } + goto tr2 + st150: + if p++; p == pe { + goto _test_eof150 + } + st_case_150: + switch data[p] { + case 181: + goto tr2 + case 190: + goto tr2 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr2 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr2 + } + goto st142 + st151: + if p++; p == pe { + goto _test_eof151 + } + st_case_151: + switch data[p] { + case 134: + goto tr148 + case 140: + goto tr148 + } + switch { + case data[p] < 142: + if 136 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 161: + if 163 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st152: + if p++; p == pe { + goto _test_eof152 + } + st_case_152: + if data[p] == 182 { + goto tr2 + } + goto tr148 + st153: + if p++; p == pe { + goto _test_eof153 + } + st_case_153: + if data[p] == 130 { + goto tr2 + } + if 131 <= data[p] && data[p] <= 137 { + goto st142 + } + goto tr148 + st154: + if p++; p == pe { + goto _test_eof154 + } + st_case_154: + if data[p] == 176 { + goto tr2 + } + goto tr148 + st155: + if p++; p == pe { + goto _test_eof155 + } + st_case_155: + switch { + case data[p] > 152: + if 154 <= data[p] && data[p] <= 160 { + goto tr2 + } + case data[p] >= 151: + goto tr2 + } + goto tr148 + st156: + if p++; p == pe { + goto _test_eof156 + } + st_case_156: + if data[p] == 190 { + goto tr2 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr2 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr2 + } + default: + goto st142 + } + goto tr148 + st157: + if p++; p == pe { + goto _test_eof157 + } + st_case_157: + if data[p] == 135 { + goto st142 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto st142 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] >= 144: + goto tr148 + } + default: + goto st142 + } + goto tr2 + st158: + if p++; p == pe { + goto _test_eof158 + } + st_case_158: + if data[p] == 156 { + goto st142 + } + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 133 { + goto st142 + } + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto st142 + } + goto tr2 + st159: + if p++; p == pe { + goto _test_eof159 + } + st_case_159: + if data[p] == 176 { + goto st142 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 159: + if 174 <= data[p] { + goto tr148 + } + default: + goto st142 + } + goto tr2 + st160: + if p++; p == pe { + goto _test_eof160 + } + st_case_160: + switch data[p] { + case 148: + goto tr2 + case 158: + goto tr2 + case 169: + goto tr2 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto st142 + } + case data[p] >= 150: + goto st142 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr2 + } + case data[p] >= 189: + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st161: + if p++; p == pe { + goto _test_eof161 + } + st_case_161: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto st142 + } + case data[p] > 175: + if 176 <= data[p] { + goto st142 + } + default: + goto tr148 + } + goto tr2 + st162: + if p++; p == pe { + goto _test_eof162 + } + st_case_162: + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr2 + } + goto st142 + st163: + if p++; p == pe { + goto _test_eof163 + } + st_case_163: + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr2 + } + case data[p] >= 166: + goto st142 + } + goto tr148 + st164: + if p++; p == pe { + goto _test_eof164 + } + st_case_164: + if data[p] == 186 { + goto tr148 + } + switch { + case data[p] < 171: + if 138 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + default: + goto st142 + } + goto tr2 + st165: + if p++; p == pe { + goto _test_eof165 + } + st_case_165: + switch data[p] { + case 160: + goto st166 + case 161: + goto st167 + case 162: + goto st168 + case 163: + goto st169 + case 164: + goto st170 + case 165: + goto st171 + case 166: + goto st172 + case 167: + goto st173 + case 168: + goto st174 + case 169: + goto st175 + case 170: + goto st176 + case 171: + goto st177 + case 172: + goto st178 + case 173: + goto st179 + case 174: + goto st180 + case 175: + goto st181 + case 176: + goto st182 + case 177: + goto st183 + case 178: + goto st184 + case 179: + goto st185 + case 180: + goto st186 + case 181: + goto st187 + case 182: + goto st188 + case 183: + goto st189 + case 184: + goto st190 + case 185: + goto st191 + case 186: + goto st192 + case 187: + goto st193 + case 188: + goto st194 + case 189: + goto st195 + case 190: + goto st196 + case 191: + goto st197 + } + goto tr2 + st166: + if p++; p == pe { + goto _test_eof166 + } + st_case_166: + switch data[p] { + case 154: + goto tr148 + case 164: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] > 149: + if 150 <= data[p] && data[p] <= 173 { + goto st142 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st167: + if p++; p == pe { + goto _test_eof167 + } + st_case_167: + switch { + case data[p] > 152: + if 153 <= data[p] && data[p] <= 155 { + goto st142 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st168: + if p++; p == pe { + goto _test_eof168 + } + st_case_168: + if 160 <= data[p] && data[p] <= 180 { + goto tr148 + } + goto tr2 + st169: + if p++; p == pe { + goto _test_eof169 + } + st_case_169: + if 163 <= data[p] { + goto st142 + } + goto tr2 + st170: + if p++; p == pe { + goto _test_eof170 + } + st_case_170: + if data[p] == 189 { + goto tr148 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr148 + } + goto st142 + st171: + if p++; p == pe { + goto _test_eof171 + } + st_case_171: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 176: + if 177 <= data[p] { + goto tr148 + } + default: + goto tr2 + } + goto st142 + st172: + if p++; p == pe { + goto _test_eof172 + } + st_case_172: + switch data[p] { + case 132: + goto tr2 + case 169: + goto tr2 + case 177: + goto tr2 + case 188: + goto st142 + } + switch { + case data[p] < 145: + switch { + case data[p] > 131: + if 141 <= data[p] && data[p] <= 142 { + goto tr2 + } + case data[p] >= 129: + goto st142 + } + case data[p] > 146: + switch { + case data[p] < 186: + if 179 <= data[p] && data[p] <= 181 { + goto tr2 + } + case data[p] > 187: + if 190 <= data[p] { + goto st142 + } + default: + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st173: + if p++; p == pe { + goto _test_eof173 + } + st_case_173: + switch data[p] { + case 142: + goto tr148 + case 158: + goto tr2 + } + switch { + case data[p] < 152: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr2 + } + case data[p] > 138: + if 143 <= data[p] && data[p] <= 150 { + goto tr2 + } + default: + goto tr2 + } + case data[p] > 155: + switch { + case data[p] < 164: + if 156 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr2 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr2 + } + default: + goto tr2 + } + goto st142 + st174: + if p++; p == pe { + goto _test_eof174 + } + st_case_174: + if data[p] == 188 { + goto st142 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto st142 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto st142 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st175: + if p++; p == pe { + goto _test_eof175 + } + st_case_175: + if data[p] == 157 { + goto tr2 + } + switch { + case data[p] < 146: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr2 + } + case data[p] > 138: + if 142 <= data[p] && data[p] <= 144 { + goto tr2 + } + default: + goto tr2 + } + case data[p] > 152: + switch { + case data[p] < 159: + if 153 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr2 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr2 + } + default: + goto tr2 + } + goto st142 + st176: + if p++; p == pe { + goto _test_eof176 + } + st_case_176: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto st142 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto st142 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st177: + if p++; p == pe { + goto _test_eof177 + } + st_case_177: + switch data[p] { + case 134: + goto tr2 + case 138: + goto tr2 + case 144: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 160: + if 142 <= data[p] && data[p] <= 159 { + goto tr2 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr2 + } + default: + goto tr148 + } + goto st142 + st178: + if p++; p == pe { + goto _test_eof178 + } + st_case_178: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto st142 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto st142 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st179: + if p++; p == pe { + goto _test_eof179 + } + st_case_179: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto st142 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto st142 + } + default: + goto st142 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 161: + if 162 <= data[p] && data[p] <= 163 { + goto st142 + } + default: + goto tr148 + } + default: + goto st142 + } + goto tr2 + st180: + if p++; p == pe { + goto _test_eof180 + } + st_case_180: + switch data[p] { + case 130: + goto st142 + case 131: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 158: + switch { + case data[p] < 142: + if 133 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 149: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] < 168: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto st142 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st181: + if p++; p == pe { + goto _test_eof181 + } + st_case_181: + switch data[p] { + case 144: + goto tr148 + case 151: + goto st142 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto st142 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto st142 + } + default: + goto st142 + } + goto tr2 + st182: + if p++; p == pe { + goto _test_eof182 + } + st_case_182: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto st142 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 190 <= data[p] { + goto st142 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st183: + if p++; p == pe { + goto _test_eof183 + } + st_case_183: + switch data[p] { + case 133: + goto tr2 + case 137: + goto tr2 + case 151: + goto tr2 + } + switch { + case data[p] < 155: + switch { + case data[p] > 148: + if 152 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 142: + goto tr2 + } + case data[p] > 159: + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr2 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr2 + } + goto st142 + st184: + if p++; p == pe { + goto _test_eof184 + } + st_case_184: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto st142 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto st142 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st185: + if p++; p == pe { + goto _test_eof185 + } + st_case_185: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto st142 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto st142 + } + default: + goto st142 + } + case data[p] > 150: + switch { + case data[p] < 162: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 163: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + default: + goto st142 + } + default: + goto st142 + } + goto tr2 + st186: + if p++; p == pe { + goto _test_eof186 + } + st_case_186: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto st142 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto st142 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st187: + if p++; p == pe { + goto _test_eof187 + } + st_case_187: + switch data[p] { + case 133: + goto tr2 + case 137: + goto tr2 + case 142: + goto tr148 + } + switch { + case data[p] < 159: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 158 { + goto tr2 + } + case data[p] >= 143: + goto tr2 + } + case data[p] > 161: + switch { + case data[p] < 186: + if 164 <= data[p] && data[p] <= 185 { + goto tr2 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr2 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto st142 + st188: + if p++; p == pe { + goto _test_eof188 + } + st_case_188: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto st142 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st189: + if p++; p == pe { + goto _test_eof189 + } + st_case_189: + switch data[p] { + case 138: + goto st142 + case 150: + goto st142 + } + switch { + case data[p] < 143: + if 128 <= data[p] && data[p] <= 134 { + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 159: + if 178 <= data[p] && data[p] <= 179 { + goto st142 + } + case data[p] >= 152: + goto st142 + } + default: + goto st142 + } + goto tr2 + st190: + if p++; p == pe { + goto _test_eof190 + } + st_case_190: + if data[p] == 177 { + goto st142 + } + if 180 <= data[p] && data[p] <= 186 { + goto st142 + } + goto tr2 + st191: + if p++; p == pe { + goto _test_eof191 + } + st_case_191: + if 135 <= data[p] && data[p] <= 142 { + goto st142 + } + goto tr2 + st192: + if p++; p == pe { + goto _test_eof192 + } + st_case_192: + if data[p] == 177 { + goto st142 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto st142 + } + case data[p] >= 180: + goto st142 + } + goto tr2 + st193: + if p++; p == pe { + goto _test_eof193 + } + st_case_193: + if 136 <= data[p] && data[p] <= 141 { + goto st142 + } + goto tr2 + st194: + if p++; p == pe { + goto _test_eof194 + } + st_case_194: + switch data[p] { + case 128: + goto tr148 + case 181: + goto st142 + case 183: + goto st142 + case 185: + goto st142 + } + switch { + case data[p] > 153: + if 190 <= data[p] && data[p] <= 191 { + goto st142 + } + case data[p] >= 152: + goto st142 + } + goto tr2 + st195: + if p++; p == pe { + goto _test_eof195 + } + st_case_195: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto st142 + } + default: + goto tr148 + } + goto tr2 + st196: + if p++; p == pe { + goto _test_eof196 + } + st_case_196: + switch { + case data[p] < 136: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 135 { + goto st142 + } + case data[p] >= 128: + goto st142 + } + case data[p] > 140: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto st142 + } + case data[p] >= 141: + goto st142 + } + default: + goto tr148 + } + goto tr2 + st197: + if p++; p == pe { + goto _test_eof197 + } + st_case_197: + if data[p] == 134 { + goto st142 + } + goto tr2 + st198: + if p++; p == pe { + goto _test_eof198 + } + st_case_198: + switch data[p] { + case 128: + goto st199 + case 129: + goto st200 + case 130: + goto st201 + case 131: + goto st202 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st207 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st214 + case 157: + goto st215 + case 158: + goto st216 + case 159: + goto st217 + case 160: + goto st218 + case 161: + goto st219 + case 162: + goto st220 + case 163: + goto st221 + case 164: + goto st222 + case 168: + goto st223 + case 169: + goto st224 + case 170: + goto st225 + case 172: + goto st226 + case 173: + goto st227 + case 174: + goto st228 + case 175: + goto st229 + case 176: + goto st230 + case 177: + goto st231 + case 179: + goto st232 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st233 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + } + switch { + case data[p] < 180: + if 132 <= data[p] && data[p] <= 152 { + goto st145 + } + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + default: + goto st147 + } + goto tr2 + st199: + if p++; p == pe { + goto _test_eof199 + } + st_case_199: + if 171 <= data[p] && data[p] <= 190 { + goto st142 + } + goto tr2 + st200: + if p++; p == pe { + goto _test_eof200 + } + st_case_200: + switch { + case data[p] < 162: + switch { + case data[p] > 153: + if 158 <= data[p] && data[p] <= 160 { + goto st142 + } + case data[p] >= 150: + goto st142 + } + case data[p] > 164: + switch { + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto st142 + } + case data[p] >= 167: + goto st142 + } + default: + goto st142 + } + goto tr2 + st201: + if p++; p == pe { + goto _test_eof201 + } + st_case_201: + if data[p] == 143 { + goto st142 + } + switch { + case data[p] < 154: + if 130 <= data[p] && data[p] <= 141 { + goto st142 + } + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + default: + goto st142 + } + goto tr2 + st202: + if p++; p == pe { + goto _test_eof202 + } + st_case_202: + switch data[p] { + case 134: + goto tr2 + case 187: + goto tr2 + } + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 143 { + goto tr2 + } + case data[p] >= 136: + goto tr2 + } + goto tr148 + st203: + if p++; p == pe { + goto _test_eof203 + } + st_case_203: + switch data[p] { + case 137: + goto tr2 + case 151: + goto tr2 + case 153: + goto tr2 + } + switch { + case data[p] > 143: + if 158 <= data[p] && data[p] <= 159 { + goto tr2 + } + case data[p] >= 142: + goto tr2 + } + goto tr148 + st204: + if p++; p == pe { + goto _test_eof204 + } + st_case_204: + switch data[p] { + case 137: + goto tr2 + case 177: + goto tr2 + } + switch { + case data[p] < 182: + if 142 <= data[p] && data[p] <= 143 { + goto tr2 + } + case data[p] > 183: + if 191 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st205: + if p++; p == pe { + goto _test_eof205 + } + st_case_205: + if data[p] == 128 { + goto tr148 + } + switch { + case data[p] < 136: + if 130 <= data[p] && data[p] <= 133 { + goto tr148 + } + case data[p] > 150: + if 152 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st206: + if p++; p == pe { + goto _test_eof206 + } + st_case_206: + if data[p] == 145 { + goto tr2 + } + if 150 <= data[p] && data[p] <= 151 { + goto tr2 + } + goto tr148 + st207: + if p++; p == pe { + goto _test_eof207 + } + st_case_207: + switch { + case data[p] < 157: + if 155 <= data[p] && data[p] <= 156 { + goto tr2 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr2 + } + default: + goto st142 + } + goto tr148 + st208: + if p++; p == pe { + goto _test_eof208 + } + st_case_208: + switch { + case data[p] > 143: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st209: + if p++; p == pe { + goto _test_eof209 + } + st_case_209: + switch { + case data[p] > 183: + if 190 <= data[p] { + goto tr2 + } + case data[p] >= 182: + goto tr2 + } + goto tr148 + st210: + if p++; p == pe { + goto _test_eof210 + } + st_case_210: + if 129 <= data[p] { + goto tr148 + } + goto tr2 + st211: + if p++; p == pe { + goto _test_eof211 + } + st_case_211: + switch { + case data[p] > 174: + if 192 <= data[p] { + goto tr2 + } + case data[p] >= 173: + goto tr2 + } + goto tr148 + st212: + if p++; p == pe { + goto _test_eof212 + } + st_case_212: + switch { + case data[p] > 154: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 129: + goto tr148 + } + goto tr2 + st213: + if p++; p == pe { + goto _test_eof213 + } + st_case_213: + switch { + case data[p] > 173: + if 185 <= data[p] { + goto tr2 + } + case data[p] >= 171: + goto tr2 + } + goto tr148 + st214: + if p++; p == pe { + goto _test_eof214 + } + st_case_214: + switch { + case data[p] < 146: + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 177: + if 178 <= data[p] && data[p] <= 180 { + goto st142 + } + case data[p] >= 160: + goto tr148 + } + default: + goto st142 + } + goto tr2 + st215: + if p++; p == pe { + goto _test_eof215 + } + st_case_215: + switch { + case data[p] < 160: + switch { + case data[p] > 145: + if 146 <= data[p] && data[p] <= 147 { + goto st142 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto st142 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st216: + if p++; p == pe { + goto _test_eof216 + } + st_case_216: + if 180 <= data[p] { + goto st142 + } + goto tr2 + st217: + if p++; p == pe { + goto _test_eof217 + } + st_case_217: + switch { + case data[p] > 156: + if 158 <= data[p] { + goto tr2 + } + case data[p] >= 148: + goto tr2 + } + goto st142 + st218: + if p++; p == pe { + goto _test_eof218 + } + st_case_218: + switch { + case data[p] > 142: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto st142 + } + goto tr2 + st219: + if p++; p == pe { + goto _test_eof219 + } + st_case_219: + if 184 <= data[p] { + goto tr2 + } + goto tr148 + st220: + if p++; p == pe { + goto _test_eof220 + } + st_case_220: + if data[p] == 169 { + goto st142 + } + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st221: + if p++; p == pe { + goto _test_eof221 + } + st_case_221: + if 182 <= data[p] { + goto tr2 + } + goto tr148 + st222: + if p++; p == pe { + goto _test_eof222 + } + st_case_222: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto st142 + } + default: + goto st142 + } + goto tr2 + st223: + if p++; p == pe { + goto _test_eof223 + } + st_case_223: + switch { + case data[p] > 150: + if 151 <= data[p] && data[p] <= 155 { + goto st142 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st224: + if p++; p == pe { + goto _test_eof224 + } + st_case_224: + if data[p] == 191 { + goto st142 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto st142 + } + case data[p] >= 149: + goto st142 + } + goto tr2 + st225: + if p++; p == pe { + goto _test_eof225 + } + st_case_225: + if 176 <= data[p] && data[p] <= 190 { + goto st142 + } + goto tr2 + st226: + if p++; p == pe { + goto _test_eof226 + } + st_case_226: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 132 { + goto st142 + } + case data[p] > 179: + if 180 <= data[p] { + goto st142 + } + default: + goto tr148 + } + goto tr2 + st227: + if p++; p == pe { + goto _test_eof227 + } + st_case_227: + switch { + case data[p] < 140: + if 133 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 170: + if 180 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto st142 + st228: + if p++; p == pe { + goto _test_eof228 + } + st_case_228: + switch { + case data[p] < 161: + switch { + case data[p] > 130: + if 131 <= data[p] && data[p] <= 160 { + goto tr148 + } + case data[p] >= 128: + goto st142 + } + case data[p] > 173: + switch { + case data[p] > 175: + if 186 <= data[p] { + goto tr148 + } + case data[p] >= 174: + goto tr148 + } + default: + goto st142 + } + goto tr2 + st229: + if p++; p == pe { + goto _test_eof229 + } + st_case_229: + switch { + case data[p] > 179: + if 180 <= data[p] { + goto tr2 + } + case data[p] >= 166: + goto st142 + } + goto tr148 + st230: + if p++; p == pe { + goto _test_eof230 + } + st_case_230: + switch { + case data[p] > 163: + if 164 <= data[p] && data[p] <= 183 { + goto st142 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st231: + if p++; p == pe { + goto _test_eof231 + } + st_case_231: + switch { + case data[p] > 143: + if 154 <= data[p] && data[p] <= 189 { + goto tr148 + } + case data[p] >= 141: + goto tr148 + } + goto tr2 + st232: + if p++; p == pe { + goto _test_eof232 + } + st_case_232: + if data[p] == 173 { + goto st142 + } + switch { + case data[p] < 169: + switch { + case data[p] > 146: + if 148 <= data[p] && data[p] <= 168 { + goto st142 + } + case data[p] >= 144: + goto st142 + } + case data[p] > 177: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 180 { + goto st142 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto st142 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st233: + if p++; p == pe { + goto _test_eof233 + } + st_case_233: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto st142 + } + case data[p] >= 128: + goto st142 + } + goto tr2 + st234: + if p++; p == pe { + goto _test_eof234 + } + st_case_234: + switch { + case data[p] > 151: + if 158 <= data[p] && data[p] <= 159 { + goto tr2 + } + case data[p] >= 150: + goto tr2 + } + goto tr148 + st235: + if p++; p == pe { + goto _test_eof235 + } + st_case_235: + switch data[p] { + case 152: + goto tr2 + case 154: + goto tr2 + case 156: + goto tr2 + case 158: + goto tr2 + } + switch { + case data[p] < 142: + if 134 <= data[p] && data[p] <= 135 { + goto tr2 + } + case data[p] > 143: + if 190 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st236: + if p++; p == pe { + goto _test_eof236 + } + st_case_236: + if data[p] == 190 { + goto tr148 + } + switch { + case data[p] > 180: + if 182 <= data[p] && data[p] <= 188 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st237: + if p++; p == pe { + goto _test_eof237 + } + st_case_237: + switch { + case data[p] < 150: + switch { + case data[p] < 134: + if 130 <= data[p] && data[p] <= 132 { + goto tr148 + } + case data[p] > 140: + if 144 <= data[p] && data[p] <= 147 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 155: + switch { + case data[p] < 178: + if 160 <= data[p] && data[p] <= 172 { + goto tr148 + } + case data[p] > 180: + if 182 <= data[p] && data[p] <= 188 { + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st238: + if p++; p == pe { + goto _test_eof238 + } + st_case_238: + switch data[p] { + case 128: + goto st239 + case 129: + goto st240 + case 130: + goto st241 + case 131: + goto st242 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st250 + case 180: + goto st251 + case 181: + goto st252 + case 182: + goto st253 + case 183: + goto st254 + case 184: + goto st255 + } + goto tr2 + st239: + if p++; p == pe { + goto _test_eof239 + } + st_case_239: + switch { + case data[p] > 143: + if 170 <= data[p] && data[p] <= 174 { + goto st142 + } + case data[p] >= 140: + goto st142 + } + goto tr2 + st240: + if p++; p == pe { + goto _test_eof240 + } + st_case_240: + switch data[p] { + case 177: + goto tr148 + case 191: + goto tr148 + } + switch { + case data[p] > 164: + if 166 <= data[p] && data[p] <= 175 { + goto st142 + } + case data[p] >= 160: + goto st142 + } + goto tr2 + st241: + if p++; p == pe { + goto _test_eof241 + } + st_case_241: + if 144 <= data[p] && data[p] <= 156 { + goto tr148 + } + goto tr2 + st242: + if p++; p == pe { + goto _test_eof242 + } + st_case_242: + if 144 <= data[p] && data[p] <= 176 { + goto st142 + } + goto tr2 + st243: + if p++; p == pe { + goto _test_eof243 + } + st_case_243: + switch data[p] { + case 130: + goto tr148 + case 135: + goto tr148 + case 149: + goto tr148 + case 164: + goto tr148 + case 166: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] < 170: + switch { + case data[p] > 147: + if 153 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] >= 138: + goto tr148 + } + case data[p] > 173: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr148 + } + case data[p] >= 175: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st244: + if p++; p == pe { + goto _test_eof244 + } + st_case_244: + if data[p] == 142 { + goto tr148 + } + switch { + case data[p] > 137: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 133: + goto tr148 + } + goto tr2 + st245: + if p++; p == pe { + goto _test_eof245 + } + st_case_245: + if 137 <= data[p] { + goto tr2 + } + goto tr148 + st246: + if p++; p == pe { + goto _test_eof246 + } + st_case_246: + if 182 <= data[p] { + goto tr148 + } + goto tr2 + st247: + if p++; p == pe { + goto _test_eof247 + } + st_case_247: + if 170 <= data[p] { + goto tr2 + } + goto tr148 + st248: + if p++; p == pe { + goto _test_eof248 + } + st_case_248: + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st249: + if p++; p == pe { + goto _test_eof249 + } + st_case_249: + if data[p] == 159 { + goto tr2 + } + goto tr148 + st250: + if p++; p == pe { + goto _test_eof250 + } + st_case_250: + switch { + case data[p] < 175: + if 165 <= data[p] && data[p] <= 170 { + goto tr2 + } + case data[p] > 177: + if 180 <= data[p] { + goto tr2 + } + default: + goto st142 + } + goto tr148 + st251: + if p++; p == pe { + goto _test_eof251 + } + st_case_251: + switch data[p] { + case 167: + goto tr148 + case 173: + goto tr148 + } + switch { + case data[p] > 165: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st252: + if p++; p == pe { + goto _test_eof252 + } + st_case_252: + if data[p] == 191 { + goto st142 + } + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr2 + } + case data[p] >= 168: + goto tr2 + } + goto tr148 + st253: + if p++; p == pe { + goto _test_eof253 + } + st_case_253: + switch { + case data[p] < 168: + switch { + case data[p] > 150: + if 160 <= data[p] && data[p] <= 166 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 174: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 190 { + goto tr148 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st254: + if p++; p == pe { + goto _test_eof254 + } + st_case_254: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto st142 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st255: + if p++; p == pe { + goto _test_eof255 + } + st_case_255: + if data[p] == 175 { + goto tr148 + } + goto tr2 + st256: + if p++; p == pe { + goto _test_eof256 + } + st_case_256: + switch data[p] { + case 128: + goto st257 + case 130: + goto st258 + case 132: + goto st259 + case 133: + goto st145 + case 134: + goto st260 + } + goto tr2 + st257: + if p++; p == pe { + goto _test_eof257 + } + st_case_257: + if data[p] == 133 { + goto tr148 + } + switch { + case data[p] > 175: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + case data[p] >= 170: + goto st142 + } + goto tr2 + st258: + if p++; p == pe { + goto _test_eof258 + } + st_case_258: + if 153 <= data[p] && data[p] <= 154 { + goto st142 + } + goto tr2 + st259: + if p++; p == pe { + goto _test_eof259 + } + st_case_259: + switch { + case data[p] > 173: + if 177 <= data[p] { + goto tr148 + } + case data[p] >= 133: + goto tr148 + } + goto tr2 + st260: + if p++; p == pe { + goto _test_eof260 + } + st_case_260: + switch { + case data[p] > 159: + if 187 <= data[p] { + goto tr2 + } + case data[p] >= 143: + goto tr2 + } + goto tr148 + st261: + if p++; p == pe { + goto _test_eof261 + } + st_case_261: + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st264 + case 153: + goto st265 + case 154: + goto st266 + case 155: + goto st267 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st271 + case 161: + goto st272 + case 162: + goto st273 + case 163: + goto st274 + case 164: + goto st275 + case 165: + goto st276 + case 166: + goto st277 + case 167: + goto st278 + case 168: + goto st279 + case 169: + goto st280 + case 170: + goto st281 + case 171: + goto st282 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st285 + case 176: + goto st147 + } + if 129 <= data[p] { + goto st145 + } + goto tr2 + st262: + if p++; p == pe { + goto _test_eof262 + } + st_case_262: + if 141 <= data[p] { + goto tr2 + } + goto tr148 + st263: + if p++; p == pe { + goto _test_eof263 + } + st_case_263: + if 144 <= data[p] && data[p] <= 189 { + goto tr148 + } + goto tr2 + st264: + if p++; p == pe { + goto _test_eof264 + } + st_case_264: + switch { + case data[p] < 160: + if 141 <= data[p] && data[p] <= 143 { + goto tr2 + } + case data[p] > 169: + if 172 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st265: + if p++; p == pe { + goto _test_eof265 + } + st_case_265: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto st142 + } + default: + goto st142 + } + goto tr2 + st266: + if p++; p == pe { + goto _test_eof266 + } + st_case_266: + switch { + case data[p] < 158: + if 128 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr148 + } + default: + goto st142 + } + goto tr2 + st267: + if p++; p == pe { + goto _test_eof267 + } + st_case_267: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr2 + } + case data[p] >= 176: + goto st142 + } + goto tr148 + st268: + if p++; p == pe { + goto _test_eof268 + } + st_case_268: + switch { + case data[p] > 159: + if 162 <= data[p] { + goto tr148 + } + case data[p] >= 151: + goto tr148 + } + goto tr2 + st269: + if p++; p == pe { + goto _test_eof269 + } + st_case_269: + switch { + case data[p] < 174: + if 137 <= data[p] && data[p] <= 138 { + goto tr2 + } + case data[p] > 175: + if 184 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st270: + if p++; p == pe { + goto _test_eof270 + } + st_case_270: + if 183 <= data[p] { + goto tr148 + } + goto tr2 + st271: + if p++; p == pe { + goto _test_eof271 + } + st_case_271: + switch data[p] { + case 130: + goto st142 + case 134: + goto st142 + case 139: + goto st142 + } + switch { + case data[p] > 167: + if 168 <= data[p] { + goto tr2 + } + case data[p] >= 163: + goto st142 + } + goto tr148 + st272: + if p++; p == pe { + goto _test_eof272 + } + st_case_272: + if 128 <= data[p] && data[p] <= 179 { + goto tr148 + } + goto tr2 + st273: + if p++; p == pe { + goto _test_eof273 + } + st_case_273: + switch { + case data[p] < 130: + if 128 <= data[p] && data[p] <= 129 { + goto st142 + } + case data[p] > 179: + if 180 <= data[p] { + goto st142 + } + default: + goto tr148 + } + goto tr2 + st274: + if p++; p == pe { + goto _test_eof274 + } + st_case_274: + switch data[p] { + case 187: + goto tr148 + case 189: + goto tr148 + } + switch { + case data[p] < 178: + if 133 <= data[p] && data[p] <= 159 { + goto tr2 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr2 + } + default: + goto tr148 + } + goto st142 + st275: + if p++; p == pe { + goto _test_eof275 + } + st_case_275: + switch { + case data[p] < 166: + if 138 <= data[p] && data[p] <= 165 { + goto tr148 + } + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + default: + goto st142 + } + goto tr2 + st276: + if p++; p == pe { + goto _test_eof276 + } + st_case_276: + switch { + case data[p] < 148: + if 135 <= data[p] && data[p] <= 147 { + goto st142 + } + case data[p] > 159: + if 189 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st277: + if p++; p == pe { + goto _test_eof277 + } + st_case_277: + switch { + case data[p] < 132: + if 128 <= data[p] && data[p] <= 131 { + goto st142 + } + case data[p] > 178: + if 179 <= data[p] { + goto st142 + } + default: + goto tr148 + } + goto tr2 + st278: + if p++; p == pe { + goto _test_eof278 + } + st_case_278: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] > 164: + if 166 <= data[p] { + goto tr2 + } + case data[p] >= 129: + goto tr2 + } + goto st142 + st279: + if p++; p == pe { + goto _test_eof279 + } + st_case_279: + switch { + case data[p] > 168: + if 169 <= data[p] && data[p] <= 182 { + goto st142 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st280: + if p++; p == pe { + goto _test_eof280 + } + st_case_280: + if data[p] == 131 { + goto st142 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 141: + if 187 <= data[p] && data[p] <= 189 { + goto st142 + } + default: + goto st142 + } + goto tr2 + st281: + if p++; p == pe { + goto _test_eof281 + } + st_case_281: + if data[p] == 176 { + goto st142 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto st142 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto st142 + } + default: + goto st142 + } + goto tr2 + st282: + if p++; p == pe { + goto _test_eof282 + } + st_case_282: + if data[p] == 129 { + goto st142 + } + switch { + case data[p] < 171: + if 160 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 181 <= data[p] && data[p] <= 182 { + goto st142 + } + case data[p] >= 178: + goto tr148 + } + default: + goto st142 + } + goto tr2 + st283: + if p++; p == pe { + goto _test_eof283 + } + st_case_283: + switch { + case data[p] < 145: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 129: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] < 168: + if 160 <= data[p] && data[p] <= 166 { + goto tr148 + } + case data[p] > 174: + if 176 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st284: + if p++; p == pe { + goto _test_eof284 + } + st_case_284: + if data[p] == 155 { + goto tr2 + } + if 166 <= data[p] && data[p] <= 175 { + goto tr2 + } + goto tr148 + st285: + if p++; p == pe { + goto _test_eof285 + } + st_case_285: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 162 { + goto tr148 + } + case data[p] > 170: + if 172 <= data[p] && data[p] <= 173 { + goto st142 + } + default: + goto st142 + } + goto tr2 + st286: + if p++; p == pe { + goto _test_eof286 + } + st_case_286: + goto st145 + st287: + if p++; p == pe { + goto _test_eof287 + } + st_case_287: + switch data[p] { + case 158: + goto st288 + case 159: + goto st289 + } + if 160 <= data[p] { + goto tr2 + } + goto st145 + st288: + if p++; p == pe { + goto _test_eof288 + } + st_case_288: + if 164 <= data[p] && data[p] <= 175 { + goto tr2 + } + goto tr148 + st289: + if p++; p == pe { + goto _test_eof289 + } + st_case_289: + switch { + case data[p] > 138: + if 188 <= data[p] { + goto tr2 + } + case data[p] >= 135: + goto tr2 + } + goto tr148 + st290: + if p++; p == pe { + goto _test_eof290 + } + st_case_290: + switch data[p] { + case 172: + goto st291 + case 173: + goto st292 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st299 + case 185: + goto st300 + case 187: + goto st301 + case 188: + goto st302 + case 189: + goto st303 + case 190: + goto st304 + case 191: + goto st305 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr2 + st291: + if p++; p == pe { + goto _test_eof291 + } + st_case_291: + switch data[p] { + case 158: + goto st142 + case 190: + goto tr148 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr148 + } + case data[p] >= 170: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st292: + if p++; p == pe { + goto _test_eof292 + } + st_case_292: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 129 { + goto tr148 + } + case data[p] > 132: + if 134 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st293: + if p++; p == pe { + goto _test_eof293 + } + st_case_293: + if 178 <= data[p] { + goto tr2 + } + goto tr148 + st294: + if p++; p == pe { + goto _test_eof294 + } + st_case_294: + if 147 <= data[p] { + goto tr148 + } + goto tr2 + st295: + if p++; p == pe { + goto _test_eof295 + } + st_case_295: + if 190 <= data[p] { + goto tr2 + } + goto tr148 + st296: + if p++; p == pe { + goto _test_eof296 + } + st_case_296: + if 144 <= data[p] { + goto tr148 + } + goto tr2 + st297: + if p++; p == pe { + goto _test_eof297 + } + st_case_297: + if 144 <= data[p] && data[p] <= 145 { + goto tr2 + } + goto tr148 + st298: + if p++; p == pe { + goto _test_eof298 + } + st_case_298: + switch { + case data[p] > 175: + if 188 <= data[p] { + goto tr2 + } + case data[p] >= 136: + goto tr2 + } + goto tr148 + st299: + if p++; p == pe { + goto _test_eof299 + } + st_case_299: + switch { + case data[p] > 143: + if 160 <= data[p] && data[p] <= 175 { + goto st142 + } + case data[p] >= 128: + goto st142 + } + goto tr2 + st300: + if p++; p == pe { + goto _test_eof300 + } + st_case_300: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr148 + } + case data[p] >= 176: + goto tr148 + } + goto tr2 + st301: + if p++; p == pe { + goto _test_eof301 + } + st_case_301: + if data[p] == 191 { + goto st142 + } + if 189 <= data[p] { + goto tr2 + } + goto tr148 + st302: + if p++; p == pe { + goto _test_eof302 + } + st_case_302: + if 161 <= data[p] && data[p] <= 186 { + goto tr148 + } + goto tr2 + st303: + if p++; p == pe { + goto _test_eof303 + } + st_case_303: + if 129 <= data[p] && data[p] <= 154 { + goto tr148 + } + goto tr2 + st304: + if p++; p == pe { + goto _test_eof304 + } + st_case_304: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 190 { + goto tr148 + } + case data[p] >= 158: + goto st142 + } + goto tr2 + st305: + if p++; p == pe { + goto _test_eof305 + } + st_case_305: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] >= 130: + goto tr148 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto st142 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st306: + if p++; p == pe { + goto _test_eof306 + } + st_case_306: + switch data[p] { + case 144: + goto st307 + case 145: + goto st338 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st369 + case 155: + goto st377 + case 157: + goto st380 + case 158: + goto st398 + case 159: + goto st403 + } + goto tr2 + st307: + if p++; p == pe { + goto _test_eof307 + } + st_case_307: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st312 + case 138: + goto st313 + case 139: + goto st314 + case 140: + goto st315 + case 141: + goto st316 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st319 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st330 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st333 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr2 + st308: + if p++; p == pe { + goto _test_eof308 + } + st_case_308: + switch { + case data[p] < 168: + switch { + case data[p] > 139: + if 141 <= data[p] && data[p] <= 166 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 186: + switch { + case data[p] > 189: + if 191 <= data[p] { + goto tr148 + } + case data[p] >= 188: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st309: + if p++; p == pe { + goto _test_eof309 + } + st_case_309: + switch { + case data[p] > 143: + if 158 <= data[p] { + goto tr2 + } + case data[p] >= 142: + goto tr2 + } + goto tr148 + st310: + if p++; p == pe { + goto _test_eof310 + } + st_case_310: + if 187 <= data[p] { + goto tr2 + } + goto tr148 + st311: + if p++; p == pe { + goto _test_eof311 + } + st_case_311: + if 128 <= data[p] && data[p] <= 180 { + goto tr148 + } + goto tr2 + st312: + if p++; p == pe { + goto _test_eof312 + } + st_case_312: + if data[p] == 189 { + goto st142 + } + goto tr2 + st313: + if p++; p == pe { + goto _test_eof313 + } + st_case_313: + switch { + case data[p] > 156: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st314: + if p++; p == pe { + goto _test_eof314 + } + st_case_314: + if data[p] == 160 { + goto st142 + } + if 145 <= data[p] { + goto tr2 + } + goto tr148 + st315: + if p++; p == pe { + goto _test_eof315 + } + st_case_315: + switch { + case data[p] > 159: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st316: + if p++; p == pe { + goto _test_eof316 + } + st_case_316: + switch { + case data[p] < 182: + if 139 <= data[p] && data[p] <= 143 { + goto tr2 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr2 + } + default: + goto st142 + } + goto tr148 + st317: + if p++; p == pe { + goto _test_eof317 + } + st_case_317: + switch { + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st318: + if p++; p == pe { + goto _test_eof318 + } + st_case_318: + if data[p] == 144 { + goto tr2 + } + switch { + case data[p] > 135: + if 150 <= data[p] { + goto tr2 + } + case data[p] >= 132: + goto tr2 + } + goto tr148 + st319: + if p++; p == pe { + goto _test_eof319 + } + st_case_319: + if 158 <= data[p] { + goto tr2 + } + goto tr148 + st320: + if p++; p == pe { + goto _test_eof320 + } + st_case_320: + switch { + case data[p] > 167: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st321: + if p++; p == pe { + goto _test_eof321 + } + st_case_321: + if 164 <= data[p] { + goto tr2 + } + goto tr148 + st322: + if p++; p == pe { + goto _test_eof322 + } + st_case_322: + if 183 <= data[p] { + goto tr2 + } + goto tr148 + st323: + if p++; p == pe { + goto _test_eof323 + } + st_case_323: + switch { + case data[p] > 149: + if 160 <= data[p] && data[p] <= 167 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st324: + if p++; p == pe { + goto _test_eof324 + } + st_case_324: + switch data[p] { + case 136: + goto tr148 + case 188: + goto tr148 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 133 { + goto tr148 + } + case data[p] > 181: + switch { + case data[p] > 184: + if 191 <= data[p] { + goto tr148 + } + case data[p] >= 183: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st325: + if p++; p == pe { + goto _test_eof325 + } + st_case_325: + switch { + case data[p] > 159: + if 183 <= data[p] { + goto tr2 + } + case data[p] >= 150: + goto tr2 + } + goto tr148 + st326: + if p++; p == pe { + goto _test_eof326 + } + st_case_326: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + goto tr2 + st327: + if p++; p == pe { + goto _test_eof327 + } + st_case_327: + switch { + case data[p] > 178: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 160: + goto tr148 + } + goto tr2 + st328: + if p++; p == pe { + goto _test_eof328 + } + st_case_328: + switch { + case data[p] > 149: + if 160 <= data[p] && data[p] <= 185 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st329: + if p++; p == pe { + goto _test_eof329 + } + st_case_329: + switch { + case data[p] > 183: + if 190 <= data[p] && data[p] <= 191 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st330: + if p++; p == pe { + goto _test_eof330 + } + st_case_330: + switch data[p] { + case 128: + goto tr148 + case 191: + goto st142 + } + switch { + case data[p] < 144: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto st142 + } + case data[p] > 134: + if 140 <= data[p] && data[p] <= 143 { + goto st142 + } + default: + goto st142 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto st142 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st331: + if p++; p == pe { + goto _test_eof331 + } + st_case_331: + if 160 <= data[p] && data[p] <= 188 { + goto tr148 + } + goto tr2 + st332: + if p++; p == pe { + goto _test_eof332 + } + st_case_332: + if 128 <= data[p] && data[p] <= 156 { + goto tr148 + } + goto tr2 + st333: + if p++; p == pe { + goto _test_eof333 + } + st_case_333: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 164: + if 165 <= data[p] && data[p] <= 166 { + goto st142 + } + default: + goto tr148 + } + goto tr2 + st334: + if p++; p == pe { + goto _test_eof334 + } + st_case_334: + if 128 <= data[p] && data[p] <= 181 { + goto tr148 + } + goto tr2 + st335: + if p++; p == pe { + goto _test_eof335 + } + st_case_335: + switch { + case data[p] > 149: + if 160 <= data[p] && data[p] <= 178 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st336: + if p++; p == pe { + goto _test_eof336 + } + st_case_336: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + goto tr2 + st337: + if p++; p == pe { + goto _test_eof337 + } + st_case_337: + if 128 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr2 + st338: + if p++; p == pe { + goto _test_eof338 + } + st_case_338: + switch data[p] { + case 128: + goto st339 + case 129: + goto st340 + case 130: + goto st341 + case 131: + goto st342 + case 132: + goto st343 + case 133: + goto st344 + case 134: + goto st345 + case 135: + goto st346 + case 136: + goto st347 + case 138: + goto st348 + case 139: + goto st349 + case 140: + goto st350 + case 141: + goto st351 + case 146: + goto st352 + case 147: + goto st353 + case 150: + goto st354 + case 151: + goto st355 + case 152: + goto st352 + case 153: + goto st356 + case 154: + goto st357 + case 156: + goto st358 + case 162: + goto st359 + case 163: + goto st360 + case 171: + goto st361 + } + goto tr2 + st339: + if p++; p == pe { + goto _test_eof339 + } + st_case_339: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto st142 + } + case data[p] > 183: + if 184 <= data[p] { + goto st142 + } + default: + goto tr148 + } + goto tr2 + st340: + if p++; p == pe { + goto _test_eof340 + } + st_case_340: + if 135 <= data[p] && data[p] <= 190 { + goto tr2 + } + goto st142 + st341: + if p++; p == pe { + goto _test_eof341 + } + st_case_341: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto st142 + st342: + if p++; p == pe { + goto _test_eof342 + } + st_case_342: + if 144 <= data[p] && data[p] <= 168 { + goto tr148 + } + goto tr2 + st343: + if p++; p == pe { + goto _test_eof343 + } + st_case_343: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto st142 + } + case data[p] > 166: + if 167 <= data[p] && data[p] <= 180 { + goto st142 + } + default: + goto tr148 + } + goto tr2 + st344: + if p++; p == pe { + goto _test_eof344 + } + st_case_344: + switch data[p] { + case 179: + goto st142 + case 182: + goto tr148 + } + if 144 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr2 + st345: + if p++; p == pe { + goto _test_eof345 + } + st_case_345: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto st142 + } + case data[p] > 178: + if 179 <= data[p] { + goto st142 + } + default: + goto tr148 + } + goto tr2 + st346: + if p++; p == pe { + goto _test_eof346 + } + st_case_346: + switch data[p] { + case 154: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 132 { + goto tr148 + } + case data[p] > 137: + if 141 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto st142 + st347: + if p++; p == pe { + goto _test_eof347 + } + st_case_347: + switch { + case data[p] < 147: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] > 171: + if 172 <= data[p] && data[p] <= 183 { + goto st142 + } + default: + goto tr148 + } + goto tr2 + st348: + if p++; p == pe { + goto _test_eof348 + } + st_case_348: + if data[p] == 136 { + goto tr148 + } + switch { + case data[p] < 143: + switch { + case data[p] > 134: + if 138 <= data[p] && data[p] <= 141 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 157: + switch { + case data[p] > 168: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 159: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st349: + if p++; p == pe { + goto _test_eof349 + } + st_case_349: + switch { + case data[p] > 170: + if 171 <= data[p] { + goto tr2 + } + case data[p] >= 159: + goto st142 + } + goto tr148 + st350: + if p++; p == pe { + goto _test_eof350 + } + st_case_350: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto st142 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto st142 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st351: + if p++; p == pe { + goto _test_eof351 + } + st_case_351: + switch data[p] { + case 144: + goto tr148 + case 151: + goto st142 + } + switch { + case data[p] < 157: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto st142 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto st142 + } + default: + goto st142 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto st142 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto st142 + } + default: + goto st142 + } + default: + goto tr148 + } + goto tr2 + st352: + if p++; p == pe { + goto _test_eof352 + } + st_case_352: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto st142 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st353: + if p++; p == pe { + goto _test_eof353 + } + st_case_353: + if data[p] == 134 { + goto tr2 + } + switch { + case data[p] > 135: + if 136 <= data[p] { + goto tr2 + } + case data[p] >= 132: + goto tr148 + } + goto st142 + st354: + if p++; p == pe { + goto _test_eof354 + } + st_case_354: + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 181: + if 184 <= data[p] { + goto st142 + } + default: + goto st142 + } + goto tr2 + st355: + if p++; p == pe { + goto _test_eof355 + } + st_case_355: + switch { + case data[p] < 152: + if 129 <= data[p] && data[p] <= 151 { + goto tr2 + } + case data[p] > 155: + if 158 <= data[p] { + goto tr2 + } + default: + goto tr148 + } + goto st142 + st356: + if p++; p == pe { + goto _test_eof356 + } + st_case_356: + if data[p] == 132 { + goto tr148 + } + if 129 <= data[p] { + goto tr2 + } + goto st142 + st357: + if p++; p == pe { + goto _test_eof357 + } + st_case_357: + switch { + case data[p] > 170: + if 171 <= data[p] && data[p] <= 183 { + goto st142 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st358: + if p++; p == pe { + goto _test_eof358 + } + st_case_358: + if 157 <= data[p] && data[p] <= 171 { + goto st142 + } + goto tr2 + st359: + if p++; p == pe { + goto _test_eof359 + } + st_case_359: + if 160 <= data[p] { + goto tr148 + } + goto tr2 + st360: + if p++; p == pe { + goto _test_eof360 + } + st_case_360: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr2 + } + case data[p] >= 160: + goto tr2 + } + goto tr148 + st361: + if p++; p == pe { + goto _test_eof361 + } + st_case_361: + if 128 <= data[p] && data[p] <= 184 { + goto tr148 + } + goto tr2 + st362: + if p++; p == pe { + goto _test_eof362 + } + st_case_362: + switch data[p] { + case 128: + goto st147 + case 142: + goto st363 + case 145: + goto st364 + case 149: + goto st365 + } + switch { + case data[p] < 144: + if 129 <= data[p] && data[p] <= 141 { + goto st145 + } + case data[p] > 146: + if 147 <= data[p] && data[p] <= 148 { + goto st145 + } + default: + goto st147 + } + goto tr2 + st363: + if p++; p == pe { + goto _test_eof363 + } + st_case_363: + if 154 <= data[p] { + goto tr2 + } + goto tr148 + st364: + if p++; p == pe { + goto _test_eof364 + } + st_case_364: + if 175 <= data[p] { + goto tr2 + } + goto tr148 + st365: + if p++; p == pe { + goto _test_eof365 + } + st_case_365: + if 132 <= data[p] { + goto tr2 + } + goto tr148 + st366: + if p++; p == pe { + goto _test_eof366 + } + st_case_366: + switch data[p] { + case 128: + goto st147 + case 144: + goto st364 + } + if 129 <= data[p] && data[p] <= 143 { + goto st145 + } + goto tr2 + st367: + if p++; p == pe { + goto _test_eof367 + } + st_case_367: + switch data[p] { + case 144: + goto st147 + case 153: + goto st368 + } + if 145 <= data[p] && data[p] <= 152 { + goto st145 + } + goto tr2 + st368: + if p++; p == pe { + goto _test_eof368 + } + st_case_368: + if 135 <= data[p] { + goto tr2 + } + goto tr148 + st369: + if p++; p == pe { + goto _test_eof369 + } + st_case_369: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st326 + case 171: + goto st371 + case 172: + goto st372 + case 173: + goto st373 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st375 + case 190: + goto st376 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr2 + st370: + if p++; p == pe { + goto _test_eof370 + } + st_case_370: + if 185 <= data[p] { + goto tr2 + } + goto tr148 + st371: + if p++; p == pe { + goto _test_eof371 + } + st_case_371: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto st142 + } + case data[p] >= 144: + goto tr148 + } + goto tr2 + st372: + if p++; p == pe { + goto _test_eof372 + } + st_case_372: + switch { + case data[p] > 175: + if 176 <= data[p] && data[p] <= 182 { + goto st142 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st373: + if p++; p == pe { + goto _test_eof373 + } + st_case_373: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 131 { + goto tr148 + } + case data[p] > 183: + if 189 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st374: + if p++; p == pe { + goto _test_eof374 + } + st_case_374: + if 144 <= data[p] { + goto tr2 + } + goto tr148 + st375: + if p++; p == pe { + goto _test_eof375 + } + st_case_375: + switch { + case data[p] < 145: + if 133 <= data[p] && data[p] <= 143 { + goto tr2 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr2 + } + default: + goto st142 + } + goto tr148 + st376: + if p++; p == pe { + goto _test_eof376 + } + st_case_376: + switch { + case data[p] > 146: + if 147 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 143: + goto st142 + } + goto tr2 + st377: + if p++; p == pe { + goto _test_eof377 + } + st_case_377: + switch data[p] { + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st379 + } + goto tr2 + st378: + if p++; p == pe { + goto _test_eof378 + } + st_case_378: + switch { + case data[p] > 175: + if 189 <= data[p] { + goto tr2 + } + case data[p] >= 171: + goto tr2 + } + goto tr148 + st379: + if p++; p == pe { + goto _test_eof379 + } + st_case_379: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto st142 + } + case data[p] >= 157: + goto st142 + } + default: + goto tr148 + } + goto tr2 + st380: + if p++; p == pe { + goto _test_eof380 + } + st_case_380: + switch data[p] { + case 133: + goto st381 + case 134: + goto st382 + case 137: + goto st383 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st394 + case 168: + goto st395 + case 169: + goto st396 + case 170: + goto st397 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr2 + st381: + if p++; p == pe { + goto _test_eof381 + } + st_case_381: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto st142 + } + case data[p] >= 165: + goto st142 + } + goto tr2 + st382: + if p++; p == pe { + goto _test_eof382 + } + st_case_382: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr2 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto st142 + st383: + if p++; p == pe { + goto _test_eof383 + } + st_case_383: + if 130 <= data[p] && data[p] <= 132 { + goto st142 + } + goto tr2 + st384: + if p++; p == pe { + goto _test_eof384 + } + st_case_384: + if data[p] == 149 { + goto tr2 + } + goto tr148 + st385: + if p++; p == pe { + goto _test_eof385 + } + st_case_385: + switch data[p] { + case 157: + goto tr2 + case 173: + goto tr2 + case 186: + goto tr2 + case 188: + goto tr2 + } + switch { + case data[p] < 163: + if 160 <= data[p] && data[p] <= 161 { + goto tr2 + } + case data[p] > 164: + if 167 <= data[p] && data[p] <= 168 { + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st386: + if p++; p == pe { + goto _test_eof386 + } + st_case_386: + if data[p] == 132 { + goto tr2 + } + goto tr148 + st387: + if p++; p == pe { + goto _test_eof387 + } + st_case_387: + switch data[p] { + case 134: + goto tr2 + case 149: + goto tr2 + case 157: + goto tr2 + case 186: + goto tr2 + } + switch { + case data[p] > 140: + if 191 <= data[p] { + goto tr2 + } + case data[p] >= 139: + goto tr2 + } + goto tr148 + st388: + if p++; p == pe { + goto _test_eof388 + } + st_case_388: + if data[p] == 134 { + goto tr148 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 132 { + goto tr148 + } + case data[p] > 144: + if 146 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st389: + if p++; p == pe { + goto _test_eof389 + } + st_case_389: + if 166 <= data[p] && data[p] <= 167 { + goto tr2 + } + goto tr148 + st390: + if p++; p == pe { + goto _test_eof390 + } + st_case_390: + switch data[p] { + case 129: + goto tr2 + case 155: + goto tr2 + case 187: + goto tr2 + } + goto tr148 + st391: + if p++; p == pe { + goto _test_eof391 + } + st_case_391: + switch data[p] { + case 149: + goto tr2 + case 181: + goto tr2 + } + goto tr148 + st392: + if p++; p == pe { + goto _test_eof392 + } + st_case_392: + switch data[p] { + case 143: + goto tr2 + case 175: + goto tr2 + } + goto tr148 + st393: + if p++; p == pe { + goto _test_eof393 + } + st_case_393: + switch data[p] { + case 137: + goto tr2 + case 169: + goto tr2 + } + goto tr148 + st394: + if p++; p == pe { + goto _test_eof394 + } + st_case_394: + if data[p] == 131 { + goto tr2 + } + if 140 <= data[p] { + goto tr2 + } + goto tr148 + st395: + if p++; p == pe { + goto _test_eof395 + } + st_case_395: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto st142 + } + case data[p] >= 128: + goto st142 + } + goto tr2 + st396: + if p++; p == pe { + goto _test_eof396 + } + st_case_396: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr2 + } + case data[p] >= 173: + goto tr2 + } + goto st142 + st397: + if p++; p == pe { + goto _test_eof397 + } + st_case_397: + if data[p] == 132 { + goto st142 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto st142 + } + case data[p] >= 155: + goto st142 + } + goto tr2 + st398: + if p++; p == pe { + goto _test_eof398 + } + st_case_398: + switch data[p] { + case 160: + goto st147 + case 163: + goto st399 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr2 + st399: + if p++; p == pe { + goto _test_eof399 + } + st_case_399: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr2 + } + case data[p] > 150: + if 151 <= data[p] { + goto tr2 + } + default: + goto st142 + } + goto tr148 + st400: + if p++; p == pe { + goto _test_eof400 + } + st_case_400: + switch data[p] { + case 164: + goto tr148 + case 167: + goto tr148 + case 185: + goto tr148 + case 187: + goto tr148 + } + switch { + case data[p] < 161: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 162: + switch { + case data[p] > 178: + if 180 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] >= 169: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st401: + if p++; p == pe { + goto _test_eof401 + } + st_case_401: + switch data[p] { + case 130: + goto tr148 + case 135: + goto tr148 + case 137: + goto tr148 + case 139: + goto tr148 + case 148: + goto tr148 + case 151: + goto tr148 + case 153: + goto tr148 + case 155: + goto tr148 + case 157: + goto tr148 + case 159: + goto tr148 + case 164: + goto tr148 + case 190: + goto tr148 + } + switch { + case data[p] < 167: + switch { + case data[p] < 145: + if 141 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] > 146: + if 161 <= data[p] && data[p] <= 162 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 170: + switch { + case data[p] < 180: + if 172 <= data[p] && data[p] <= 178 { + goto tr148 + } + case data[p] > 183: + if 185 <= data[p] && data[p] <= 188 { + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st402: + if p++; p == pe { + goto _test_eof402 + } + st_case_402: + switch { + case data[p] < 161: + switch { + case data[p] > 137: + if 139 <= data[p] && data[p] <= 155 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 163: + switch { + case data[p] > 169: + if 171 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 165: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st403: + if p++; p == pe { + goto _test_eof403 + } + st_case_403: + switch data[p] { + case 132: + goto st404 + case 133: + goto st405 + case 134: + goto st406 + } + goto tr2 + st404: + if p++; p == pe { + goto _test_eof404 + } + st_case_404: + if 176 <= data[p] { + goto tr148 + } + goto tr2 + st405: + if p++; p == pe { + goto _test_eof405 + } + st_case_405: + switch { + case data[p] > 143: + if 170 <= data[p] && data[p] <= 175 { + goto tr2 + } + case data[p] >= 138: + goto tr2 + } + goto tr148 + st406: + if p++; p == pe { + goto _test_eof406 + } + st_case_406: + if 138 <= data[p] { + goto tr2 + } + goto tr148 + st407: + if p++; p == pe { + goto _test_eof407 + } + st_case_407: + if data[p] == 160 { + goto st408 + } + goto tr2 + st408: + if p++; p == pe { + goto _test_eof408 + } + st_case_408: + switch data[p] { + case 128: + goto st409 + case 129: + goto st410 + case 132: + goto st149 + case 135: + goto st412 + } + if 133 <= data[p] && data[p] <= 134 { + goto st411 + } + goto tr2 + st409: + if p++; p == pe { + goto _test_eof409 + } + st_case_409: + if data[p] == 129 { + goto st142 + } + if 160 <= data[p] { + goto st142 + } + goto tr2 + st410: + if p++; p == pe { + goto _test_eof410 + } + st_case_410: + if 192 <= data[p] { + goto tr2 + } + goto st142 + st411: + if p++; p == pe { + goto _test_eof411 + } + st_case_411: + goto st142 + st412: + if p++; p == pe { + goto _test_eof412 + } + st_case_412: + if 176 <= data[p] { + goto tr2 + } + goto st142 +tr421: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4868 + st4868: + if p++; p == pe { + goto _test_eof4868 + } + st_case_4868: +//line segment_words_prod.go:19436 + switch data[p] { + case 39: + goto st413 + case 44: + goto st413 + case 46: + goto st413 + case 59: + goto st413 + case 95: + goto tr571 + case 194: + goto st1312 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st148 + case 204: + goto st1313 + case 205: + goto st1314 + case 206: + goto st151 + case 207: + goto st152 + case 210: + goto st1315 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1316 + case 215: + goto st1317 + case 216: + goto st1318 + case 217: + goto st1319 + case 219: + goto st1320 + case 220: + goto st1321 + case 221: + goto st1322 + case 222: + goto st1323 + case 223: + goto st1324 + case 224: + goto st1325 + case 225: + goto st1357 + case 226: + goto st1379 + case 227: + goto st1386 + case 234: + goto st1389 + case 237: + goto st287 + case 239: + goto st1405 + case 240: + goto st1413 + case 243: + goto st1455 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 + st413: + if p++; p == pe { + goto _test_eof413 + } + st_case_413: + switch data[p] { + case 194: + goto st414 + case 204: + goto st415 + case 205: + goto st416 + case 210: + goto st417 + case 214: + goto st418 + case 215: + goto st419 + case 216: + goto st420 + case 217: + goto st421 + case 219: + goto st422 + case 220: + goto st423 + case 221: + goto st424 + case 222: + goto st425 + case 223: + goto st426 + case 224: + goto st427 + case 225: + goto st456 + case 226: + goto st481 + case 227: + goto st488 + case 234: + goto st491 + case 239: + goto st508 + case 240: + goto st512 + case 243: + goto st557 + } + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + goto tr420 + st414: + if p++; p == pe { + goto _test_eof414 + } + st_case_414: + if data[p] == 173 { + goto st413 + } + goto tr420 + st415: + if p++; p == pe { + goto _test_eof415 + } + st_case_415: + if data[p] <= 127 { + goto tr420 + } + goto st413 + st416: + if p++; p == pe { + goto _test_eof416 + } + st_case_416: + if 176 <= data[p] { + goto tr420 + } + goto st413 + st417: + if p++; p == pe { + goto _test_eof417 + } + st_case_417: + if 131 <= data[p] && data[p] <= 137 { + goto st413 + } + goto tr420 + st418: + if p++; p == pe { + goto _test_eof418 + } + st_case_418: + if data[p] == 191 { + goto st413 + } + if 145 <= data[p] && data[p] <= 189 { + goto st413 + } + goto tr420 + st419: + if p++; p == pe { + goto _test_eof419 + } + st_case_419: + if data[p] == 135 { + goto st413 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto st413 + } + case data[p] >= 129: + goto st413 + } + goto tr420 + st420: + if p++; p == pe { + goto _test_eof420 + } + st_case_420: + if data[p] == 156 { + goto st413 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto st413 + } + case data[p] >= 128: + goto st413 + } + goto tr420 + st421: + if p++; p == pe { + goto _test_eof421 + } + st_case_421: + switch data[p] { + case 171: + goto tr421 + case 176: + goto st413 + } + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 169 { + goto tr421 + } + case data[p] >= 139: + goto st413 + } + goto tr420 + st422: + if p++; p == pe { + goto _test_eof422 + } + st_case_422: + switch { + case data[p] < 167: + switch { + case data[p] > 157: + if 159 <= data[p] && data[p] <= 164 { + goto st413 + } + case data[p] >= 150: + goto st413 + } + case data[p] > 168: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 170: + goto st413 + } + default: + goto st413 + } + goto tr420 + st423: + if p++; p == pe { + goto _test_eof423 + } + st_case_423: + switch data[p] { + case 143: + goto st413 + case 145: + goto st413 + } + if 176 <= data[p] { + goto st413 + } + goto tr420 + st424: + if p++; p == pe { + goto _test_eof424 + } + st_case_424: + if 139 <= data[p] { + goto tr420 + } + goto st413 + st425: + if p++; p == pe { + goto _test_eof425 + } + st_case_425: + if 166 <= data[p] && data[p] <= 176 { + goto st413 + } + goto tr420 + st426: + if p++; p == pe { + goto _test_eof426 + } + st_case_426: + switch { + case data[p] > 137: + if 171 <= data[p] && data[p] <= 179 { + goto st413 + } + case data[p] >= 128: + goto tr421 + } + goto tr420 + st427: + if p++; p == pe { + goto _test_eof427 + } + st_case_427: + switch data[p] { + case 160: + goto st428 + case 161: + goto st429 + case 163: + goto st430 + case 164: + goto st431 + case 165: + goto st432 + case 167: + goto st434 + case 169: + goto st435 + case 171: + goto st436 + case 173: + goto st438 + case 174: + goto st439 + case 175: + goto st440 + case 176: + goto st441 + case 177: + goto st442 + case 179: + goto st443 + case 180: + goto st444 + case 181: + goto st445 + case 182: + goto st446 + case 183: + goto st447 + case 184: + goto st448 + case 185: + goto st449 + case 186: + goto st450 + case 187: + goto st451 + case 188: + goto st452 + case 189: + goto st453 + case 190: + goto st454 + case 191: + goto st455 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto st437 + } + case data[p] >= 166: + goto st433 + } + goto tr420 + st428: + if p++; p == pe { + goto _test_eof428 + } + st_case_428: + switch { + case data[p] < 155: + if 150 <= data[p] && data[p] <= 153 { + goto st413 + } + case data[p] > 163: + switch { + case data[p] > 167: + if 169 <= data[p] && data[p] <= 173 { + goto st413 + } + case data[p] >= 165: + goto st413 + } + default: + goto st413 + } + goto tr420 + st429: + if p++; p == pe { + goto _test_eof429 + } + st_case_429: + if 153 <= data[p] && data[p] <= 155 { + goto st413 + } + goto tr420 + st430: + if p++; p == pe { + goto _test_eof430 + } + st_case_430: + if 163 <= data[p] { + goto st413 + } + goto tr420 + st431: + if p++; p == pe { + goto _test_eof431 + } + st_case_431: + if data[p] == 189 { + goto tr420 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr420 + } + goto st413 + st432: + if p++; p == pe { + goto _test_eof432 + } + st_case_432: + if data[p] == 144 { + goto tr420 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr420 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr420 + } + goto st413 + st433: + if p++; p == pe { + goto _test_eof433 + } + st_case_433: + if data[p] == 188 { + goto st413 + } + switch { + case data[p] > 131: + if 190 <= data[p] { + goto st413 + } + case data[p] >= 129: + goto st413 + } + goto tr420 + st434: + if p++; p == pe { + goto _test_eof434 + } + st_case_434: + switch { + case data[p] < 152: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + if 142 <= data[p] && data[p] <= 150 { + goto tr420 + } + default: + goto tr420 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + default: + goto tr420 + } + goto st413 + st435: + if p++; p == pe { + goto _test_eof435 + } + st_case_435: + switch { + case data[p] < 146: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + if 142 <= data[p] && data[p] <= 144 { + goto tr420 + } + default: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] < 178: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto st413 + st436: + if p++; p == pe { + goto _test_eof436 + } + st_case_436: + switch data[p] { + case 134: + goto tr420 + case 138: + goto tr420 + } + switch { + case data[p] < 164: + if 142 <= data[p] && data[p] <= 161 { + goto tr420 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr420 + } + goto st413 + st437: + if p++; p == pe { + goto _test_eof437 + } + st_case_437: + if data[p] == 188 { + goto st413 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto st413 + } + case data[p] >= 129: + goto st413 + } + goto tr420 + st438: + if p++; p == pe { + goto _test_eof438 + } + st_case_438: + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto st413 + } + case data[p] >= 128: + goto st413 + } + case data[p] > 141: + switch { + case data[p] < 162: + if 150 <= data[p] && data[p] <= 151 { + goto st413 + } + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + default: + goto st413 + } + default: + goto st413 + } + goto tr420 + st439: + if p++; p == pe { + goto _test_eof439 + } + st_case_439: + if data[p] == 130 { + goto st413 + } + if 190 <= data[p] && data[p] <= 191 { + goto st413 + } + goto tr420 + st440: + if p++; p == pe { + goto _test_eof440 + } + st_case_440: + if data[p] == 151 { + goto st413 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto st413 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 138: + goto st413 + } + default: + goto st413 + } + goto tr420 + st441: + if p++; p == pe { + goto _test_eof441 + } + st_case_441: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto st413 + } + case data[p] >= 128: + goto st413 + } + goto tr420 + st442: + if p++; p == pe { + goto _test_eof442 + } + st_case_442: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + } + switch { + case data[p] < 164: + switch { + case data[p] > 148: + if 151 <= data[p] && data[p] <= 161 { + goto tr420 + } + case data[p] >= 142: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr420 + } + goto st413 + st443: + if p++; p == pe { + goto _test_eof443 + } + st_case_443: + switch { + case data[p] < 138: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 136 { + goto st413 + } + case data[p] >= 128: + goto st413 + } + case data[p] > 141: + switch { + case data[p] < 162: + if 149 <= data[p] && data[p] <= 150 { + goto st413 + } + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + default: + goto st413 + } + default: + goto st413 + } + goto tr420 + st444: + if p++; p == pe { + goto _test_eof444 + } + st_case_444: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto st413 + } + case data[p] >= 129: + goto st413 + } + goto tr420 + st445: + if p++; p == pe { + goto _test_eof445 + } + st_case_445: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + } + switch { + case data[p] < 164: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 161 { + goto tr420 + } + case data[p] >= 142: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr420 + } + goto st413 + st446: + if p++; p == pe { + goto _test_eof446 + } + st_case_446: + if 130 <= data[p] && data[p] <= 131 { + goto st413 + } + goto tr420 + st447: + if p++; p == pe { + goto _test_eof447 + } + st_case_447: + switch data[p] { + case 138: + goto st413 + case 150: + goto st413 + } + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 148 { + goto st413 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto st413 + } + case data[p] >= 166: + goto tr421 + } + default: + goto st413 + } + goto tr420 + st448: + if p++; p == pe { + goto _test_eof448 + } + st_case_448: + if data[p] == 177 { + goto st413 + } + if 180 <= data[p] && data[p] <= 186 { + goto st413 + } + goto tr420 + st449: + if p++; p == pe { + goto _test_eof449 + } + st_case_449: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 135: + goto st413 + } + goto tr420 + st450: + if p++; p == pe { + goto _test_eof450 + } + st_case_450: + if data[p] == 177 { + goto st413 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto st413 + } + case data[p] >= 180: + goto st413 + } + goto tr420 + st451: + if p++; p == pe { + goto _test_eof451 + } + st_case_451: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 136: + goto st413 + } + goto tr420 + st452: + if p++; p == pe { + goto _test_eof452 + } + st_case_452: + switch data[p] { + case 181: + goto st413 + case 183: + goto st413 + case 185: + goto st413 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto st413 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto st413 + } + default: + goto tr421 + } + goto tr420 + st453: + if p++; p == pe { + goto _test_eof453 + } + st_case_453: + if 177 <= data[p] && data[p] <= 191 { + goto st413 + } + goto tr420 + st454: + if p++; p == pe { + goto _test_eof454 + } + st_case_454: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto st413 + } + case data[p] > 135: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto st413 + } + case data[p] >= 141: + goto st413 + } + default: + goto st413 + } + goto tr420 + st455: + if p++; p == pe { + goto _test_eof455 + } + st_case_455: + if data[p] == 134 { + goto st413 + } + goto tr420 + st456: + if p++; p == pe { + goto _test_eof456 + } + st_case_456: + switch data[p] { + case 128: + goto st457 + case 129: + goto st458 + case 130: + goto st459 + case 141: + goto st460 + case 156: + goto st461 + case 157: + goto st462 + case 158: + goto st463 + case 159: + goto st464 + case 160: + goto st465 + case 162: + goto st466 + case 164: + goto st467 + case 165: + goto st468 + case 167: + goto st469 + case 168: + goto st470 + case 169: + goto st471 + case 170: + goto st472 + case 172: + goto st473 + case 173: + goto st474 + case 174: + goto st475 + case 175: + goto st476 + case 176: + goto st477 + case 177: + goto st478 + case 179: + goto st479 + case 183: + goto st480 + } + goto tr420 + st457: + if p++; p == pe { + goto _test_eof457 + } + st_case_457: + if 171 <= data[p] && data[p] <= 190 { + goto st413 + } + goto tr420 + st458: + if p++; p == pe { + goto _test_eof458 + } + st_case_458: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto st413 + } + case data[p] >= 128: + goto tr421 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto st413 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto st413 + } + default: + goto st413 + } + default: + goto st413 + } + goto tr420 + st459: + if p++; p == pe { + goto _test_eof459 + } + st_case_459: + if data[p] == 143 { + goto st413 + } + switch { + case data[p] < 144: + if 130 <= data[p] && data[p] <= 141 { + goto st413 + } + case data[p] > 153: + if 154 <= data[p] && data[p] <= 157 { + goto st413 + } + default: + goto tr421 + } + goto tr420 + st460: + if p++; p == pe { + goto _test_eof460 + } + st_case_460: + if 157 <= data[p] && data[p] <= 159 { + goto st413 + } + goto tr420 + st461: + if p++; p == pe { + goto _test_eof461 + } + st_case_461: + switch { + case data[p] > 148: + if 178 <= data[p] && data[p] <= 180 { + goto st413 + } + case data[p] >= 146: + goto st413 + } + goto tr420 + st462: + if p++; p == pe { + goto _test_eof462 + } + st_case_462: + switch { + case data[p] > 147: + if 178 <= data[p] && data[p] <= 179 { + goto st413 + } + case data[p] >= 146: + goto st413 + } + goto tr420 + st463: + if p++; p == pe { + goto _test_eof463 + } + st_case_463: + if 180 <= data[p] { + goto st413 + } + goto tr420 + st464: + if p++; p == pe { + goto _test_eof464 + } + st_case_464: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 170 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr420 + } + goto st413 + st465: + if p++; p == pe { + goto _test_eof465 + } + st_case_465: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 139: + goto st413 + } + goto tr420 + st466: + if p++; p == pe { + goto _test_eof466 + } + st_case_466: + if data[p] == 169 { + goto st413 + } + goto tr420 + st467: + if p++; p == pe { + goto _test_eof467 + } + st_case_467: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto st413 + } + case data[p] >= 160: + goto st413 + } + goto tr420 + st468: + if p++; p == pe { + goto _test_eof468 + } + st_case_468: + if 134 <= data[p] && data[p] <= 143 { + goto tr421 + } + goto tr2 + st469: + if p++; p == pe { + goto _test_eof469 + } + st_case_469: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + goto tr2 + st470: + if p++; p == pe { + goto _test_eof470 + } + st_case_470: + if 151 <= data[p] && data[p] <= 155 { + goto st413 + } + goto tr420 + st471: + if p++; p == pe { + goto _test_eof471 + } + st_case_471: + if data[p] == 191 { + goto st413 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto st413 + } + case data[p] >= 149: + goto st413 + } + goto tr420 + st472: + if p++; p == pe { + goto _test_eof472 + } + st_case_472: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto st413 + } + default: + goto tr421 + } + goto tr420 + st473: + if p++; p == pe { + goto _test_eof473 + } + st_case_473: + switch { + case data[p] > 132: + if 180 <= data[p] { + goto st413 + } + case data[p] >= 128: + goto st413 + } + goto tr420 + st474: + if p++; p == pe { + goto _test_eof474 + } + st_case_474: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 153: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 154: + goto tr420 + } + default: + goto tr421 + } + goto st413 + st475: + if p++; p == pe { + goto _test_eof475 + } + st_case_475: + switch { + case data[p] < 161: + if 128 <= data[p] && data[p] <= 130 { + goto st413 + } + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + default: + goto st413 + } + goto tr420 + st476: + if p++; p == pe { + goto _test_eof476 + } + st_case_476: + if 166 <= data[p] && data[p] <= 179 { + goto st413 + } + goto tr420 + st477: + if p++; p == pe { + goto _test_eof477 + } + st_case_477: + if 164 <= data[p] && data[p] <= 183 { + goto st413 + } + goto tr420 + st478: + if p++; p == pe { + goto _test_eof478 + } + st_case_478: + switch { + case data[p] > 137: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 128: + goto tr421 + } + goto tr420 + st479: + if p++; p == pe { + goto _test_eof479 + } + st_case_479: + if data[p] == 173 { + goto st413 + } + switch { + case data[p] < 148: + if 144 <= data[p] && data[p] <= 146 { + goto st413 + } + case data[p] > 168: + switch { + case data[p] > 180: + if 184 <= data[p] && data[p] <= 185 { + goto st413 + } + case data[p] >= 178: + goto st413 + } + default: + goto st413 + } + goto tr420 + st480: + if p++; p == pe { + goto _test_eof480 + } + st_case_480: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto st413 + } + case data[p] >= 128: + goto st413 + } + goto tr420 + st481: + if p++; p == pe { + goto _test_eof481 + } + st_case_481: + switch data[p] { + case 128: + goto st482 + case 129: + goto st483 + case 131: + goto st484 + case 179: + goto st485 + case 181: + goto st486 + case 183: + goto st487 + } + goto tr420 + st482: + if p++; p == pe { + goto _test_eof482 + } + st_case_482: + switch { + case data[p] > 143: + if 170 <= data[p] && data[p] <= 174 { + goto st413 + } + case data[p] >= 140: + goto st413 + } + goto tr420 + st483: + if p++; p == pe { + goto _test_eof483 + } + st_case_483: + switch { + case data[p] > 164: + if 166 <= data[p] && data[p] <= 175 { + goto st413 + } + case data[p] >= 160: + goto st413 + } + goto tr420 + st484: + if p++; p == pe { + goto _test_eof484 + } + st_case_484: + if 144 <= data[p] && data[p] <= 176 { + goto st413 + } + goto tr420 + st485: + if p++; p == pe { + goto _test_eof485 + } + st_case_485: + if 175 <= data[p] && data[p] <= 177 { + goto st413 + } + goto tr420 + st486: + if p++; p == pe { + goto _test_eof486 + } + st_case_486: + if data[p] == 191 { + goto st413 + } + goto tr420 + st487: + if p++; p == pe { + goto _test_eof487 + } + st_case_487: + if 160 <= data[p] && data[p] <= 191 { + goto st413 + } + goto tr420 + st488: + if p++; p == pe { + goto _test_eof488 + } + st_case_488: + switch data[p] { + case 128: + goto st489 + case 130: + goto st490 + } + goto tr420 + st489: + if p++; p == pe { + goto _test_eof489 + } + st_case_489: + if 170 <= data[p] && data[p] <= 175 { + goto st413 + } + goto tr420 + st490: + if p++; p == pe { + goto _test_eof490 + } + st_case_490: + if 153 <= data[p] && data[p] <= 154 { + goto st413 + } + goto tr420 + st491: + if p++; p == pe { + goto _test_eof491 + } + st_case_491: + switch data[p] { + case 152: + goto st492 + case 153: + goto st493 + case 154: + goto st494 + case 155: + goto st495 + case 160: + goto st496 + case 162: + goto st497 + case 163: + goto st498 + case 164: + goto st499 + case 165: + goto st500 + case 166: + goto st501 + case 167: + goto st502 + case 168: + goto st503 + case 169: + goto st504 + case 170: + goto st505 + case 171: + goto st506 + case 175: + goto st507 + } + goto tr420 + st492: + if p++; p == pe { + goto _test_eof492 + } + st_case_492: + if 160 <= data[p] && data[p] <= 169 { + goto tr421 + } + goto tr420 + st493: + if p++; p == pe { + goto _test_eof493 + } + st_case_493: + switch { + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto st413 + } + case data[p] >= 175: + goto st413 + } + goto tr420 + st494: + if p++; p == pe { + goto _test_eof494 + } + st_case_494: + if 158 <= data[p] && data[p] <= 159 { + goto st413 + } + goto tr420 + st495: + if p++; p == pe { + goto _test_eof495 + } + st_case_495: + if 176 <= data[p] && data[p] <= 177 { + goto st413 + } + goto tr420 + st496: + if p++; p == pe { + goto _test_eof496 + } + st_case_496: + switch data[p] { + case 130: + goto st413 + case 134: + goto st413 + case 139: + goto st413 + } + if 163 <= data[p] && data[p] <= 167 { + goto st413 + } + goto tr420 + st497: + if p++; p == pe { + goto _test_eof497 + } + st_case_497: + switch { + case data[p] > 129: + if 180 <= data[p] { + goto st413 + } + case data[p] >= 128: + goto st413 + } + goto tr420 + st498: + if p++; p == pe { + goto _test_eof498 + } + st_case_498: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 153: + switch { + case data[p] > 159: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 154: + goto tr420 + } + default: + goto tr421 + } + goto st413 + st499: + if p++; p == pe { + goto _test_eof499 + } + st_case_499: + switch { + case data[p] > 137: + if 166 <= data[p] && data[p] <= 173 { + goto st413 + } + case data[p] >= 128: + goto tr421 + } + goto tr420 + st500: + if p++; p == pe { + goto _test_eof500 + } + st_case_500: + if 135 <= data[p] && data[p] <= 147 { + goto st413 + } + goto tr420 + st501: + if p++; p == pe { + goto _test_eof501 + } + st_case_501: + switch { + case data[p] > 131: + if 179 <= data[p] { + goto st413 + } + case data[p] >= 128: + goto st413 + } + goto tr420 + st502: + if p++; p == pe { + goto _test_eof502 + } + st_case_502: + switch { + case data[p] < 154: + switch { + case data[p] > 143: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 129: + goto tr420 + } + case data[p] > 164: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr420 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + default: + goto tr420 + } + goto st413 + st503: + if p++; p == pe { + goto _test_eof503 + } + st_case_503: + if 169 <= data[p] && data[p] <= 182 { + goto st413 + } + goto tr420 + st504: + if p++; p == pe { + goto _test_eof504 + } + st_case_504: + if data[p] == 131 { + goto st413 + } + switch { + case data[p] < 144: + if 140 <= data[p] && data[p] <= 141 { + goto st413 + } + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto st413 + } + default: + goto tr421 + } + goto tr420 + st505: + if p++; p == pe { + goto _test_eof505 + } + st_case_505: + if data[p] == 176 { + goto st413 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto st413 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto st413 + } + default: + goto st413 + } + goto tr420 + st506: + if p++; p == pe { + goto _test_eof506 + } + st_case_506: + if data[p] == 129 { + goto st413 + } + switch { + case data[p] > 175: + if 181 <= data[p] && data[p] <= 182 { + goto st413 + } + case data[p] >= 171: + goto st413 + } + goto tr420 + st507: + if p++; p == pe { + goto _test_eof507 + } + st_case_507: + switch { + case data[p] < 172: + if 163 <= data[p] && data[p] <= 170 { + goto st413 + } + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + default: + goto st413 + } + goto tr420 + st508: + if p++; p == pe { + goto _test_eof508 + } + st_case_508: + switch data[p] { + case 172: + goto st509 + case 184: + goto st510 + case 187: + goto st486 + case 190: + goto st494 + case 191: + goto st511 + } + goto tr420 + st509: + if p++; p == pe { + goto _test_eof509 + } + st_case_509: + if data[p] == 158 { + goto st413 + } + goto tr420 + st510: + if p++; p == pe { + goto _test_eof510 + } + st_case_510: + switch { + case data[p] > 143: + if 160 <= data[p] && data[p] <= 175 { + goto st413 + } + case data[p] >= 128: + goto st413 + } + goto tr420 + st511: + if p++; p == pe { + goto _test_eof511 + } + st_case_511: + if 185 <= data[p] && data[p] <= 187 { + goto st413 + } + goto tr420 + st512: + if p++; p == pe { + goto _test_eof512 + } + st_case_512: + switch data[p] { + case 144: + goto st513 + case 145: + goto st519 + case 150: + goto st540 + case 155: + goto st545 + case 157: + goto st547 + case 158: + goto st555 + } + goto tr420 + st513: + if p++; p == pe { + goto _test_eof513 + } + st_case_513: + switch data[p] { + case 135: + goto st514 + case 139: + goto st515 + case 141: + goto st516 + case 146: + goto st492 + case 168: + goto st517 + case 171: + goto st518 + } + goto tr420 + st514: + if p++; p == pe { + goto _test_eof514 + } + st_case_514: + if data[p] == 189 { + goto st413 + } + goto tr420 + st515: + if p++; p == pe { + goto _test_eof515 + } + st_case_515: + if data[p] == 160 { + goto st413 + } + goto tr420 + st516: + if p++; p == pe { + goto _test_eof516 + } + st_case_516: + if 182 <= data[p] && data[p] <= 186 { + goto st413 + } + goto tr420 + st517: + if p++; p == pe { + goto _test_eof517 + } + st_case_517: + if data[p] == 191 { + goto st413 + } + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto st413 + } + case data[p] > 134: + switch { + case data[p] > 143: + if 184 <= data[p] && data[p] <= 186 { + goto st413 + } + case data[p] >= 140: + goto st413 + } + default: + goto st413 + } + goto tr420 + st518: + if p++; p == pe { + goto _test_eof518 + } + st_case_518: + if 165 <= data[p] && data[p] <= 166 { + goto st413 + } + goto tr420 + st519: + if p++; p == pe { + goto _test_eof519 + } + st_case_519: + switch data[p] { + case 128: + goto st520 + case 129: + goto st521 + case 130: + goto st522 + case 131: + goto st523 + case 132: + goto st524 + case 133: + goto st525 + case 134: + goto st526 + case 135: + goto st527 + case 136: + goto st528 + case 139: + goto st529 + case 140: + goto st530 + case 141: + goto st531 + case 146: + goto st532 + case 147: + goto st533 + case 150: + goto st534 + case 151: + goto st535 + case 152: + goto st532 + case 153: + goto st536 + case 154: + goto st537 + case 155: + goto st538 + case 156: + goto st539 + case 163: + goto st492 + } + goto tr420 + st520: + if p++; p == pe { + goto _test_eof520 + } + st_case_520: + switch { + case data[p] > 130: + if 184 <= data[p] { + goto st413 + } + case data[p] >= 128: + goto st413 + } + goto tr420 + st521: + if p++; p == pe { + goto _test_eof521 + } + st_case_521: + switch { + case data[p] < 166: + if 135 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] && data[p] <= 190 { + goto tr420 + } + default: + goto tr421 + } + goto st413 + st522: + if p++; p == pe { + goto _test_eof522 + } + st_case_522: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr420 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto st413 + st523: + if p++; p == pe { + goto _test_eof523 + } + st_case_523: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + goto tr420 + st524: + if p++; p == pe { + goto _test_eof524 + } + st_case_524: + switch { + case data[p] < 167: + if 128 <= data[p] && data[p] <= 130 { + goto st413 + } + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr421 + } + default: + goto st413 + } + goto tr420 + st525: + if p++; p == pe { + goto _test_eof525 + } + st_case_525: + if data[p] == 179 { + goto st413 + } + goto tr420 + st526: + if p++; p == pe { + goto _test_eof526 + } + st_case_526: + switch { + case data[p] > 130: + if 179 <= data[p] { + goto st413 + } + case data[p] >= 128: + goto st413 + } + goto tr420 + st527: + if p++; p == pe { + goto _test_eof527 + } + st_case_527: + switch { + case data[p] < 141: + if 129 <= data[p] && data[p] <= 137 { + goto tr420 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr420 + } + goto st413 + st528: + if p++; p == pe { + goto _test_eof528 + } + st_case_528: + if 172 <= data[p] && data[p] <= 183 { + goto st413 + } + goto tr420 + st529: + if p++; p == pe { + goto _test_eof529 + } + st_case_529: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 159: + goto st413 + } + goto tr420 + st530: + if p++; p == pe { + goto _test_eof530 + } + st_case_530: + if data[p] == 188 { + goto st413 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto st413 + } + case data[p] >= 128: + goto st413 + } + goto tr420 + st531: + if p++; p == pe { + goto _test_eof531 + } + st_case_531: + if data[p] == 151 { + goto st413 + } + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto st413 + } + case data[p] >= 128: + goto st413 + } + case data[p] > 141: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto st413 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto st413 + } + default: + goto st413 + } + default: + goto st413 + } + goto tr420 + st532: + if p++; p == pe { + goto _test_eof532 + } + st_case_532: + if 176 <= data[p] { + goto st413 + } + goto tr420 + st533: + if p++; p == pe { + goto _test_eof533 + } + st_case_533: + switch { + case data[p] < 144: + if 132 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + goto st413 + st534: + if p++; p == pe { + goto _test_eof534 + } + st_case_534: + switch { + case data[p] > 181: + if 184 <= data[p] { + goto st413 + } + case data[p] >= 175: + goto st413 + } + goto tr420 + st535: + if p++; p == pe { + goto _test_eof535 + } + st_case_535: + switch { + case data[p] > 155: + if 158 <= data[p] { + goto tr420 + } + case data[p] >= 129: + goto tr420 + } + goto st413 + st536: + if p++; p == pe { + goto _test_eof536 + } + st_case_536: + switch { + case data[p] < 144: + if 129 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + goto st413 + st537: + if p++; p == pe { + goto _test_eof537 + } + st_case_537: + if 171 <= data[p] && data[p] <= 183 { + goto st413 + } + goto tr420 + st538: + if p++; p == pe { + goto _test_eof538 + } + st_case_538: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + goto tr2 + st539: + if p++; p == pe { + goto _test_eof539 + } + st_case_539: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 157: + goto st413 + } + goto tr420 + st540: + if p++; p == pe { + goto _test_eof540 + } + st_case_540: + switch data[p] { + case 169: + goto st492 + case 171: + goto st541 + case 172: + goto st542 + case 173: + goto st469 + case 189: + goto st543 + case 190: + goto st544 + } + goto tr420 + st541: + if p++; p == pe { + goto _test_eof541 + } + st_case_541: + if 176 <= data[p] && data[p] <= 180 { + goto st413 + } + goto tr420 + st542: + if p++; p == pe { + goto _test_eof542 + } + st_case_542: + if 176 <= data[p] && data[p] <= 182 { + goto st413 + } + goto tr420 + st543: + if p++; p == pe { + goto _test_eof543 + } + st_case_543: + if 145 <= data[p] && data[p] <= 190 { + goto st413 + } + goto tr420 + st544: + if p++; p == pe { + goto _test_eof544 + } + st_case_544: + if 143 <= data[p] && data[p] <= 146 { + goto st413 + } + goto tr420 + st545: + if p++; p == pe { + goto _test_eof545 + } + st_case_545: + if data[p] == 178 { + goto st546 + } + goto tr420 + st546: + if p++; p == pe { + goto _test_eof546 + } + st_case_546: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto st413 + } + case data[p] >= 157: + goto st413 + } + goto tr420 + st547: + if p++; p == pe { + goto _test_eof547 + } + st_case_547: + switch data[p] { + case 133: + goto st548 + case 134: + goto st549 + case 137: + goto st550 + case 159: + goto st551 + case 168: + goto st552 + case 169: + goto st553 + case 170: + goto st554 + } + goto tr420 + st548: + if p++; p == pe { + goto _test_eof548 + } + st_case_548: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto st413 + } + case data[p] >= 165: + goto st413 + } + goto tr420 + st549: + if p++; p == pe { + goto _test_eof549 + } + st_case_549: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr420 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto st413 + st550: + if p++; p == pe { + goto _test_eof550 + } + st_case_550: + if 130 <= data[p] && data[p] <= 132 { + goto st413 + } + goto tr420 + st551: + if p++; p == pe { + goto _test_eof551 + } + st_case_551: + if 142 <= data[p] && data[p] <= 191 { + goto tr421 + } + goto tr420 + st552: + if p++; p == pe { + goto _test_eof552 + } + st_case_552: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto st413 + } + case data[p] >= 128: + goto st413 + } + goto tr420 + st553: + if p++; p == pe { + goto _test_eof553 + } + st_case_553: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 173: + goto tr420 + } + goto st413 + st554: + if p++; p == pe { + goto _test_eof554 + } + st_case_554: + if data[p] == 132 { + goto st413 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto st413 + } + case data[p] >= 155: + goto st413 + } + goto tr420 + st555: + if p++; p == pe { + goto _test_eof555 + } + st_case_555: + if data[p] == 163 { + goto st556 + } + goto tr420 + st556: + if p++; p == pe { + goto _test_eof556 + } + st_case_556: + if 144 <= data[p] && data[p] <= 150 { + goto st413 + } + goto tr420 + st557: + if p++; p == pe { + goto _test_eof557 + } + st_case_557: + if data[p] == 160 { + goto st558 + } + goto tr420 + st558: + if p++; p == pe { + goto _test_eof558 + } + st_case_558: + switch data[p] { + case 128: + goto st559 + case 129: + goto st560 + case 132: + goto st415 + case 135: + goto st416 + } + if 133 <= data[p] && data[p] <= 134 { + goto st561 + } + goto tr420 + st559: + if p++; p == pe { + goto _test_eof559 + } + st_case_559: + if data[p] == 129 { + goto st413 + } + if 160 <= data[p] { + goto st413 + } + goto tr420 + st560: + if p++; p == pe { + goto _test_eof560 + } + st_case_560: + if 192 <= data[p] { + goto tr420 + } + goto st413 + st561: + if p++; p == pe { + goto _test_eof561 + } + st_case_561: + goto st413 +tr571: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4869 + st4869: + if p++; p == pe { + goto _test_eof4869 + } + st_case_4869: +//line segment_words_prod.go:22013 + switch data[p] { + case 95: + goto tr571 + case 194: + goto st562 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st148 + case 204: + goto st563 + case 205: + goto st564 + case 206: + goto st151 + case 207: + goto st152 + case 210: + goto st565 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st566 + case 215: + goto st567 + case 216: + goto st1020 + case 217: + goto st1021 + case 219: + goto st1022 + case 220: + goto st1023 + case 221: + goto st1024 + case 222: + goto st1025 + case 223: + goto st1026 + case 224: + goto st1027 + case 225: + goto st1059 + case 226: + goto st1081 + case 227: + goto st1088 + case 234: + goto st1241 + case 237: + goto st287 + case 239: + goto st1257 + case 240: + goto st1264 + case 243: + goto st1306 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 + st562: + if p++; p == pe { + goto _test_eof562 + } + st_case_562: + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr571 + case 181: + goto tr148 + case 186: + goto tr148 + } + goto tr420 + st563: + if p++; p == pe { + goto _test_eof563 + } + st_case_563: + if data[p] <= 127 { + goto tr420 + } + goto tr571 + st564: + if p++; p == pe { + goto _test_eof564 + } + st_case_564: + switch data[p] { + case 181: + goto tr420 + case 190: + goto tr420 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + goto tr571 + st565: + if p++; p == pe { + goto _test_eof565 + } + st_case_565: + if data[p] == 130 { + goto tr420 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr571 + } + goto tr148 + st566: + if p++; p == pe { + goto _test_eof566 + } + st_case_566: + if data[p] == 190 { + goto tr420 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr420 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + default: + goto tr571 + } + goto tr148 + st567: + if p++; p == pe { + goto _test_eof567 + } + st_case_567: + switch data[p] { + case 135: + goto tr571 + case 179: + goto tr148 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr571 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr571 + } + goto tr420 +tr572: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4870 + st4870: + if p++; p == pe { + goto _test_eof4870 + } + st_case_4870: +//line segment_words_prod.go:22233 + switch data[p] { + case 34: + goto st568 + case 39: + goto tr595 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st869 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st871 + case 205: + goto st872 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st874 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st875 + case 215: + goto st876 + case 216: + goto st877 + case 217: + goto st878 + case 219: + goto st879 + case 220: + goto st880 + case 221: + goto st881 + case 222: + goto st882 + case 223: + goto st883 + case 224: + goto st884 + case 225: + goto st916 + case 226: + goto st938 + case 227: + goto st945 + case 234: + goto st948 + case 237: + goto st287 + case 239: + goto st964 + case 240: + goto st972 + case 243: + goto st1014 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 + st568: + if p++; p == pe { + goto _test_eof568 + } + st_case_568: + switch data[p] { + case 194: + goto st569 + case 204: + goto st570 + case 205: + goto st571 + case 210: + goto st572 + case 214: + goto st573 + case 215: + goto st574 + case 216: + goto st733 + case 217: + goto st734 + case 219: + goto st735 + case 220: + goto st736 + case 221: + goto st737 + case 222: + goto st738 + case 223: + goto st739 + case 224: + goto st740 + case 225: + goto st769 + case 226: + goto st791 + case 227: + goto st798 + case 234: + goto st801 + case 239: + goto st817 + case 240: + goto st822 + case 243: + goto st864 + } + goto tr420 + st569: + if p++; p == pe { + goto _test_eof569 + } + st_case_569: + if data[p] == 173 { + goto st568 + } + goto tr420 + st570: + if p++; p == pe { + goto _test_eof570 + } + st_case_570: + if data[p] <= 127 { + goto tr420 + } + goto st568 + st571: + if p++; p == pe { + goto _test_eof571 + } + st_case_571: + if 176 <= data[p] { + goto tr420 + } + goto st568 + st572: + if p++; p == pe { + goto _test_eof572 + } + st_case_572: + if 131 <= data[p] && data[p] <= 137 { + goto st568 + } + goto tr420 + st573: + if p++; p == pe { + goto _test_eof573 + } + st_case_573: + if data[p] == 191 { + goto st568 + } + if 145 <= data[p] && data[p] <= 189 { + goto st568 + } + goto tr420 + st574: + if p++; p == pe { + goto _test_eof574 + } + st_case_574: + if data[p] == 135 { + goto st568 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto st568 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr595 + } + case data[p] >= 144: + goto tr595 + } + default: + goto st568 + } + goto tr420 +tr595: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4871 + st4871: + if p++; p == pe { + goto _test_eof4871 + } + st_case_4871: +//line segment_words_prod.go:22469 + switch data[p] { + case 95: + goto tr571 + case 194: + goto st575 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st148 + case 204: + goto st576 + case 205: + goto st577 + case 206: + goto st151 + case 207: + goto st152 + case 210: + goto st578 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st579 + case 215: + goto st580 + case 216: + goto st581 + case 217: + goto st582 + case 219: + goto st583 + case 220: + goto st584 + case 221: + goto st585 + case 222: + goto st586 + case 223: + goto st587 + case 224: + goto st588 + case 225: + goto st620 + case 226: + goto st643 + case 227: + goto st650 + case 234: + goto st653 + case 237: + goto st287 + case 239: + goto st670 + case 240: + goto st679 + case 243: + goto st727 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 + st575: + if p++; p == pe { + goto _test_eof575 + } + st_case_575: + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr595 + case 181: + goto tr148 + case 186: + goto tr148 + } + goto tr420 + st576: + if p++; p == pe { + goto _test_eof576 + } + st_case_576: + if data[p] <= 127 { + goto tr420 + } + goto tr595 + st577: + if p++; p == pe { + goto _test_eof577 + } + st_case_577: + switch data[p] { + case 181: + goto tr420 + case 190: + goto tr420 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + goto tr595 + st578: + if p++; p == pe { + goto _test_eof578 + } + st_case_578: + if data[p] == 130 { + goto tr420 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr595 + } + goto tr148 + st579: + if p++; p == pe { + goto _test_eof579 + } + st_case_579: + if data[p] == 190 { + goto tr420 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr420 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + default: + goto tr595 + } + goto tr148 + st580: + if p++; p == pe { + goto _test_eof580 + } + st_case_580: + switch data[p] { + case 135: + goto tr595 + case 179: + goto tr148 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr595 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr595 + } + goto tr420 + st581: + if p++; p == pe { + goto _test_eof581 + } + st_case_581: + if data[p] == 156 { + goto tr595 + } + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 133 { + goto tr595 + } + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr595 + } + goto tr420 + st582: + if p++; p == pe { + goto _test_eof582 + } + st_case_582: + switch data[p] { + case 171: + goto tr421 + case 176: + goto tr595 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr595 + } + goto tr420 + st583: + if p++; p == pe { + goto _test_eof583 + } + st_case_583: + switch data[p] { + case 148: + goto tr420 + case 158: + goto tr420 + case 169: + goto tr420 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr595 + } + case data[p] >= 150: + goto tr595 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 189: + goto tr420 + } + default: + goto tr421 + } + goto tr148 + st584: + if p++; p == pe { + goto _test_eof584 + } + st_case_584: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto tr595 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr595 + } + default: + goto tr148 + } + goto tr420 + st585: + if p++; p == pe { + goto _test_eof585 + } + st_case_585: + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr420 + } + goto tr595 + st586: + if p++; p == pe { + goto _test_eof586 + } + st_case_586: + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr595 + } + goto tr148 + st587: + if p++; p == pe { + goto _test_eof587 + } + st_case_587: + if data[p] == 186 { + goto tr148 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 170: + switch { + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 171: + goto tr595 + } + default: + goto tr148 + } + goto tr420 + st588: + if p++; p == pe { + goto _test_eof588 + } + st_case_588: + switch data[p] { + case 160: + goto st589 + case 161: + goto st590 + case 162: + goto st168 + case 163: + goto st591 + case 164: + goto st592 + case 165: + goto st593 + case 166: + goto st594 + case 167: + goto st595 + case 168: + goto st596 + case 169: + goto st597 + case 170: + goto st598 + case 171: + goto st599 + case 172: + goto st600 + case 173: + goto st601 + case 174: + goto st602 + case 175: + goto st603 + case 176: + goto st604 + case 177: + goto st605 + case 178: + goto st606 + case 179: + goto st607 + case 180: + goto st608 + case 181: + goto st609 + case 182: + goto st610 + case 183: + goto st611 + case 184: + goto st612 + case 185: + goto st613 + case 186: + goto st614 + case 187: + goto st615 + case 188: + goto st616 + case 189: + goto st617 + case 190: + goto st618 + case 191: + goto st619 + } + goto tr420 + st589: + if p++; p == pe { + goto _test_eof589 + } + st_case_589: + switch data[p] { + case 154: + goto tr148 + case 164: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] > 149: + if 150 <= data[p] && data[p] <= 173 { + goto tr595 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st590: + if p++; p == pe { + goto _test_eof590 + } + st_case_590: + switch { + case data[p] > 152: + if 153 <= data[p] && data[p] <= 155 { + goto tr595 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st591: + if p++; p == pe { + goto _test_eof591 + } + st_case_591: + if 163 <= data[p] { + goto tr595 + } + goto tr420 + st592: + if p++; p == pe { + goto _test_eof592 + } + st_case_592: + if data[p] == 189 { + goto tr148 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr148 + } + goto tr595 + st593: + if p++; p == pe { + goto _test_eof593 + } + st_case_593: + switch data[p] { + case 144: + goto tr148 + case 176: + goto tr420 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 177 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr420 + } + goto tr595 + st594: + if p++; p == pe { + goto _test_eof594 + } + st_case_594: + switch data[p] { + case 132: + goto tr420 + case 169: + goto tr420 + case 177: + goto tr420 + case 188: + goto tr595 + } + switch { + case data[p] < 145: + switch { + case data[p] > 131: + if 141 <= data[p] && data[p] <= 142 { + goto tr420 + } + case data[p] >= 129: + goto tr595 + } + case data[p] > 146: + switch { + case data[p] < 186: + if 179 <= data[p] && data[p] <= 181 { + goto tr420 + } + case data[p] > 187: + if 190 <= data[p] { + goto tr595 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st595: + if p++; p == pe { + goto _test_eof595 + } + st_case_595: + switch data[p] { + case 142: + goto tr148 + case 158: + goto tr420 + } + switch { + case data[p] < 156: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 155 { + goto tr420 + } + case data[p] >= 143: + goto tr420 + } + default: + goto tr420 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr595 + st596: + if p++; p == pe { + goto _test_eof596 + } + st_case_596: + if data[p] == 188 { + goto tr595 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr595 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto tr595 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st597: + if p++; p == pe { + goto _test_eof597 + } + st_case_597: + if data[p] == 157 { + goto tr420 + } + switch { + case data[p] < 153: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 146 <= data[p] && data[p] <= 152 { + goto tr420 + } + case data[p] >= 142: + goto tr420 + } + default: + goto tr420 + } + case data[p] > 158: + switch { + case data[p] < 166: + if 159 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr595 + st598: + if p++; p == pe { + goto _test_eof598 + } + st_case_598: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr595 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto tr595 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st599: + if p++; p == pe { + goto _test_eof599 + } + st_case_599: + switch data[p] { + case 134: + goto tr420 + case 138: + goto tr420 + case 144: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] >= 142: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr420 + } + goto tr595 + st600: + if p++; p == pe { + goto _test_eof600 + } + st_case_600: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr595 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr595 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st601: + if p++; p == pe { + goto _test_eof601 + } + st_case_601: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr595 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr595 + } + default: + goto tr595 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 161: + switch { + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 162: + goto tr595 + } + default: + goto tr148 + } + default: + goto tr595 + } + goto tr420 + st602: + if p++; p == pe { + goto _test_eof602 + } + st_case_602: + switch data[p] { + case 130: + goto tr595 + case 131: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 158: + switch { + case data[p] < 142: + if 133 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 149: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] < 168: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto tr595 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st603: + if p++; p == pe { + goto _test_eof603 + } + st_case_603: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr595 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr595 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 138: + goto tr595 + } + default: + goto tr595 + } + goto tr420 + st604: + if p++; p == pe { + goto _test_eof604 + } + st_case_604: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto tr595 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 190 <= data[p] { + goto tr595 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st605: + if p++; p == pe { + goto _test_eof605 + } + st_case_605: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 151: + goto tr420 + } + switch { + case data[p] < 160: + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 148 { + goto tr420 + } + case data[p] > 154: + if 155 <= data[p] && data[p] <= 159 { + goto tr420 + } + default: + goto tr148 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr595 + st606: + if p++; p == pe { + goto _test_eof606 + } + st_case_606: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr595 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr595 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st607: + if p++; p == pe { + goto _test_eof607 + } + st_case_607: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr595 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr595 + } + default: + goto tr595 + } + case data[p] > 150: + switch { + case data[p] < 162: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 163: + switch { + case data[p] > 175: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr595 + } + default: + goto tr595 + } + goto tr420 + st608: + if p++; p == pe { + goto _test_eof608 + } + st_case_608: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto tr595 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto tr595 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st609: + if p++; p == pe { + goto _test_eof609 + } + st_case_609: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 142: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 150 { + goto tr420 + } + case data[p] > 158: + if 159 <= data[p] && data[p] <= 161 { + goto tr148 + } + default: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr595 + st610: + if p++; p == pe { + goto _test_eof610 + } + st_case_610: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr595 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st611: + if p++; p == pe { + goto _test_eof611 + } + st_case_611: + switch data[p] { + case 138: + goto tr595 + case 150: + goto tr595 + } + switch { + case data[p] < 152: + switch { + case data[p] > 134: + if 143 <= data[p] && data[p] <= 148 { + goto tr595 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto tr595 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr595 + } + goto tr420 + st612: + if p++; p == pe { + goto _test_eof612 + } + st_case_612: + if data[p] == 177 { + goto tr595 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr595 + } + goto tr420 + st613: + if p++; p == pe { + goto _test_eof613 + } + st_case_613: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 135: + goto tr595 + } + goto tr420 + st614: + if p++; p == pe { + goto _test_eof614 + } + st_case_614: + if data[p] == 177 { + goto tr595 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr595 + } + case data[p] >= 180: + goto tr595 + } + goto tr420 + st615: + if p++; p == pe { + goto _test_eof615 + } + st_case_615: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 136: + goto tr595 + } + goto tr420 + st616: + if p++; p == pe { + goto _test_eof616 + } + st_case_616: + switch data[p] { + case 128: + goto tr148 + case 181: + goto tr595 + case 183: + goto tr595 + case 185: + goto tr595 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto tr595 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto tr595 + } + default: + goto tr421 + } + goto tr420 + st617: + if p++; p == pe { + goto _test_eof617 + } + st_case_617: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto tr595 + } + default: + goto tr148 + } + goto tr420 + st618: + if p++; p == pe { + goto _test_eof618 + } + st_case_618: + switch { + case data[p] < 136: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 135 { + goto tr595 + } + case data[p] >= 128: + goto tr595 + } + case data[p] > 140: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr595 + } + case data[p] >= 141: + goto tr595 + } + default: + goto tr148 + } + goto tr420 + st619: + if p++; p == pe { + goto _test_eof619 + } + st_case_619: + if data[p] == 134 { + goto tr595 + } + goto tr420 + st620: + if p++; p == pe { + goto _test_eof620 + } + st_case_620: + switch data[p] { + case 128: + goto st621 + case 129: + goto st622 + case 130: + goto st623 + case 131: + goto st202 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st624 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st625 + case 157: + goto st626 + case 158: + goto st627 + case 159: + goto st628 + case 160: + goto st629 + case 161: + goto st219 + case 162: + goto st630 + case 163: + goto st221 + case 164: + goto st631 + case 165: + goto st468 + case 167: + goto st469 + case 168: + goto st632 + case 169: + goto st633 + case 170: + goto st634 + case 172: + goto st635 + case 173: + goto st636 + case 174: + goto st637 + case 175: + goto st638 + case 176: + goto st639 + case 177: + goto st640 + case 179: + goto st641 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st642 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + } + switch { + case data[p] < 180: + if 132 <= data[p] && data[p] <= 152 { + goto st145 + } + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + default: + goto st147 + } + goto tr420 + st621: + if p++; p == pe { + goto _test_eof621 + } + st_case_621: + if 171 <= data[p] && data[p] <= 190 { + goto tr595 + } + goto tr420 + st622: + if p++; p == pe { + goto _test_eof622 + } + st_case_622: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto tr595 + } + case data[p] >= 128: + goto tr421 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto tr595 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr595 + } + default: + goto tr595 + } + default: + goto tr595 + } + goto tr420 + st623: + if p++; p == pe { + goto _test_eof623 + } + st_case_623: + if data[p] == 143 { + goto tr595 + } + switch { + case data[p] < 144: + if 130 <= data[p] && data[p] <= 141 { + goto tr595 + } + case data[p] > 153: + switch { + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 154: + goto tr595 + } + default: + goto tr421 + } + goto tr420 + st624: + if p++; p == pe { + goto _test_eof624 + } + st_case_624: + switch { + case data[p] < 157: + if 155 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr420 + } + default: + goto tr595 + } + goto tr148 + st625: + if p++; p == pe { + goto _test_eof625 + } + st_case_625: + switch { + case data[p] < 146: + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 177: + if 178 <= data[p] && data[p] <= 180 { + goto tr595 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr595 + } + goto tr420 + st626: + if p++; p == pe { + goto _test_eof626 + } + st_case_626: + switch { + case data[p] < 160: + switch { + case data[p] > 145: + if 146 <= data[p] && data[p] <= 147 { + goto tr595 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto tr595 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st627: + if p++; p == pe { + goto _test_eof627 + } + st_case_627: + if 180 <= data[p] { + goto tr595 + } + goto tr420 + st628: + if p++; p == pe { + goto _test_eof628 + } + st_case_628: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 170 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr420 + } + goto tr595 + st629: + if p++; p == pe { + goto _test_eof629 + } + st_case_629: + switch { + case data[p] < 144: + if 139 <= data[p] && data[p] <= 142 { + goto tr595 + } + case data[p] > 153: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + goto tr420 + st630: + if p++; p == pe { + goto _test_eof630 + } + st_case_630: + if data[p] == 169 { + goto tr595 + } + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st631: + if p++; p == pe { + goto _test_eof631 + } + st_case_631: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr595 + } + default: + goto tr595 + } + goto tr420 + st632: + if p++; p == pe { + goto _test_eof632 + } + st_case_632: + switch { + case data[p] > 150: + if 151 <= data[p] && data[p] <= 155 { + goto tr595 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st633: + if p++; p == pe { + goto _test_eof633 + } + st_case_633: + if data[p] == 191 { + goto tr595 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr595 + } + case data[p] >= 149: + goto tr595 + } + goto tr420 + st634: + if p++; p == pe { + goto _test_eof634 + } + st_case_634: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto tr595 + } + default: + goto tr421 + } + goto tr420 + st635: + if p++; p == pe { + goto _test_eof635 + } + st_case_635: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 132 { + goto tr595 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr595 + } + default: + goto tr148 + } + goto tr420 + st636: + if p++; p == pe { + goto _test_eof636 + } + st_case_636: + switch { + case data[p] < 144: + switch { + case data[p] > 139: + if 140 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] >= 133: + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 154: + goto tr420 + } + default: + goto tr421 + } + goto tr595 + st637: + if p++; p == pe { + goto _test_eof637 + } + st_case_637: + switch { + case data[p] < 161: + switch { + case data[p] > 130: + if 131 <= data[p] && data[p] <= 160 { + goto tr148 + } + case data[p] >= 128: + goto tr595 + } + case data[p] > 173: + switch { + case data[p] < 176: + if 174 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + default: + goto tr595 + } + goto tr420 + st638: + if p++; p == pe { + goto _test_eof638 + } + st_case_638: + switch { + case data[p] > 179: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr595 + } + goto tr148 + st639: + if p++; p == pe { + goto _test_eof639 + } + st_case_639: + switch { + case data[p] > 163: + if 164 <= data[p] && data[p] <= 183 { + goto tr595 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st640: + if p++; p == pe { + goto _test_eof640 + } + st_case_640: + switch { + case data[p] < 141: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] && data[p] <= 189 { + goto tr148 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr148 + } + goto tr2 + st641: + if p++; p == pe { + goto _test_eof641 + } + st_case_641: + if data[p] == 173 { + goto tr595 + } + switch { + case data[p] < 169: + switch { + case data[p] > 146: + if 148 <= data[p] && data[p] <= 168 { + goto tr595 + } + case data[p] >= 144: + goto tr595 + } + case data[p] > 177: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 180 { + goto tr595 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto tr595 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st642: + if p++; p == pe { + goto _test_eof642 + } + st_case_642: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr595 + } + case data[p] >= 128: + goto tr595 + } + goto tr420 + st643: + if p++; p == pe { + goto _test_eof643 + } + st_case_643: + switch data[p] { + case 128: + goto st644 + case 129: + goto st645 + case 130: + goto st241 + case 131: + goto st646 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st647 + case 180: + goto st251 + case 181: + goto st648 + case 182: + goto st253 + case 183: + goto st649 + case 184: + goto st255 + } + goto tr420 + st644: + if p++; p == pe { + goto _test_eof644 + } + st_case_644: + switch { + case data[p] < 170: + if 140 <= data[p] && data[p] <= 143 { + goto tr595 + } + case data[p] > 174: + if 191 <= data[p] { + goto tr571 + } + default: + goto tr595 + } + goto tr420 + st645: + if p++; p == pe { + goto _test_eof645 + } + st_case_645: + switch data[p] { + case 165: + goto tr420 + case 177: + goto tr148 + case 191: + goto tr148 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr595 + } + default: + goto tr420 + } + goto tr571 + st646: + if p++; p == pe { + goto _test_eof646 + } + st_case_646: + if 144 <= data[p] && data[p] <= 176 { + goto tr595 + } + goto tr420 + st647: + if p++; p == pe { + goto _test_eof647 + } + st_case_647: + switch { + case data[p] < 175: + if 165 <= data[p] && data[p] <= 170 { + goto tr420 + } + case data[p] > 177: + if 180 <= data[p] { + goto tr420 + } + default: + goto tr595 + } + goto tr148 + st648: + if p++; p == pe { + goto _test_eof648 + } + st_case_648: + if data[p] == 191 { + goto tr595 + } + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 168: + goto tr420 + } + goto tr148 + st649: + if p++; p == pe { + goto _test_eof649 + } + st_case_649: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto tr595 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st650: + if p++; p == pe { + goto _test_eof650 + } + st_case_650: + switch data[p] { + case 128: + goto st651 + case 130: + goto st652 + case 132: + goto st259 + case 133: + goto st145 + case 134: + goto st260 + } + goto tr420 + st651: + if p++; p == pe { + goto _test_eof651 + } + st_case_651: + if data[p] == 133 { + goto tr148 + } + switch { + case data[p] > 175: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + case data[p] >= 170: + goto tr595 + } + goto tr420 + st652: + if p++; p == pe { + goto _test_eof652 + } + st_case_652: + if 153 <= data[p] && data[p] <= 154 { + goto tr595 + } + goto tr420 + st653: + if p++; p == pe { + goto _test_eof653 + } + st_case_653: + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st654 + case 153: + goto st655 + case 154: + goto st656 + case 155: + goto st657 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st658 + case 161: + goto st272 + case 162: + goto st659 + case 163: + goto st660 + case 164: + goto st661 + case 165: + goto st662 + case 166: + goto st663 + case 167: + goto st664 + case 168: + goto st665 + case 169: + goto st666 + case 170: + goto st667 + case 171: + goto st668 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st669 + case 176: + goto st147 + } + if 129 <= data[p] { + goto st145 + } + goto tr420 + st654: + if p++; p == pe { + goto _test_eof654 + } + st_case_654: + switch { + case data[p] < 160: + if 141 <= data[p] && data[p] <= 143 { + goto tr2 + } + case data[p] > 169: + if 172 <= data[p] { + goto tr2 + } + default: + goto tr421 + } + goto tr148 + st655: + if p++; p == pe { + goto _test_eof655 + } + st_case_655: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr595 + } + default: + goto tr595 + } + goto tr420 + st656: + if p++; p == pe { + goto _test_eof656 + } + st_case_656: + switch { + case data[p] < 158: + if 128 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr595 + } + goto tr420 + st657: + if p++; p == pe { + goto _test_eof657 + } + st_case_657: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr595 + } + goto tr148 + st658: + if p++; p == pe { + goto _test_eof658 + } + st_case_658: + switch data[p] { + case 130: + goto tr595 + case 134: + goto tr595 + case 139: + goto tr595 + } + switch { + case data[p] > 167: + if 168 <= data[p] { + goto tr420 + } + case data[p] >= 163: + goto tr595 + } + goto tr148 + st659: + if p++; p == pe { + goto _test_eof659 + } + st_case_659: + switch { + case data[p] < 130: + if 128 <= data[p] && data[p] <= 129 { + goto tr595 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr595 + } + default: + goto tr148 + } + goto tr420 + st660: + if p++; p == pe { + goto _test_eof660 + } + st_case_660: + switch data[p] { + case 187: + goto tr148 + case 189: + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 143: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 133: + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 183: + if 184 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr420 + } + goto tr595 + st661: + if p++; p == pe { + goto _test_eof661 + } + st_case_661: + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 165: + switch { + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr595 + } + default: + goto tr148 + } + goto tr420 + st662: + if p++; p == pe { + goto _test_eof662 + } + st_case_662: + switch { + case data[p] < 148: + if 135 <= data[p] && data[p] <= 147 { + goto tr595 + } + case data[p] > 159: + if 189 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st663: + if p++; p == pe { + goto _test_eof663 + } + st_case_663: + switch { + case data[p] < 132: + if 128 <= data[p] && data[p] <= 131 { + goto tr595 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr595 + } + default: + goto tr148 + } + goto tr420 + st664: + if p++; p == pe { + goto _test_eof664 + } + st_case_664: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 129: + goto tr420 + } + case data[p] > 164: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr420 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + default: + goto tr420 + } + goto tr595 + st665: + if p++; p == pe { + goto _test_eof665 + } + st_case_665: + switch { + case data[p] > 168: + if 169 <= data[p] && data[p] <= 182 { + goto tr595 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st666: + if p++; p == pe { + goto _test_eof666 + } + st_case_666: + if data[p] == 131 { + goto tr595 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 141: + switch { + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto tr595 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr595 + } + goto tr420 + st667: + if p++; p == pe { + goto _test_eof667 + } + st_case_667: + if data[p] == 176 { + goto tr595 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr595 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr595 + } + default: + goto tr595 + } + goto tr420 + st668: + if p++; p == pe { + goto _test_eof668 + } + st_case_668: + if data[p] == 129 { + goto tr595 + } + switch { + case data[p] < 171: + if 160 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 181 <= data[p] && data[p] <= 182 { + goto tr595 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr595 + } + goto tr420 + st669: + if p++; p == pe { + goto _test_eof669 + } + st_case_669: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 162 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 172: + goto tr595 + } + default: + goto tr595 + } + goto tr420 + st670: + if p++; p == pe { + goto _test_eof670 + } + st_case_670: + switch data[p] { + case 172: + goto st671 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st673 + case 185: + goto st674 + case 187: + goto st675 + case 188: + goto st676 + case 189: + goto st303 + case 190: + goto st677 + case 191: + goto st678 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr420 + st671: + if p++; p == pe { + goto _test_eof671 + } + st_case_671: + switch data[p] { + case 158: + goto tr595 + case 190: + goto tr572 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 170: + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st672: + if p++; p == pe { + goto _test_eof672 + } + st_case_672: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 129 { + goto tr572 + } + case data[p] > 132: + switch { + case data[p] > 143: + if 144 <= data[p] { + goto tr148 + } + case data[p] >= 134: + goto tr572 + } + default: + goto tr572 + } + goto tr2 + st673: + if p++; p == pe { + goto _test_eof673 + } + st_case_673: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr595 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr571 + } + default: + goto tr595 + } + goto tr420 + st674: + if p++; p == pe { + goto _test_eof674 + } + st_case_674: + switch { + case data[p] < 176: + if 141 <= data[p] && data[p] <= 143 { + goto tr571 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st675: + if p++; p == pe { + goto _test_eof675 + } + st_case_675: + if data[p] == 191 { + goto tr595 + } + if 189 <= data[p] { + goto tr420 + } + goto tr148 + st676: + if p++; p == pe { + goto _test_eof676 + } + st_case_676: + if data[p] == 191 { + goto tr571 + } + if 161 <= data[p] && data[p] <= 186 { + goto tr148 + } + goto tr420 + st677: + if p++; p == pe { + goto _test_eof677 + } + st_case_677: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 190 { + goto tr148 + } + case data[p] >= 158: + goto tr595 + } + goto tr420 + st678: + if p++; p == pe { + goto _test_eof678 + } + st_case_678: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] >= 130: + goto tr148 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr595 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st679: + if p++; p == pe { + goto _test_eof679 + } + st_case_679: + switch data[p] { + case 144: + goto st680 + case 145: + goto st687 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st708 + case 155: + goto st715 + case 157: + goto st717 + case 158: + goto st725 + case 159: + goto st403 + } + goto tr420 + st680: + if p++; p == pe { + goto _test_eof680 + } + st_case_680: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st681 + case 138: + goto st313 + case 139: + goto st682 + case 140: + goto st315 + case 141: + goto st683 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st684 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st685 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st686 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr420 + st681: + if p++; p == pe { + goto _test_eof681 + } + st_case_681: + if data[p] == 189 { + goto tr595 + } + goto tr420 + st682: + if p++; p == pe { + goto _test_eof682 + } + st_case_682: + if data[p] == 160 { + goto tr595 + } + if 145 <= data[p] { + goto tr420 + } + goto tr148 + st683: + if p++; p == pe { + goto _test_eof683 + } + st_case_683: + switch { + case data[p] < 182: + if 139 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr420 + } + default: + goto tr595 + } + goto tr148 + st684: + if p++; p == pe { + goto _test_eof684 + } + st_case_684: + switch { + case data[p] < 160: + if 158 <= data[p] && data[p] <= 159 { + goto tr2 + } + case data[p] > 169: + if 170 <= data[p] { + goto tr2 + } + default: + goto tr421 + } + goto tr148 + st685: + if p++; p == pe { + goto _test_eof685 + } + st_case_685: + switch data[p] { + case 128: + goto tr148 + case 191: + goto tr595 + } + switch { + case data[p] < 144: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr595 + } + case data[p] > 134: + if 140 <= data[p] && data[p] <= 143 { + goto tr595 + } + default: + goto tr595 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto tr595 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st686: + if p++; p == pe { + goto _test_eof686 + } + st_case_686: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 164: + if 165 <= data[p] && data[p] <= 166 { + goto tr595 + } + default: + goto tr148 + } + goto tr420 + st687: + if p++; p == pe { + goto _test_eof687 + } + st_case_687: + switch data[p] { + case 128: + goto st688 + case 129: + goto st689 + case 130: + goto st690 + case 131: + goto st691 + case 132: + goto st692 + case 133: + goto st693 + case 134: + goto st694 + case 135: + goto st695 + case 136: + goto st696 + case 138: + goto st348 + case 139: + goto st697 + case 140: + goto st698 + case 141: + goto st699 + case 146: + goto st700 + case 147: + goto st701 + case 150: + goto st702 + case 151: + goto st703 + case 152: + goto st700 + case 153: + goto st704 + case 154: + goto st705 + case 155: + goto st538 + case 156: + goto st706 + case 162: + goto st359 + case 163: + goto st707 + case 171: + goto st361 + } + goto tr420 + st688: + if p++; p == pe { + goto _test_eof688 + } + st_case_688: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr595 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr595 + } + default: + goto tr148 + } + goto tr420 + st689: + if p++; p == pe { + goto _test_eof689 + } + st_case_689: + switch { + case data[p] < 166: + if 135 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] && data[p] <= 190 { + goto tr420 + } + default: + goto tr421 + } + goto tr595 + st690: + if p++; p == pe { + goto _test_eof690 + } + st_case_690: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr595 + st691: + if p++; p == pe { + goto _test_eof691 + } + st_case_691: + switch { + case data[p] > 168: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 144: + goto tr148 + } + goto tr2 + st692: + if p++; p == pe { + goto _test_eof692 + } + st_case_692: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr595 + } + case data[p] > 166: + switch { + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr421 + } + case data[p] >= 167: + goto tr595 + } + default: + goto tr148 + } + goto tr420 + st693: + if p++; p == pe { + goto _test_eof693 + } + st_case_693: + switch data[p] { + case 179: + goto tr595 + case 182: + goto tr148 + } + if 144 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr420 + st694: + if p++; p == pe { + goto _test_eof694 + } + st_case_694: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr595 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr595 + } + default: + goto tr148 + } + goto tr420 + st695: + if p++; p == pe { + goto _test_eof695 + } + st_case_695: + if data[p] == 155 { + goto tr420 + } + switch { + case data[p] < 141: + switch { + case data[p] > 132: + if 133 <= data[p] && data[p] <= 137 { + goto tr420 + } + case data[p] >= 129: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] < 154: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] > 156: + if 157 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + default: + goto tr420 + } + goto tr595 + st696: + if p++; p == pe { + goto _test_eof696 + } + st_case_696: + switch { + case data[p] < 147: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] > 171: + if 172 <= data[p] && data[p] <= 183 { + goto tr595 + } + default: + goto tr148 + } + goto tr420 + st697: + if p++; p == pe { + goto _test_eof697 + } + st_case_697: + switch { + case data[p] < 171: + if 159 <= data[p] && data[p] <= 170 { + goto tr595 + } + case data[p] > 175: + switch { + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr421 + } + default: + goto tr420 + } + goto tr148 + st698: + if p++; p == pe { + goto _test_eof698 + } + st_case_698: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto tr595 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr595 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st699: + if p++; p == pe { + goto _test_eof699 + } + st_case_699: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr595 + } + switch { + case data[p] < 157: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr595 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr595 + } + default: + goto tr595 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr595 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr595 + } + default: + goto tr595 + } + default: + goto tr148 + } + goto tr420 + st700: + if p++; p == pe { + goto _test_eof700 + } + st_case_700: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr595 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st701: + if p++; p == pe { + goto _test_eof701 + } + st_case_701: + if data[p] == 134 { + goto tr420 + } + switch { + case data[p] < 136: + if 132 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr420 + } + goto tr595 + st702: + if p++; p == pe { + goto _test_eof702 + } + st_case_702: + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 181: + if 184 <= data[p] { + goto tr595 + } + default: + goto tr595 + } + goto tr420 + st703: + if p++; p == pe { + goto _test_eof703 + } + st_case_703: + switch { + case data[p] < 152: + if 129 <= data[p] && data[p] <= 151 { + goto tr420 + } + case data[p] > 155: + if 158 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + goto tr595 + st704: + if p++; p == pe { + goto _test_eof704 + } + st_case_704: + if data[p] == 132 { + goto tr148 + } + switch { + case data[p] < 144: + if 129 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + goto tr595 + st705: + if p++; p == pe { + goto _test_eof705 + } + st_case_705: + switch { + case data[p] > 170: + if 171 <= data[p] && data[p] <= 183 { + goto tr595 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st706: + if p++; p == pe { + goto _test_eof706 + } + st_case_706: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 157: + goto tr595 + } + goto tr420 + st707: + if p++; p == pe { + goto _test_eof707 + } + st_case_707: + switch { + case data[p] < 170: + if 160 <= data[p] && data[p] <= 169 { + goto tr421 + } + case data[p] > 190: + if 192 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st708: + if p++; p == pe { + goto _test_eof708 + } + st_case_708: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st709 + case 171: + goto st710 + case 172: + goto st711 + case 173: + goto st712 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st713 + case 190: + goto st714 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr420 + st709: + if p++; p == pe { + goto _test_eof709 + } + st_case_709: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 169 { + goto tr421 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st710: + if p++; p == pe { + goto _test_eof710 + } + st_case_710: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto tr595 + } + case data[p] >= 144: + goto tr148 + } + goto tr420 + st711: + if p++; p == pe { + goto _test_eof711 + } + st_case_711: + switch { + case data[p] > 175: + if 176 <= data[p] && data[p] <= 182 { + goto tr595 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st712: + if p++; p == pe { + goto _test_eof712 + } + st_case_712: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 131 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 183: + if 189 <= data[p] { + goto tr148 + } + case data[p] >= 163: + goto tr148 + } + default: + goto tr421 + } + goto tr2 + st713: + if p++; p == pe { + goto _test_eof713 + } + st_case_713: + switch { + case data[p] < 145: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr420 + } + default: + goto tr595 + } + goto tr148 + st714: + if p++; p == pe { + goto _test_eof714 + } + st_case_714: + switch { + case data[p] > 146: + if 147 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 143: + goto tr595 + } + goto tr420 + st715: + if p++; p == pe { + goto _test_eof715 + } + st_case_715: + switch data[p] { + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st716 + } + goto tr420 + st716: + if p++; p == pe { + goto _test_eof716 + } + st_case_716: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr595 + } + case data[p] >= 157: + goto tr595 + } + default: + goto tr148 + } + goto tr420 + st717: + if p++; p == pe { + goto _test_eof717 + } + st_case_717: + switch data[p] { + case 133: + goto st718 + case 134: + goto st719 + case 137: + goto st720 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st721 + case 168: + goto st722 + case 169: + goto st723 + case 170: + goto st724 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr420 + st718: + if p++; p == pe { + goto _test_eof718 + } + st_case_718: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr595 + } + case data[p] >= 165: + goto tr595 + } + goto tr420 + st719: + if p++; p == pe { + goto _test_eof719 + } + st_case_719: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr420 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr595 + st720: + if p++; p == pe { + goto _test_eof720 + } + st_case_720: + if 130 <= data[p] && data[p] <= 132 { + goto tr595 + } + goto tr420 + st721: + if p++; p == pe { + goto _test_eof721 + } + st_case_721: + if data[p] == 131 { + goto tr2 + } + switch { + case data[p] < 142: + if 140 <= data[p] && data[p] <= 141 { + goto tr2 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr2 + } + default: + goto tr421 + } + goto tr148 + st722: + if p++; p == pe { + goto _test_eof722 + } + st_case_722: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr595 + } + case data[p] >= 128: + goto tr595 + } + goto tr420 + st723: + if p++; p == pe { + goto _test_eof723 + } + st_case_723: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 173: + goto tr420 + } + goto tr595 + st724: + if p++; p == pe { + goto _test_eof724 + } + st_case_724: + if data[p] == 132 { + goto tr595 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr595 + } + case data[p] >= 155: + goto tr595 + } + goto tr420 + st725: + if p++; p == pe { + goto _test_eof725 + } + st_case_725: + switch data[p] { + case 160: + goto st147 + case 163: + goto st726 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr420 + st726: + if p++; p == pe { + goto _test_eof726 + } + st_case_726: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 150: + if 151 <= data[p] { + goto tr420 + } + default: + goto tr595 + } + goto tr148 + st727: + if p++; p == pe { + goto _test_eof727 + } + st_case_727: + if data[p] == 160 { + goto st728 + } + goto tr420 + st728: + if p++; p == pe { + goto _test_eof728 + } + st_case_728: + switch data[p] { + case 128: + goto st729 + case 129: + goto st730 + case 132: + goto st576 + case 135: + goto st732 + } + if 133 <= data[p] && data[p] <= 134 { + goto st731 + } + goto tr420 + st729: + if p++; p == pe { + goto _test_eof729 + } + st_case_729: + if data[p] == 129 { + goto tr595 + } + if 160 <= data[p] { + goto tr595 + } + goto tr420 + st730: + if p++; p == pe { + goto _test_eof730 + } + st_case_730: + if 192 <= data[p] { + goto tr420 + } + goto tr595 + st731: + if p++; p == pe { + goto _test_eof731 + } + st_case_731: + goto tr595 + st732: + if p++; p == pe { + goto _test_eof732 + } + st_case_732: + if 176 <= data[p] { + goto tr420 + } + goto tr595 + st733: + if p++; p == pe { + goto _test_eof733 + } + st_case_733: + if data[p] == 156 { + goto st568 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto st568 + } + case data[p] >= 128: + goto st568 + } + goto tr420 + st734: + if p++; p == pe { + goto _test_eof734 + } + st_case_734: + if data[p] == 176 { + goto st568 + } + if 139 <= data[p] && data[p] <= 159 { + goto st568 + } + goto tr420 + st735: + if p++; p == pe { + goto _test_eof735 + } + st_case_735: + switch { + case data[p] < 159: + if 150 <= data[p] && data[p] <= 157 { + goto st568 + } + case data[p] > 164: + switch { + case data[p] > 168: + if 170 <= data[p] && data[p] <= 173 { + goto st568 + } + case data[p] >= 167: + goto st568 + } + default: + goto st568 + } + goto tr420 + st736: + if p++; p == pe { + goto _test_eof736 + } + st_case_736: + switch data[p] { + case 143: + goto st568 + case 145: + goto st568 + } + if 176 <= data[p] { + goto st568 + } + goto tr420 + st737: + if p++; p == pe { + goto _test_eof737 + } + st_case_737: + if 139 <= data[p] { + goto tr420 + } + goto st568 + st738: + if p++; p == pe { + goto _test_eof738 + } + st_case_738: + if 166 <= data[p] && data[p] <= 176 { + goto st568 + } + goto tr420 + st739: + if p++; p == pe { + goto _test_eof739 + } + st_case_739: + if 171 <= data[p] && data[p] <= 179 { + goto st568 + } + goto tr420 + st740: + if p++; p == pe { + goto _test_eof740 + } + st_case_740: + switch data[p] { + case 160: + goto st741 + case 161: + goto st742 + case 163: + goto st743 + case 164: + goto st744 + case 165: + goto st745 + case 167: + goto st747 + case 169: + goto st748 + case 171: + goto st749 + case 173: + goto st751 + case 174: + goto st752 + case 175: + goto st753 + case 176: + goto st754 + case 177: + goto st755 + case 179: + goto st756 + case 180: + goto st757 + case 181: + goto st758 + case 182: + goto st759 + case 183: + goto st760 + case 184: + goto st761 + case 185: + goto st762 + case 186: + goto st763 + case 187: + goto st764 + case 188: + goto st765 + case 189: + goto st766 + case 190: + goto st767 + case 191: + goto st768 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto st750 + } + case data[p] >= 166: + goto st746 + } + goto tr420 + st741: + if p++; p == pe { + goto _test_eof741 + } + st_case_741: + switch { + case data[p] < 155: + if 150 <= data[p] && data[p] <= 153 { + goto st568 + } + case data[p] > 163: + switch { + case data[p] > 167: + if 169 <= data[p] && data[p] <= 173 { + goto st568 + } + case data[p] >= 165: + goto st568 + } + default: + goto st568 + } + goto tr420 + st742: + if p++; p == pe { + goto _test_eof742 + } + st_case_742: + if 153 <= data[p] && data[p] <= 155 { + goto st568 + } + goto tr420 + st743: + if p++; p == pe { + goto _test_eof743 + } + st_case_743: + if 163 <= data[p] { + goto st568 + } + goto tr420 + st744: + if p++; p == pe { + goto _test_eof744 + } + st_case_744: + if data[p] == 189 { + goto tr420 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr420 + } + goto st568 + st745: + if p++; p == pe { + goto _test_eof745 + } + st_case_745: + if data[p] == 144 { + goto tr420 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr420 + } + case data[p] >= 152: + goto tr420 + } + goto st568 + st746: + if p++; p == pe { + goto _test_eof746 + } + st_case_746: + if data[p] == 188 { + goto st568 + } + switch { + case data[p] > 131: + if 190 <= data[p] { + goto st568 + } + case data[p] >= 129: + goto st568 + } + goto tr420 + st747: + if p++; p == pe { + goto _test_eof747 + } + st_case_747: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr420 + } + case data[p] >= 133: + goto tr420 + } + case data[p] > 150: + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr420 + } + case data[p] >= 152: + goto tr420 + } + default: + goto tr420 + } + goto st568 + st748: + if p++; p == pe { + goto _test_eof748 + } + st_case_748: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr420 + } + case data[p] >= 131: + goto tr420 + } + case data[p] > 144: + switch { + case data[p] < 178: + if 146 <= data[p] && data[p] <= 175 { + goto tr420 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto st568 + st749: + if p++; p == pe { + goto _test_eof749 + } + st_case_749: + switch data[p] { + case 134: + goto tr420 + case 138: + goto tr420 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr420 + } + case data[p] >= 142: + goto tr420 + } + goto st568 + st750: + if p++; p == pe { + goto _test_eof750 + } + st_case_750: + if data[p] == 188 { + goto st568 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto st568 + } + case data[p] >= 129: + goto st568 + } + goto tr420 + st751: + if p++; p == pe { + goto _test_eof751 + } + st_case_751: + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto st568 + } + case data[p] >= 128: + goto st568 + } + case data[p] > 141: + switch { + case data[p] > 151: + if 162 <= data[p] && data[p] <= 163 { + goto st568 + } + case data[p] >= 150: + goto st568 + } + default: + goto st568 + } + goto tr420 + st752: + if p++; p == pe { + goto _test_eof752 + } + st_case_752: + if data[p] == 130 { + goto st568 + } + if 190 <= data[p] && data[p] <= 191 { + goto st568 + } + goto tr420 + st753: + if p++; p == pe { + goto _test_eof753 + } + st_case_753: + if data[p] == 151 { + goto st568 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto st568 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto st568 + } + default: + goto st568 + } + goto tr420 + st754: + if p++; p == pe { + goto _test_eof754 + } + st_case_754: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto st568 + } + case data[p] >= 128: + goto st568 + } + goto tr420 + st755: + if p++; p == pe { + goto _test_eof755 + } + st_case_755: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + } + switch { + case data[p] < 151: + if 142 <= data[p] && data[p] <= 148 { + goto tr420 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto st568 + st756: + if p++; p == pe { + goto _test_eof756 + } + st_case_756: + switch { + case data[p] < 138: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 136 { + goto st568 + } + case data[p] >= 128: + goto st568 + } + case data[p] > 141: + switch { + case data[p] > 150: + if 162 <= data[p] && data[p] <= 163 { + goto st568 + } + case data[p] >= 149: + goto st568 + } + default: + goto st568 + } + goto tr420 + st757: + if p++; p == pe { + goto _test_eof757 + } + st_case_757: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto st568 + } + case data[p] >= 129: + goto st568 + } + goto tr420 + st758: + if p++; p == pe { + goto _test_eof758 + } + st_case_758: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + } + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 150 { + goto tr420 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto st568 + st759: + if p++; p == pe { + goto _test_eof759 + } + st_case_759: + if 130 <= data[p] && data[p] <= 131 { + goto st568 + } + goto tr420 + st760: + if p++; p == pe { + goto _test_eof760 + } + st_case_760: + switch data[p] { + case 138: + goto st568 + case 150: + goto st568 + } + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 148 { + goto st568 + } + case data[p] > 159: + if 178 <= data[p] && data[p] <= 179 { + goto st568 + } + default: + goto st568 + } + goto tr420 + st761: + if p++; p == pe { + goto _test_eof761 + } + st_case_761: + if data[p] == 177 { + goto st568 + } + if 180 <= data[p] && data[p] <= 186 { + goto st568 + } + goto tr420 + st762: + if p++; p == pe { + goto _test_eof762 + } + st_case_762: + if 135 <= data[p] && data[p] <= 142 { + goto st568 + } + goto tr420 + st763: + if p++; p == pe { + goto _test_eof763 + } + st_case_763: + if data[p] == 177 { + goto st568 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto st568 + } + case data[p] >= 180: + goto st568 + } + goto tr420 + st764: + if p++; p == pe { + goto _test_eof764 + } + st_case_764: + if 136 <= data[p] && data[p] <= 141 { + goto st568 + } + goto tr420 + st765: + if p++; p == pe { + goto _test_eof765 + } + st_case_765: + switch data[p] { + case 181: + goto st568 + case 183: + goto st568 + case 185: + goto st568 + } + switch { + case data[p] > 153: + if 190 <= data[p] && data[p] <= 191 { + goto st568 + } + case data[p] >= 152: + goto st568 + } + goto tr420 + st766: + if p++; p == pe { + goto _test_eof766 + } + st_case_766: + if 177 <= data[p] && data[p] <= 191 { + goto st568 + } + goto tr420 + st767: + if p++; p == pe { + goto _test_eof767 + } + st_case_767: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto st568 + } + case data[p] > 135: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto st568 + } + case data[p] >= 141: + goto st568 + } + default: + goto st568 + } + goto tr420 + st768: + if p++; p == pe { + goto _test_eof768 + } + st_case_768: + if data[p] == 134 { + goto st568 + } + goto tr420 + st769: + if p++; p == pe { + goto _test_eof769 + } + st_case_769: + switch data[p] { + case 128: + goto st770 + case 129: + goto st771 + case 130: + goto st772 + case 141: + goto st773 + case 156: + goto st774 + case 157: + goto st775 + case 158: + goto st776 + case 159: + goto st777 + case 160: + goto st778 + case 162: + goto st779 + case 164: + goto st780 + case 168: + goto st781 + case 169: + goto st782 + case 170: + goto st783 + case 172: + goto st784 + case 173: + goto st785 + case 174: + goto st786 + case 175: + goto st787 + case 176: + goto st788 + case 179: + goto st789 + case 183: + goto st790 + } + goto tr420 + st770: + if p++; p == pe { + goto _test_eof770 + } + st_case_770: + if 171 <= data[p] && data[p] <= 190 { + goto st568 + } + goto tr420 + st771: + if p++; p == pe { + goto _test_eof771 + } + st_case_771: + switch { + case data[p] < 162: + switch { + case data[p] > 153: + if 158 <= data[p] && data[p] <= 160 { + goto st568 + } + case data[p] >= 150: + goto st568 + } + case data[p] > 164: + switch { + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto st568 + } + case data[p] >= 167: + goto st568 + } + default: + goto st568 + } + goto tr420 + st772: + if p++; p == pe { + goto _test_eof772 + } + st_case_772: + if data[p] == 143 { + goto st568 + } + switch { + case data[p] > 141: + if 154 <= data[p] && data[p] <= 157 { + goto st568 + } + case data[p] >= 130: + goto st568 + } + goto tr420 + st773: + if p++; p == pe { + goto _test_eof773 + } + st_case_773: + if 157 <= data[p] && data[p] <= 159 { + goto st568 + } + goto tr420 + st774: + if p++; p == pe { + goto _test_eof774 + } + st_case_774: + switch { + case data[p] > 148: + if 178 <= data[p] && data[p] <= 180 { + goto st568 + } + case data[p] >= 146: + goto st568 + } + goto tr420 + st775: + if p++; p == pe { + goto _test_eof775 + } + st_case_775: + switch { + case data[p] > 147: + if 178 <= data[p] && data[p] <= 179 { + goto st568 + } + case data[p] >= 146: + goto st568 + } + goto tr420 + st776: + if p++; p == pe { + goto _test_eof776 + } + st_case_776: + if 180 <= data[p] { + goto st568 + } + goto tr420 + st777: + if p++; p == pe { + goto _test_eof777 + } + st_case_777: + switch { + case data[p] > 156: + if 158 <= data[p] { + goto tr420 + } + case data[p] >= 148: + goto tr420 + } + goto st568 + st778: + if p++; p == pe { + goto _test_eof778 + } + st_case_778: + if 139 <= data[p] && data[p] <= 142 { + goto st568 + } + goto tr420 + st779: + if p++; p == pe { + goto _test_eof779 + } + st_case_779: + if data[p] == 169 { + goto st568 + } + goto tr420 + st780: + if p++; p == pe { + goto _test_eof780 + } + st_case_780: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto st568 + } + case data[p] >= 160: + goto st568 + } + goto tr420 + st781: + if p++; p == pe { + goto _test_eof781 + } + st_case_781: + if 151 <= data[p] && data[p] <= 155 { + goto st568 + } + goto tr420 + st782: + if p++; p == pe { + goto _test_eof782 + } + st_case_782: + if data[p] == 191 { + goto st568 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto st568 + } + case data[p] >= 149: + goto st568 + } + goto tr420 + st783: + if p++; p == pe { + goto _test_eof783 + } + st_case_783: + if 176 <= data[p] && data[p] <= 190 { + goto st568 + } + goto tr420 + st784: + if p++; p == pe { + goto _test_eof784 + } + st_case_784: + switch { + case data[p] > 132: + if 180 <= data[p] { + goto st568 + } + case data[p] >= 128: + goto st568 + } + goto tr420 + st785: + if p++; p == pe { + goto _test_eof785 + } + st_case_785: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 133: + goto tr420 + } + goto st568 + st786: + if p++; p == pe { + goto _test_eof786 + } + st_case_786: + switch { + case data[p] > 130: + if 161 <= data[p] && data[p] <= 173 { + goto st568 + } + case data[p] >= 128: + goto st568 + } + goto tr420 + st787: + if p++; p == pe { + goto _test_eof787 + } + st_case_787: + if 166 <= data[p] && data[p] <= 179 { + goto st568 + } + goto tr420 + st788: + if p++; p == pe { + goto _test_eof788 + } + st_case_788: + if 164 <= data[p] && data[p] <= 183 { + goto st568 + } + goto tr420 + st789: + if p++; p == pe { + goto _test_eof789 + } + st_case_789: + if data[p] == 173 { + goto st568 + } + switch { + case data[p] < 148: + if 144 <= data[p] && data[p] <= 146 { + goto st568 + } + case data[p] > 168: + switch { + case data[p] > 180: + if 184 <= data[p] && data[p] <= 185 { + goto st568 + } + case data[p] >= 178: + goto st568 + } + default: + goto st568 + } + goto tr420 + st790: + if p++; p == pe { + goto _test_eof790 + } + st_case_790: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto st568 + } + case data[p] >= 128: + goto st568 + } + goto tr420 + st791: + if p++; p == pe { + goto _test_eof791 + } + st_case_791: + switch data[p] { + case 128: + goto st792 + case 129: + goto st793 + case 131: + goto st794 + case 179: + goto st795 + case 181: + goto st796 + case 183: + goto st797 + } + goto tr420 + st792: + if p++; p == pe { + goto _test_eof792 + } + st_case_792: + switch { + case data[p] > 143: + if 170 <= data[p] && data[p] <= 174 { + goto st568 + } + case data[p] >= 140: + goto st568 + } + goto tr420 + st793: + if p++; p == pe { + goto _test_eof793 + } + st_case_793: + switch { + case data[p] > 164: + if 166 <= data[p] && data[p] <= 175 { + goto st568 + } + case data[p] >= 160: + goto st568 + } + goto tr420 + st794: + if p++; p == pe { + goto _test_eof794 + } + st_case_794: + if 144 <= data[p] && data[p] <= 176 { + goto st568 + } + goto tr420 + st795: + if p++; p == pe { + goto _test_eof795 + } + st_case_795: + if 175 <= data[p] && data[p] <= 177 { + goto st568 + } + goto tr420 + st796: + if p++; p == pe { + goto _test_eof796 + } + st_case_796: + if data[p] == 191 { + goto st568 + } + goto tr420 + st797: + if p++; p == pe { + goto _test_eof797 + } + st_case_797: + if 160 <= data[p] && data[p] <= 191 { + goto st568 + } + goto tr420 + st798: + if p++; p == pe { + goto _test_eof798 + } + st_case_798: + switch data[p] { + case 128: + goto st799 + case 130: + goto st800 + } + goto tr420 + st799: + if p++; p == pe { + goto _test_eof799 + } + st_case_799: + if 170 <= data[p] && data[p] <= 175 { + goto st568 + } + goto tr420 + st800: + if p++; p == pe { + goto _test_eof800 + } + st_case_800: + if 153 <= data[p] && data[p] <= 154 { + goto st568 + } + goto tr420 + st801: + if p++; p == pe { + goto _test_eof801 + } + st_case_801: + switch data[p] { + case 153: + goto st802 + case 154: + goto st803 + case 155: + goto st804 + case 160: + goto st805 + case 162: + goto st806 + case 163: + goto st807 + case 164: + goto st808 + case 165: + goto st809 + case 166: + goto st810 + case 167: + goto st811 + case 168: + goto st812 + case 169: + goto st813 + case 170: + goto st814 + case 171: + goto st815 + case 175: + goto st816 + } + goto tr420 + st802: + if p++; p == pe { + goto _test_eof802 + } + st_case_802: + switch { + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto st568 + } + case data[p] >= 175: + goto st568 + } + goto tr420 + st803: + if p++; p == pe { + goto _test_eof803 + } + st_case_803: + if 158 <= data[p] && data[p] <= 159 { + goto st568 + } + goto tr420 + st804: + if p++; p == pe { + goto _test_eof804 + } + st_case_804: + if 176 <= data[p] && data[p] <= 177 { + goto st568 + } + goto tr420 + st805: + if p++; p == pe { + goto _test_eof805 + } + st_case_805: + switch data[p] { + case 130: + goto st568 + case 134: + goto st568 + case 139: + goto st568 + } + if 163 <= data[p] && data[p] <= 167 { + goto st568 + } + goto tr420 + st806: + if p++; p == pe { + goto _test_eof806 + } + st_case_806: + switch { + case data[p] > 129: + if 180 <= data[p] { + goto st568 + } + case data[p] >= 128: + goto st568 + } + goto tr420 + st807: + if p++; p == pe { + goto _test_eof807 + } + st_case_807: + switch { + case data[p] > 159: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 133: + goto tr420 + } + goto st568 + st808: + if p++; p == pe { + goto _test_eof808 + } + st_case_808: + if 166 <= data[p] && data[p] <= 173 { + goto st568 + } + goto tr420 + st809: + if p++; p == pe { + goto _test_eof809 + } + st_case_809: + if 135 <= data[p] && data[p] <= 147 { + goto st568 + } + goto tr420 + st810: + if p++; p == pe { + goto _test_eof810 + } + st_case_810: + switch { + case data[p] > 131: + if 179 <= data[p] { + goto st568 + } + case data[p] >= 128: + goto st568 + } + goto tr420 + st811: + if p++; p == pe { + goto _test_eof811 + } + st_case_811: + switch { + case data[p] > 164: + if 166 <= data[p] { + goto tr420 + } + case data[p] >= 129: + goto tr420 + } + goto st568 + st812: + if p++; p == pe { + goto _test_eof812 + } + st_case_812: + if 169 <= data[p] && data[p] <= 182 { + goto st568 + } + goto tr420 + st813: + if p++; p == pe { + goto _test_eof813 + } + st_case_813: + if data[p] == 131 { + goto st568 + } + switch { + case data[p] > 141: + if 187 <= data[p] && data[p] <= 189 { + goto st568 + } + case data[p] >= 140: + goto st568 + } + goto tr420 + st814: + if p++; p == pe { + goto _test_eof814 + } + st_case_814: + if data[p] == 176 { + goto st568 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto st568 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto st568 + } + default: + goto st568 + } + goto tr420 + st815: + if p++; p == pe { + goto _test_eof815 + } + st_case_815: + if data[p] == 129 { + goto st568 + } + switch { + case data[p] > 175: + if 181 <= data[p] && data[p] <= 182 { + goto st568 + } + case data[p] >= 171: + goto st568 + } + goto tr420 + st816: + if p++; p == pe { + goto _test_eof816 + } + st_case_816: + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 173 { + goto st568 + } + case data[p] >= 163: + goto st568 + } + goto tr420 + st817: + if p++; p == pe { + goto _test_eof817 + } + st_case_817: + switch data[p] { + case 172: + goto st818 + case 173: + goto st819 + case 184: + goto st820 + case 187: + goto st796 + case 190: + goto st803 + case 191: + goto st821 + } + goto tr420 + st818: + if p++; p == pe { + goto _test_eof818 + } + st_case_818: + switch data[p] { + case 158: + goto st568 + case 190: + goto tr595 + } + switch { + case data[p] < 170: + if 157 <= data[p] && data[p] <= 168 { + goto tr595 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr595 + } + default: + goto tr595 + } + goto tr420 + st819: + if p++; p == pe { + goto _test_eof819 + } + st_case_819: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 129 { + goto tr595 + } + case data[p] > 132: + if 134 <= data[p] && data[p] <= 143 { + goto tr595 + } + default: + goto tr595 + } + goto tr420 + st820: + if p++; p == pe { + goto _test_eof820 + } + st_case_820: + switch { + case data[p] > 143: + if 160 <= data[p] && data[p] <= 175 { + goto st568 + } + case data[p] >= 128: + goto st568 + } + goto tr420 + st821: + if p++; p == pe { + goto _test_eof821 + } + st_case_821: + if 185 <= data[p] && data[p] <= 187 { + goto st568 + } + goto tr420 + st822: + if p++; p == pe { + goto _test_eof822 + } + st_case_822: + switch data[p] { + case 144: + goto st823 + case 145: + goto st829 + case 150: + goto st848 + case 155: + goto st853 + case 157: + goto st855 + case 158: + goto st862 + } + goto tr420 + st823: + if p++; p == pe { + goto _test_eof823 + } + st_case_823: + switch data[p] { + case 135: + goto st824 + case 139: + goto st825 + case 141: + goto st826 + case 168: + goto st827 + case 171: + goto st828 + } + goto tr420 + st824: + if p++; p == pe { + goto _test_eof824 + } + st_case_824: + if data[p] == 189 { + goto st568 + } + goto tr420 + st825: + if p++; p == pe { + goto _test_eof825 + } + st_case_825: + if data[p] == 160 { + goto st568 + } + goto tr420 + st826: + if p++; p == pe { + goto _test_eof826 + } + st_case_826: + if 182 <= data[p] && data[p] <= 186 { + goto st568 + } + goto tr420 + st827: + if p++; p == pe { + goto _test_eof827 + } + st_case_827: + if data[p] == 191 { + goto st568 + } + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto st568 + } + case data[p] > 134: + switch { + case data[p] > 143: + if 184 <= data[p] && data[p] <= 186 { + goto st568 + } + case data[p] >= 140: + goto st568 + } + default: + goto st568 + } + goto tr420 + st828: + if p++; p == pe { + goto _test_eof828 + } + st_case_828: + if 165 <= data[p] && data[p] <= 166 { + goto st568 + } + goto tr420 + st829: + if p++; p == pe { + goto _test_eof829 + } + st_case_829: + switch data[p] { + case 128: + goto st830 + case 129: + goto st831 + case 130: + goto st832 + case 132: + goto st833 + case 133: + goto st834 + case 134: + goto st835 + case 135: + goto st836 + case 136: + goto st837 + case 139: + goto st838 + case 140: + goto st839 + case 141: + goto st840 + case 146: + goto st841 + case 147: + goto st842 + case 150: + goto st843 + case 151: + goto st844 + case 152: + goto st841 + case 153: + goto st845 + case 154: + goto st846 + case 156: + goto st847 + } + goto tr420 + st830: + if p++; p == pe { + goto _test_eof830 + } + st_case_830: + switch { + case data[p] > 130: + if 184 <= data[p] { + goto st568 + } + case data[p] >= 128: + goto st568 + } + goto tr420 + st831: + if p++; p == pe { + goto _test_eof831 + } + st_case_831: + if 135 <= data[p] && data[p] <= 190 { + goto tr420 + } + goto st568 + st832: + if p++; p == pe { + goto _test_eof832 + } + st_case_832: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr420 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto st568 + st833: + if p++; p == pe { + goto _test_eof833 + } + st_case_833: + switch { + case data[p] > 130: + if 167 <= data[p] && data[p] <= 180 { + goto st568 + } + case data[p] >= 128: + goto st568 + } + goto tr420 + st834: + if p++; p == pe { + goto _test_eof834 + } + st_case_834: + if data[p] == 179 { + goto st568 + } + goto tr420 + st835: + if p++; p == pe { + goto _test_eof835 + } + st_case_835: + switch { + case data[p] > 130: + if 179 <= data[p] { + goto st568 + } + case data[p] >= 128: + goto st568 + } + goto tr420 + st836: + if p++; p == pe { + goto _test_eof836 + } + st_case_836: + switch { + case data[p] > 137: + if 141 <= data[p] { + goto tr420 + } + case data[p] >= 129: + goto tr420 + } + goto st568 + st837: + if p++; p == pe { + goto _test_eof837 + } + st_case_837: + if 172 <= data[p] && data[p] <= 183 { + goto st568 + } + goto tr420 + st838: + if p++; p == pe { + goto _test_eof838 + } + st_case_838: + if 159 <= data[p] && data[p] <= 170 { + goto st568 + } + goto tr420 + st839: + if p++; p == pe { + goto _test_eof839 + } + st_case_839: + if data[p] == 188 { + goto st568 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto st568 + } + case data[p] >= 128: + goto st568 + } + goto tr420 + st840: + if p++; p == pe { + goto _test_eof840 + } + st_case_840: + if data[p] == 151 { + goto st568 + } + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto st568 + } + case data[p] >= 128: + goto st568 + } + case data[p] > 141: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto st568 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto st568 + } + default: + goto st568 + } + default: + goto st568 + } + goto tr420 + st841: + if p++; p == pe { + goto _test_eof841 + } + st_case_841: + if 176 <= data[p] { + goto st568 + } + goto tr420 + st842: + if p++; p == pe { + goto _test_eof842 + } + st_case_842: + if 132 <= data[p] { + goto tr420 + } + goto st568 + st843: + if p++; p == pe { + goto _test_eof843 + } + st_case_843: + switch { + case data[p] > 181: + if 184 <= data[p] { + goto st568 + } + case data[p] >= 175: + goto st568 + } + goto tr420 + st844: + if p++; p == pe { + goto _test_eof844 + } + st_case_844: + switch { + case data[p] > 155: + if 158 <= data[p] { + goto tr420 + } + case data[p] >= 129: + goto tr420 + } + goto st568 + st845: + if p++; p == pe { + goto _test_eof845 + } + st_case_845: + if 129 <= data[p] { + goto tr420 + } + goto st568 + st846: + if p++; p == pe { + goto _test_eof846 + } + st_case_846: + if 171 <= data[p] && data[p] <= 183 { + goto st568 + } + goto tr420 + st847: + if p++; p == pe { + goto _test_eof847 + } + st_case_847: + if 157 <= data[p] && data[p] <= 171 { + goto st568 + } + goto tr420 + st848: + if p++; p == pe { + goto _test_eof848 + } + st_case_848: + switch data[p] { + case 171: + goto st849 + case 172: + goto st850 + case 189: + goto st851 + case 190: + goto st852 + } + goto tr420 + st849: + if p++; p == pe { + goto _test_eof849 + } + st_case_849: + if 176 <= data[p] && data[p] <= 180 { + goto st568 + } + goto tr420 + st850: + if p++; p == pe { + goto _test_eof850 + } + st_case_850: + if 176 <= data[p] && data[p] <= 182 { + goto st568 + } + goto tr420 + st851: + if p++; p == pe { + goto _test_eof851 + } + st_case_851: + if 145 <= data[p] && data[p] <= 190 { + goto st568 + } + goto tr420 + st852: + if p++; p == pe { + goto _test_eof852 + } + st_case_852: + if 143 <= data[p] && data[p] <= 146 { + goto st568 + } + goto tr420 + st853: + if p++; p == pe { + goto _test_eof853 + } + st_case_853: + if data[p] == 178 { + goto st854 + } + goto tr420 + st854: + if p++; p == pe { + goto _test_eof854 + } + st_case_854: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto st568 + } + case data[p] >= 157: + goto st568 + } + goto tr420 + st855: + if p++; p == pe { + goto _test_eof855 + } + st_case_855: + switch data[p] { + case 133: + goto st856 + case 134: + goto st857 + case 137: + goto st858 + case 168: + goto st859 + case 169: + goto st860 + case 170: + goto st861 + } + goto tr420 + st856: + if p++; p == pe { + goto _test_eof856 + } + st_case_856: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto st568 + } + case data[p] >= 165: + goto st568 + } + goto tr420 + st857: + if p++; p == pe { + goto _test_eof857 + } + st_case_857: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr420 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto st568 + st858: + if p++; p == pe { + goto _test_eof858 + } + st_case_858: + if 130 <= data[p] && data[p] <= 132 { + goto st568 + } + goto tr420 + st859: + if p++; p == pe { + goto _test_eof859 + } + st_case_859: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto st568 + } + case data[p] >= 128: + goto st568 + } + goto tr420 + st860: + if p++; p == pe { + goto _test_eof860 + } + st_case_860: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 173: + goto tr420 + } + goto st568 + st861: + if p++; p == pe { + goto _test_eof861 + } + st_case_861: + if data[p] == 132 { + goto st568 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto st568 + } + case data[p] >= 155: + goto st568 + } + goto tr420 + st862: + if p++; p == pe { + goto _test_eof862 + } + st_case_862: + if data[p] == 163 { + goto st863 + } + goto tr420 + st863: + if p++; p == pe { + goto _test_eof863 + } + st_case_863: + if 144 <= data[p] && data[p] <= 150 { + goto st568 + } + goto tr420 + st864: + if p++; p == pe { + goto _test_eof864 + } + st_case_864: + if data[p] == 160 { + goto st865 + } + goto tr420 + st865: + if p++; p == pe { + goto _test_eof865 + } + st_case_865: + switch data[p] { + case 128: + goto st866 + case 129: + goto st867 + case 132: + goto st570 + case 135: + goto st571 + } + if 133 <= data[p] && data[p] <= 134 { + goto st868 + } + goto tr420 + st866: + if p++; p == pe { + goto _test_eof866 + } + st_case_866: + if data[p] == 129 { + goto st568 + } + if 160 <= data[p] { + goto st568 + } + goto tr420 + st867: + if p++; p == pe { + goto _test_eof867 + } + st_case_867: + if 192 <= data[p] { + goto tr420 + } + goto st568 + st868: + if p++; p == pe { + goto _test_eof868 + } + st_case_868: + goto st568 + st869: + if p++; p == pe { + goto _test_eof869 + } + st_case_869: + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr572 + case 181: + goto tr148 + case 183: + goto st142 + case 186: + goto tr148 + } + goto tr420 + st870: + if p++; p == pe { + goto _test_eof870 + } + st_case_870: + switch data[p] { + case 151: + goto st142 + case 173: + goto tr2 + } + switch { + case data[p] < 146: + if 130 <= data[p] && data[p] <= 133 { + goto tr2 + } + case data[p] > 159: + switch { + case data[p] > 171: + if 175 <= data[p] { + goto tr2 + } + case data[p] >= 165: + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st871: + if p++; p == pe { + goto _test_eof871 + } + st_case_871: + if data[p] <= 127 { + goto tr420 + } + goto tr572 + st872: + if p++; p == pe { + goto _test_eof872 + } + st_case_872: + switch data[p] { + case 181: + goto tr420 + case 190: + goto tr420 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + goto tr572 + st873: + if p++; p == pe { + goto _test_eof873 + } + st_case_873: + switch data[p] { + case 135: + goto st142 + case 140: + goto tr148 + } + switch { + case data[p] < 142: + if 134 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 161: + if 163 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st874: + if p++; p == pe { + goto _test_eof874 + } + st_case_874: + if data[p] == 130 { + goto tr420 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr572 + } + goto tr148 + st875: + if p++; p == pe { + goto _test_eof875 + } + st_case_875: + if data[p] == 190 { + goto tr420 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr420 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + default: + goto tr572 + } + goto tr148 + st876: + if p++; p == pe { + goto _test_eof876 + } + st_case_876: + switch data[p] { + case 135: + goto tr572 + case 179: + goto tr148 + case 180: + goto st142 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr572 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st877: + if p++; p == pe { + goto _test_eof877 + } + st_case_877: + if data[p] == 156 { + goto tr572 + } + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 133 { + goto tr572 + } + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr572 + } + goto tr420 + st878: + if p++; p == pe { + goto _test_eof878 + } + st_case_878: + switch data[p] { + case 171: + goto tr421 + case 176: + goto tr572 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr572 + } + goto tr420 + st879: + if p++; p == pe { + goto _test_eof879 + } + st_case_879: + switch data[p] { + case 148: + goto tr420 + case 158: + goto tr420 + case 169: + goto tr420 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr572 + } + case data[p] >= 150: + goto tr572 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 189: + goto tr420 + } + default: + goto tr421 + } + goto tr148 + st880: + if p++; p == pe { + goto _test_eof880 + } + st_case_880: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto tr572 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr572 + } + default: + goto tr148 + } + goto tr420 + st881: + if p++; p == pe { + goto _test_eof881 + } + st_case_881: + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr420 + } + goto tr572 + st882: + if p++; p == pe { + goto _test_eof882 + } + st_case_882: + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr572 + } + goto tr148 + st883: + if p++; p == pe { + goto _test_eof883 + } + st_case_883: + if data[p] == 186 { + goto tr148 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 170: + switch { + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 171: + goto tr572 + } + default: + goto tr148 + } + goto tr420 + st884: + if p++; p == pe { + goto _test_eof884 + } + st_case_884: + switch data[p] { + case 160: + goto st885 + case 161: + goto st886 + case 162: + goto st168 + case 163: + goto st887 + case 164: + goto st888 + case 165: + goto st889 + case 166: + goto st890 + case 167: + goto st891 + case 168: + goto st892 + case 169: + goto st893 + case 170: + goto st894 + case 171: + goto st895 + case 172: + goto st896 + case 173: + goto st897 + case 174: + goto st898 + case 175: + goto st899 + case 176: + goto st900 + case 177: + goto st901 + case 178: + goto st902 + case 179: + goto st903 + case 180: + goto st904 + case 181: + goto st905 + case 182: + goto st906 + case 183: + goto st907 + case 184: + goto st908 + case 185: + goto st909 + case 186: + goto st910 + case 187: + goto st911 + case 188: + goto st912 + case 189: + goto st913 + case 190: + goto st914 + case 191: + goto st915 + } + goto tr420 + st885: + if p++; p == pe { + goto _test_eof885 + } + st_case_885: + switch data[p] { + case 154: + goto tr148 + case 164: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] > 149: + if 150 <= data[p] && data[p] <= 173 { + goto tr572 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st886: + if p++; p == pe { + goto _test_eof886 + } + st_case_886: + switch { + case data[p] > 152: + if 153 <= data[p] && data[p] <= 155 { + goto tr572 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st887: + if p++; p == pe { + goto _test_eof887 + } + st_case_887: + if 163 <= data[p] { + goto tr572 + } + goto tr420 + st888: + if p++; p == pe { + goto _test_eof888 + } + st_case_888: + if data[p] == 189 { + goto tr148 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr148 + } + goto tr572 + st889: + if p++; p == pe { + goto _test_eof889 + } + st_case_889: + switch data[p] { + case 144: + goto tr148 + case 176: + goto tr420 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 177 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr420 + } + goto tr572 + st890: + if p++; p == pe { + goto _test_eof890 + } + st_case_890: + switch data[p] { + case 132: + goto tr420 + case 169: + goto tr420 + case 177: + goto tr420 + case 188: + goto tr572 + } + switch { + case data[p] < 145: + switch { + case data[p] > 131: + if 141 <= data[p] && data[p] <= 142 { + goto tr420 + } + case data[p] >= 129: + goto tr572 + } + case data[p] > 146: + switch { + case data[p] < 186: + if 179 <= data[p] && data[p] <= 181 { + goto tr420 + } + case data[p] > 187: + if 190 <= data[p] { + goto tr572 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st891: + if p++; p == pe { + goto _test_eof891 + } + st_case_891: + switch data[p] { + case 142: + goto tr148 + case 158: + goto tr420 + } + switch { + case data[p] < 156: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 155 { + goto tr420 + } + case data[p] >= 143: + goto tr420 + } + default: + goto tr420 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr572 + st892: + if p++; p == pe { + goto _test_eof892 + } + st_case_892: + if data[p] == 188 { + goto tr572 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr572 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto tr572 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st893: + if p++; p == pe { + goto _test_eof893 + } + st_case_893: + if data[p] == 157 { + goto tr420 + } + switch { + case data[p] < 153: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 146 <= data[p] && data[p] <= 152 { + goto tr420 + } + case data[p] >= 142: + goto tr420 + } + default: + goto tr420 + } + case data[p] > 158: + switch { + case data[p] < 166: + if 159 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr572 + st894: + if p++; p == pe { + goto _test_eof894 + } + st_case_894: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr572 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto tr572 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st895: + if p++; p == pe { + goto _test_eof895 + } + st_case_895: + switch data[p] { + case 134: + goto tr420 + case 138: + goto tr420 + case 144: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] >= 142: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr420 + } + goto tr572 + st896: + if p++; p == pe { + goto _test_eof896 + } + st_case_896: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr572 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr572 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st897: + if p++; p == pe { + goto _test_eof897 + } + st_case_897: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr572 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr572 + } + default: + goto tr572 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 161: + switch { + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 162: + goto tr572 + } + default: + goto tr148 + } + default: + goto tr572 + } + goto tr420 + st898: + if p++; p == pe { + goto _test_eof898 + } + st_case_898: + switch data[p] { + case 130: + goto tr572 + case 131: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 158: + switch { + case data[p] < 142: + if 133 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 149: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] < 168: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto tr572 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st899: + if p++; p == pe { + goto _test_eof899 + } + st_case_899: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr572 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr572 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 138: + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st900: + if p++; p == pe { + goto _test_eof900 + } + st_case_900: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto tr572 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 190 <= data[p] { + goto tr572 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st901: + if p++; p == pe { + goto _test_eof901 + } + st_case_901: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 151: + goto tr420 + } + switch { + case data[p] < 160: + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 148 { + goto tr420 + } + case data[p] > 154: + if 155 <= data[p] && data[p] <= 159 { + goto tr420 + } + default: + goto tr148 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr572 + st902: + if p++; p == pe { + goto _test_eof902 + } + st_case_902: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr572 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr572 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st903: + if p++; p == pe { + goto _test_eof903 + } + st_case_903: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr572 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr572 + } + default: + goto tr572 + } + case data[p] > 150: + switch { + case data[p] < 162: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 163: + switch { + case data[p] > 175: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st904: + if p++; p == pe { + goto _test_eof904 + } + st_case_904: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto tr572 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto tr572 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st905: + if p++; p == pe { + goto _test_eof905 + } + st_case_905: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 142: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 150 { + goto tr420 + } + case data[p] > 158: + if 159 <= data[p] && data[p] <= 161 { + goto tr148 + } + default: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr572 + st906: + if p++; p == pe { + goto _test_eof906 + } + st_case_906: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr572 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st907: + if p++; p == pe { + goto _test_eof907 + } + st_case_907: + switch data[p] { + case 138: + goto tr572 + case 150: + goto tr572 + } + switch { + case data[p] < 152: + switch { + case data[p] > 134: + if 143 <= data[p] && data[p] <= 148 { + goto tr572 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto tr572 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr572 + } + goto tr420 + st908: + if p++; p == pe { + goto _test_eof908 + } + st_case_908: + if data[p] == 177 { + goto tr572 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr572 + } + goto tr420 + st909: + if p++; p == pe { + goto _test_eof909 + } + st_case_909: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 135: + goto tr572 + } + goto tr420 + st910: + if p++; p == pe { + goto _test_eof910 + } + st_case_910: + if data[p] == 177 { + goto tr572 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 180: + goto tr572 + } + goto tr420 + st911: + if p++; p == pe { + goto _test_eof911 + } + st_case_911: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 136: + goto tr572 + } + goto tr420 + st912: + if p++; p == pe { + goto _test_eof912 + } + st_case_912: + switch data[p] { + case 128: + goto tr148 + case 181: + goto tr572 + case 183: + goto tr572 + case 185: + goto tr572 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto tr572 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto tr572 + } + default: + goto tr421 + } + goto tr420 + st913: + if p++; p == pe { + goto _test_eof913 + } + st_case_913: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto tr572 + } + default: + goto tr148 + } + goto tr420 + st914: + if p++; p == pe { + goto _test_eof914 + } + st_case_914: + switch { + case data[p] < 136: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 135 { + goto tr572 + } + case data[p] >= 128: + goto tr572 + } + case data[p] > 140: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 141: + goto tr572 + } + default: + goto tr148 + } + goto tr420 + st915: + if p++; p == pe { + goto _test_eof915 + } + st_case_915: + if data[p] == 134 { + goto tr572 + } + goto tr420 + st916: + if p++; p == pe { + goto _test_eof916 + } + st_case_916: + switch data[p] { + case 128: + goto st917 + case 129: + goto st918 + case 130: + goto st919 + case 131: + goto st202 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st920 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st921 + case 157: + goto st922 + case 158: + goto st923 + case 159: + goto st924 + case 160: + goto st925 + case 161: + goto st219 + case 162: + goto st926 + case 163: + goto st221 + case 164: + goto st927 + case 165: + goto st468 + case 167: + goto st469 + case 168: + goto st928 + case 169: + goto st929 + case 170: + goto st930 + case 172: + goto st931 + case 173: + goto st932 + case 174: + goto st933 + case 175: + goto st934 + case 176: + goto st935 + case 177: + goto st640 + case 179: + goto st936 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st937 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + } + switch { + case data[p] < 180: + if 132 <= data[p] && data[p] <= 152 { + goto st145 + } + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + default: + goto st147 + } + goto tr420 + st917: + if p++; p == pe { + goto _test_eof917 + } + st_case_917: + if 171 <= data[p] && data[p] <= 190 { + goto tr572 + } + goto tr420 + st918: + if p++; p == pe { + goto _test_eof918 + } + st_case_918: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto tr572 + } + case data[p] >= 128: + goto tr421 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto tr572 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr572 + } + default: + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st919: + if p++; p == pe { + goto _test_eof919 + } + st_case_919: + if data[p] == 143 { + goto tr572 + } + switch { + case data[p] < 144: + if 130 <= data[p] && data[p] <= 141 { + goto tr572 + } + case data[p] > 153: + switch { + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 154: + goto tr572 + } + default: + goto tr421 + } + goto tr420 + st920: + if p++; p == pe { + goto _test_eof920 + } + st_case_920: + switch { + case data[p] < 157: + if 155 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr420 + } + default: + goto tr572 + } + goto tr148 + st921: + if p++; p == pe { + goto _test_eof921 + } + st_case_921: + switch { + case data[p] < 146: + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 177: + if 178 <= data[p] && data[p] <= 180 { + goto tr572 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr572 + } + goto tr420 + st922: + if p++; p == pe { + goto _test_eof922 + } + st_case_922: + switch { + case data[p] < 160: + switch { + case data[p] > 145: + if 146 <= data[p] && data[p] <= 147 { + goto tr572 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto tr572 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st923: + if p++; p == pe { + goto _test_eof923 + } + st_case_923: + if 180 <= data[p] { + goto tr572 + } + goto tr420 + st924: + if p++; p == pe { + goto _test_eof924 + } + st_case_924: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 170 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr420 + } + goto tr572 + st925: + if p++; p == pe { + goto _test_eof925 + } + st_case_925: + switch { + case data[p] < 144: + if 139 <= data[p] && data[p] <= 142 { + goto tr572 + } + case data[p] > 153: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + goto tr420 + st926: + if p++; p == pe { + goto _test_eof926 + } + st_case_926: + if data[p] == 169 { + goto tr572 + } + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st927: + if p++; p == pe { + goto _test_eof927 + } + st_case_927: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st928: + if p++; p == pe { + goto _test_eof928 + } + st_case_928: + switch { + case data[p] > 150: + if 151 <= data[p] && data[p] <= 155 { + goto tr572 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st929: + if p++; p == pe { + goto _test_eof929 + } + st_case_929: + if data[p] == 191 { + goto tr572 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 149: + goto tr572 + } + goto tr420 + st930: + if p++; p == pe { + goto _test_eof930 + } + st_case_930: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto tr572 + } + default: + goto tr421 + } + goto tr420 + st931: + if p++; p == pe { + goto _test_eof931 + } + st_case_931: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 132 { + goto tr572 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr572 + } + default: + goto tr148 + } + goto tr420 + st932: + if p++; p == pe { + goto _test_eof932 + } + st_case_932: + switch { + case data[p] < 144: + switch { + case data[p] > 139: + if 140 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] >= 133: + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 154: + goto tr420 + } + default: + goto tr421 + } + goto tr572 + st933: + if p++; p == pe { + goto _test_eof933 + } + st_case_933: + switch { + case data[p] < 161: + switch { + case data[p] > 130: + if 131 <= data[p] && data[p] <= 160 { + goto tr148 + } + case data[p] >= 128: + goto tr572 + } + case data[p] > 173: + switch { + case data[p] < 176: + if 174 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + default: + goto tr572 + } + goto tr420 + st934: + if p++; p == pe { + goto _test_eof934 + } + st_case_934: + switch { + case data[p] > 179: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr572 + } + goto tr148 + st935: + if p++; p == pe { + goto _test_eof935 + } + st_case_935: + switch { + case data[p] > 163: + if 164 <= data[p] && data[p] <= 183 { + goto tr572 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st936: + if p++; p == pe { + goto _test_eof936 + } + st_case_936: + if data[p] == 173 { + goto tr572 + } + switch { + case data[p] < 169: + switch { + case data[p] > 146: + if 148 <= data[p] && data[p] <= 168 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + case data[p] > 177: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 180 { + goto tr572 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto tr572 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st937: + if p++; p == pe { + goto _test_eof937 + } + st_case_937: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr572 + } + case data[p] >= 128: + goto tr572 + } + goto tr420 + st938: + if p++; p == pe { + goto _test_eof938 + } + st_case_938: + switch data[p] { + case 128: + goto st939 + case 129: + goto st940 + case 130: + goto st241 + case 131: + goto st941 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st942 + case 180: + goto st251 + case 181: + goto st943 + case 182: + goto st253 + case 183: + goto st944 + case 184: + goto st255 + } + goto tr420 + st939: + if p++; p == pe { + goto _test_eof939 + } + st_case_939: + switch data[p] { + case 164: + goto st142 + case 167: + goto st142 + } + switch { + case data[p] < 152: + if 140 <= data[p] && data[p] <= 143 { + goto tr572 + } + case data[p] > 153: + switch { + case data[p] > 174: + if 191 <= data[p] { + goto tr571 + } + case data[p] >= 170: + goto tr572 + } + default: + goto st142 + } + goto tr420 + st940: + if p++; p == pe { + goto _test_eof940 + } + st_case_940: + switch data[p] { + case 165: + goto tr420 + case 177: + goto tr148 + case 191: + goto tr148 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr572 + } + default: + goto tr420 + } + goto tr571 + st941: + if p++; p == pe { + goto _test_eof941 + } + st_case_941: + if 144 <= data[p] && data[p] <= 176 { + goto tr572 + } + goto tr420 + st942: + if p++; p == pe { + goto _test_eof942 + } + st_case_942: + switch { + case data[p] < 175: + if 165 <= data[p] && data[p] <= 170 { + goto tr420 + } + case data[p] > 177: + if 180 <= data[p] { + goto tr420 + } + default: + goto tr572 + } + goto tr148 + st943: + if p++; p == pe { + goto _test_eof943 + } + st_case_943: + if data[p] == 191 { + goto tr572 + } + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 168: + goto tr420 + } + goto tr148 + st944: + if p++; p == pe { + goto _test_eof944 + } + st_case_944: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto tr572 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st945: + if p++; p == pe { + goto _test_eof945 + } + st_case_945: + switch data[p] { + case 128: + goto st946 + case 130: + goto st947 + case 132: + goto st259 + case 133: + goto st145 + case 134: + goto st260 + } + goto tr420 + st946: + if p++; p == pe { + goto _test_eof946 + } + st_case_946: + if data[p] == 133 { + goto tr148 + } + switch { + case data[p] > 175: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + case data[p] >= 170: + goto tr572 + } + goto tr420 + st947: + if p++; p == pe { + goto _test_eof947 + } + st_case_947: + if 153 <= data[p] && data[p] <= 154 { + goto tr572 + } + goto tr420 + st948: + if p++; p == pe { + goto _test_eof948 + } + st_case_948: + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st654 + case 153: + goto st949 + case 154: + goto st950 + case 155: + goto st951 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st952 + case 161: + goto st272 + case 162: + goto st953 + case 163: + goto st954 + case 164: + goto st955 + case 165: + goto st956 + case 166: + goto st957 + case 167: + goto st958 + case 168: + goto st959 + case 169: + goto st960 + case 170: + goto st961 + case 171: + goto st962 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st963 + case 176: + goto st147 + } + if 129 <= data[p] { + goto st145 + } + goto tr420 + st949: + if p++; p == pe { + goto _test_eof949 + } + st_case_949: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st950: + if p++; p == pe { + goto _test_eof950 + } + st_case_950: + switch { + case data[p] < 158: + if 128 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr572 + } + goto tr420 + st951: + if p++; p == pe { + goto _test_eof951 + } + st_case_951: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr572 + } + goto tr148 + st952: + if p++; p == pe { + goto _test_eof952 + } + st_case_952: + switch data[p] { + case 130: + goto tr572 + case 134: + goto tr572 + case 139: + goto tr572 + } + switch { + case data[p] > 167: + if 168 <= data[p] { + goto tr420 + } + case data[p] >= 163: + goto tr572 + } + goto tr148 + st953: + if p++; p == pe { + goto _test_eof953 + } + st_case_953: + switch { + case data[p] < 130: + if 128 <= data[p] && data[p] <= 129 { + goto tr572 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr572 + } + default: + goto tr148 + } + goto tr420 + st954: + if p++; p == pe { + goto _test_eof954 + } + st_case_954: + switch data[p] { + case 187: + goto tr148 + case 189: + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 143: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 133: + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 183: + if 184 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr420 + } + goto tr572 + st955: + if p++; p == pe { + goto _test_eof955 + } + st_case_955: + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 165: + switch { + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr572 + } + default: + goto tr148 + } + goto tr420 + st956: + if p++; p == pe { + goto _test_eof956 + } + st_case_956: + switch { + case data[p] < 148: + if 135 <= data[p] && data[p] <= 147 { + goto tr572 + } + case data[p] > 159: + if 189 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st957: + if p++; p == pe { + goto _test_eof957 + } + st_case_957: + switch { + case data[p] < 132: + if 128 <= data[p] && data[p] <= 131 { + goto tr572 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr572 + } + default: + goto tr148 + } + goto tr420 + st958: + if p++; p == pe { + goto _test_eof958 + } + st_case_958: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 129: + goto tr420 + } + case data[p] > 164: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr420 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + default: + goto tr420 + } + goto tr572 + st959: + if p++; p == pe { + goto _test_eof959 + } + st_case_959: + switch { + case data[p] > 168: + if 169 <= data[p] && data[p] <= 182 { + goto tr572 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st960: + if p++; p == pe { + goto _test_eof960 + } + st_case_960: + if data[p] == 131 { + goto tr572 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 141: + switch { + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto tr572 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr572 + } + goto tr420 + st961: + if p++; p == pe { + goto _test_eof961 + } + st_case_961: + if data[p] == 176 { + goto tr572 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr572 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st962: + if p++; p == pe { + goto _test_eof962 + } + st_case_962: + if data[p] == 129 { + goto tr572 + } + switch { + case data[p] < 171: + if 160 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 181 <= data[p] && data[p] <= 182 { + goto tr572 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr572 + } + goto tr420 + st963: + if p++; p == pe { + goto _test_eof963 + } + st_case_963: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 162 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 172: + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st964: + if p++; p == pe { + goto _test_eof964 + } + st_case_964: + switch data[p] { + case 172: + goto st965 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st966 + case 185: + goto st967 + case 187: + goto st968 + case 188: + goto st969 + case 189: + goto st303 + case 190: + goto st970 + case 191: + goto st971 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr420 + st965: + if p++; p == pe { + goto _test_eof965 + } + st_case_965: + if data[p] == 190 { + goto tr572 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 170: + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st966: + if p++; p == pe { + goto _test_eof966 + } + st_case_966: + if data[p] == 147 { + goto st142 + } + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr572 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr571 + } + default: + goto tr572 + } + goto tr420 + st967: + if p++; p == pe { + goto _test_eof967 + } + st_case_967: + switch data[p] { + case 146: + goto st142 + case 149: + goto st142 + } + switch { + case data[p] < 176: + if 141 <= data[p] && data[p] <= 143 { + goto tr571 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st968: + if p++; p == pe { + goto _test_eof968 + } + st_case_968: + if data[p] == 191 { + goto tr572 + } + if 189 <= data[p] { + goto tr420 + } + goto tr148 + st969: + if p++; p == pe { + goto _test_eof969 + } + st_case_969: + switch data[p] { + case 135: + goto st142 + case 142: + goto st142 + case 154: + goto st142 + case 191: + goto tr571 + } + if 161 <= data[p] && data[p] <= 186 { + goto tr148 + } + goto tr2 + st970: + if p++; p == pe { + goto _test_eof970 + } + st_case_970: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 190 { + goto tr148 + } + case data[p] >= 158: + goto tr572 + } + goto tr420 + st971: + if p++; p == pe { + goto _test_eof971 + } + st_case_971: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] >= 130: + goto tr148 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr572 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st972: + if p++; p == pe { + goto _test_eof972 + } + st_case_972: + switch data[p] { + case 144: + goto st973 + case 145: + goto st979 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st998 + case 155: + goto st1003 + case 157: + goto st1005 + case 158: + goto st1012 + case 159: + goto st403 + } + goto tr420 + st973: + if p++; p == pe { + goto _test_eof973 + } + st_case_973: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st974 + case 138: + goto st313 + case 139: + goto st975 + case 140: + goto st315 + case 141: + goto st976 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st684 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st977 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st978 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr420 + st974: + if p++; p == pe { + goto _test_eof974 + } + st_case_974: + if data[p] == 189 { + goto tr572 + } + goto tr420 + st975: + if p++; p == pe { + goto _test_eof975 + } + st_case_975: + if data[p] == 160 { + goto tr572 + } + if 145 <= data[p] { + goto tr420 + } + goto tr148 + st976: + if p++; p == pe { + goto _test_eof976 + } + st_case_976: + switch { + case data[p] < 182: + if 139 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr420 + } + default: + goto tr572 + } + goto tr148 + st977: + if p++; p == pe { + goto _test_eof977 + } + st_case_977: + switch data[p] { + case 128: + goto tr148 + case 191: + goto tr572 + } + switch { + case data[p] < 144: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr572 + } + case data[p] > 134: + if 140 <= data[p] && data[p] <= 143 { + goto tr572 + } + default: + goto tr572 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto tr572 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st978: + if p++; p == pe { + goto _test_eof978 + } + st_case_978: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 164: + if 165 <= data[p] && data[p] <= 166 { + goto tr572 + } + default: + goto tr148 + } + goto tr420 + st979: + if p++; p == pe { + goto _test_eof979 + } + st_case_979: + switch data[p] { + case 128: + goto st980 + case 129: + goto st981 + case 130: + goto st982 + case 131: + goto st691 + case 132: + goto st983 + case 133: + goto st984 + case 134: + goto st985 + case 135: + goto st986 + case 136: + goto st987 + case 138: + goto st348 + case 139: + goto st988 + case 140: + goto st989 + case 141: + goto st990 + case 146: + goto st991 + case 147: + goto st992 + case 150: + goto st993 + case 151: + goto st994 + case 152: + goto st991 + case 153: + goto st995 + case 154: + goto st996 + case 155: + goto st538 + case 156: + goto st997 + case 162: + goto st359 + case 163: + goto st707 + case 171: + goto st361 + } + goto tr420 + st980: + if p++; p == pe { + goto _test_eof980 + } + st_case_980: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr572 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr572 + } + default: + goto tr148 + } + goto tr420 + st981: + if p++; p == pe { + goto _test_eof981 + } + st_case_981: + switch { + case data[p] < 166: + if 135 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] && data[p] <= 190 { + goto tr420 + } + default: + goto tr421 + } + goto tr572 + st982: + if p++; p == pe { + goto _test_eof982 + } + st_case_982: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr572 + st983: + if p++; p == pe { + goto _test_eof983 + } + st_case_983: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr572 + } + case data[p] > 166: + switch { + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr421 + } + case data[p] >= 167: + goto tr572 + } + default: + goto tr148 + } + goto tr420 + st984: + if p++; p == pe { + goto _test_eof984 + } + st_case_984: + switch data[p] { + case 179: + goto tr572 + case 182: + goto tr148 + } + if 144 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr420 + st985: + if p++; p == pe { + goto _test_eof985 + } + st_case_985: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr572 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr572 + } + default: + goto tr148 + } + goto tr420 + st986: + if p++; p == pe { + goto _test_eof986 + } + st_case_986: + if data[p] == 155 { + goto tr420 + } + switch { + case data[p] < 141: + switch { + case data[p] > 132: + if 133 <= data[p] && data[p] <= 137 { + goto tr420 + } + case data[p] >= 129: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] < 154: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] > 156: + if 157 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + default: + goto tr420 + } + goto tr572 + st987: + if p++; p == pe { + goto _test_eof987 + } + st_case_987: + switch { + case data[p] < 147: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] > 171: + if 172 <= data[p] && data[p] <= 183 { + goto tr572 + } + default: + goto tr148 + } + goto tr420 + st988: + if p++; p == pe { + goto _test_eof988 + } + st_case_988: + switch { + case data[p] < 171: + if 159 <= data[p] && data[p] <= 170 { + goto tr572 + } + case data[p] > 175: + switch { + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr421 + } + default: + goto tr420 + } + goto tr148 + st989: + if p++; p == pe { + goto _test_eof989 + } + st_case_989: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto tr572 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr572 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st990: + if p++; p == pe { + goto _test_eof990 + } + st_case_990: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr572 + } + switch { + case data[p] < 157: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr572 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr572 + } + default: + goto tr572 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr572 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr572 + } + default: + goto tr572 + } + default: + goto tr148 + } + goto tr420 + st991: + if p++; p == pe { + goto _test_eof991 + } + st_case_991: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr572 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st992: + if p++; p == pe { + goto _test_eof992 + } + st_case_992: + if data[p] == 134 { + goto tr420 + } + switch { + case data[p] < 136: + if 132 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr420 + } + goto tr572 + st993: + if p++; p == pe { + goto _test_eof993 + } + st_case_993: + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 181: + if 184 <= data[p] { + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st994: + if p++; p == pe { + goto _test_eof994 + } + st_case_994: + switch { + case data[p] < 152: + if 129 <= data[p] && data[p] <= 151 { + goto tr420 + } + case data[p] > 155: + if 158 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + goto tr572 + st995: + if p++; p == pe { + goto _test_eof995 + } + st_case_995: + if data[p] == 132 { + goto tr148 + } + switch { + case data[p] < 144: + if 129 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + goto tr572 + st996: + if p++; p == pe { + goto _test_eof996 + } + st_case_996: + switch { + case data[p] > 170: + if 171 <= data[p] && data[p] <= 183 { + goto tr572 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st997: + if p++; p == pe { + goto _test_eof997 + } + st_case_997: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 157: + goto tr572 + } + goto tr420 + st998: + if p++; p == pe { + goto _test_eof998 + } + st_case_998: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st709 + case 171: + goto st999 + case 172: + goto st1000 + case 173: + goto st712 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st1001 + case 190: + goto st1002 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr420 + st999: + if p++; p == pe { + goto _test_eof999 + } + st_case_999: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto tr572 + } + case data[p] >= 144: + goto tr148 + } + goto tr420 + st1000: + if p++; p == pe { + goto _test_eof1000 + } + st_case_1000: + switch { + case data[p] > 175: + if 176 <= data[p] && data[p] <= 182 { + goto tr572 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1001: + if p++; p == pe { + goto _test_eof1001 + } + st_case_1001: + switch { + case data[p] < 145: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr420 + } + default: + goto tr572 + } + goto tr148 + st1002: + if p++; p == pe { + goto _test_eof1002 + } + st_case_1002: + switch { + case data[p] > 146: + if 147 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 143: + goto tr572 + } + goto tr420 + st1003: + if p++; p == pe { + goto _test_eof1003 + } + st_case_1003: + switch data[p] { + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st1004 + } + goto tr420 + st1004: + if p++; p == pe { + goto _test_eof1004 + } + st_case_1004: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr572 + } + case data[p] >= 157: + goto tr572 + } + default: + goto tr148 + } + goto tr420 + st1005: + if p++; p == pe { + goto _test_eof1005 + } + st_case_1005: + switch data[p] { + case 133: + goto st1006 + case 134: + goto st1007 + case 137: + goto st1008 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st721 + case 168: + goto st1009 + case 169: + goto st1010 + case 170: + goto st1011 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr420 + st1006: + if p++; p == pe { + goto _test_eof1006 + } + st_case_1006: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr572 + } + case data[p] >= 165: + goto tr572 + } + goto tr420 + st1007: + if p++; p == pe { + goto _test_eof1007 + } + st_case_1007: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr420 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr572 + st1008: + if p++; p == pe { + goto _test_eof1008 + } + st_case_1008: + if 130 <= data[p] && data[p] <= 132 { + goto tr572 + } + goto tr420 + st1009: + if p++; p == pe { + goto _test_eof1009 + } + st_case_1009: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr572 + } + case data[p] >= 128: + goto tr572 + } + goto tr420 + st1010: + if p++; p == pe { + goto _test_eof1010 + } + st_case_1010: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 173: + goto tr420 + } + goto tr572 + st1011: + if p++; p == pe { + goto _test_eof1011 + } + st_case_1011: + if data[p] == 132 { + goto tr572 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr572 + } + case data[p] >= 155: + goto tr572 + } + goto tr420 + st1012: + if p++; p == pe { + goto _test_eof1012 + } + st_case_1012: + switch data[p] { + case 160: + goto st147 + case 163: + goto st1013 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr420 + st1013: + if p++; p == pe { + goto _test_eof1013 + } + st_case_1013: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 150: + if 151 <= data[p] { + goto tr420 + } + default: + goto tr572 + } + goto tr148 + st1014: + if p++; p == pe { + goto _test_eof1014 + } + st_case_1014: + if data[p] == 160 { + goto st1015 + } + goto tr420 + st1015: + if p++; p == pe { + goto _test_eof1015 + } + st_case_1015: + switch data[p] { + case 128: + goto st1016 + case 129: + goto st1017 + case 132: + goto st871 + case 135: + goto st1019 + } + if 133 <= data[p] && data[p] <= 134 { + goto st1018 + } + goto tr420 + st1016: + if p++; p == pe { + goto _test_eof1016 + } + st_case_1016: + if data[p] == 129 { + goto tr572 + } + if 160 <= data[p] { + goto tr572 + } + goto tr420 + st1017: + if p++; p == pe { + goto _test_eof1017 + } + st_case_1017: + if 192 <= data[p] { + goto tr420 + } + goto tr572 + st1018: + if p++; p == pe { + goto _test_eof1018 + } + st_case_1018: + goto tr572 + st1019: + if p++; p == pe { + goto _test_eof1019 + } + st_case_1019: + if 176 <= data[p] { + goto tr420 + } + goto tr572 + st1020: + if p++; p == pe { + goto _test_eof1020 + } + st_case_1020: + if data[p] == 156 { + goto tr571 + } + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 133 { + goto tr571 + } + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr571 + } + goto tr420 + st1021: + if p++; p == pe { + goto _test_eof1021 + } + st_case_1021: + switch data[p] { + case 171: + goto tr421 + case 176: + goto tr571 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr571 + } + goto tr420 + st1022: + if p++; p == pe { + goto _test_eof1022 + } + st_case_1022: + switch data[p] { + case 148: + goto tr420 + case 158: + goto tr420 + case 169: + goto tr420 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr571 + } + case data[p] >= 150: + goto tr571 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 189: + goto tr420 + } + default: + goto tr421 + } + goto tr148 + st1023: + if p++; p == pe { + goto _test_eof1023 + } + st_case_1023: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto tr571 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr571 + } + default: + goto tr148 + } + goto tr420 + st1024: + if p++; p == pe { + goto _test_eof1024 + } + st_case_1024: + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr420 + } + goto tr571 + st1025: + if p++; p == pe { + goto _test_eof1025 + } + st_case_1025: + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr571 + } + goto tr148 + st1026: + if p++; p == pe { + goto _test_eof1026 + } + st_case_1026: + if data[p] == 186 { + goto tr148 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 170: + switch { + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 171: + goto tr571 + } + default: + goto tr148 + } + goto tr420 + st1027: + if p++; p == pe { + goto _test_eof1027 + } + st_case_1027: + switch data[p] { + case 160: + goto st1028 + case 161: + goto st1029 + case 162: + goto st168 + case 163: + goto st1030 + case 164: + goto st1031 + case 165: + goto st1032 + case 166: + goto st1033 + case 167: + goto st1034 + case 168: + goto st1035 + case 169: + goto st1036 + case 170: + goto st1037 + case 171: + goto st1038 + case 172: + goto st1039 + case 173: + goto st1040 + case 174: + goto st1041 + case 175: + goto st1042 + case 176: + goto st1043 + case 177: + goto st1044 + case 178: + goto st1045 + case 179: + goto st1046 + case 180: + goto st1047 + case 181: + goto st1048 + case 182: + goto st1049 + case 183: + goto st1050 + case 184: + goto st1051 + case 185: + goto st1052 + case 186: + goto st1053 + case 187: + goto st1054 + case 188: + goto st1055 + case 189: + goto st1056 + case 190: + goto st1057 + case 191: + goto st1058 + } + goto tr420 + st1028: + if p++; p == pe { + goto _test_eof1028 + } + st_case_1028: + switch data[p] { + case 154: + goto tr148 + case 164: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] > 149: + if 150 <= data[p] && data[p] <= 173 { + goto tr571 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1029: + if p++; p == pe { + goto _test_eof1029 + } + st_case_1029: + switch { + case data[p] > 152: + if 153 <= data[p] && data[p] <= 155 { + goto tr571 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1030: + if p++; p == pe { + goto _test_eof1030 + } + st_case_1030: + if 163 <= data[p] { + goto tr571 + } + goto tr420 + st1031: + if p++; p == pe { + goto _test_eof1031 + } + st_case_1031: + if data[p] == 189 { + goto tr148 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr148 + } + goto tr571 + st1032: + if p++; p == pe { + goto _test_eof1032 + } + st_case_1032: + switch data[p] { + case 144: + goto tr148 + case 176: + goto tr420 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 177 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr420 + } + goto tr571 + st1033: + if p++; p == pe { + goto _test_eof1033 + } + st_case_1033: + switch data[p] { + case 132: + goto tr420 + case 169: + goto tr420 + case 177: + goto tr420 + case 188: + goto tr571 + } + switch { + case data[p] < 145: + switch { + case data[p] > 131: + if 141 <= data[p] && data[p] <= 142 { + goto tr420 + } + case data[p] >= 129: + goto tr571 + } + case data[p] > 146: + switch { + case data[p] < 186: + if 179 <= data[p] && data[p] <= 181 { + goto tr420 + } + case data[p] > 187: + if 190 <= data[p] { + goto tr571 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st1034: + if p++; p == pe { + goto _test_eof1034 + } + st_case_1034: + switch data[p] { + case 142: + goto tr148 + case 158: + goto tr420 + } + switch { + case data[p] < 156: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 155 { + goto tr420 + } + case data[p] >= 143: + goto tr420 + } + default: + goto tr420 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr571 + st1035: + if p++; p == pe { + goto _test_eof1035 + } + st_case_1035: + if data[p] == 188 { + goto tr571 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr571 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto tr571 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1036: + if p++; p == pe { + goto _test_eof1036 + } + st_case_1036: + if data[p] == 157 { + goto tr420 + } + switch { + case data[p] < 153: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 146 <= data[p] && data[p] <= 152 { + goto tr420 + } + case data[p] >= 142: + goto tr420 + } + default: + goto tr420 + } + case data[p] > 158: + switch { + case data[p] < 166: + if 159 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr571 + st1037: + if p++; p == pe { + goto _test_eof1037 + } + st_case_1037: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr571 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto tr571 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1038: + if p++; p == pe { + goto _test_eof1038 + } + st_case_1038: + switch data[p] { + case 134: + goto tr420 + case 138: + goto tr420 + case 144: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] >= 142: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr420 + } + goto tr571 + st1039: + if p++; p == pe { + goto _test_eof1039 + } + st_case_1039: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr571 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr571 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1040: + if p++; p == pe { + goto _test_eof1040 + } + st_case_1040: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr571 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr571 + } + default: + goto tr571 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 161: + switch { + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 162: + goto tr571 + } + default: + goto tr148 + } + default: + goto tr571 + } + goto tr420 + st1041: + if p++; p == pe { + goto _test_eof1041 + } + st_case_1041: + switch data[p] { + case 130: + goto tr571 + case 131: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 158: + switch { + case data[p] < 142: + if 133 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 149: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] < 168: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto tr571 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1042: + if p++; p == pe { + goto _test_eof1042 + } + st_case_1042: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr571 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr571 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 138: + goto tr571 + } + default: + goto tr571 + } + goto tr420 + st1043: + if p++; p == pe { + goto _test_eof1043 + } + st_case_1043: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto tr571 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 190 <= data[p] { + goto tr571 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1044: + if p++; p == pe { + goto _test_eof1044 + } + st_case_1044: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 151: + goto tr420 + } + switch { + case data[p] < 160: + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 148 { + goto tr420 + } + case data[p] > 154: + if 155 <= data[p] && data[p] <= 159 { + goto tr420 + } + default: + goto tr148 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr571 + st1045: + if p++; p == pe { + goto _test_eof1045 + } + st_case_1045: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr571 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr571 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1046: + if p++; p == pe { + goto _test_eof1046 + } + st_case_1046: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr571 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr571 + } + default: + goto tr571 + } + case data[p] > 150: + switch { + case data[p] < 162: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 163: + switch { + case data[p] > 175: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr571 + } + default: + goto tr571 + } + goto tr420 + st1047: + if p++; p == pe { + goto _test_eof1047 + } + st_case_1047: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto tr571 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto tr571 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1048: + if p++; p == pe { + goto _test_eof1048 + } + st_case_1048: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 142: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 150 { + goto tr420 + } + case data[p] > 158: + if 159 <= data[p] && data[p] <= 161 { + goto tr148 + } + default: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr571 + st1049: + if p++; p == pe { + goto _test_eof1049 + } + st_case_1049: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr571 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1050: + if p++; p == pe { + goto _test_eof1050 + } + st_case_1050: + switch data[p] { + case 138: + goto tr571 + case 150: + goto tr571 + } + switch { + case data[p] < 152: + switch { + case data[p] > 134: + if 143 <= data[p] && data[p] <= 148 { + goto tr571 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto tr571 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr571 + } + goto tr420 + st1051: + if p++; p == pe { + goto _test_eof1051 + } + st_case_1051: + if data[p] == 177 { + goto tr571 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr571 + } + goto tr420 + st1052: + if p++; p == pe { + goto _test_eof1052 + } + st_case_1052: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 135: + goto tr571 + } + goto tr420 + st1053: + if p++; p == pe { + goto _test_eof1053 + } + st_case_1053: + if data[p] == 177 { + goto tr571 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr571 + } + case data[p] >= 180: + goto tr571 + } + goto tr420 + st1054: + if p++; p == pe { + goto _test_eof1054 + } + st_case_1054: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 136: + goto tr571 + } + goto tr420 + st1055: + if p++; p == pe { + goto _test_eof1055 + } + st_case_1055: + switch data[p] { + case 128: + goto tr148 + case 181: + goto tr571 + case 183: + goto tr571 + case 185: + goto tr571 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto tr571 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto tr571 + } + default: + goto tr421 + } + goto tr420 + st1056: + if p++; p == pe { + goto _test_eof1056 + } + st_case_1056: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto tr571 + } + default: + goto tr148 + } + goto tr420 + st1057: + if p++; p == pe { + goto _test_eof1057 + } + st_case_1057: + switch { + case data[p] < 136: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 135 { + goto tr571 + } + case data[p] >= 128: + goto tr571 + } + case data[p] > 140: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr571 + } + case data[p] >= 141: + goto tr571 + } + default: + goto tr148 + } + goto tr420 + st1058: + if p++; p == pe { + goto _test_eof1058 + } + st_case_1058: + if data[p] == 134 { + goto tr571 + } + goto tr420 + st1059: + if p++; p == pe { + goto _test_eof1059 + } + st_case_1059: + switch data[p] { + case 128: + goto st1060 + case 129: + goto st1061 + case 130: + goto st1062 + case 131: + goto st202 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st1063 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st1064 + case 157: + goto st1065 + case 158: + goto st1066 + case 159: + goto st1067 + case 160: + goto st1068 + case 161: + goto st219 + case 162: + goto st1069 + case 163: + goto st221 + case 164: + goto st1070 + case 165: + goto st468 + case 167: + goto st469 + case 168: + goto st1071 + case 169: + goto st1072 + case 170: + goto st1073 + case 172: + goto st1074 + case 173: + goto st1075 + case 174: + goto st1076 + case 175: + goto st1077 + case 176: + goto st1078 + case 177: + goto st640 + case 179: + goto st1079 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st1080 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + } + switch { + case data[p] < 180: + if 132 <= data[p] && data[p] <= 152 { + goto st145 + } + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + default: + goto st147 + } + goto tr420 + st1060: + if p++; p == pe { + goto _test_eof1060 + } + st_case_1060: + if 171 <= data[p] && data[p] <= 190 { + goto tr571 + } + goto tr420 + st1061: + if p++; p == pe { + goto _test_eof1061 + } + st_case_1061: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto tr571 + } + case data[p] >= 128: + goto tr421 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto tr571 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr571 + } + default: + goto tr571 + } + default: + goto tr571 + } + goto tr420 + st1062: + if p++; p == pe { + goto _test_eof1062 + } + st_case_1062: + if data[p] == 143 { + goto tr571 + } + switch { + case data[p] < 144: + if 130 <= data[p] && data[p] <= 141 { + goto tr571 + } + case data[p] > 153: + switch { + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 154: + goto tr571 + } + default: + goto tr421 + } + goto tr420 + st1063: + if p++; p == pe { + goto _test_eof1063 + } + st_case_1063: + switch { + case data[p] < 157: + if 155 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr420 + } + default: + goto tr571 + } + goto tr148 + st1064: + if p++; p == pe { + goto _test_eof1064 + } + st_case_1064: + switch { + case data[p] < 146: + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 177: + if 178 <= data[p] && data[p] <= 180 { + goto tr571 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr571 + } + goto tr420 + st1065: + if p++; p == pe { + goto _test_eof1065 + } + st_case_1065: + switch { + case data[p] < 160: + switch { + case data[p] > 145: + if 146 <= data[p] && data[p] <= 147 { + goto tr571 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto tr571 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1066: + if p++; p == pe { + goto _test_eof1066 + } + st_case_1066: + if 180 <= data[p] { + goto tr571 + } + goto tr420 + st1067: + if p++; p == pe { + goto _test_eof1067 + } + st_case_1067: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 170 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr420 + } + goto tr571 + st1068: + if p++; p == pe { + goto _test_eof1068 + } + st_case_1068: + switch { + case data[p] < 144: + if 139 <= data[p] && data[p] <= 142 { + goto tr571 + } + case data[p] > 153: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + goto tr420 + st1069: + if p++; p == pe { + goto _test_eof1069 + } + st_case_1069: + if data[p] == 169 { + goto tr571 + } + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1070: + if p++; p == pe { + goto _test_eof1070 + } + st_case_1070: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr571 + } + default: + goto tr571 + } + goto tr420 + st1071: + if p++; p == pe { + goto _test_eof1071 + } + st_case_1071: + switch { + case data[p] > 150: + if 151 <= data[p] && data[p] <= 155 { + goto tr571 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1072: + if p++; p == pe { + goto _test_eof1072 + } + st_case_1072: + if data[p] == 191 { + goto tr571 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr571 + } + case data[p] >= 149: + goto tr571 + } + goto tr420 + st1073: + if p++; p == pe { + goto _test_eof1073 + } + st_case_1073: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto tr571 + } + default: + goto tr421 + } + goto tr420 + st1074: + if p++; p == pe { + goto _test_eof1074 + } + st_case_1074: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 132 { + goto tr571 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr571 + } + default: + goto tr148 + } + goto tr420 + st1075: + if p++; p == pe { + goto _test_eof1075 + } + st_case_1075: + switch { + case data[p] < 144: + switch { + case data[p] > 139: + if 140 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] >= 133: + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 154: + goto tr420 + } + default: + goto tr421 + } + goto tr571 + st1076: + if p++; p == pe { + goto _test_eof1076 + } + st_case_1076: + switch { + case data[p] < 161: + switch { + case data[p] > 130: + if 131 <= data[p] && data[p] <= 160 { + goto tr148 + } + case data[p] >= 128: + goto tr571 + } + case data[p] > 173: + switch { + case data[p] < 176: + if 174 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + default: + goto tr571 + } + goto tr420 + st1077: + if p++; p == pe { + goto _test_eof1077 + } + st_case_1077: + switch { + case data[p] > 179: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr571 + } + goto tr148 + st1078: + if p++; p == pe { + goto _test_eof1078 + } + st_case_1078: + switch { + case data[p] > 163: + if 164 <= data[p] && data[p] <= 183 { + goto tr571 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1079: + if p++; p == pe { + goto _test_eof1079 + } + st_case_1079: + if data[p] == 173 { + goto tr571 + } + switch { + case data[p] < 169: + switch { + case data[p] > 146: + if 148 <= data[p] && data[p] <= 168 { + goto tr571 + } + case data[p] >= 144: + goto tr571 + } + case data[p] > 177: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 180 { + goto tr571 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto tr571 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1080: + if p++; p == pe { + goto _test_eof1080 + } + st_case_1080: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr571 + } + case data[p] >= 128: + goto tr571 + } + goto tr420 + st1081: + if p++; p == pe { + goto _test_eof1081 + } + st_case_1081: + switch data[p] { + case 128: + goto st1082 + case 129: + goto st1083 + case 130: + goto st241 + case 131: + goto st1084 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st1085 + case 180: + goto st251 + case 181: + goto st1086 + case 182: + goto st253 + case 183: + goto st1087 + case 184: + goto st255 + } + goto tr420 + st1082: + if p++; p == pe { + goto _test_eof1082 + } + st_case_1082: + switch { + case data[p] < 170: + if 140 <= data[p] && data[p] <= 143 { + goto tr571 + } + case data[p] > 174: + if 191 <= data[p] { + goto tr571 + } + default: + goto tr571 + } + goto tr420 + st1083: + if p++; p == pe { + goto _test_eof1083 + } + st_case_1083: + switch data[p] { + case 165: + goto tr420 + case 177: + goto tr148 + case 191: + goto tr148 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr420 + } + case data[p] > 159: + if 176 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr571 + st1084: + if p++; p == pe { + goto _test_eof1084 + } + st_case_1084: + if 144 <= data[p] && data[p] <= 176 { + goto tr571 + } + goto tr420 + st1085: + if p++; p == pe { + goto _test_eof1085 + } + st_case_1085: + switch { + case data[p] < 175: + if 165 <= data[p] && data[p] <= 170 { + goto tr420 + } + case data[p] > 177: + if 180 <= data[p] { + goto tr420 + } + default: + goto tr571 + } + goto tr148 + st1086: + if p++; p == pe { + goto _test_eof1086 + } + st_case_1086: + if data[p] == 191 { + goto tr571 + } + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 168: + goto tr420 + } + goto tr148 + st1087: + if p++; p == pe { + goto _test_eof1087 + } + st_case_1087: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto tr571 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1088: + if p++; p == pe { + goto _test_eof1088 + } + st_case_1088: + switch data[p] { + case 128: + goto st1089 + case 130: + goto st1240 + case 131: + goto st1164 + case 132: + goto st259 + case 133: + goto st145 + case 134: + goto st260 + case 135: + goto st1165 + case 139: + goto st1166 + case 140: + goto st1091 + case 141: + goto st1167 + } + goto tr420 + st1089: + if p++; p == pe { + goto _test_eof1089 + } + st_case_1089: + if data[p] == 133 { + goto tr148 + } + switch { + case data[p] < 177: + if 170 <= data[p] && data[p] <= 175 { + goto tr571 + } + case data[p] > 181: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + default: + goto tr1049 + } + goto tr420 +tr1049: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4872 + st4872: + if p++; p == pe { + goto _test_eof4872 + } + st_case_4872: +//line segment_words_prod.go:34183 + switch data[p] { + case 95: + goto tr571 + case 194: + goto st1090 + case 204: + goto st1091 + case 205: + goto st1092 + case 210: + goto st1093 + case 214: + goto st1094 + case 215: + goto st1095 + case 216: + goto st1096 + case 217: + goto st1097 + case 219: + goto st1098 + case 220: + goto st1099 + case 221: + goto st1100 + case 222: + goto st1101 + case 223: + goto st1102 + case 224: + goto st1103 + case 225: + goto st1132 + case 226: + goto st1154 + case 227: + goto st1161 + case 234: + goto st1168 + case 239: + goto st1184 + case 240: + goto st1192 + case 243: + goto st1235 + } + goto tr4562 + st1090: + if p++; p == pe { + goto _test_eof1090 + } + st_case_1090: + if data[p] == 173 { + goto tr1049 + } + goto tr420 + st1091: + if p++; p == pe { + goto _test_eof1091 + } + st_case_1091: + if 128 <= data[p] { + goto tr1049 + } + goto tr2 + st1092: + if p++; p == pe { + goto _test_eof1092 + } + st_case_1092: + if 176 <= data[p] { + goto tr420 + } + goto tr1049 + st1093: + if p++; p == pe { + goto _test_eof1093 + } + st_case_1093: + if 131 <= data[p] && data[p] <= 137 { + goto tr1049 + } + goto tr420 + st1094: + if p++; p == pe { + goto _test_eof1094 + } + st_case_1094: + if data[p] == 191 { + goto tr1049 + } + if 145 <= data[p] && data[p] <= 189 { + goto tr1049 + } + goto tr420 + st1095: + if p++; p == pe { + goto _test_eof1095 + } + st_case_1095: + if data[p] == 135 { + goto tr1049 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto tr1049 + } + case data[p] >= 129: + goto tr1049 + } + goto tr420 + st1096: + if p++; p == pe { + goto _test_eof1096 + } + st_case_1096: + if data[p] == 156 { + goto tr1049 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto tr1049 + } + case data[p] >= 128: + goto tr1049 + } + goto tr420 + st1097: + if p++; p == pe { + goto _test_eof1097 + } + st_case_1097: + if data[p] == 176 { + goto tr1049 + } + if 139 <= data[p] && data[p] <= 159 { + goto tr1049 + } + goto tr420 + st1098: + if p++; p == pe { + goto _test_eof1098 + } + st_case_1098: + switch { + case data[p] < 159: + if 150 <= data[p] && data[p] <= 157 { + goto tr1049 + } + case data[p] > 164: + switch { + case data[p] > 168: + if 170 <= data[p] && data[p] <= 173 { + goto tr1049 + } + case data[p] >= 167: + goto tr1049 + } + default: + goto tr1049 + } + goto tr420 + st1099: + if p++; p == pe { + goto _test_eof1099 + } + st_case_1099: + switch data[p] { + case 143: + goto tr1049 + case 145: + goto tr1049 + } + if 176 <= data[p] { + goto tr1049 + } + goto tr420 + st1100: + if p++; p == pe { + goto _test_eof1100 + } + st_case_1100: + if 139 <= data[p] { + goto tr420 + } + goto tr1049 + st1101: + if p++; p == pe { + goto _test_eof1101 + } + st_case_1101: + if 166 <= data[p] && data[p] <= 176 { + goto tr1049 + } + goto tr420 + st1102: + if p++; p == pe { + goto _test_eof1102 + } + st_case_1102: + if 171 <= data[p] && data[p] <= 179 { + goto tr1049 + } + goto tr420 + st1103: + if p++; p == pe { + goto _test_eof1103 + } + st_case_1103: + switch data[p] { + case 160: + goto st1104 + case 161: + goto st1105 + case 163: + goto st1106 + case 164: + goto st1107 + case 165: + goto st1108 + case 167: + goto st1110 + case 169: + goto st1111 + case 171: + goto st1112 + case 173: + goto st1114 + case 174: + goto st1115 + case 175: + goto st1116 + case 176: + goto st1117 + case 177: + goto st1118 + case 179: + goto st1119 + case 180: + goto st1120 + case 181: + goto st1121 + case 182: + goto st1122 + case 183: + goto st1123 + case 184: + goto st1124 + case 185: + goto st1125 + case 186: + goto st1126 + case 187: + goto st1127 + case 188: + goto st1128 + case 189: + goto st1129 + case 190: + goto st1130 + case 191: + goto st1131 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto st1113 + } + case data[p] >= 166: + goto st1109 + } + goto tr420 + st1104: + if p++; p == pe { + goto _test_eof1104 + } + st_case_1104: + switch { + case data[p] < 155: + if 150 <= data[p] && data[p] <= 153 { + goto tr1049 + } + case data[p] > 163: + switch { + case data[p] > 167: + if 169 <= data[p] && data[p] <= 173 { + goto tr1049 + } + case data[p] >= 165: + goto tr1049 + } + default: + goto tr1049 + } + goto tr420 + st1105: + if p++; p == pe { + goto _test_eof1105 + } + st_case_1105: + if 153 <= data[p] && data[p] <= 155 { + goto tr1049 + } + goto tr420 + st1106: + if p++; p == pe { + goto _test_eof1106 + } + st_case_1106: + if 163 <= data[p] { + goto tr1049 + } + goto tr420 + st1107: + if p++; p == pe { + goto _test_eof1107 + } + st_case_1107: + if data[p] == 189 { + goto tr420 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr420 + } + goto tr1049 + st1108: + if p++; p == pe { + goto _test_eof1108 + } + st_case_1108: + if data[p] == 144 { + goto tr420 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr420 + } + case data[p] >= 152: + goto tr420 + } + goto tr1049 + st1109: + if p++; p == pe { + goto _test_eof1109 + } + st_case_1109: + if data[p] == 188 { + goto tr1049 + } + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr1049 + } + case data[p] >= 129: + goto tr1049 + } + goto tr420 + st1110: + if p++; p == pe { + goto _test_eof1110 + } + st_case_1110: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr420 + } + case data[p] >= 133: + goto tr420 + } + case data[p] > 150: + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr420 + } + case data[p] >= 152: + goto tr420 + } + default: + goto tr420 + } + goto tr1049 + st1111: + if p++; p == pe { + goto _test_eof1111 + } + st_case_1111: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr420 + } + case data[p] >= 131: + goto tr420 + } + case data[p] > 144: + switch { + case data[p] < 178: + if 146 <= data[p] && data[p] <= 175 { + goto tr420 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr1049 + st1112: + if p++; p == pe { + goto _test_eof1112 + } + st_case_1112: + switch data[p] { + case 134: + goto tr420 + case 138: + goto tr420 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr420 + } + case data[p] >= 142: + goto tr420 + } + goto tr1049 + st1113: + if p++; p == pe { + goto _test_eof1113 + } + st_case_1113: + if data[p] == 188 { + goto tr1049 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr1049 + } + case data[p] >= 129: + goto tr1049 + } + goto tr420 + st1114: + if p++; p == pe { + goto _test_eof1114 + } + st_case_1114: + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr1049 + } + case data[p] >= 128: + goto tr1049 + } + case data[p] > 141: + switch { + case data[p] > 151: + if 162 <= data[p] && data[p] <= 163 { + goto tr1049 + } + case data[p] >= 150: + goto tr1049 + } + default: + goto tr1049 + } + goto tr420 + st1115: + if p++; p == pe { + goto _test_eof1115 + } + st_case_1115: + if data[p] == 130 { + goto tr1049 + } + if 190 <= data[p] && data[p] <= 191 { + goto tr1049 + } + goto tr420 + st1116: + if p++; p == pe { + goto _test_eof1116 + } + st_case_1116: + if data[p] == 151 { + goto tr1049 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr1049 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr1049 + } + default: + goto tr1049 + } + goto tr420 + st1117: + if p++; p == pe { + goto _test_eof1117 + } + st_case_1117: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr1049 + } + case data[p] >= 128: + goto tr1049 + } + goto tr420 + st1118: + if p++; p == pe { + goto _test_eof1118 + } + st_case_1118: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + } + switch { + case data[p] < 151: + if 142 <= data[p] && data[p] <= 148 { + goto tr420 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr1049 + st1119: + if p++; p == pe { + goto _test_eof1119 + } + st_case_1119: + switch { + case data[p] < 138: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 136 { + goto tr1049 + } + case data[p] >= 128: + goto tr1049 + } + case data[p] > 141: + switch { + case data[p] > 150: + if 162 <= data[p] && data[p] <= 163 { + goto tr1049 + } + case data[p] >= 149: + goto tr1049 + } + default: + goto tr1049 + } + goto tr420 + st1120: + if p++; p == pe { + goto _test_eof1120 + } + st_case_1120: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr1049 + } + case data[p] >= 129: + goto tr1049 + } + goto tr420 + st1121: + if p++; p == pe { + goto _test_eof1121 + } + st_case_1121: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + } + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 150 { + goto tr420 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr1049 + st1122: + if p++; p == pe { + goto _test_eof1122 + } + st_case_1122: + if 130 <= data[p] && data[p] <= 131 { + goto tr1049 + } + goto tr420 + st1123: + if p++; p == pe { + goto _test_eof1123 + } + st_case_1123: + switch data[p] { + case 138: + goto tr1049 + case 150: + goto tr1049 + } + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 148 { + goto tr1049 + } + case data[p] > 159: + if 178 <= data[p] && data[p] <= 179 { + goto tr1049 + } + default: + goto tr1049 + } + goto tr420 + st1124: + if p++; p == pe { + goto _test_eof1124 + } + st_case_1124: + if data[p] == 177 { + goto tr1049 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr1049 + } + goto tr420 + st1125: + if p++; p == pe { + goto _test_eof1125 + } + st_case_1125: + if 135 <= data[p] && data[p] <= 142 { + goto tr1049 + } + goto tr420 + st1126: + if p++; p == pe { + goto _test_eof1126 + } + st_case_1126: + if data[p] == 177 { + goto tr1049 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr1049 + } + case data[p] >= 180: + goto tr1049 + } + goto tr420 + st1127: + if p++; p == pe { + goto _test_eof1127 + } + st_case_1127: + if 136 <= data[p] && data[p] <= 141 { + goto tr1049 + } + goto tr420 + st1128: + if p++; p == pe { + goto _test_eof1128 + } + st_case_1128: + switch data[p] { + case 181: + goto tr1049 + case 183: + goto tr1049 + case 185: + goto tr1049 + } + switch { + case data[p] > 153: + if 190 <= data[p] && data[p] <= 191 { + goto tr1049 + } + case data[p] >= 152: + goto tr1049 + } + goto tr420 + st1129: + if p++; p == pe { + goto _test_eof1129 + } + st_case_1129: + if 177 <= data[p] && data[p] <= 191 { + goto tr1049 + } + goto tr420 + st1130: + if p++; p == pe { + goto _test_eof1130 + } + st_case_1130: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr1049 + } + case data[p] > 135: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr1049 + } + case data[p] >= 141: + goto tr1049 + } + default: + goto tr1049 + } + goto tr420 + st1131: + if p++; p == pe { + goto _test_eof1131 + } + st_case_1131: + if data[p] == 134 { + goto tr1049 + } + goto tr420 + st1132: + if p++; p == pe { + goto _test_eof1132 + } + st_case_1132: + switch data[p] { + case 128: + goto st1133 + case 129: + goto st1134 + case 130: + goto st1135 + case 141: + goto st1136 + case 156: + goto st1137 + case 157: + goto st1138 + case 158: + goto st1139 + case 159: + goto st1140 + case 160: + goto st1141 + case 162: + goto st1142 + case 164: + goto st1143 + case 168: + goto st1144 + case 169: + goto st1145 + case 170: + goto st1146 + case 172: + goto st1147 + case 173: + goto st1148 + case 174: + goto st1149 + case 175: + goto st1150 + case 176: + goto st1151 + case 179: + goto st1152 + case 183: + goto st1153 + } + goto tr420 + st1133: + if p++; p == pe { + goto _test_eof1133 + } + st_case_1133: + if 171 <= data[p] && data[p] <= 190 { + goto tr1049 + } + goto tr420 + st1134: + if p++; p == pe { + goto _test_eof1134 + } + st_case_1134: + switch { + case data[p] < 162: + switch { + case data[p] > 153: + if 158 <= data[p] && data[p] <= 160 { + goto tr1049 + } + case data[p] >= 150: + goto tr1049 + } + case data[p] > 164: + switch { + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr1049 + } + case data[p] >= 167: + goto tr1049 + } + default: + goto tr1049 + } + goto tr420 + st1135: + if p++; p == pe { + goto _test_eof1135 + } + st_case_1135: + if data[p] == 143 { + goto tr1049 + } + switch { + case data[p] > 141: + if 154 <= data[p] && data[p] <= 157 { + goto tr1049 + } + case data[p] >= 130: + goto tr1049 + } + goto tr420 + st1136: + if p++; p == pe { + goto _test_eof1136 + } + st_case_1136: + if 157 <= data[p] && data[p] <= 159 { + goto tr1049 + } + goto tr420 + st1137: + if p++; p == pe { + goto _test_eof1137 + } + st_case_1137: + switch { + case data[p] > 148: + if 178 <= data[p] && data[p] <= 180 { + goto tr1049 + } + case data[p] >= 146: + goto tr1049 + } + goto tr420 + st1138: + if p++; p == pe { + goto _test_eof1138 + } + st_case_1138: + switch { + case data[p] > 147: + if 178 <= data[p] && data[p] <= 179 { + goto tr1049 + } + case data[p] >= 146: + goto tr1049 + } + goto tr420 + st1139: + if p++; p == pe { + goto _test_eof1139 + } + st_case_1139: + if 180 <= data[p] { + goto tr1049 + } + goto tr420 + st1140: + if p++; p == pe { + goto _test_eof1140 + } + st_case_1140: + switch { + case data[p] > 156: + if 158 <= data[p] { + goto tr420 + } + case data[p] >= 148: + goto tr420 + } + goto tr1049 + st1141: + if p++; p == pe { + goto _test_eof1141 + } + st_case_1141: + if 139 <= data[p] && data[p] <= 142 { + goto tr1049 + } + goto tr420 + st1142: + if p++; p == pe { + goto _test_eof1142 + } + st_case_1142: + if data[p] == 169 { + goto tr1049 + } + goto tr420 + st1143: + if p++; p == pe { + goto _test_eof1143 + } + st_case_1143: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr1049 + } + case data[p] >= 160: + goto tr1049 + } + goto tr420 + st1144: + if p++; p == pe { + goto _test_eof1144 + } + st_case_1144: + if 151 <= data[p] && data[p] <= 155 { + goto tr1049 + } + goto tr420 + st1145: + if p++; p == pe { + goto _test_eof1145 + } + st_case_1145: + if data[p] == 191 { + goto tr1049 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr1049 + } + case data[p] >= 149: + goto tr1049 + } + goto tr420 + st1146: + if p++; p == pe { + goto _test_eof1146 + } + st_case_1146: + if 176 <= data[p] && data[p] <= 190 { + goto tr1049 + } + goto tr420 + st1147: + if p++; p == pe { + goto _test_eof1147 + } + st_case_1147: + switch { + case data[p] > 132: + if 180 <= data[p] { + goto tr1049 + } + case data[p] >= 128: + goto tr1049 + } + goto tr420 + st1148: + if p++; p == pe { + goto _test_eof1148 + } + st_case_1148: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 133: + goto tr420 + } + goto tr1049 + st1149: + if p++; p == pe { + goto _test_eof1149 + } + st_case_1149: + switch { + case data[p] > 130: + if 161 <= data[p] && data[p] <= 173 { + goto tr1049 + } + case data[p] >= 128: + goto tr1049 + } + goto tr420 + st1150: + if p++; p == pe { + goto _test_eof1150 + } + st_case_1150: + if 166 <= data[p] && data[p] <= 179 { + goto tr1049 + } + goto tr420 + st1151: + if p++; p == pe { + goto _test_eof1151 + } + st_case_1151: + if 164 <= data[p] && data[p] <= 183 { + goto tr1049 + } + goto tr420 + st1152: + if p++; p == pe { + goto _test_eof1152 + } + st_case_1152: + if data[p] == 173 { + goto tr1049 + } + switch { + case data[p] < 148: + if 144 <= data[p] && data[p] <= 146 { + goto tr1049 + } + case data[p] > 168: + switch { + case data[p] > 180: + if 184 <= data[p] && data[p] <= 185 { + goto tr1049 + } + case data[p] >= 178: + goto tr1049 + } + default: + goto tr1049 + } + goto tr420 + st1153: + if p++; p == pe { + goto _test_eof1153 + } + st_case_1153: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr1049 + } + case data[p] >= 128: + goto tr1049 + } + goto tr420 + st1154: + if p++; p == pe { + goto _test_eof1154 + } + st_case_1154: + switch data[p] { + case 128: + goto st1155 + case 129: + goto st1156 + case 131: + goto st1157 + case 179: + goto st1158 + case 181: + goto st1159 + case 183: + goto st1160 + } + goto tr420 + st1155: + if p++; p == pe { + goto _test_eof1155 + } + st_case_1155: + switch { + case data[p] < 170: + if 140 <= data[p] && data[p] <= 143 { + goto tr1049 + } + case data[p] > 174: + if 191 <= data[p] { + goto tr571 + } + default: + goto tr1049 + } + goto tr420 + st1156: + if p++; p == pe { + goto _test_eof1156 + } + st_case_1156: + if data[p] == 165 { + goto tr420 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr1049 + } + default: + goto tr420 + } + goto tr571 + st1157: + if p++; p == pe { + goto _test_eof1157 + } + st_case_1157: + if 144 <= data[p] && data[p] <= 176 { + goto tr1049 + } + goto tr420 + st1158: + if p++; p == pe { + goto _test_eof1158 + } + st_case_1158: + if 175 <= data[p] && data[p] <= 177 { + goto tr1049 + } + goto tr420 + st1159: + if p++; p == pe { + goto _test_eof1159 + } + st_case_1159: + if data[p] == 191 { + goto tr1049 + } + goto tr420 + st1160: + if p++; p == pe { + goto _test_eof1160 + } + st_case_1160: + if 160 <= data[p] && data[p] <= 191 { + goto tr1049 + } + goto tr420 + st1161: + if p++; p == pe { + goto _test_eof1161 + } + st_case_1161: + switch data[p] { + case 128: + goto st1162 + case 130: + goto st1163 + case 131: + goto st1164 + case 135: + goto st1165 + case 139: + goto st1166 + case 140: + goto st1091 + case 141: + goto st1167 + } + goto tr420 + st1162: + if p++; p == pe { + goto _test_eof1162 + } + st_case_1162: + switch { + case data[p] > 175: + if 177 <= data[p] && data[p] <= 181 { + goto tr1049 + } + case data[p] >= 170: + goto tr1049 + } + goto tr420 + st1163: + if p++; p == pe { + goto _test_eof1163 + } + st_case_1163: + switch { + case data[p] > 156: + if 160 <= data[p] { + goto tr1049 + } + case data[p] >= 153: + goto tr1049 + } + goto tr420 + st1164: + if p++; p == pe { + goto _test_eof1164 + } + st_case_1164: + if data[p] == 187 { + goto tr2 + } + if 192 <= data[p] { + goto tr2 + } + goto tr1049 + st1165: + if p++; p == pe { + goto _test_eof1165 + } + st_case_1165: + if 176 <= data[p] && data[p] <= 191 { + goto tr1049 + } + goto tr2 + st1166: + if p++; p == pe { + goto _test_eof1166 + } + st_case_1166: + if 144 <= data[p] && data[p] <= 190 { + goto tr1049 + } + goto tr2 + st1167: + if p++; p == pe { + goto _test_eof1167 + } + st_case_1167: + if 152 <= data[p] { + goto tr2 + } + goto tr1049 + st1168: + if p++; p == pe { + goto _test_eof1168 + } + st_case_1168: + switch data[p] { + case 153: + goto st1169 + case 154: + goto st1170 + case 155: + goto st1171 + case 160: + goto st1172 + case 162: + goto st1173 + case 163: + goto st1174 + case 164: + goto st1175 + case 165: + goto st1176 + case 166: + goto st1177 + case 167: + goto st1178 + case 168: + goto st1179 + case 169: + goto st1180 + case 170: + goto st1181 + case 171: + goto st1182 + case 175: + goto st1183 + } + goto tr420 + st1169: + if p++; p == pe { + goto _test_eof1169 + } + st_case_1169: + switch { + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr1049 + } + case data[p] >= 175: + goto tr1049 + } + goto tr420 + st1170: + if p++; p == pe { + goto _test_eof1170 + } + st_case_1170: + if 158 <= data[p] && data[p] <= 159 { + goto tr1049 + } + goto tr420 + st1171: + if p++; p == pe { + goto _test_eof1171 + } + st_case_1171: + if 176 <= data[p] && data[p] <= 177 { + goto tr1049 + } + goto tr420 + st1172: + if p++; p == pe { + goto _test_eof1172 + } + st_case_1172: + switch data[p] { + case 130: + goto tr1049 + case 134: + goto tr1049 + case 139: + goto tr1049 + } + if 163 <= data[p] && data[p] <= 167 { + goto tr1049 + } + goto tr420 + st1173: + if p++; p == pe { + goto _test_eof1173 + } + st_case_1173: + switch { + case data[p] > 129: + if 180 <= data[p] { + goto tr1049 + } + case data[p] >= 128: + goto tr1049 + } + goto tr420 + st1174: + if p++; p == pe { + goto _test_eof1174 + } + st_case_1174: + switch { + case data[p] > 159: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 133: + goto tr420 + } + goto tr1049 + st1175: + if p++; p == pe { + goto _test_eof1175 + } + st_case_1175: + if 166 <= data[p] && data[p] <= 173 { + goto tr1049 + } + goto tr420 + st1176: + if p++; p == pe { + goto _test_eof1176 + } + st_case_1176: + if 135 <= data[p] && data[p] <= 147 { + goto tr1049 + } + goto tr420 + st1177: + if p++; p == pe { + goto _test_eof1177 + } + st_case_1177: + switch { + case data[p] > 131: + if 179 <= data[p] { + goto tr1049 + } + case data[p] >= 128: + goto tr1049 + } + goto tr420 + st1178: + if p++; p == pe { + goto _test_eof1178 + } + st_case_1178: + switch { + case data[p] > 164: + if 166 <= data[p] { + goto tr420 + } + case data[p] >= 129: + goto tr420 + } + goto tr1049 + st1179: + if p++; p == pe { + goto _test_eof1179 + } + st_case_1179: + if 169 <= data[p] && data[p] <= 182 { + goto tr1049 + } + goto tr420 + st1180: + if p++; p == pe { + goto _test_eof1180 + } + st_case_1180: + if data[p] == 131 { + goto tr1049 + } + switch { + case data[p] > 141: + if 187 <= data[p] && data[p] <= 189 { + goto tr1049 + } + case data[p] >= 140: + goto tr1049 + } + goto tr420 + st1181: + if p++; p == pe { + goto _test_eof1181 + } + st_case_1181: + if data[p] == 176 { + goto tr1049 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr1049 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr1049 + } + default: + goto tr1049 + } + goto tr420 + st1182: + if p++; p == pe { + goto _test_eof1182 + } + st_case_1182: + if data[p] == 129 { + goto tr1049 + } + switch { + case data[p] > 175: + if 181 <= data[p] && data[p] <= 182 { + goto tr1049 + } + case data[p] >= 171: + goto tr1049 + } + goto tr420 + st1183: + if p++; p == pe { + goto _test_eof1183 + } + st_case_1183: + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 173 { + goto tr1049 + } + case data[p] >= 163: + goto tr1049 + } + goto tr420 + st1184: + if p++; p == pe { + goto _test_eof1184 + } + st_case_1184: + switch data[p] { + case 172: + goto st1185 + case 184: + goto st1186 + case 185: + goto st1187 + case 187: + goto st1159 + case 188: + goto st1188 + case 189: + goto st1189 + case 190: + goto st1190 + case 191: + goto st1191 + } + goto tr420 + st1185: + if p++; p == pe { + goto _test_eof1185 + } + st_case_1185: + if data[p] == 158 { + goto tr1049 + } + goto tr420 + st1186: + if p++; p == pe { + goto _test_eof1186 + } + st_case_1186: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr1049 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr571 + } + default: + goto tr1049 + } + goto tr420 + st1187: + if p++; p == pe { + goto _test_eof1187 + } + st_case_1187: + if 141 <= data[p] && data[p] <= 143 { + goto tr571 + } + goto tr2 + st1188: + if p++; p == pe { + goto _test_eof1188 + } + st_case_1188: + if data[p] == 191 { + goto tr571 + } + goto tr2 + st1189: + if p++; p == pe { + goto _test_eof1189 + } + st_case_1189: + if 166 <= data[p] { + goto tr1049 + } + goto tr420 + st1190: + if p++; p == pe { + goto _test_eof1190 + } + st_case_1190: + if 160 <= data[p] { + goto tr420 + } + goto tr1049 + st1191: + if p++; p == pe { + goto _test_eof1191 + } + st_case_1191: + if 185 <= data[p] && data[p] <= 187 { + goto tr1049 + } + goto tr420 + st1192: + if p++; p == pe { + goto _test_eof1192 + } + st_case_1192: + switch data[p] { + case 144: + goto st1193 + case 145: + goto st1199 + case 150: + goto st1218 + case 155: + goto st1223 + case 157: + goto st1226 + case 158: + goto st1233 + } + goto tr420 + st1193: + if p++; p == pe { + goto _test_eof1193 + } + st_case_1193: + switch data[p] { + case 135: + goto st1194 + case 139: + goto st1195 + case 141: + goto st1196 + case 168: + goto st1197 + case 171: + goto st1198 + } + goto tr420 + st1194: + if p++; p == pe { + goto _test_eof1194 + } + st_case_1194: + if data[p] == 189 { + goto tr1049 + } + goto tr420 + st1195: + if p++; p == pe { + goto _test_eof1195 + } + st_case_1195: + if data[p] == 160 { + goto tr1049 + } + goto tr420 + st1196: + if p++; p == pe { + goto _test_eof1196 + } + st_case_1196: + if 182 <= data[p] && data[p] <= 186 { + goto tr1049 + } + goto tr420 + st1197: + if p++; p == pe { + goto _test_eof1197 + } + st_case_1197: + if data[p] == 191 { + goto tr1049 + } + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr1049 + } + case data[p] > 134: + switch { + case data[p] > 143: + if 184 <= data[p] && data[p] <= 186 { + goto tr1049 + } + case data[p] >= 140: + goto tr1049 + } + default: + goto tr1049 + } + goto tr420 + st1198: + if p++; p == pe { + goto _test_eof1198 + } + st_case_1198: + if 165 <= data[p] && data[p] <= 166 { + goto tr1049 + } + goto tr420 + st1199: + if p++; p == pe { + goto _test_eof1199 + } + st_case_1199: + switch data[p] { + case 128: + goto st1200 + case 129: + goto st1201 + case 130: + goto st1202 + case 132: + goto st1203 + case 133: + goto st1204 + case 134: + goto st1205 + case 135: + goto st1206 + case 136: + goto st1207 + case 139: + goto st1208 + case 140: + goto st1209 + case 141: + goto st1210 + case 146: + goto st1211 + case 147: + goto st1212 + case 150: + goto st1213 + case 151: + goto st1214 + case 152: + goto st1211 + case 153: + goto st1215 + case 154: + goto st1216 + case 156: + goto st1217 + } + goto tr420 + st1200: + if p++; p == pe { + goto _test_eof1200 + } + st_case_1200: + switch { + case data[p] > 130: + if 184 <= data[p] { + goto tr1049 + } + case data[p] >= 128: + goto tr1049 + } + goto tr420 + st1201: + if p++; p == pe { + goto _test_eof1201 + } + st_case_1201: + if 135 <= data[p] && data[p] <= 190 { + goto tr420 + } + goto tr1049 + st1202: + if p++; p == pe { + goto _test_eof1202 + } + st_case_1202: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr420 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr1049 + st1203: + if p++; p == pe { + goto _test_eof1203 + } + st_case_1203: + switch { + case data[p] > 130: + if 167 <= data[p] && data[p] <= 180 { + goto tr1049 + } + case data[p] >= 128: + goto tr1049 + } + goto tr420 + st1204: + if p++; p == pe { + goto _test_eof1204 + } + st_case_1204: + if data[p] == 179 { + goto tr1049 + } + goto tr420 + st1205: + if p++; p == pe { + goto _test_eof1205 + } + st_case_1205: + switch { + case data[p] > 130: + if 179 <= data[p] { + goto tr1049 + } + case data[p] >= 128: + goto tr1049 + } + goto tr420 + st1206: + if p++; p == pe { + goto _test_eof1206 + } + st_case_1206: + switch { + case data[p] > 137: + if 141 <= data[p] { + goto tr420 + } + case data[p] >= 129: + goto tr420 + } + goto tr1049 + st1207: + if p++; p == pe { + goto _test_eof1207 + } + st_case_1207: + if 172 <= data[p] && data[p] <= 183 { + goto tr1049 + } + goto tr420 + st1208: + if p++; p == pe { + goto _test_eof1208 + } + st_case_1208: + if 159 <= data[p] && data[p] <= 170 { + goto tr1049 + } + goto tr420 + st1209: + if p++; p == pe { + goto _test_eof1209 + } + st_case_1209: + if data[p] == 188 { + goto tr1049 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr1049 + } + case data[p] >= 128: + goto tr1049 + } + goto tr420 + st1210: + if p++; p == pe { + goto _test_eof1210 + } + st_case_1210: + if data[p] == 151 { + goto tr1049 + } + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr1049 + } + case data[p] >= 128: + goto tr1049 + } + case data[p] > 141: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr1049 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr1049 + } + default: + goto tr1049 + } + default: + goto tr1049 + } + goto tr420 + st1211: + if p++; p == pe { + goto _test_eof1211 + } + st_case_1211: + if 176 <= data[p] { + goto tr1049 + } + goto tr420 + st1212: + if p++; p == pe { + goto _test_eof1212 + } + st_case_1212: + if 132 <= data[p] { + goto tr420 + } + goto tr1049 + st1213: + if p++; p == pe { + goto _test_eof1213 + } + st_case_1213: + switch { + case data[p] > 181: + if 184 <= data[p] { + goto tr1049 + } + case data[p] >= 175: + goto tr1049 + } + goto tr420 + st1214: + if p++; p == pe { + goto _test_eof1214 + } + st_case_1214: + switch { + case data[p] > 155: + if 158 <= data[p] { + goto tr420 + } + case data[p] >= 129: + goto tr420 + } + goto tr1049 + st1215: + if p++; p == pe { + goto _test_eof1215 + } + st_case_1215: + if 129 <= data[p] { + goto tr420 + } + goto tr1049 + st1216: + if p++; p == pe { + goto _test_eof1216 + } + st_case_1216: + if 171 <= data[p] && data[p] <= 183 { + goto tr1049 + } + goto tr420 + st1217: + if p++; p == pe { + goto _test_eof1217 + } + st_case_1217: + if 157 <= data[p] && data[p] <= 171 { + goto tr1049 + } + goto tr420 + st1218: + if p++; p == pe { + goto _test_eof1218 + } + st_case_1218: + switch data[p] { + case 171: + goto st1219 + case 172: + goto st1220 + case 189: + goto st1221 + case 190: + goto st1222 + } + goto tr420 + st1219: + if p++; p == pe { + goto _test_eof1219 + } + st_case_1219: + if 176 <= data[p] && data[p] <= 180 { + goto tr1049 + } + goto tr420 + st1220: + if p++; p == pe { + goto _test_eof1220 + } + st_case_1220: + if 176 <= data[p] && data[p] <= 182 { + goto tr1049 + } + goto tr420 + st1221: + if p++; p == pe { + goto _test_eof1221 + } + st_case_1221: + if 145 <= data[p] && data[p] <= 190 { + goto tr1049 + } + goto tr420 + st1222: + if p++; p == pe { + goto _test_eof1222 + } + st_case_1222: + if 143 <= data[p] && data[p] <= 146 { + goto tr1049 + } + goto tr420 + st1223: + if p++; p == pe { + goto _test_eof1223 + } + st_case_1223: + switch data[p] { + case 128: + goto st1224 + case 178: + goto st1225 + } + goto tr420 + st1224: + if p++; p == pe { + goto _test_eof1224 + } + st_case_1224: + if data[p] == 128 { + goto tr1049 + } + goto tr2 + st1225: + if p++; p == pe { + goto _test_eof1225 + } + st_case_1225: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr1049 + } + case data[p] >= 157: + goto tr1049 + } + goto tr420 + st1226: + if p++; p == pe { + goto _test_eof1226 + } + st_case_1226: + switch data[p] { + case 133: + goto st1227 + case 134: + goto st1228 + case 137: + goto st1229 + case 168: + goto st1230 + case 169: + goto st1231 + case 170: + goto st1232 + } + goto tr420 + st1227: + if p++; p == pe { + goto _test_eof1227 + } + st_case_1227: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr1049 + } + case data[p] >= 165: + goto tr1049 + } + goto tr420 + st1228: + if p++; p == pe { + goto _test_eof1228 + } + st_case_1228: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr420 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr1049 + st1229: + if p++; p == pe { + goto _test_eof1229 + } + st_case_1229: + if 130 <= data[p] && data[p] <= 132 { + goto tr1049 + } + goto tr420 + st1230: + if p++; p == pe { + goto _test_eof1230 + } + st_case_1230: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr1049 + } + case data[p] >= 128: + goto tr1049 + } + goto tr420 + st1231: + if p++; p == pe { + goto _test_eof1231 + } + st_case_1231: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 173: + goto tr420 + } + goto tr1049 + st1232: + if p++; p == pe { + goto _test_eof1232 + } + st_case_1232: + if data[p] == 132 { + goto tr1049 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr1049 + } + case data[p] >= 155: + goto tr1049 + } + goto tr420 + st1233: + if p++; p == pe { + goto _test_eof1233 + } + st_case_1233: + if data[p] == 163 { + goto st1234 + } + goto tr420 + st1234: + if p++; p == pe { + goto _test_eof1234 + } + st_case_1234: + if 144 <= data[p] && data[p] <= 150 { + goto tr1049 + } + goto tr420 + st1235: + if p++; p == pe { + goto _test_eof1235 + } + st_case_1235: + if data[p] == 160 { + goto st1236 + } + goto tr420 + st1236: + if p++; p == pe { + goto _test_eof1236 + } + st_case_1236: + switch data[p] { + case 128: + goto st1237 + case 129: + goto st1238 + case 132: + goto st1091 + case 135: + goto st1092 + } + if 133 <= data[p] && data[p] <= 134 { + goto st1239 + } + goto tr420 + st1237: + if p++; p == pe { + goto _test_eof1237 + } + st_case_1237: + if data[p] == 129 { + goto tr1049 + } + if 160 <= data[p] { + goto tr1049 + } + goto tr420 + st1238: + if p++; p == pe { + goto _test_eof1238 + } + st_case_1238: + if 192 <= data[p] { + goto tr420 + } + goto tr1049 + st1239: + if p++; p == pe { + goto _test_eof1239 + } + st_case_1239: + goto tr1049 + st1240: + if p++; p == pe { + goto _test_eof1240 + } + st_case_1240: + switch { + case data[p] < 155: + if 153 <= data[p] && data[p] <= 154 { + goto tr571 + } + case data[p] > 156: + if 160 <= data[p] { + goto tr1049 + } + default: + goto tr1049 + } + goto tr420 + st1241: + if p++; p == pe { + goto _test_eof1241 + } + st_case_1241: + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st654 + case 153: + goto st1242 + case 154: + goto st1243 + case 155: + goto st1244 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st1245 + case 161: + goto st272 + case 162: + goto st1246 + case 163: + goto st1247 + case 164: + goto st1248 + case 165: + goto st1249 + case 166: + goto st1250 + case 167: + goto st1251 + case 168: + goto st1252 + case 169: + goto st1253 + case 170: + goto st1254 + case 171: + goto st1255 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st1256 + case 176: + goto st147 + } + if 129 <= data[p] { + goto st145 + } + goto tr420 + st1242: + if p++; p == pe { + goto _test_eof1242 + } + st_case_1242: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr571 + } + default: + goto tr571 + } + goto tr420 + st1243: + if p++; p == pe { + goto _test_eof1243 + } + st_case_1243: + switch { + case data[p] < 158: + if 128 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr571 + } + goto tr420 + st1244: + if p++; p == pe { + goto _test_eof1244 + } + st_case_1244: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr571 + } + goto tr148 + st1245: + if p++; p == pe { + goto _test_eof1245 + } + st_case_1245: + switch data[p] { + case 130: + goto tr571 + case 134: + goto tr571 + case 139: + goto tr571 + } + switch { + case data[p] > 167: + if 168 <= data[p] { + goto tr420 + } + case data[p] >= 163: + goto tr571 + } + goto tr148 + st1246: + if p++; p == pe { + goto _test_eof1246 + } + st_case_1246: + switch { + case data[p] < 130: + if 128 <= data[p] && data[p] <= 129 { + goto tr571 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr571 + } + default: + goto tr148 + } + goto tr420 + st1247: + if p++; p == pe { + goto _test_eof1247 + } + st_case_1247: + switch data[p] { + case 187: + goto tr148 + case 189: + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 143: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 133: + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 183: + if 184 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr420 + } + goto tr571 + st1248: + if p++; p == pe { + goto _test_eof1248 + } + st_case_1248: + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 165: + switch { + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr571 + } + default: + goto tr148 + } + goto tr420 + st1249: + if p++; p == pe { + goto _test_eof1249 + } + st_case_1249: + switch { + case data[p] < 148: + if 135 <= data[p] && data[p] <= 147 { + goto tr571 + } + case data[p] > 159: + if 189 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st1250: + if p++; p == pe { + goto _test_eof1250 + } + st_case_1250: + switch { + case data[p] < 132: + if 128 <= data[p] && data[p] <= 131 { + goto tr571 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr571 + } + default: + goto tr148 + } + goto tr420 + st1251: + if p++; p == pe { + goto _test_eof1251 + } + st_case_1251: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 129: + goto tr420 + } + case data[p] > 164: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr420 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + default: + goto tr420 + } + goto tr571 + st1252: + if p++; p == pe { + goto _test_eof1252 + } + st_case_1252: + switch { + case data[p] > 168: + if 169 <= data[p] && data[p] <= 182 { + goto tr571 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1253: + if p++; p == pe { + goto _test_eof1253 + } + st_case_1253: + if data[p] == 131 { + goto tr571 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 141: + switch { + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto tr571 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr571 + } + goto tr420 + st1254: + if p++; p == pe { + goto _test_eof1254 + } + st_case_1254: + if data[p] == 176 { + goto tr571 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr571 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr571 + } + default: + goto tr571 + } + goto tr420 + st1255: + if p++; p == pe { + goto _test_eof1255 + } + st_case_1255: + if data[p] == 129 { + goto tr571 + } + switch { + case data[p] < 171: + if 160 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 181 <= data[p] && data[p] <= 182 { + goto tr571 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr571 + } + goto tr420 + st1256: + if p++; p == pe { + goto _test_eof1256 + } + st_case_1256: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 162 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 172: + goto tr571 + } + default: + goto tr571 + } + goto tr420 + st1257: + if p++; p == pe { + goto _test_eof1257 + } + st_case_1257: + switch data[p] { + case 172: + goto st1258 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st1259 + case 185: + goto st674 + case 187: + goto st1260 + case 188: + goto st676 + case 189: + goto st1261 + case 190: + goto st1262 + case 191: + goto st1263 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr420 + st1258: + if p++; p == pe { + goto _test_eof1258 + } + st_case_1258: + switch data[p] { + case 158: + goto tr571 + case 190: + goto tr572 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 170: + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st1259: + if p++; p == pe { + goto _test_eof1259 + } + st_case_1259: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr571 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr571 + } + default: + goto tr571 + } + goto tr420 + st1260: + if p++; p == pe { + goto _test_eof1260 + } + st_case_1260: + if data[p] == 191 { + goto tr571 + } + if 189 <= data[p] { + goto tr420 + } + goto tr148 + st1261: + if p++; p == pe { + goto _test_eof1261 + } + st_case_1261: + switch { + case data[p] > 154: + if 166 <= data[p] { + goto tr1049 + } + case data[p] >= 129: + goto tr148 + } + goto tr2 + st1262: + if p++; p == pe { + goto _test_eof1262 + } + st_case_1262: + switch { + case data[p] < 160: + if 158 <= data[p] && data[p] <= 159 { + goto tr571 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + goto tr1049 + st1263: + if p++; p == pe { + goto _test_eof1263 + } + st_case_1263: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] >= 130: + goto tr148 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr571 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1264: + if p++; p == pe { + goto _test_eof1264 + } + st_case_1264: + switch data[p] { + case 144: + goto st1265 + case 145: + goto st1271 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st1290 + case 155: + goto st1295 + case 157: + goto st1297 + case 158: + goto st1304 + case 159: + goto st403 + } + goto tr420 + st1265: + if p++; p == pe { + goto _test_eof1265 + } + st_case_1265: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st1266 + case 138: + goto st313 + case 139: + goto st1267 + case 140: + goto st315 + case 141: + goto st1268 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st684 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st1269 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st1270 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr420 + st1266: + if p++; p == pe { + goto _test_eof1266 + } + st_case_1266: + if data[p] == 189 { + goto tr571 + } + goto tr420 + st1267: + if p++; p == pe { + goto _test_eof1267 + } + st_case_1267: + if data[p] == 160 { + goto tr571 + } + if 145 <= data[p] { + goto tr420 + } + goto tr148 + st1268: + if p++; p == pe { + goto _test_eof1268 + } + st_case_1268: + switch { + case data[p] < 182: + if 139 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr420 + } + default: + goto tr571 + } + goto tr148 + st1269: + if p++; p == pe { + goto _test_eof1269 + } + st_case_1269: + switch data[p] { + case 128: + goto tr148 + case 191: + goto tr571 + } + switch { + case data[p] < 144: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr571 + } + case data[p] > 134: + if 140 <= data[p] && data[p] <= 143 { + goto tr571 + } + default: + goto tr571 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto tr571 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1270: + if p++; p == pe { + goto _test_eof1270 + } + st_case_1270: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 164: + if 165 <= data[p] && data[p] <= 166 { + goto tr571 + } + default: + goto tr148 + } + goto tr420 + st1271: + if p++; p == pe { + goto _test_eof1271 + } + st_case_1271: + switch data[p] { + case 128: + goto st1272 + case 129: + goto st1273 + case 130: + goto st1274 + case 131: + goto st691 + case 132: + goto st1275 + case 133: + goto st1276 + case 134: + goto st1277 + case 135: + goto st1278 + case 136: + goto st1279 + case 138: + goto st348 + case 139: + goto st1280 + case 140: + goto st1281 + case 141: + goto st1282 + case 146: + goto st1283 + case 147: + goto st1284 + case 150: + goto st1285 + case 151: + goto st1286 + case 152: + goto st1283 + case 153: + goto st1287 + case 154: + goto st1288 + case 155: + goto st538 + case 156: + goto st1289 + case 162: + goto st359 + case 163: + goto st707 + case 171: + goto st361 + } + goto tr420 + st1272: + if p++; p == pe { + goto _test_eof1272 + } + st_case_1272: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr571 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr571 + } + default: + goto tr148 + } + goto tr420 + st1273: + if p++; p == pe { + goto _test_eof1273 + } + st_case_1273: + switch { + case data[p] < 166: + if 135 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] && data[p] <= 190 { + goto tr420 + } + default: + goto tr421 + } + goto tr571 + st1274: + if p++; p == pe { + goto _test_eof1274 + } + st_case_1274: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr571 + st1275: + if p++; p == pe { + goto _test_eof1275 + } + st_case_1275: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr571 + } + case data[p] > 166: + switch { + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr421 + } + case data[p] >= 167: + goto tr571 + } + default: + goto tr148 + } + goto tr420 + st1276: + if p++; p == pe { + goto _test_eof1276 + } + st_case_1276: + switch data[p] { + case 179: + goto tr571 + case 182: + goto tr148 + } + if 144 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr420 + st1277: + if p++; p == pe { + goto _test_eof1277 + } + st_case_1277: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr571 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr571 + } + default: + goto tr148 + } + goto tr420 + st1278: + if p++; p == pe { + goto _test_eof1278 + } + st_case_1278: + if data[p] == 155 { + goto tr420 + } + switch { + case data[p] < 141: + switch { + case data[p] > 132: + if 133 <= data[p] && data[p] <= 137 { + goto tr420 + } + case data[p] >= 129: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] < 154: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] > 156: + if 157 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + default: + goto tr420 + } + goto tr571 + st1279: + if p++; p == pe { + goto _test_eof1279 + } + st_case_1279: + switch { + case data[p] < 147: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] > 171: + if 172 <= data[p] && data[p] <= 183 { + goto tr571 + } + default: + goto tr148 + } + goto tr420 + st1280: + if p++; p == pe { + goto _test_eof1280 + } + st_case_1280: + switch { + case data[p] < 171: + if 159 <= data[p] && data[p] <= 170 { + goto tr571 + } + case data[p] > 175: + switch { + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr421 + } + default: + goto tr420 + } + goto tr148 + st1281: + if p++; p == pe { + goto _test_eof1281 + } + st_case_1281: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto tr571 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr571 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1282: + if p++; p == pe { + goto _test_eof1282 + } + st_case_1282: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr571 + } + switch { + case data[p] < 157: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr571 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr571 + } + default: + goto tr571 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr571 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr571 + } + default: + goto tr571 + } + default: + goto tr148 + } + goto tr420 + st1283: + if p++; p == pe { + goto _test_eof1283 + } + st_case_1283: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr571 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1284: + if p++; p == pe { + goto _test_eof1284 + } + st_case_1284: + if data[p] == 134 { + goto tr420 + } + switch { + case data[p] < 136: + if 132 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr420 + } + goto tr571 + st1285: + if p++; p == pe { + goto _test_eof1285 + } + st_case_1285: + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 181: + if 184 <= data[p] { + goto tr571 + } + default: + goto tr571 + } + goto tr420 + st1286: + if p++; p == pe { + goto _test_eof1286 + } + st_case_1286: + switch { + case data[p] < 152: + if 129 <= data[p] && data[p] <= 151 { + goto tr420 + } + case data[p] > 155: + if 158 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + goto tr571 + st1287: + if p++; p == pe { + goto _test_eof1287 + } + st_case_1287: + if data[p] == 132 { + goto tr148 + } + switch { + case data[p] < 144: + if 129 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + goto tr571 + st1288: + if p++; p == pe { + goto _test_eof1288 + } + st_case_1288: + switch { + case data[p] > 170: + if 171 <= data[p] && data[p] <= 183 { + goto tr571 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1289: + if p++; p == pe { + goto _test_eof1289 + } + st_case_1289: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 157: + goto tr571 + } + goto tr420 + st1290: + if p++; p == pe { + goto _test_eof1290 + } + st_case_1290: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st709 + case 171: + goto st1291 + case 172: + goto st1292 + case 173: + goto st712 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st1293 + case 190: + goto st1294 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr420 + st1291: + if p++; p == pe { + goto _test_eof1291 + } + st_case_1291: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto tr571 + } + case data[p] >= 144: + goto tr148 + } + goto tr420 + st1292: + if p++; p == pe { + goto _test_eof1292 + } + st_case_1292: + switch { + case data[p] > 175: + if 176 <= data[p] && data[p] <= 182 { + goto tr571 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1293: + if p++; p == pe { + goto _test_eof1293 + } + st_case_1293: + switch { + case data[p] < 145: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr420 + } + default: + goto tr571 + } + goto tr148 + st1294: + if p++; p == pe { + goto _test_eof1294 + } + st_case_1294: + switch { + case data[p] > 146: + if 147 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 143: + goto tr571 + } + goto tr420 + st1295: + if p++; p == pe { + goto _test_eof1295 + } + st_case_1295: + switch data[p] { + case 128: + goto st1224 + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st1296 + } + goto tr420 + st1296: + if p++; p == pe { + goto _test_eof1296 + } + st_case_1296: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr571 + } + case data[p] >= 157: + goto tr571 + } + default: + goto tr148 + } + goto tr420 + st1297: + if p++; p == pe { + goto _test_eof1297 + } + st_case_1297: + switch data[p] { + case 133: + goto st1298 + case 134: + goto st1299 + case 137: + goto st1300 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st721 + case 168: + goto st1301 + case 169: + goto st1302 + case 170: + goto st1303 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr420 + st1298: + if p++; p == pe { + goto _test_eof1298 + } + st_case_1298: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr571 + } + case data[p] >= 165: + goto tr571 + } + goto tr420 + st1299: + if p++; p == pe { + goto _test_eof1299 + } + st_case_1299: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr420 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr571 + st1300: + if p++; p == pe { + goto _test_eof1300 + } + st_case_1300: + if 130 <= data[p] && data[p] <= 132 { + goto tr571 + } + goto tr420 + st1301: + if p++; p == pe { + goto _test_eof1301 + } + st_case_1301: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr571 + } + case data[p] >= 128: + goto tr571 + } + goto tr420 + st1302: + if p++; p == pe { + goto _test_eof1302 + } + st_case_1302: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 173: + goto tr420 + } + goto tr571 + st1303: + if p++; p == pe { + goto _test_eof1303 + } + st_case_1303: + if data[p] == 132 { + goto tr571 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr571 + } + case data[p] >= 155: + goto tr571 + } + goto tr420 + st1304: + if p++; p == pe { + goto _test_eof1304 + } + st_case_1304: + switch data[p] { + case 160: + goto st147 + case 163: + goto st1305 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr420 + st1305: + if p++; p == pe { + goto _test_eof1305 + } + st_case_1305: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 150: + if 151 <= data[p] { + goto tr420 + } + default: + goto tr571 + } + goto tr148 + st1306: + if p++; p == pe { + goto _test_eof1306 + } + st_case_1306: + if data[p] == 160 { + goto st1307 + } + goto tr420 + st1307: + if p++; p == pe { + goto _test_eof1307 + } + st_case_1307: + switch data[p] { + case 128: + goto st1308 + case 129: + goto st1309 + case 132: + goto st563 + case 135: + goto st1311 + } + if 133 <= data[p] && data[p] <= 134 { + goto st1310 + } + goto tr420 + st1308: + if p++; p == pe { + goto _test_eof1308 + } + st_case_1308: + if data[p] == 129 { + goto tr571 + } + if 160 <= data[p] { + goto tr571 + } + goto tr420 + st1309: + if p++; p == pe { + goto _test_eof1309 + } + st_case_1309: + if 192 <= data[p] { + goto tr420 + } + goto tr571 + st1310: + if p++; p == pe { + goto _test_eof1310 + } + st_case_1310: + goto tr571 + st1311: + if p++; p == pe { + goto _test_eof1311 + } + st_case_1311: + if 176 <= data[p] { + goto tr420 + } + goto tr571 + st1312: + if p++; p == pe { + goto _test_eof1312 + } + st_case_1312: + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr421 + case 181: + goto tr148 + case 186: + goto tr148 + } + goto tr420 + st1313: + if p++; p == pe { + goto _test_eof1313 + } + st_case_1313: + if 128 <= data[p] { + goto tr421 + } + goto tr420 + st1314: + if p++; p == pe { + goto _test_eof1314 + } + st_case_1314: + switch data[p] { + case 181: + goto tr420 + case 190: + goto st413 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + goto tr421 + st1315: + if p++; p == pe { + goto _test_eof1315 + } + st_case_1315: + if data[p] == 130 { + goto tr420 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr421 + } + goto tr148 + st1316: + if p++; p == pe { + goto _test_eof1316 + } + st_case_1316: + switch data[p] { + case 137: + goto st413 + case 190: + goto tr420 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr420 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + goto tr148 + st1317: + if p++; p == pe { + goto _test_eof1317 + } + st_case_1317: + switch data[p] { + case 135: + goto tr421 + case 179: + goto tr148 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr421 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr421 + } + goto tr420 + st1318: + if p++; p == pe { + goto _test_eof1318 + } + st_case_1318: + if data[p] == 156 { + goto tr421 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 133 { + goto tr421 + } + case data[p] > 141: + switch { + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + case data[p] >= 144: + goto tr421 + } + default: + goto st413 + } + goto tr420 + st1319: + if p++; p == pe { + goto _test_eof1319 + } + st_case_1319: + switch data[p] { + case 171: + goto tr421 + case 172: + goto st413 + case 176: + goto tr421 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + goto tr420 + st1320: + if p++; p == pe { + goto _test_eof1320 + } + st_case_1320: + switch data[p] { + case 148: + goto tr420 + case 158: + goto tr420 + case 169: + goto tr420 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr421 + } + case data[p] >= 150: + goto tr421 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 189: + goto tr420 + } + default: + goto tr421 + } + goto tr148 + st1321: + if p++; p == pe { + goto _test_eof1321 + } + st_case_1321: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto tr421 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr421 + } + default: + goto tr148 + } + goto tr420 + st1322: + if p++; p == pe { + goto _test_eof1322 + } + st_case_1322: + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr420 + } + goto tr421 + st1323: + if p++; p == pe { + goto _test_eof1323 + } + st_case_1323: + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr421 + } + goto tr148 + st1324: + if p++; p == pe { + goto _test_eof1324 + } + st_case_1324: + switch data[p] { + case 184: + goto st413 + case 186: + goto tr148 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 170: + switch { + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 171: + goto tr421 + } + default: + goto tr148 + } + goto tr420 + st1325: + if p++; p == pe { + goto _test_eof1325 + } + st_case_1325: + switch data[p] { + case 160: + goto st1326 + case 161: + goto st1327 + case 162: + goto st168 + case 163: + goto st1328 + case 164: + goto st1329 + case 165: + goto st1330 + case 166: + goto st1331 + case 167: + goto st1332 + case 168: + goto st1333 + case 169: + goto st1334 + case 170: + goto st1335 + case 171: + goto st1336 + case 172: + goto st1337 + case 173: + goto st1338 + case 174: + goto st1339 + case 175: + goto st1340 + case 176: + goto st1341 + case 177: + goto st1342 + case 178: + goto st1343 + case 179: + goto st1344 + case 180: + goto st1345 + case 181: + goto st1346 + case 182: + goto st1347 + case 183: + goto st1348 + case 184: + goto st1349 + case 185: + goto st1350 + case 186: + goto st1351 + case 187: + goto st1352 + case 188: + goto st1353 + case 189: + goto st1354 + case 190: + goto st1355 + case 191: + goto st1356 + } + goto tr420 + st1326: + if p++; p == pe { + goto _test_eof1326 + } + st_case_1326: + switch data[p] { + case 154: + goto tr148 + case 164: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] > 149: + if 150 <= data[p] && data[p] <= 173 { + goto tr421 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1327: + if p++; p == pe { + goto _test_eof1327 + } + st_case_1327: + switch { + case data[p] > 152: + if 153 <= data[p] && data[p] <= 155 { + goto tr421 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1328: + if p++; p == pe { + goto _test_eof1328 + } + st_case_1328: + if 163 <= data[p] { + goto tr421 + } + goto tr420 + st1329: + if p++; p == pe { + goto _test_eof1329 + } + st_case_1329: + if data[p] == 189 { + goto tr148 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr148 + } + goto tr421 + st1330: + if p++; p == pe { + goto _test_eof1330 + } + st_case_1330: + switch data[p] { + case 144: + goto tr148 + case 176: + goto tr420 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + if 177 <= data[p] { + goto tr148 + } + default: + goto tr420 + } + goto tr421 + st1331: + if p++; p == pe { + goto _test_eof1331 + } + st_case_1331: + switch data[p] { + case 132: + goto tr420 + case 169: + goto tr420 + case 177: + goto tr420 + case 188: + goto tr421 + } + switch { + case data[p] < 145: + switch { + case data[p] > 131: + if 141 <= data[p] && data[p] <= 142 { + goto tr420 + } + case data[p] >= 129: + goto tr421 + } + case data[p] > 146: + switch { + case data[p] < 186: + if 179 <= data[p] && data[p] <= 181 { + goto tr420 + } + case data[p] > 187: + if 190 <= data[p] { + goto tr421 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st1332: + if p++; p == pe { + goto _test_eof1332 + } + st_case_1332: + switch data[p] { + case 142: + goto tr148 + case 158: + goto tr420 + } + switch { + case data[p] < 152: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + if 143 <= data[p] && data[p] <= 150 { + goto tr420 + } + default: + goto tr420 + } + case data[p] > 155: + switch { + case data[p] < 164: + if 156 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr421 + st1333: + if p++; p == pe { + goto _test_eof1333 + } + st_case_1333: + if data[p] == 188 { + goto tr421 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr421 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto tr421 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1334: + if p++; p == pe { + goto _test_eof1334 + } + st_case_1334: + if data[p] == 157 { + goto tr420 + } + switch { + case data[p] < 146: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + if 142 <= data[p] && data[p] <= 144 { + goto tr420 + } + default: + goto tr420 + } + case data[p] > 152: + switch { + case data[p] < 159: + if 153 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 165: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr421 + st1335: + if p++; p == pe { + goto _test_eof1335 + } + st_case_1335: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr421 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto tr421 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1336: + if p++; p == pe { + goto _test_eof1336 + } + st_case_1336: + switch data[p] { + case 134: + goto tr420 + case 138: + goto tr420 + case 144: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 160: + if 142 <= data[p] && data[p] <= 159 { + goto tr420 + } + case data[p] > 161: + switch { + case data[p] > 165: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 164: + goto tr420 + } + default: + goto tr148 + } + goto tr421 + st1337: + if p++; p == pe { + goto _test_eof1337 + } + st_case_1337: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr421 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr421 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1338: + if p++; p == pe { + goto _test_eof1338 + } + st_case_1338: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr421 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr421 + } + default: + goto tr421 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 161: + switch { + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 162: + goto tr421 + } + default: + goto tr148 + } + default: + goto tr421 + } + goto tr420 + st1339: + if p++; p == pe { + goto _test_eof1339 + } + st_case_1339: + switch data[p] { + case 130: + goto tr421 + case 131: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 158: + switch { + case data[p] < 142: + if 133 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 149: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] < 168: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto tr421 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1340: + if p++; p == pe { + goto _test_eof1340 + } + st_case_1340: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr421 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr421 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 138: + goto tr421 + } + default: + goto tr421 + } + goto tr420 + st1341: + if p++; p == pe { + goto _test_eof1341 + } + st_case_1341: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto tr421 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 190 <= data[p] { + goto tr421 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1342: + if p++; p == pe { + goto _test_eof1342 + } + st_case_1342: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 151: + goto tr420 + } + switch { + case data[p] < 155: + switch { + case data[p] > 148: + if 152 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 142: + goto tr420 + } + case data[p] > 159: + switch { + case data[p] < 164: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + if 176 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr421 + st1343: + if p++; p == pe { + goto _test_eof1343 + } + st_case_1343: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr421 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr421 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1344: + if p++; p == pe { + goto _test_eof1344 + } + st_case_1344: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr421 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr421 + } + default: + goto tr421 + } + case data[p] > 150: + switch { + case data[p] < 162: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 163: + switch { + case data[p] > 175: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr421 + } + default: + goto tr421 + } + goto tr420 + st1345: + if p++; p == pe { + goto _test_eof1345 + } + st_case_1345: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto tr421 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto tr421 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1346: + if p++; p == pe { + goto _test_eof1346 + } + st_case_1346: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 142: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 150 { + goto tr420 + } + case data[p] > 158: + if 159 <= data[p] && data[p] <= 161 { + goto tr148 + } + default: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] < 186: + if 176 <= data[p] && data[p] <= 185 { + goto tr420 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + default: + goto tr420 + } + goto tr421 + st1347: + if p++; p == pe { + goto _test_eof1347 + } + st_case_1347: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr421 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1348: + if p++; p == pe { + goto _test_eof1348 + } + st_case_1348: + switch data[p] { + case 138: + goto tr421 + case 150: + goto tr421 + } + switch { + case data[p] < 152: + switch { + case data[p] > 134: + if 143 <= data[p] && data[p] <= 148 { + goto tr421 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto tr421 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr421 + } + goto tr420 + st1349: + if p++; p == pe { + goto _test_eof1349 + } + st_case_1349: + if data[p] == 177 { + goto tr421 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr421 + } + goto tr420 + st1350: + if p++; p == pe { + goto _test_eof1350 + } + st_case_1350: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 135: + goto tr421 + } + goto tr420 + st1351: + if p++; p == pe { + goto _test_eof1351 + } + st_case_1351: + if data[p] == 177 { + goto tr421 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr421 + } + case data[p] >= 180: + goto tr421 + } + goto tr420 + st1352: + if p++; p == pe { + goto _test_eof1352 + } + st_case_1352: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 136: + goto tr421 + } + goto tr420 + st1353: + if p++; p == pe { + goto _test_eof1353 + } + st_case_1353: + switch data[p] { + case 128: + goto tr148 + case 181: + goto tr421 + case 183: + goto tr421 + case 185: + goto tr421 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto tr421 + } + default: + goto tr421 + } + goto tr420 + st1354: + if p++; p == pe { + goto _test_eof1354 + } + st_case_1354: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto tr421 + } + default: + goto tr148 + } + goto tr420 + st1355: + if p++; p == pe { + goto _test_eof1355 + } + st_case_1355: + switch { + case data[p] < 136: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 135 { + goto tr421 + } + case data[p] >= 128: + goto tr421 + } + case data[p] > 140: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr421 + } + case data[p] >= 141: + goto tr421 + } + default: + goto tr148 + } + goto tr420 + st1356: + if p++; p == pe { + goto _test_eof1356 + } + st_case_1356: + if data[p] == 134 { + goto tr421 + } + goto tr420 + st1357: + if p++; p == pe { + goto _test_eof1357 + } + st_case_1357: + switch data[p] { + case 128: + goto st1358 + case 129: + goto st1359 + case 130: + goto st1360 + case 131: + goto st202 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st1361 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st1362 + case 157: + goto st1363 + case 158: + goto st1364 + case 159: + goto st1365 + case 160: + goto st1366 + case 161: + goto st219 + case 162: + goto st1367 + case 163: + goto st221 + case 164: + goto st1368 + case 165: + goto st468 + case 167: + goto st469 + case 168: + goto st1369 + case 169: + goto st1370 + case 170: + goto st1371 + case 172: + goto st1372 + case 173: + goto st1373 + case 174: + goto st1374 + case 175: + goto st1375 + case 176: + goto st1376 + case 177: + goto st640 + case 179: + goto st1377 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st1378 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + } + switch { + case data[p] < 180: + if 132 <= data[p] && data[p] <= 152 { + goto st145 + } + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + default: + goto st147 + } + goto tr420 + st1358: + if p++; p == pe { + goto _test_eof1358 + } + st_case_1358: + if 171 <= data[p] && data[p] <= 190 { + goto tr421 + } + goto tr420 + st1359: + if p++; p == pe { + goto _test_eof1359 + } + st_case_1359: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 128: + goto tr421 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto tr421 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr421 + } + default: + goto tr421 + } + default: + goto tr421 + } + goto tr420 + st1360: + if p++; p == pe { + goto _test_eof1360 + } + st_case_1360: + switch { + case data[p] < 143: + if 130 <= data[p] && data[p] <= 141 { + goto tr421 + } + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + goto tr420 + st1361: + if p++; p == pe { + goto _test_eof1361 + } + st_case_1361: + switch { + case data[p] < 157: + if 155 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + goto tr148 + st1362: + if p++; p == pe { + goto _test_eof1362 + } + st_case_1362: + switch { + case data[p] < 146: + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 177: + if 178 <= data[p] && data[p] <= 180 { + goto tr421 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr421 + } + goto tr420 + st1363: + if p++; p == pe { + goto _test_eof1363 + } + st_case_1363: + switch { + case data[p] < 160: + switch { + case data[p] > 145: + if 146 <= data[p] && data[p] <= 147 { + goto tr421 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto tr421 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1364: + if p++; p == pe { + goto _test_eof1364 + } + st_case_1364: + if 180 <= data[p] { + goto tr421 + } + goto tr420 + st1365: + if p++; p == pe { + goto _test_eof1365 + } + st_case_1365: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + if 170 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr421 + st1366: + if p++; p == pe { + goto _test_eof1366 + } + st_case_1366: + switch { + case data[p] < 144: + if 139 <= data[p] && data[p] <= 142 { + goto tr421 + } + case data[p] > 153: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + goto tr420 + st1367: + if p++; p == pe { + goto _test_eof1367 + } + st_case_1367: + if data[p] == 169 { + goto tr421 + } + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1368: + if p++; p == pe { + goto _test_eof1368 + } + st_case_1368: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr421 + } + default: + goto tr421 + } + goto tr420 + st1369: + if p++; p == pe { + goto _test_eof1369 + } + st_case_1369: + switch { + case data[p] > 150: + if 151 <= data[p] && data[p] <= 155 { + goto tr421 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1370: + if p++; p == pe { + goto _test_eof1370 + } + st_case_1370: + if data[p] == 191 { + goto tr421 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr421 + } + case data[p] >= 149: + goto tr421 + } + goto tr420 + st1371: + if p++; p == pe { + goto _test_eof1371 + } + st_case_1371: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto tr421 + } + default: + goto tr421 + } + goto tr420 + st1372: + if p++; p == pe { + goto _test_eof1372 + } + st_case_1372: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 132 { + goto tr421 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr421 + } + default: + goto tr148 + } + goto tr420 + st1373: + if p++; p == pe { + goto _test_eof1373 + } + st_case_1373: + switch { + case data[p] < 140: + if 133 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 143: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 154: + goto tr420 + } + default: + goto tr420 + } + goto tr421 + st1374: + if p++; p == pe { + goto _test_eof1374 + } + st_case_1374: + switch { + case data[p] < 161: + switch { + case data[p] > 130: + if 131 <= data[p] && data[p] <= 160 { + goto tr148 + } + case data[p] >= 128: + goto tr421 + } + case data[p] > 173: + switch { + case data[p] < 176: + if 174 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + default: + goto tr421 + } + goto tr420 + st1375: + if p++; p == pe { + goto _test_eof1375 + } + st_case_1375: + switch { + case data[p] > 179: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr421 + } + goto tr148 + st1376: + if p++; p == pe { + goto _test_eof1376 + } + st_case_1376: + switch { + case data[p] > 163: + if 164 <= data[p] && data[p] <= 183 { + goto tr421 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1377: + if p++; p == pe { + goto _test_eof1377 + } + st_case_1377: + if data[p] == 173 { + goto tr421 + } + switch { + case data[p] < 169: + switch { + case data[p] > 146: + if 148 <= data[p] && data[p] <= 168 { + goto tr421 + } + case data[p] >= 144: + goto tr421 + } + case data[p] > 177: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 180 { + goto tr421 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto tr421 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1378: + if p++; p == pe { + goto _test_eof1378 + } + st_case_1378: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr421 + } + case data[p] >= 128: + goto tr421 + } + goto tr420 + st1379: + if p++; p == pe { + goto _test_eof1379 + } + st_case_1379: + switch data[p] { + case 128: + goto st1380 + case 129: + goto st1381 + case 130: + goto st241 + case 131: + goto st1382 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st1383 + case 180: + goto st251 + case 181: + goto st1384 + case 182: + goto st253 + case 183: + goto st1385 + case 184: + goto st255 + } + goto tr420 + st1380: + if p++; p == pe { + goto _test_eof1380 + } + st_case_1380: + if data[p] == 164 { + goto st413 + } + switch { + case data[p] < 152: + if 140 <= data[p] && data[p] <= 143 { + goto tr421 + } + case data[p] > 153: + switch { + case data[p] > 174: + if 191 <= data[p] { + goto tr571 + } + case data[p] >= 170: + goto tr421 + } + default: + goto st413 + } + goto tr420 + st1381: + if p++; p == pe { + goto _test_eof1381 + } + st_case_1381: + switch data[p] { + case 132: + goto st413 + case 165: + goto tr420 + case 177: + goto tr148 + case 191: + goto tr148 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr420 + } + goto tr571 + st1382: + if p++; p == pe { + goto _test_eof1382 + } + st_case_1382: + if 144 <= data[p] && data[p] <= 176 { + goto tr421 + } + goto tr420 + st1383: + if p++; p == pe { + goto _test_eof1383 + } + st_case_1383: + switch { + case data[p] < 175: + if 165 <= data[p] && data[p] <= 170 { + goto tr420 + } + case data[p] > 177: + if 180 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + goto tr148 + st1384: + if p++; p == pe { + goto _test_eof1384 + } + st_case_1384: + if data[p] == 191 { + goto tr421 + } + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 168: + goto tr420 + } + goto tr148 + st1385: + if p++; p == pe { + goto _test_eof1385 + } + st_case_1385: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto tr421 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1386: + if p++; p == pe { + goto _test_eof1386 + } + st_case_1386: + switch data[p] { + case 128: + goto st1387 + case 130: + goto st1388 + case 132: + goto st259 + case 133: + goto st145 + case 134: + goto st260 + } + goto tr420 + st1387: + if p++; p == pe { + goto _test_eof1387 + } + st_case_1387: + if data[p] == 133 { + goto tr148 + } + switch { + case data[p] > 175: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + case data[p] >= 170: + goto tr421 + } + goto tr420 + st1388: + if p++; p == pe { + goto _test_eof1388 + } + st_case_1388: + if 153 <= data[p] && data[p] <= 154 { + goto tr421 + } + goto tr420 + st1389: + if p++; p == pe { + goto _test_eof1389 + } + st_case_1389: + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st654 + case 153: + goto st1390 + case 154: + goto st1391 + case 155: + goto st1392 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st1393 + case 161: + goto st272 + case 162: + goto st1394 + case 163: + goto st1395 + case 164: + goto st1396 + case 165: + goto st1397 + case 166: + goto st1398 + case 167: + goto st1399 + case 168: + goto st1400 + case 169: + goto st1401 + case 170: + goto st1402 + case 171: + goto st1403 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st1404 + case 176: + goto st147 + } + if 129 <= data[p] { + goto st145 + } + goto tr420 + st1390: + if p++; p == pe { + goto _test_eof1390 + } + st_case_1390: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr421 + } + default: + goto tr421 + } + goto tr420 + st1391: + if p++; p == pe { + goto _test_eof1391 + } + st_case_1391: + switch { + case data[p] < 158: + if 128 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + goto tr420 + st1392: + if p++; p == pe { + goto _test_eof1392 + } + st_case_1392: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr421 + } + goto tr148 + st1393: + if p++; p == pe { + goto _test_eof1393 + } + st_case_1393: + switch data[p] { + case 130: + goto tr421 + case 134: + goto tr421 + case 139: + goto tr421 + } + switch { + case data[p] > 167: + if 168 <= data[p] { + goto tr420 + } + case data[p] >= 163: + goto tr421 + } + goto tr148 + st1394: + if p++; p == pe { + goto _test_eof1394 + } + st_case_1394: + switch { + case data[p] < 130: + if 128 <= data[p] && data[p] <= 129 { + goto tr421 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr421 + } + default: + goto tr148 + } + goto tr420 + st1395: + if p++; p == pe { + goto _test_eof1395 + } + st_case_1395: + switch data[p] { + case 187: + goto tr148 + case 189: + goto tr148 + } + switch { + case data[p] < 154: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 183: + if 184 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr420 + } + goto tr421 + st1396: + if p++; p == pe { + goto _test_eof1396 + } + st_case_1396: + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 165: + switch { + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr148 + } + goto tr420 + st1397: + if p++; p == pe { + goto _test_eof1397 + } + st_case_1397: + switch { + case data[p] < 148: + if 135 <= data[p] && data[p] <= 147 { + goto tr421 + } + case data[p] > 159: + if 189 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st1398: + if p++; p == pe { + goto _test_eof1398 + } + st_case_1398: + switch { + case data[p] < 132: + if 128 <= data[p] && data[p] <= 131 { + goto tr421 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr421 + } + default: + goto tr148 + } + goto tr420 + st1399: + if p++; p == pe { + goto _test_eof1399 + } + st_case_1399: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] < 154: + if 129 <= data[p] && data[p] <= 142 { + goto tr420 + } + case data[p] > 164: + switch { + case data[p] > 175: + if 186 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr420 + } + default: + goto tr420 + } + goto tr421 + st1400: + if p++; p == pe { + goto _test_eof1400 + } + st_case_1400: + switch { + case data[p] > 168: + if 169 <= data[p] && data[p] <= 182 { + goto tr421 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1401: + if p++; p == pe { + goto _test_eof1401 + } + st_case_1401: + if data[p] == 131 { + goto tr421 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 141: + switch { + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto tr421 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr421 + } + goto tr420 + st1402: + if p++; p == pe { + goto _test_eof1402 + } + st_case_1402: + if data[p] == 176 { + goto tr421 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr421 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr421 + } + default: + goto tr421 + } + goto tr420 + st1403: + if p++; p == pe { + goto _test_eof1403 + } + st_case_1403: + if data[p] == 129 { + goto tr421 + } + switch { + case data[p] < 171: + if 160 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 181 <= data[p] && data[p] <= 182 { + goto tr421 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr421 + } + goto tr420 + st1404: + if p++; p == pe { + goto _test_eof1404 + } + st_case_1404: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 162 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 172: + goto tr421 + } + default: + goto tr421 + } + goto tr420 + st1405: + if p++; p == pe { + goto _test_eof1405 + } + st_case_1405: + switch data[p] { + case 172: + goto st1406 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st1407 + case 185: + goto st1408 + case 187: + goto st1409 + case 188: + goto st1410 + case 189: + goto st303 + case 190: + goto st1411 + case 191: + goto st1412 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr420 + st1406: + if p++; p == pe { + goto _test_eof1406 + } + st_case_1406: + switch data[p] { + case 158: + goto tr421 + case 190: + goto tr572 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 170: + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st1407: + if p++; p == pe { + goto _test_eof1407 + } + st_case_1407: + switch data[p] { + case 144: + goto st413 + case 148: + goto st413 + } + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr421 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr571 + } + default: + goto tr421 + } + goto tr420 + st1408: + if p++; p == pe { + goto _test_eof1408 + } + st_case_1408: + switch data[p] { + case 144: + goto st413 + case 146: + goto st413 + case 148: + goto st413 + } + switch { + case data[p] < 176: + if 141 <= data[p] && data[p] <= 143 { + goto tr571 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1409: + if p++; p == pe { + goto _test_eof1409 + } + st_case_1409: + if data[p] == 191 { + goto tr421 + } + if 189 <= data[p] { + goto tr420 + } + goto tr148 + st1410: + if p++; p == pe { + goto _test_eof1410 + } + st_case_1410: + switch data[p] { + case 135: + goto st413 + case 140: + goto st413 + case 142: + goto st413 + case 155: + goto st413 + case 191: + goto tr571 + } + if 161 <= data[p] && data[p] <= 186 { + goto tr148 + } + goto tr420 + st1411: + if p++; p == pe { + goto _test_eof1411 + } + st_case_1411: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 190 { + goto tr148 + } + case data[p] >= 158: + goto tr421 + } + goto tr420 + st1412: + if p++; p == pe { + goto _test_eof1412 + } + st_case_1412: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] >= 130: + goto tr148 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr421 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1413: + if p++; p == pe { + goto _test_eof1413 + } + st_case_1413: + switch data[p] { + case 144: + goto st1414 + case 145: + goto st1420 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st1439 + case 155: + goto st1444 + case 157: + goto st1446 + case 158: + goto st1453 + case 159: + goto st403 + } + goto tr420 + st1414: + if p++; p == pe { + goto _test_eof1414 + } + st_case_1414: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st1415 + case 138: + goto st313 + case 139: + goto st1416 + case 140: + goto st315 + case 141: + goto st1417 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st684 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st1418 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st1419 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr420 + st1415: + if p++; p == pe { + goto _test_eof1415 + } + st_case_1415: + if data[p] == 189 { + goto tr421 + } + goto tr420 + st1416: + if p++; p == pe { + goto _test_eof1416 + } + st_case_1416: + if data[p] == 160 { + goto tr421 + } + if 145 <= data[p] { + goto tr420 + } + goto tr148 + st1417: + if p++; p == pe { + goto _test_eof1417 + } + st_case_1417: + switch { + case data[p] < 182: + if 139 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + goto tr148 + st1418: + if p++; p == pe { + goto _test_eof1418 + } + st_case_1418: + switch data[p] { + case 128: + goto tr148 + case 191: + goto tr421 + } + switch { + case data[p] < 144: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr421 + } + case data[p] > 134: + if 140 <= data[p] && data[p] <= 143 { + goto tr421 + } + default: + goto tr421 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto tr421 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1419: + if p++; p == pe { + goto _test_eof1419 + } + st_case_1419: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 164: + if 165 <= data[p] && data[p] <= 166 { + goto tr421 + } + default: + goto tr148 + } + goto tr420 + st1420: + if p++; p == pe { + goto _test_eof1420 + } + st_case_1420: + switch data[p] { + case 128: + goto st1421 + case 129: + goto st1422 + case 130: + goto st1423 + case 131: + goto st691 + case 132: + goto st1424 + case 133: + goto st1425 + case 134: + goto st1426 + case 135: + goto st1427 + case 136: + goto st1428 + case 138: + goto st348 + case 139: + goto st1429 + case 140: + goto st1430 + case 141: + goto st1431 + case 146: + goto st1432 + case 147: + goto st1433 + case 150: + goto st1434 + case 151: + goto st1435 + case 152: + goto st1432 + case 153: + goto st1436 + case 154: + goto st1437 + case 155: + goto st538 + case 156: + goto st1438 + case 162: + goto st359 + case 163: + goto st707 + case 171: + goto st361 + } + goto tr420 + st1421: + if p++; p == pe { + goto _test_eof1421 + } + st_case_1421: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr421 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr421 + } + default: + goto tr148 + } + goto tr420 + st1422: + if p++; p == pe { + goto _test_eof1422 + } + st_case_1422: + switch { + case data[p] > 165: + if 176 <= data[p] && data[p] <= 190 { + goto tr420 + } + case data[p] >= 135: + goto tr420 + } + goto tr421 + st1423: + if p++; p == pe { + goto _test_eof1423 + } + st_case_1423: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr421 + st1424: + if p++; p == pe { + goto _test_eof1424 + } + st_case_1424: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr421 + } + case data[p] > 166: + switch { + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr421 + } + case data[p] >= 167: + goto tr421 + } + default: + goto tr148 + } + goto tr420 + st1425: + if p++; p == pe { + goto _test_eof1425 + } + st_case_1425: + switch data[p] { + case 179: + goto tr421 + case 182: + goto tr148 + } + if 144 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr420 + st1426: + if p++; p == pe { + goto _test_eof1426 + } + st_case_1426: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr421 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr421 + } + default: + goto tr148 + } + goto tr420 + st1427: + if p++; p == pe { + goto _test_eof1427 + } + st_case_1427: + if data[p] == 155 { + goto tr420 + } + switch { + case data[p] < 141: + switch { + case data[p] > 132: + if 133 <= data[p] && data[p] <= 137 { + goto tr420 + } + case data[p] >= 129: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] > 156: + if 157 <= data[p] { + goto tr420 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr420 + } + goto tr421 + st1428: + if p++; p == pe { + goto _test_eof1428 + } + st_case_1428: + switch { + case data[p] < 147: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] > 171: + if 172 <= data[p] && data[p] <= 183 { + goto tr421 + } + default: + goto tr148 + } + goto tr420 + st1429: + if p++; p == pe { + goto _test_eof1429 + } + st_case_1429: + switch { + case data[p] < 171: + if 159 <= data[p] && data[p] <= 170 { + goto tr421 + } + case data[p] > 175: + switch { + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr421 + } + default: + goto tr420 + } + goto tr148 + st1430: + if p++; p == pe { + goto _test_eof1430 + } + st_case_1430: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto tr421 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr421 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1431: + if p++; p == pe { + goto _test_eof1431 + } + st_case_1431: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr421 + } + switch { + case data[p] < 157: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr421 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr421 + } + default: + goto tr421 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr421 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr421 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr420 + st1432: + if p++; p == pe { + goto _test_eof1432 + } + st_case_1432: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr421 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1433: + if p++; p == pe { + goto _test_eof1433 + } + st_case_1433: + if data[p] == 134 { + goto tr420 + } + switch { + case data[p] < 136: + if 132 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 143: + if 154 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr421 + st1434: + if p++; p == pe { + goto _test_eof1434 + } + st_case_1434: + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 181: + if 184 <= data[p] { + goto tr421 + } + default: + goto tr421 + } + goto tr420 + st1435: + if p++; p == pe { + goto _test_eof1435 + } + st_case_1435: + switch { + case data[p] < 152: + if 129 <= data[p] && data[p] <= 151 { + goto tr420 + } + case data[p] > 155: + if 158 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + goto tr421 + st1436: + if p++; p == pe { + goto _test_eof1436 + } + st_case_1436: + if data[p] == 132 { + goto tr148 + } + switch { + case data[p] > 143: + if 154 <= data[p] { + goto tr420 + } + case data[p] >= 129: + goto tr420 + } + goto tr421 + st1437: + if p++; p == pe { + goto _test_eof1437 + } + st_case_1437: + switch { + case data[p] > 170: + if 171 <= data[p] && data[p] <= 183 { + goto tr421 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1438: + if p++; p == pe { + goto _test_eof1438 + } + st_case_1438: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 157: + goto tr421 + } + goto tr420 + st1439: + if p++; p == pe { + goto _test_eof1439 + } + st_case_1439: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st709 + case 171: + goto st1440 + case 172: + goto st1441 + case 173: + goto st712 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st1442 + case 190: + goto st1443 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr420 + st1440: + if p++; p == pe { + goto _test_eof1440 + } + st_case_1440: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto tr421 + } + case data[p] >= 144: + goto tr148 + } + goto tr420 + st1441: + if p++; p == pe { + goto _test_eof1441 + } + st_case_1441: + switch { + case data[p] > 175: + if 176 <= data[p] && data[p] <= 182 { + goto tr421 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st1442: + if p++; p == pe { + goto _test_eof1442 + } + st_case_1442: + switch { + case data[p] < 145: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + goto tr148 + st1443: + if p++; p == pe { + goto _test_eof1443 + } + st_case_1443: + switch { + case data[p] > 146: + if 147 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 143: + goto tr421 + } + goto tr420 + st1444: + if p++; p == pe { + goto _test_eof1444 + } + st_case_1444: + switch data[p] { + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st1445 + } + goto tr420 + st1445: + if p++; p == pe { + goto _test_eof1445 + } + st_case_1445: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr421 + } + case data[p] >= 157: + goto tr421 + } + default: + goto tr148 + } + goto tr420 + st1446: + if p++; p == pe { + goto _test_eof1446 + } + st_case_1446: + switch data[p] { + case 133: + goto st1447 + case 134: + goto st1448 + case 137: + goto st1449 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st721 + case 168: + goto st1450 + case 169: + goto st1451 + case 170: + goto st1452 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr420 + st1447: + if p++; p == pe { + goto _test_eof1447 + } + st_case_1447: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr421 + } + case data[p] >= 165: + goto tr421 + } + goto tr420 + st1448: + if p++; p == pe { + goto _test_eof1448 + } + st_case_1448: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr420 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr421 + st1449: + if p++; p == pe { + goto _test_eof1449 + } + st_case_1449: + if 130 <= data[p] && data[p] <= 132 { + goto tr421 + } + goto tr420 + st1450: + if p++; p == pe { + goto _test_eof1450 + } + st_case_1450: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr421 + } + case data[p] >= 128: + goto tr421 + } + goto tr420 + st1451: + if p++; p == pe { + goto _test_eof1451 + } + st_case_1451: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 173: + goto tr420 + } + goto tr421 + st1452: + if p++; p == pe { + goto _test_eof1452 + } + st_case_1452: + if data[p] == 132 { + goto tr421 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 155: + goto tr421 + } + goto tr420 + st1453: + if p++; p == pe { + goto _test_eof1453 + } + st_case_1453: + switch data[p] { + case 160: + goto st147 + case 163: + goto st1454 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr420 + st1454: + if p++; p == pe { + goto _test_eof1454 + } + st_case_1454: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 150: + if 151 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + goto tr148 + st1455: + if p++; p == pe { + goto _test_eof1455 + } + st_case_1455: + if data[p] == 160 { + goto st1456 + } + goto tr420 + st1456: + if p++; p == pe { + goto _test_eof1456 + } + st_case_1456: + switch data[p] { + case 128: + goto st1457 + case 129: + goto st1458 + case 132: + goto st1313 + case 135: + goto st1460 + } + if 133 <= data[p] && data[p] <= 134 { + goto st1459 + } + goto tr420 + st1457: + if p++; p == pe { + goto _test_eof1457 + } + st_case_1457: + if data[p] == 129 { + goto tr421 + } + if 160 <= data[p] { + goto tr421 + } + goto tr420 + st1458: + if p++; p == pe { + goto _test_eof1458 + } + st_case_1458: + if 192 <= data[p] { + goto tr420 + } + goto tr421 + st1459: + if p++; p == pe { + goto _test_eof1459 + } + st_case_1459: + goto tr421 + st1460: + if p++; p == pe { + goto _test_eof1460 + } + st_case_1460: + if 176 <= data[p] { + goto tr420 + } + goto tr421 + st1461: + if p++; p == pe { + goto _test_eof1461 + } + st_case_1461: + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr148 + case 181: + goto tr148 + case 183: + goto st142 + case 186: + goto tr148 + } + goto tr420 + st1462: + if p++; p == pe { + goto _test_eof1462 + } + st_case_1462: + switch data[p] { + case 181: + goto tr420 + case 190: + goto tr420 + } + switch { + case data[p] > 185: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 184: + goto tr420 + } + goto tr148 + st1463: + if p++; p == pe { + goto _test_eof1463 + } + st_case_1463: + if data[p] == 130 { + goto tr420 + } + goto tr148 + st1464: + if p++; p == pe { + goto _test_eof1464 + } + st_case_1464: + if data[p] == 190 { + goto tr420 + } + switch { + case data[p] > 144: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 136: + goto tr420 + } + goto tr148 + st1465: + if p++; p == pe { + goto _test_eof1465 + } + st_case_1465: + switch data[p] { + case 135: + goto tr148 + case 179: + goto tr148 + case 180: + goto st142 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr148 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr148 + } + goto tr420 + st1466: + if p++; p == pe { + goto _test_eof1466 + } + st_case_1466: + if data[p] == 156 { + goto tr148 + } + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 133 { + goto tr148 + } + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st1467: + if p++; p == pe { + goto _test_eof1467 + } + st_case_1467: + if data[p] == 171 { + goto tr421 + } + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + goto tr420 + st1468: + if p++; p == pe { + goto _test_eof1468 + } + st_case_1468: + switch data[p] { + case 148: + goto tr420 + case 158: + goto tr420 + case 169: + goto tr420 + } + switch { + case data[p] < 189: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] > 190: + if 192 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st1469: + if p++; p == pe { + goto _test_eof1469 + } + st_case_1469: + if 143 <= data[p] { + goto tr148 + } + goto tr420 + st1470: + if p++; p == pe { + goto _test_eof1470 + } + st_case_1470: + if 139 <= data[p] && data[p] <= 140 { + goto tr420 + } + goto tr148 + st1471: + if p++; p == pe { + goto _test_eof1471 + } + st_case_1471: + if data[p] == 186 { + goto tr148 + } + switch { + case data[p] > 137: + if 138 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 128: + goto tr421 + } + goto tr420 + st1472: + if p++; p == pe { + goto _test_eof1472 + } + st_case_1472: + switch data[p] { + case 160: + goto st1473 + case 161: + goto st1474 + case 162: + goto st168 + case 163: + goto st1475 + case 164: + goto st145 + case 165: + goto st1476 + case 166: + goto st1477 + case 167: + goto st1478 + case 168: + goto st1479 + case 169: + goto st1480 + case 170: + goto st1481 + case 171: + goto st1482 + case 172: + goto st1483 + case 173: + goto st1484 + case 174: + goto st1485 + case 175: + goto st1486 + case 176: + goto st1487 + case 177: + goto st1488 + case 178: + goto st1489 + case 179: + goto st1490 + case 180: + goto st1491 + case 181: + goto st1492 + case 182: + goto st1493 + case 183: + goto st1494 + case 184: + goto st1495 + case 185: + goto st1496 + case 186: + goto st1497 + case 187: + goto st1498 + case 188: + goto st1499 + case 189: + goto st1500 + case 190: + goto st1501 + case 191: + goto st1502 + } + goto tr420 + st1473: + if p++; p == pe { + goto _test_eof1473 + } + st_case_1473: + if 128 <= data[p] && data[p] <= 173 { + goto tr148 + } + goto tr2 + st1474: + if p++; p == pe { + goto _test_eof1474 + } + st_case_1474: + if 128 <= data[p] && data[p] <= 155 { + goto tr148 + } + goto tr2 + st1475: + if p++; p == pe { + goto _test_eof1475 + } + st_case_1475: + if 163 <= data[p] { + goto tr148 + } + goto tr2 + st1476: + if p++; p == pe { + goto _test_eof1476 + } + st_case_1476: + if data[p] == 176 { + goto tr2 + } + switch { + case data[p] > 165: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 164: + goto tr2 + } + goto tr148 + st1477: + if p++; p == pe { + goto _test_eof1477 + } + st_case_1477: + switch data[p] { + case 132: + goto tr2 + case 169: + goto tr2 + case 177: + goto tr2 + } + switch { + case data[p] < 145: + if 141 <= data[p] && data[p] <= 142 { + goto tr2 + } + case data[p] > 146: + switch { + case data[p] > 181: + if 186 <= data[p] && data[p] <= 187 { + goto tr2 + } + case data[p] >= 179: + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st1478: + if p++; p == pe { + goto _test_eof1478 + } + st_case_1478: + if data[p] == 158 { + goto tr2 + } + switch { + case data[p] < 152: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr2 + } + case data[p] > 138: + if 143 <= data[p] && data[p] <= 150 { + goto tr2 + } + default: + goto tr2 + } + case data[p] > 155: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr2 + } + case data[p] > 175: + if 178 <= data[p] { + goto tr2 + } + default: + goto tr421 + } + default: + goto tr2 + } + goto tr148 + st1479: + if p++; p == pe { + goto _test_eof1479 + } + st_case_1479: + if data[p] == 188 { + goto tr148 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr148 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto tr148 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1480: + if p++; p == pe { + goto _test_eof1480 + } + st_case_1480: + if data[p] == 157 { + goto tr2 + } + switch { + case data[p] < 146: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr2 + } + case data[p] > 138: + if 142 <= data[p] && data[p] <= 144 { + goto tr2 + } + default: + goto tr2 + } + case data[p] > 152: + switch { + case data[p] < 166: + if 159 <= data[p] && data[p] <= 165 { + goto tr2 + } + case data[p] > 175: + if 182 <= data[p] { + goto tr2 + } + default: + goto tr421 + } + default: + goto tr2 + } + goto tr148 + st1481: + if p++; p == pe { + goto _test_eof1481 + } + st_case_1481: + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr148 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto tr148 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1482: + if p++; p == pe { + goto _test_eof1482 + } + st_case_1482: + switch data[p] { + case 134: + goto tr2 + case 138: + goto tr2 + } + switch { + case data[p] < 164: + switch { + case data[p] > 143: + if 145 <= data[p] && data[p] <= 159 { + goto tr2 + } + case data[p] >= 142: + goto tr2 + } + case data[p] > 165: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] > 184: + if 186 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st1483: + if p++; p == pe { + goto _test_eof1483 + } + st_case_1483: + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr148 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr148 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1484: + if p++; p == pe { + goto _test_eof1484 + } + st_case_1484: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr148 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1485: + if p++; p == pe { + goto _test_eof1485 + } + st_case_1485: + if data[p] == 156 { + goto tr148 + } + switch { + case data[p] < 153: + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr148 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 146 <= data[p] && data[p] <= 149 { + goto tr148 + } + case data[p] >= 142: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 154: + switch { + case data[p] < 168: + switch { + case data[p] > 159: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] >= 158: + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto tr148 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1486: + if p++; p == pe { + goto _test_eof1486 + } + st_case_1486: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr148 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr148 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 138: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1487: + if p++; p == pe { + goto _test_eof1487 + } + st_case_1487: + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 189 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1488: + if p++; p == pe { + goto _test_eof1488 + } + st_case_1488: + switch data[p] { + case 133: + goto tr2 + case 137: + goto tr2 + case 151: + goto tr2 + } + switch { + case data[p] < 164: + switch { + case data[p] > 148: + if 155 <= data[p] && data[p] <= 159 { + goto tr2 + } + case data[p] >= 142: + goto tr2 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr2 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr2 + } + goto tr148 + st1489: + if p++; p == pe { + goto _test_eof1489 + } + st_case_1489: + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr148 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1490: + if p++; p == pe { + goto _test_eof1490 + } + st_case_1490: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr148 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] < 166: + if 160 <= data[p] && data[p] <= 163 { + goto tr148 + } + case data[p] > 175: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr2 + st1491: + if p++; p == pe { + goto _test_eof1491 + } + st_case_1491: + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 189 <= data[p] { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1492: + if p++; p == pe { + goto _test_eof1492 + } + st_case_1492: + switch data[p] { + case 133: + goto tr2 + case 137: + goto tr2 + } + switch { + case data[p] < 164: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 158 { + goto tr2 + } + case data[p] >= 143: + goto tr2 + } + case data[p] > 165: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] > 185: + if 192 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st1493: + if p++; p == pe { + goto _test_eof1493 + } + st_case_1493: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1494: + if p++; p == pe { + goto _test_eof1494 + } + st_case_1494: + switch data[p] { + case 138: + goto tr148 + case 150: + goto tr148 + } + switch { + case data[p] < 152: + switch { + case data[p] > 134: + if 143 <= data[p] && data[p] <= 148 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr148 + } + goto tr2 + st1495: + if p++; p == pe { + goto _test_eof1495 + } + st_case_1495: + if data[p] == 177 { + goto tr148 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr148 + } + goto tr2 + st1496: + if p++; p == pe { + goto _test_eof1496 + } + st_case_1496: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 135: + goto tr148 + } + goto tr2 + st1497: + if p++; p == pe { + goto _test_eof1497 + } + st_case_1497: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + case data[p] >= 180: + goto tr148 + } + goto tr2 + st1498: + if p++; p == pe { + goto _test_eof1498 + } + st_case_1498: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 136: + goto tr148 + } + goto tr2 + st1499: + if p++; p == pe { + goto _test_eof1499 + } + st_case_1499: + switch data[p] { + case 128: + goto tr148 + case 181: + goto tr148 + case 183: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto tr148 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr421 + } + goto tr2 + st1500: + if p++; p == pe { + goto _test_eof1500 + } + st_case_1500: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1501: + if p++; p == pe { + goto _test_eof1501 + } + st_case_1501: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr148 + } + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1502: + if p++; p == pe { + goto _test_eof1502 + } + st_case_1502: + if data[p] == 134 { + goto tr148 + } + goto tr2 + st1503: + if p++; p == pe { + goto _test_eof1503 + } + st_case_1503: + switch data[p] { + case 128: + goto st1504 + case 129: + goto st1505 + case 130: + goto st1506 + case 131: + goto st202 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st1507 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st1508 + case 157: + goto st1509 + case 158: + goto st1510 + case 159: + goto st1511 + case 160: + goto st1512 + case 161: + goto st219 + case 162: + goto st1513 + case 163: + goto st221 + case 164: + goto st1514 + case 165: + goto st468 + case 167: + goto st469 + case 168: + goto st1474 + case 169: + goto st1515 + case 170: + goto st1516 + case 172: + goto st147 + case 173: + goto st1517 + case 174: + goto st1518 + case 175: + goto st1519 + case 176: + goto st1520 + case 177: + goto st640 + case 179: + goto st1521 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st1522 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + } + switch { + case data[p] < 180: + if 132 <= data[p] && data[p] <= 152 { + goto st145 + } + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + default: + goto st147 + } + goto tr420 + st1504: + if p++; p == pe { + goto _test_eof1504 + } + st_case_1504: + if 171 <= data[p] && data[p] <= 190 { + goto tr148 + } + goto tr2 + st1505: + if p++; p == pe { + goto _test_eof1505 + } + st_case_1505: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto tr148 + } + case data[p] >= 128: + goto tr421 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1506: + if p++; p == pe { + goto _test_eof1506 + } + st_case_1506: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] < 144: + if 130 <= data[p] && data[p] <= 141 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr421 + } + goto tr2 + st1507: + if p++; p == pe { + goto _test_eof1507 + } + st_case_1507: + switch { + case data[p] > 156: + if 160 <= data[p] { + goto tr2 + } + case data[p] >= 155: + goto tr2 + } + goto tr148 + st1508: + if p++; p == pe { + goto _test_eof1508 + } + st_case_1508: + switch { + case data[p] < 142: + if 128 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] > 148: + if 160 <= data[p] && data[p] <= 180 { + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1509: + if p++; p == pe { + goto _test_eof1509 + } + st_case_1509: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 147 { + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1510: + if p++; p == pe { + goto _test_eof1510 + } + st_case_1510: + if 180 <= data[p] { + goto tr148 + } + goto tr2 + st1511: + if p++; p == pe { + goto _test_eof1511 + } + st_case_1511: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr2 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 170 <= data[p] { + goto tr2 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr2 + } + goto tr148 + st1512: + if p++; p == pe { + goto _test_eof1512 + } + st_case_1512: + switch { + case data[p] < 144: + if 139 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] > 153: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + goto tr2 + st1513: + if p++; p == pe { + goto _test_eof1513 + } + st_case_1513: + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st1514: + if p++; p == pe { + goto _test_eof1514 + } + st_case_1514: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1515: + if p++; p == pe { + goto _test_eof1515 + } + st_case_1515: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr148 + } + case data[p] >= 149: + goto tr148 + } + goto tr2 + st1516: + if p++; p == pe { + goto _test_eof1516 + } + st_case_1516: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto tr148 + } + default: + goto tr421 + } + goto tr2 + st1517: + if p++; p == pe { + goto _test_eof1517 + } + st_case_1517: + switch { + case data[p] < 144: + if 140 <= data[p] && data[p] <= 143 { + goto tr2 + } + case data[p] > 153: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr2 + } + case data[p] >= 154: + goto tr2 + } + default: + goto tr421 + } + goto tr148 + st1518: + if p++; p == pe { + goto _test_eof1518 + } + st_case_1518: + switch { + case data[p] < 176: + if 128 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + goto tr2 + st1519: + if p++; p == pe { + goto _test_eof1519 + } + st_case_1519: + if 180 <= data[p] { + goto tr2 + } + goto tr148 + st1520: + if p++; p == pe { + goto _test_eof1520 + } + st_case_1520: + if 128 <= data[p] && data[p] <= 183 { + goto tr148 + } + goto tr2 + st1521: + if p++; p == pe { + goto _test_eof1521 + } + st_case_1521: + switch { + case data[p] < 148: + if 144 <= data[p] && data[p] <= 146 { + goto tr148 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1522: + if p++; p == pe { + goto _test_eof1522 + } + st_case_1522: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st1523: + if p++; p == pe { + goto _test_eof1523 + } + st_case_1523: + switch data[p] { + case 128: + goto st1524 + case 129: + goto st1525 + case 130: + goto st241 + case 131: + goto st1526 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st1527 + case 180: + goto st251 + case 181: + goto st1528 + case 182: + goto st253 + case 183: + goto st1529 + case 184: + goto st255 + } + goto tr420 + st1524: + if p++; p == pe { + goto _test_eof1524 + } + st_case_1524: + switch data[p] { + case 164: + goto st142 + case 167: + goto st142 + } + switch { + case data[p] < 152: + if 140 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 174: + if 191 <= data[p] { + goto tr571 + } + case data[p] >= 170: + goto tr148 + } + default: + goto st142 + } + goto tr2 + st1525: + if p++; p == pe { + goto _test_eof1525 + } + st_case_1525: + switch data[p] { + case 165: + goto tr2 + case 176: + goto tr2 + case 191: + goto tr148 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr2 + } + case data[p] > 159: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr2 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr2 + } + goto tr571 + st1526: + if p++; p == pe { + goto _test_eof1526 + } + st_case_1526: + if 144 <= data[p] && data[p] <= 176 { + goto tr148 + } + goto tr2 + st1527: + if p++; p == pe { + goto _test_eof1527 + } + st_case_1527: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr2 + } + case data[p] >= 165: + goto tr2 + } + goto tr148 + st1528: + if p++; p == pe { + goto _test_eof1528 + } + st_case_1528: + switch { + case data[p] < 176: + if 168 <= data[p] && data[p] <= 174 { + goto tr2 + } + case data[p] > 190: + if 192 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st1529: + if p++; p == pe { + goto _test_eof1529 + } + st_case_1529: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1530: + if p++; p == pe { + goto _test_eof1530 + } + st_case_1530: + switch data[p] { + case 128: + goto st1531 + case 130: + goto st1532 + case 132: + goto st259 + case 133: + goto st145 + case 134: + goto st260 + } + goto tr420 + st1531: + if p++; p == pe { + goto _test_eof1531 + } + st_case_1531: + if data[p] == 133 { + goto tr148 + } + switch { + case data[p] > 175: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + case data[p] >= 170: + goto tr148 + } + goto tr2 + st1532: + if p++; p == pe { + goto _test_eof1532 + } + st_case_1532: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + goto tr2 + st1533: + if p++; p == pe { + goto _test_eof1533 + } + st_case_1533: + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st654 + case 153: + goto st1534 + case 154: + goto st147 + case 155: + goto st293 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st1535 + case 161: + goto st272 + case 162: + goto st147 + case 163: + goto st1536 + case 164: + goto st1537 + case 165: + goto st1538 + case 166: + goto st147 + case 167: + goto st1539 + case 168: + goto st1540 + case 169: + goto st1541 + case 170: + goto st1542 + case 171: + goto st1543 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st1544 + case 176: + goto st147 + } + if 129 <= data[p] { + goto st145 + } + goto tr420 + st1534: + if p++; p == pe { + goto _test_eof1534 + } + st_case_1534: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st1535: + if p++; p == pe { + goto _test_eof1535 + } + st_case_1535: + if 168 <= data[p] { + goto tr2 + } + goto tr148 + st1536: + if p++; p == pe { + goto _test_eof1536 + } + st_case_1536: + if data[p] == 188 { + goto tr2 + } + switch { + case data[p] < 154: + switch { + case data[p] > 143: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 133: + goto tr2 + } + case data[p] > 159: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto tr2 + } + case data[p] >= 184: + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st1537: + if p++; p == pe { + goto _test_eof1537 + } + st_case_1537: + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1538: + if p++; p == pe { + goto _test_eof1538 + } + st_case_1538: + switch { + case data[p] > 159: + if 189 <= data[p] { + goto tr2 + } + case data[p] >= 148: + goto tr2 + } + goto tr148 + st1539: + if p++; p == pe { + goto _test_eof1539 + } + st_case_1539: + switch { + case data[p] < 154: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 129: + goto tr2 + } + case data[p] > 164: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr2 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr2 + } + default: + goto tr421 + } + default: + goto tr2 + } + goto tr148 + st1540: + if p++; p == pe { + goto _test_eof1540 + } + st_case_1540: + if 128 <= data[p] && data[p] <= 182 { + goto tr148 + } + goto tr2 + st1541: + if p++; p == pe { + goto _test_eof1541 + } + st_case_1541: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 141 { + goto tr148 + } + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto tr148 + } + default: + goto tr421 + } + goto tr2 + st1542: + if p++; p == pe { + goto _test_eof1542 + } + st_case_1542: + if data[p] == 176 { + goto tr148 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr148 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1543: + if p++; p == pe { + goto _test_eof1543 + } + st_case_1543: + if data[p] == 129 { + goto tr148 + } + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 182 { + goto tr148 + } + case data[p] >= 160: + goto tr148 + } + goto tr2 + st1544: + if p++; p == pe { + goto _test_eof1544 + } + st_case_1544: + switch { + case data[p] < 172: + if 128 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + default: + goto tr148 + } + goto tr2 + st1545: + if p++; p == pe { + goto _test_eof1545 + } + st_case_1545: + switch data[p] { + case 172: + goto st1546 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st1547 + case 185: + goto st967 + case 187: + goto st1548 + case 188: + goto st969 + case 189: + goto st303 + case 190: + goto st1549 + case 191: + goto st1550 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr420 + st1546: + if p++; p == pe { + goto _test_eof1546 + } + st_case_1546: + switch data[p] { + case 158: + goto tr148 + case 190: + goto tr572 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 170: + goto tr572 + } + default: + goto tr572 + } + goto tr2 + st1547: + if p++; p == pe { + goto _test_eof1547 + } + st_case_1547: + if data[p] == 147 { + goto st142 + } + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr571 + } + default: + goto tr148 + } + goto tr2 + st1548: + if p++; p == pe { + goto _test_eof1548 + } + st_case_1548: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr2 + } + case data[p] >= 189: + goto tr2 + } + goto tr148 + st1549: + if p++; p == pe { + goto _test_eof1549 + } + st_case_1549: + if 158 <= data[p] && data[p] <= 190 { + goto tr148 + } + goto tr2 + st1550: + if p++; p == pe { + goto _test_eof1550 + } + st_case_1550: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] >= 130: + goto tr148 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1551: + if p++; p == pe { + goto _test_eof1551 + } + st_case_1551: + switch data[p] { + case 144: + goto st1552 + case 145: + goto st1558 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st1573 + case 155: + goto st1577 + case 157: + goto st1579 + case 158: + goto st1586 + case 159: + goto st403 + } + goto tr420 + st1552: + if p++; p == pe { + goto _test_eof1552 + } + st_case_1552: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st1553 + case 138: + goto st313 + case 139: + goto st1554 + case 140: + goto st315 + case 141: + goto st1555 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st684 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st1556 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st1557 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr2 + st1553: + if p++; p == pe { + goto _test_eof1553 + } + st_case_1553: + if data[p] == 189 { + goto tr148 + } + goto tr2 + st1554: + if p++; p == pe { + goto _test_eof1554 + } + st_case_1554: + switch { + case data[p] > 159: + if 161 <= data[p] { + goto tr2 + } + case data[p] >= 145: + goto tr2 + } + goto tr148 + st1555: + if p++; p == pe { + goto _test_eof1555 + } + st_case_1555: + switch { + case data[p] > 143: + if 187 <= data[p] { + goto tr2 + } + case data[p] >= 139: + goto tr2 + } + goto tr148 + st1556: + if p++; p == pe { + goto _test_eof1556 + } + st_case_1556: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 140: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 134 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1557: + if p++; p == pe { + goto _test_eof1557 + } + st_case_1557: + switch { + case data[p] > 135: + if 137 <= data[p] && data[p] <= 166 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st1558: + if p++; p == pe { + goto _test_eof1558 + } + st_case_1558: + switch data[p] { + case 129: + goto st1559 + case 130: + goto st1560 + case 131: + goto st691 + case 132: + goto st1561 + case 133: + goto st1562 + case 135: + goto st1563 + case 136: + goto st1564 + case 138: + goto st348 + case 139: + goto st1565 + case 140: + goto st1566 + case 141: + goto st1567 + case 146: + goto st147 + case 147: + goto st1568 + case 150: + goto st1569 + case 151: + goto st1570 + case 152: + goto st147 + case 153: + goto st1571 + case 154: + goto st1520 + case 155: + goto st538 + case 156: + goto st1572 + case 162: + goto st359 + case 163: + goto st707 + case 171: + goto st361 + } + if 128 <= data[p] && data[p] <= 134 { + goto st147 + } + goto tr2 + st1559: + if p++; p == pe { + goto _test_eof1559 + } + st_case_1559: + switch { + case data[p] < 166: + if 135 <= data[p] && data[p] <= 165 { + goto tr2 + } + case data[p] > 175: + if 176 <= data[p] && data[p] <= 190 { + goto tr2 + } + default: + goto tr421 + } + goto tr148 + st1560: + if p++; p == pe { + goto _test_eof1560 + } + st_case_1560: + switch { + case data[p] > 188: + if 190 <= data[p] { + goto tr2 + } + case data[p] >= 187: + goto tr2 + } + goto tr148 + st1561: + if p++; p == pe { + goto _test_eof1561 + } + st_case_1561: + switch { + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr421 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st1562: + if p++; p == pe { + goto _test_eof1562 + } + st_case_1562: + if data[p] == 182 { + goto tr148 + } + if 144 <= data[p] && data[p] <= 179 { + goto tr148 + } + goto tr2 + st1563: + if p++; p == pe { + goto _test_eof1563 + } + st_case_1563: + if data[p] == 155 { + goto tr2 + } + switch { + case data[p] < 141: + if 133 <= data[p] && data[p] <= 137 { + goto tr2 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 157 <= data[p] { + goto tr2 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr2 + } + goto tr148 + st1564: + if p++; p == pe { + goto _test_eof1564 + } + st_case_1564: + switch { + case data[p] > 145: + if 147 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st1565: + if p++; p == pe { + goto _test_eof1565 + } + st_case_1565: + switch { + case data[p] < 176: + if 171 <= data[p] && data[p] <= 175 { + goto tr2 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr2 + } + default: + goto tr421 + } + goto tr148 + st1566: + if p++; p == pe { + goto _test_eof1566 + } + st_case_1566: + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto tr148 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr148 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1567: + if p++; p == pe { + goto _test_eof1567 + } + st_case_1567: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr148 + } + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 141: + switch { + case data[p] < 166: + if 157 <= data[p] && data[p] <= 163 { + goto tr148 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1568: + if p++; p == pe { + goto _test_eof1568 + } + st_case_1568: + if data[p] == 134 { + goto tr2 + } + switch { + case data[p] < 144: + if 136 <= data[p] && data[p] <= 143 { + goto tr2 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr2 + } + default: + goto tr421 + } + goto tr148 + st1569: + if p++; p == pe { + goto _test_eof1569 + } + st_case_1569: + switch { + case data[p] > 181: + if 184 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st1570: + if p++; p == pe { + goto _test_eof1570 + } + st_case_1570: + switch { + case data[p] > 151: + if 158 <= data[p] { + goto tr2 + } + case data[p] >= 129: + goto tr2 + } + goto tr148 + st1571: + if p++; p == pe { + goto _test_eof1571 + } + st_case_1571: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] { + goto tr2 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr2 + } + goto tr148 + st1572: + if p++; p == pe { + goto _test_eof1572 + } + st_case_1572: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 157: + goto tr148 + } + goto tr2 + st1573: + if p++; p == pe { + goto _test_eof1573 + } + st_case_1573: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st709 + case 171: + goto st1574 + case 172: + goto st1540 + case 173: + goto st712 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st1575 + case 190: + goto st1576 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr2 + st1574: + if p++; p == pe { + goto _test_eof1574 + } + st_case_1574: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto tr148 + } + case data[p] >= 144: + goto tr148 + } + goto tr2 + st1575: + if p++; p == pe { + goto _test_eof1575 + } + st_case_1575: + switch { + case data[p] > 143: + if 191 <= data[p] { + goto tr2 + } + case data[p] >= 133: + goto tr2 + } + goto tr148 + st1576: + if p++; p == pe { + goto _test_eof1576 + } + st_case_1576: + if 143 <= data[p] && data[p] <= 159 { + goto tr148 + } + goto tr2 + st1577: + if p++; p == pe { + goto _test_eof1577 + } + st_case_1577: + switch data[p] { + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st1578 + } + goto tr2 + st1578: + if p++; p == pe { + goto _test_eof1578 + } + st_case_1578: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr148 + } + case data[p] >= 157: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st1579: + if p++; p == pe { + goto _test_eof1579 + } + st_case_1579: + switch data[p] { + case 133: + goto st1580 + case 134: + goto st1581 + case 137: + goto st1582 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st721 + case 168: + goto st1583 + case 169: + goto st1584 + case 170: + goto st1585 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr2 + st1580: + if p++; p == pe { + goto _test_eof1580 + } + st_case_1580: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr148 + } + case data[p] >= 165: + goto tr148 + } + goto tr2 + st1581: + if p++; p == pe { + goto _test_eof1581 + } + st_case_1581: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr2 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st1582: + if p++; p == pe { + goto _test_eof1582 + } + st_case_1582: + if 130 <= data[p] && data[p] <= 132 { + goto tr148 + } + goto tr2 + st1583: + if p++; p == pe { + goto _test_eof1583 + } + st_case_1583: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st1584: + if p++; p == pe { + goto _test_eof1584 + } + st_case_1584: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr2 + } + case data[p] >= 173: + goto tr2 + } + goto tr148 + st1585: + if p++; p == pe { + goto _test_eof1585 + } + st_case_1585: + if data[p] == 132 { + goto tr148 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] >= 155: + goto tr148 + } + goto tr2 + st1586: + if p++; p == pe { + goto _test_eof1586 + } + st_case_1586: + switch data[p] { + case 160: + goto st147 + case 163: + goto st1587 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr2 + st1587: + if p++; p == pe { + goto _test_eof1587 + } + st_case_1587: + switch { + case data[p] > 143: + if 151 <= data[p] { + goto tr2 + } + case data[p] >= 133: + goto tr2 + } + goto tr148 + st1588: + if p++; p == pe { + goto _test_eof1588 + } + st_case_1588: + if data[p] == 160 { + goto st1589 + } + goto tr420 + st1589: + if p++; p == pe { + goto _test_eof1589 + } + st_case_1589: + switch data[p] { + case 128: + goto st1590 + case 129: + goto st146 + case 132: + goto st147 + case 135: + goto st1591 + } + if 133 <= data[p] && data[p] <= 134 { + goto st145 + } + goto tr2 + st1590: + if p++; p == pe { + goto _test_eof1590 + } + st_case_1590: + if data[p] == 129 { + goto tr148 + } + if 160 <= data[p] { + goto tr148 + } + goto tr2 + st1591: + if p++; p == pe { + goto _test_eof1591 + } + st_case_1591: + if 176 <= data[p] { + goto tr2 + } + goto tr148 +tr1485: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:76 +act = 1; + goto st4873 + st4873: + if p++; p == pe { + goto _test_eof4873 + } + st_case_4873: +//line segment_words_prod.go:44764 + switch data[p] { + case 95: + goto tr1485 + case 194: + goto st1592 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st148 + case 204: + goto st1593 + case 205: + goto st1594 + case 206: + goto st151 + case 207: + goto st152 + case 210: + goto st1595 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1596 + case 215: + goto st1597 + case 216: + goto st1598 + case 217: + goto st1599 + case 219: + goto st1600 + case 220: + goto st1601 + case 221: + goto st1602 + case 222: + goto st1603 + case 223: + goto st1604 + case 224: + goto st1605 + case 225: + goto st1637 + case 226: + goto st1662 + case 227: + goto st1669 + case 234: + goto st1672 + case 237: + goto st287 + case 239: + goto st1689 + case 240: + goto st1697 + case 243: + goto st1746 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr126 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4521 + st1592: + if p++; p == pe { + goto _test_eof1592 + } + st_case_1592: + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr1485 + case 181: + goto tr148 + case 186: + goto tr148 + } + goto tr125 + st1593: + if p++; p == pe { + goto _test_eof1593 + } + st_case_1593: + if data[p] <= 127 { + goto tr125 + } + goto tr1485 + st1594: + if p++; p == pe { + goto _test_eof1594 + } + st_case_1594: + switch data[p] { + case 181: + goto tr125 + case 190: + goto tr125 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr125 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr125 + } + goto tr1485 + st1595: + if p++; p == pe { + goto _test_eof1595 + } + st_case_1595: + if data[p] == 130 { + goto tr125 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr1485 + } + goto tr148 + st1596: + if p++; p == pe { + goto _test_eof1596 + } + st_case_1596: + if data[p] == 190 { + goto tr125 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr125 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr125 + } + default: + goto tr1485 + } + goto tr148 + st1597: + if p++; p == pe { + goto _test_eof1597 + } + st_case_1597: + switch data[p] { + case 135: + goto tr1485 + case 179: + goto tr148 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr1485 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr1485 + } + goto tr125 + st1598: + if p++; p == pe { + goto _test_eof1598 + } + st_case_1598: + if data[p] == 156 { + goto tr1485 + } + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 133 { + goto tr1485 + } + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr1485 + } + goto tr125 + st1599: + if p++; p == pe { + goto _test_eof1599 + } + st_case_1599: + switch data[p] { + case 171: + goto tr126 + case 176: + goto tr1485 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + case data[p] >= 160: + goto tr126 + } + default: + goto tr1485 + } + goto tr125 + st1600: + if p++; p == pe { + goto _test_eof1600 + } + st_case_1600: + switch data[p] { + case 148: + goto tr125 + case 158: + goto tr125 + case 169: + goto tr125 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr1485 + } + case data[p] >= 150: + goto tr1485 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr125 + } + case data[p] >= 189: + goto tr125 + } + default: + goto tr126 + } + goto tr148 + st1601: + if p++; p == pe { + goto _test_eof1601 + } + st_case_1601: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto tr1485 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr1485 + } + default: + goto tr148 + } + goto tr125 + st1602: + if p++; p == pe { + goto _test_eof1602 + } + st_case_1602: + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr125 + } + goto tr1485 + st1603: + if p++; p == pe { + goto _test_eof1603 + } + st_case_1603: + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr125 + } + case data[p] >= 166: + goto tr1485 + } + goto tr148 + st1604: + if p++; p == pe { + goto _test_eof1604 + } + st_case_1604: + if data[p] == 186 { + goto tr148 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 170: + switch { + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 171: + goto tr1485 + } + default: + goto tr148 + } + goto tr125 + st1605: + if p++; p == pe { + goto _test_eof1605 + } + st_case_1605: + switch data[p] { + case 160: + goto st1606 + case 161: + goto st1607 + case 162: + goto st168 + case 163: + goto st1608 + case 164: + goto st1609 + case 165: + goto st1610 + case 166: + goto st1611 + case 167: + goto st1612 + case 168: + goto st1613 + case 169: + goto st1614 + case 170: + goto st1615 + case 171: + goto st1616 + case 172: + goto st1617 + case 173: + goto st1618 + case 174: + goto st1619 + case 175: + goto st1620 + case 176: + goto st1621 + case 177: + goto st1622 + case 178: + goto st1623 + case 179: + goto st1624 + case 180: + goto st1625 + case 181: + goto st1626 + case 182: + goto st1627 + case 183: + goto st1628 + case 184: + goto st1629 + case 185: + goto st1630 + case 186: + goto st1631 + case 187: + goto st1632 + case 188: + goto st1633 + case 189: + goto st1634 + case 190: + goto st1635 + case 191: + goto st1636 + } + goto tr125 + st1606: + if p++; p == pe { + goto _test_eof1606 + } + st_case_1606: + switch data[p] { + case 154: + goto tr148 + case 164: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] > 149: + if 150 <= data[p] && data[p] <= 173 { + goto tr1485 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st1607: + if p++; p == pe { + goto _test_eof1607 + } + st_case_1607: + switch { + case data[p] > 152: + if 153 <= data[p] && data[p] <= 155 { + goto tr1485 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st1608: + if p++; p == pe { + goto _test_eof1608 + } + st_case_1608: + if 163 <= data[p] { + goto tr1485 + } + goto tr125 + st1609: + if p++; p == pe { + goto _test_eof1609 + } + st_case_1609: + if data[p] == 189 { + goto tr148 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr148 + } + goto tr1485 + st1610: + if p++; p == pe { + goto _test_eof1610 + } + st_case_1610: + switch data[p] { + case 144: + goto tr148 + case 176: + goto tr125 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 177 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr125 + } + goto tr1485 + st1611: + if p++; p == pe { + goto _test_eof1611 + } + st_case_1611: + switch data[p] { + case 132: + goto tr125 + case 169: + goto tr125 + case 177: + goto tr125 + case 188: + goto tr1485 + } + switch { + case data[p] < 145: + switch { + case data[p] > 131: + if 141 <= data[p] && data[p] <= 142 { + goto tr125 + } + case data[p] >= 129: + goto tr1485 + } + case data[p] > 146: + switch { + case data[p] < 186: + if 179 <= data[p] && data[p] <= 181 { + goto tr125 + } + case data[p] > 187: + if 190 <= data[p] { + goto tr1485 + } + default: + goto tr125 + } + default: + goto tr125 + } + goto tr148 + st1612: + if p++; p == pe { + goto _test_eof1612 + } + st_case_1612: + switch data[p] { + case 142: + goto tr148 + case 158: + goto tr125 + } + switch { + case data[p] < 156: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr125 + } + case data[p] > 138: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 155 { + goto tr125 + } + case data[p] >= 143: + goto tr125 + } + default: + goto tr125 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr125 + } + case data[p] > 175: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr125 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr126 + } + default: + goto tr148 + } + goto tr1485 + st1613: + if p++; p == pe { + goto _test_eof1613 + } + st_case_1613: + if data[p] == 188 { + goto tr1485 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr1485 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto tr1485 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1614: + if p++; p == pe { + goto _test_eof1614 + } + st_case_1614: + if data[p] == 157 { + goto tr125 + } + switch { + case data[p] < 153: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr125 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 146 <= data[p] && data[p] <= 152 { + goto tr125 + } + case data[p] >= 142: + goto tr125 + } + default: + goto tr125 + } + case data[p] > 158: + switch { + case data[p] < 166: + if 159 <= data[p] && data[p] <= 165 { + goto tr125 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr125 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr126 + } + default: + goto tr148 + } + goto tr1485 + st1615: + if p++; p == pe { + goto _test_eof1615 + } + st_case_1615: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr1485 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto tr1485 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1616: + if p++; p == pe { + goto _test_eof1616 + } + st_case_1616: + switch data[p] { + case 134: + goto tr125 + case 138: + goto tr125 + case 144: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] >= 142: + goto tr125 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr125 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr125 + } + goto tr1485 + st1617: + if p++; p == pe { + goto _test_eof1617 + } + st_case_1617: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr1485 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr1485 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1618: + if p++; p == pe { + goto _test_eof1618 + } + st_case_1618: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr1485 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr1485 + } + default: + goto tr1485 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 161: + switch { + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] >= 162: + goto tr1485 + } + default: + goto tr148 + } + default: + goto tr1485 + } + goto tr125 + st1619: + if p++; p == pe { + goto _test_eof1619 + } + st_case_1619: + switch data[p] { + case 130: + goto tr1485 + case 131: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 158: + switch { + case data[p] < 142: + if 133 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 149: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] < 168: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto tr1485 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1620: + if p++; p == pe { + goto _test_eof1620 + } + st_case_1620: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr1485 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr1485 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] >= 138: + goto tr1485 + } + default: + goto tr1485 + } + goto tr125 + st1621: + if p++; p == pe { + goto _test_eof1621 + } + st_case_1621: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto tr1485 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 190 <= data[p] { + goto tr1485 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1622: + if p++; p == pe { + goto _test_eof1622 + } + st_case_1622: + switch data[p] { + case 133: + goto tr125 + case 137: + goto tr125 + case 151: + goto tr125 + } + switch { + case data[p] < 160: + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 148 { + goto tr125 + } + case data[p] > 154: + if 155 <= data[p] && data[p] <= 159 { + goto tr125 + } + default: + goto tr148 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr125 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr125 + } + default: + goto tr126 + } + default: + goto tr148 + } + goto tr1485 + st1623: + if p++; p == pe { + goto _test_eof1623 + } + st_case_1623: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr1485 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr1485 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1624: + if p++; p == pe { + goto _test_eof1624 + } + st_case_1624: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr1485 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr1485 + } + default: + goto tr1485 + } + case data[p] > 150: + switch { + case data[p] < 162: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 163: + switch { + case data[p] > 175: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr1485 + } + default: + goto tr1485 + } + goto tr125 + st1625: + if p++; p == pe { + goto _test_eof1625 + } + st_case_1625: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto tr1485 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto tr1485 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1626: + if p++; p == pe { + goto _test_eof1626 + } + st_case_1626: + switch data[p] { + case 133: + goto tr125 + case 137: + goto tr125 + case 142: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 150 { + goto tr125 + } + case data[p] > 158: + if 159 <= data[p] && data[p] <= 161 { + goto tr148 + } + default: + goto tr125 + } + case data[p] > 165: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr125 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr125 + } + default: + goto tr125 + } + goto tr1485 + st1627: + if p++; p == pe { + goto _test_eof1627 + } + st_case_1627: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr1485 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1628: + if p++; p == pe { + goto _test_eof1628 + } + st_case_1628: + switch data[p] { + case 138: + goto tr1485 + case 150: + goto tr1485 + } + switch { + case data[p] < 152: + switch { + case data[p] > 134: + if 143 <= data[p] && data[p] <= 148 { + goto tr1485 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto tr1485 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr1485 + } + goto tr125 + st1629: + if p++; p == pe { + goto _test_eof1629 + } + st_case_1629: + if data[p] == 177 { + goto tr1485 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr1485 + } + goto tr125 + st1630: + if p++; p == pe { + goto _test_eof1630 + } + st_case_1630: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 135: + goto tr1485 + } + goto tr125 + st1631: + if p++; p == pe { + goto _test_eof1631 + } + st_case_1631: + if data[p] == 177 { + goto tr1485 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr1485 + } + case data[p] >= 180: + goto tr1485 + } + goto tr125 + st1632: + if p++; p == pe { + goto _test_eof1632 + } + st_case_1632: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 136: + goto tr1485 + } + goto tr125 + st1633: + if p++; p == pe { + goto _test_eof1633 + } + st_case_1633: + switch data[p] { + case 128: + goto tr148 + case 181: + goto tr1485 + case 183: + goto tr1485 + case 185: + goto tr1485 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto tr1485 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto tr1485 + } + default: + goto tr126 + } + goto tr125 + st1634: + if p++; p == pe { + goto _test_eof1634 + } + st_case_1634: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto tr1485 + } + default: + goto tr148 + } + goto tr125 + st1635: + if p++; p == pe { + goto _test_eof1635 + } + st_case_1635: + switch { + case data[p] < 136: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 135 { + goto tr1485 + } + case data[p] >= 128: + goto tr1485 + } + case data[p] > 140: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr1485 + } + case data[p] >= 141: + goto tr1485 + } + default: + goto tr148 + } + goto tr125 + st1636: + if p++; p == pe { + goto _test_eof1636 + } + st_case_1636: + if data[p] == 134 { + goto tr1485 + } + goto tr125 + st1637: + if p++; p == pe { + goto _test_eof1637 + } + st_case_1637: + switch data[p] { + case 128: + goto st1638 + case 129: + goto st1639 + case 130: + goto st1640 + case 131: + goto st202 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st1641 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st1642 + case 157: + goto st1643 + case 158: + goto st1644 + case 159: + goto st1645 + case 160: + goto st1646 + case 161: + goto st219 + case 162: + goto st1647 + case 163: + goto st221 + case 164: + goto st1648 + case 165: + goto st1649 + case 167: + goto st1650 + case 168: + goto st1651 + case 169: + goto st1652 + case 170: + goto st1653 + case 172: + goto st1654 + case 173: + goto st1655 + case 174: + goto st1656 + case 175: + goto st1657 + case 176: + goto st1658 + case 177: + goto st1659 + case 179: + goto st1660 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st1661 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + } + switch { + case data[p] < 180: + if 132 <= data[p] && data[p] <= 152 { + goto st145 + } + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + default: + goto st147 + } + goto tr125 + st1638: + if p++; p == pe { + goto _test_eof1638 + } + st_case_1638: + if 171 <= data[p] && data[p] <= 190 { + goto tr1485 + } + goto tr125 + st1639: + if p++; p == pe { + goto _test_eof1639 + } + st_case_1639: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto tr1485 + } + case data[p] >= 128: + goto tr126 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto tr1485 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr1485 + } + default: + goto tr1485 + } + default: + goto tr1485 + } + goto tr125 + st1640: + if p++; p == pe { + goto _test_eof1640 + } + st_case_1640: + if data[p] == 143 { + goto tr1485 + } + switch { + case data[p] < 144: + if 130 <= data[p] && data[p] <= 141 { + goto tr1485 + } + case data[p] > 153: + switch { + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 154: + goto tr1485 + } + default: + goto tr126 + } + goto tr125 + st1641: + if p++; p == pe { + goto _test_eof1641 + } + st_case_1641: + switch { + case data[p] < 157: + if 155 <= data[p] && data[p] <= 156 { + goto tr125 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr125 + } + default: + goto tr1485 + } + goto tr148 + st1642: + if p++; p == pe { + goto _test_eof1642 + } + st_case_1642: + switch { + case data[p] < 146: + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 177: + if 178 <= data[p] && data[p] <= 180 { + goto tr1485 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr1485 + } + goto tr125 + st1643: + if p++; p == pe { + goto _test_eof1643 + } + st_case_1643: + switch { + case data[p] < 160: + switch { + case data[p] > 145: + if 146 <= data[p] && data[p] <= 147 { + goto tr1485 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto tr1485 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1644: + if p++; p == pe { + goto _test_eof1644 + } + st_case_1644: + if 180 <= data[p] { + goto tr1485 + } + goto tr125 + st1645: + if p++; p == pe { + goto _test_eof1645 + } + st_case_1645: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr125 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 170 <= data[p] { + goto tr125 + } + case data[p] >= 160: + goto tr126 + } + default: + goto tr125 + } + goto tr1485 + st1646: + if p++; p == pe { + goto _test_eof1646 + } + st_case_1646: + switch { + case data[p] < 144: + if 139 <= data[p] && data[p] <= 142 { + goto tr1485 + } + case data[p] > 153: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr126 + } + goto tr125 + st1647: + if p++; p == pe { + goto _test_eof1647 + } + st_case_1647: + if data[p] == 169 { + goto tr1485 + } + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st1648: + if p++; p == pe { + goto _test_eof1648 + } + st_case_1648: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr1485 + } + default: + goto tr1485 + } + goto tr125 + st1649: + if p++; p == pe { + goto _test_eof1649 + } + st_case_1649: + if 134 <= data[p] && data[p] <= 143 { + goto tr126 + } + goto tr2 + st1650: + if p++; p == pe { + goto _test_eof1650 + } + st_case_1650: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + goto tr2 + st1651: + if p++; p == pe { + goto _test_eof1651 + } + st_case_1651: + switch { + case data[p] > 150: + if 151 <= data[p] && data[p] <= 155 { + goto tr1485 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st1652: + if p++; p == pe { + goto _test_eof1652 + } + st_case_1652: + if data[p] == 191 { + goto tr1485 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr1485 + } + case data[p] >= 149: + goto tr1485 + } + goto tr125 + st1653: + if p++; p == pe { + goto _test_eof1653 + } + st_case_1653: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto tr1485 + } + default: + goto tr126 + } + goto tr125 + st1654: + if p++; p == pe { + goto _test_eof1654 + } + st_case_1654: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 132 { + goto tr1485 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr1485 + } + default: + goto tr148 + } + goto tr125 + st1655: + if p++; p == pe { + goto _test_eof1655 + } + st_case_1655: + switch { + case data[p] < 144: + switch { + case data[p] > 139: + if 140 <= data[p] && data[p] <= 143 { + goto tr125 + } + case data[p] >= 133: + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr125 + } + case data[p] >= 154: + goto tr125 + } + default: + goto tr126 + } + goto tr1485 + st1656: + if p++; p == pe { + goto _test_eof1656 + } + st_case_1656: + switch { + case data[p] < 161: + switch { + case data[p] > 130: + if 131 <= data[p] && data[p] <= 160 { + goto tr148 + } + case data[p] >= 128: + goto tr1485 + } + case data[p] > 173: + switch { + case data[p] < 176: + if 174 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr148 + } + default: + goto tr126 + } + default: + goto tr1485 + } + goto tr125 + st1657: + if p++; p == pe { + goto _test_eof1657 + } + st_case_1657: + switch { + case data[p] > 179: + if 180 <= data[p] { + goto tr125 + } + case data[p] >= 166: + goto tr1485 + } + goto tr148 + st1658: + if p++; p == pe { + goto _test_eof1658 + } + st_case_1658: + switch { + case data[p] > 163: + if 164 <= data[p] && data[p] <= 183 { + goto tr1485 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st1659: + if p++; p == pe { + goto _test_eof1659 + } + st_case_1659: + switch { + case data[p] < 141: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] && data[p] <= 189 { + goto tr148 + } + case data[p] >= 144: + goto tr126 + } + default: + goto tr148 + } + goto tr2 + st1660: + if p++; p == pe { + goto _test_eof1660 + } + st_case_1660: + if data[p] == 173 { + goto tr1485 + } + switch { + case data[p] < 169: + switch { + case data[p] > 146: + if 148 <= data[p] && data[p] <= 168 { + goto tr1485 + } + case data[p] >= 144: + goto tr1485 + } + case data[p] > 177: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 180 { + goto tr1485 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto tr1485 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1661: + if p++; p == pe { + goto _test_eof1661 + } + st_case_1661: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr1485 + } + case data[p] >= 128: + goto tr1485 + } + goto tr125 + st1662: + if p++; p == pe { + goto _test_eof1662 + } + st_case_1662: + switch data[p] { + case 128: + goto st1663 + case 129: + goto st1664 + case 130: + goto st241 + case 131: + goto st1665 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st1666 + case 180: + goto st251 + case 181: + goto st1667 + case 182: + goto st253 + case 183: + goto st1668 + case 184: + goto st255 + } + goto tr125 + st1663: + if p++; p == pe { + goto _test_eof1663 + } + st_case_1663: + switch { + case data[p] < 170: + if 140 <= data[p] && data[p] <= 143 { + goto tr1485 + } + case data[p] > 174: + if 191 <= data[p] { + goto tr1485 + } + default: + goto tr1485 + } + goto tr125 + st1664: + if p++; p == pe { + goto _test_eof1664 + } + st_case_1664: + switch data[p] { + case 165: + goto tr125 + case 177: + goto tr148 + case 191: + goto tr148 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr125 + } + case data[p] > 159: + if 176 <= data[p] { + goto tr125 + } + default: + goto tr125 + } + goto tr1485 + st1665: + if p++; p == pe { + goto _test_eof1665 + } + st_case_1665: + if 144 <= data[p] && data[p] <= 176 { + goto tr1485 + } + goto tr125 + st1666: + if p++; p == pe { + goto _test_eof1666 + } + st_case_1666: + switch { + case data[p] < 175: + if 165 <= data[p] && data[p] <= 170 { + goto tr125 + } + case data[p] > 177: + if 180 <= data[p] { + goto tr125 + } + default: + goto tr1485 + } + goto tr148 + st1667: + if p++; p == pe { + goto _test_eof1667 + } + st_case_1667: + if data[p] == 191 { + goto tr1485 + } + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr125 + } + case data[p] >= 168: + goto tr125 + } + goto tr148 + st1668: + if p++; p == pe { + goto _test_eof1668 + } + st_case_1668: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto tr1485 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1669: + if p++; p == pe { + goto _test_eof1669 + } + st_case_1669: + switch data[p] { + case 128: + goto st1670 + case 130: + goto st1671 + case 131: + goto st1164 + case 132: + goto st259 + case 133: + goto st145 + case 134: + goto st260 + case 135: + goto st1165 + case 139: + goto st1166 + case 140: + goto st1091 + case 141: + goto st1167 + } + goto tr125 + st1670: + if p++; p == pe { + goto _test_eof1670 + } + st_case_1670: + if data[p] == 133 { + goto tr148 + } + switch { + case data[p] < 177: + if 170 <= data[p] && data[p] <= 175 { + goto tr1485 + } + case data[p] > 181: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + default: + goto tr1049 + } + goto tr125 + st1671: + if p++; p == pe { + goto _test_eof1671 + } + st_case_1671: + switch { + case data[p] < 155: + if 153 <= data[p] && data[p] <= 154 { + goto tr1485 + } + case data[p] > 156: + if 160 <= data[p] { + goto tr1049 + } + default: + goto tr1049 + } + goto tr125 + st1672: + if p++; p == pe { + goto _test_eof1672 + } + st_case_1672: + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st1673 + case 153: + goto st1674 + case 154: + goto st1675 + case 155: + goto st1676 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st1677 + case 161: + goto st272 + case 162: + goto st1678 + case 163: + goto st1679 + case 164: + goto st1680 + case 165: + goto st1681 + case 166: + goto st1682 + case 167: + goto st1683 + case 168: + goto st1684 + case 169: + goto st1685 + case 170: + goto st1686 + case 171: + goto st1687 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st1688 + case 176: + goto st147 + } + if 129 <= data[p] { + goto st145 + } + goto tr125 + st1673: + if p++; p == pe { + goto _test_eof1673 + } + st_case_1673: + switch { + case data[p] < 160: + if 141 <= data[p] && data[p] <= 143 { + goto tr2 + } + case data[p] > 169: + if 172 <= data[p] { + goto tr2 + } + default: + goto tr126 + } + goto tr148 + st1674: + if p++; p == pe { + goto _test_eof1674 + } + st_case_1674: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr1485 + } + default: + goto tr1485 + } + goto tr125 + st1675: + if p++; p == pe { + goto _test_eof1675 + } + st_case_1675: + switch { + case data[p] < 158: + if 128 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr1485 + } + goto tr125 + st1676: + if p++; p == pe { + goto _test_eof1676 + } + st_case_1676: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr125 + } + case data[p] >= 176: + goto tr1485 + } + goto tr148 + st1677: + if p++; p == pe { + goto _test_eof1677 + } + st_case_1677: + switch data[p] { + case 130: + goto tr1485 + case 134: + goto tr1485 + case 139: + goto tr1485 + } + switch { + case data[p] > 167: + if 168 <= data[p] { + goto tr125 + } + case data[p] >= 163: + goto tr1485 + } + goto tr148 + st1678: + if p++; p == pe { + goto _test_eof1678 + } + st_case_1678: + switch { + case data[p] < 130: + if 128 <= data[p] && data[p] <= 129 { + goto tr1485 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr1485 + } + default: + goto tr148 + } + goto tr125 + st1679: + if p++; p == pe { + goto _test_eof1679 + } + st_case_1679: + switch data[p] { + case 187: + goto tr148 + case 189: + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 143: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 133: + goto tr125 + } + case data[p] > 159: + switch { + case data[p] > 183: + if 184 <= data[p] { + goto tr125 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr125 + } + goto tr1485 + st1680: + if p++; p == pe { + goto _test_eof1680 + } + st_case_1680: + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 165: + switch { + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr1485 + } + default: + goto tr148 + } + goto tr125 + st1681: + if p++; p == pe { + goto _test_eof1681 + } + st_case_1681: + switch { + case data[p] < 148: + if 135 <= data[p] && data[p] <= 147 { + goto tr1485 + } + case data[p] > 159: + if 189 <= data[p] { + goto tr125 + } + default: + goto tr125 + } + goto tr148 + st1682: + if p++; p == pe { + goto _test_eof1682 + } + st_case_1682: + switch { + case data[p] < 132: + if 128 <= data[p] && data[p] <= 131 { + goto tr1485 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr1485 + } + default: + goto tr148 + } + goto tr125 + st1683: + if p++; p == pe { + goto _test_eof1683 + } + st_case_1683: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 129: + goto tr125 + } + case data[p] > 164: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr125 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr125 + } + default: + goto tr126 + } + default: + goto tr125 + } + goto tr1485 + st1684: + if p++; p == pe { + goto _test_eof1684 + } + st_case_1684: + switch { + case data[p] > 168: + if 169 <= data[p] && data[p] <= 182 { + goto tr1485 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st1685: + if p++; p == pe { + goto _test_eof1685 + } + st_case_1685: + if data[p] == 131 { + goto tr1485 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 141: + switch { + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto tr1485 + } + case data[p] >= 144: + goto tr126 + } + default: + goto tr1485 + } + goto tr125 + st1686: + if p++; p == pe { + goto _test_eof1686 + } + st_case_1686: + if data[p] == 176 { + goto tr1485 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr1485 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr1485 + } + default: + goto tr1485 + } + goto tr125 + st1687: + if p++; p == pe { + goto _test_eof1687 + } + st_case_1687: + if data[p] == 129 { + goto tr1485 + } + switch { + case data[p] < 171: + if 160 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 181 <= data[p] && data[p] <= 182 { + goto tr1485 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr1485 + } + goto tr125 + st1688: + if p++; p == pe { + goto _test_eof1688 + } + st_case_1688: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 162 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + case data[p] >= 172: + goto tr1485 + } + default: + goto tr1485 + } + goto tr125 + st1689: + if p++; p == pe { + goto _test_eof1689 + } + st_case_1689: + switch data[p] { + case 172: + goto st1690 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st1691 + case 185: + goto st1692 + case 187: + goto st1693 + case 188: + goto st1694 + case 189: + goto st1261 + case 190: + goto st1695 + case 191: + goto st1696 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr125 + st1690: + if p++; p == pe { + goto _test_eof1690 + } + st_case_1690: + switch data[p] { + case 158: + goto tr1485 + case 190: + goto tr572 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 170: + goto tr572 + } + default: + goto tr572 + } + goto tr125 + st1691: + if p++; p == pe { + goto _test_eof1691 + } + st_case_1691: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr1485 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr1485 + } + default: + goto tr1485 + } + goto tr125 + st1692: + if p++; p == pe { + goto _test_eof1692 + } + st_case_1692: + switch { + case data[p] < 176: + if 141 <= data[p] && data[p] <= 143 { + goto tr1485 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1693: + if p++; p == pe { + goto _test_eof1693 + } + st_case_1693: + if data[p] == 191 { + goto tr1485 + } + if 189 <= data[p] { + goto tr125 + } + goto tr148 + st1694: + if p++; p == pe { + goto _test_eof1694 + } + st_case_1694: + if data[p] == 191 { + goto tr1485 + } + if 161 <= data[p] && data[p] <= 186 { + goto tr148 + } + goto tr125 + st1695: + if p++; p == pe { + goto _test_eof1695 + } + st_case_1695: + switch { + case data[p] < 160: + if 158 <= data[p] && data[p] <= 159 { + goto tr1485 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr125 + } + default: + goto tr148 + } + goto tr1049 + st1696: + if p++; p == pe { + goto _test_eof1696 + } + st_case_1696: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] >= 130: + goto tr148 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr1485 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1697: + if p++; p == pe { + goto _test_eof1697 + } + st_case_1697: + switch data[p] { + case 144: + goto st1698 + case 145: + goto st1705 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st1727 + case 155: + goto st1734 + case 157: + goto st1736 + case 158: + goto st1744 + case 159: + goto st403 + } + goto tr125 + st1698: + if p++; p == pe { + goto _test_eof1698 + } + st_case_1698: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st1699 + case 138: + goto st313 + case 139: + goto st1700 + case 140: + goto st315 + case 141: + goto st1701 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st1702 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st1703 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st1704 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr125 + st1699: + if p++; p == pe { + goto _test_eof1699 + } + st_case_1699: + if data[p] == 189 { + goto tr1485 + } + goto tr125 + st1700: + if p++; p == pe { + goto _test_eof1700 + } + st_case_1700: + if data[p] == 160 { + goto tr1485 + } + if 145 <= data[p] { + goto tr125 + } + goto tr148 + st1701: + if p++; p == pe { + goto _test_eof1701 + } + st_case_1701: + switch { + case data[p] < 182: + if 139 <= data[p] && data[p] <= 143 { + goto tr125 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr125 + } + default: + goto tr1485 + } + goto tr148 + st1702: + if p++; p == pe { + goto _test_eof1702 + } + st_case_1702: + switch { + case data[p] < 160: + if 158 <= data[p] && data[p] <= 159 { + goto tr2 + } + case data[p] > 169: + if 170 <= data[p] { + goto tr2 + } + default: + goto tr126 + } + goto tr148 + st1703: + if p++; p == pe { + goto _test_eof1703 + } + st_case_1703: + switch data[p] { + case 128: + goto tr148 + case 191: + goto tr1485 + } + switch { + case data[p] < 144: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr1485 + } + case data[p] > 134: + if 140 <= data[p] && data[p] <= 143 { + goto tr1485 + } + default: + goto tr1485 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto tr1485 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1704: + if p++; p == pe { + goto _test_eof1704 + } + st_case_1704: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 164: + if 165 <= data[p] && data[p] <= 166 { + goto tr1485 + } + default: + goto tr148 + } + goto tr125 + st1705: + if p++; p == pe { + goto _test_eof1705 + } + st_case_1705: + switch data[p] { + case 128: + goto st1706 + case 129: + goto st1707 + case 130: + goto st1708 + case 131: + goto st1709 + case 132: + goto st1710 + case 133: + goto st1711 + case 134: + goto st1712 + case 135: + goto st1713 + case 136: + goto st1714 + case 138: + goto st348 + case 139: + goto st1715 + case 140: + goto st1716 + case 141: + goto st1717 + case 146: + goto st1718 + case 147: + goto st1719 + case 150: + goto st1720 + case 151: + goto st1721 + case 152: + goto st1718 + case 153: + goto st1722 + case 154: + goto st1723 + case 155: + goto st1724 + case 156: + goto st1725 + case 162: + goto st359 + case 163: + goto st1726 + case 171: + goto st361 + } + goto tr125 + st1706: + if p++; p == pe { + goto _test_eof1706 + } + st_case_1706: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr1485 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr1485 + } + default: + goto tr148 + } + goto tr125 + st1707: + if p++; p == pe { + goto _test_eof1707 + } + st_case_1707: + switch { + case data[p] < 166: + if 135 <= data[p] && data[p] <= 165 { + goto tr125 + } + case data[p] > 175: + if 176 <= data[p] && data[p] <= 190 { + goto tr125 + } + default: + goto tr126 + } + goto tr1485 + st1708: + if p++; p == pe { + goto _test_eof1708 + } + st_case_1708: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr125 + } + default: + goto tr125 + } + goto tr1485 + st1709: + if p++; p == pe { + goto _test_eof1709 + } + st_case_1709: + switch { + case data[p] > 168: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + case data[p] >= 144: + goto tr148 + } + goto tr2 + st1710: + if p++; p == pe { + goto _test_eof1710 + } + st_case_1710: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr1485 + } + case data[p] > 166: + switch { + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr126 + } + case data[p] >= 167: + goto tr1485 + } + default: + goto tr148 + } + goto tr125 + st1711: + if p++; p == pe { + goto _test_eof1711 + } + st_case_1711: + switch data[p] { + case 179: + goto tr1485 + case 182: + goto tr148 + } + if 144 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr125 + st1712: + if p++; p == pe { + goto _test_eof1712 + } + st_case_1712: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr1485 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr1485 + } + default: + goto tr148 + } + goto tr125 + st1713: + if p++; p == pe { + goto _test_eof1713 + } + st_case_1713: + if data[p] == 155 { + goto tr125 + } + switch { + case data[p] < 141: + switch { + case data[p] > 132: + if 133 <= data[p] && data[p] <= 137 { + goto tr125 + } + case data[p] >= 129: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] < 154: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] > 156: + if 157 <= data[p] { + goto tr125 + } + default: + goto tr148 + } + default: + goto tr125 + } + goto tr1485 + st1714: + if p++; p == pe { + goto _test_eof1714 + } + st_case_1714: + switch { + case data[p] < 147: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] > 171: + if 172 <= data[p] && data[p] <= 183 { + goto tr1485 + } + default: + goto tr148 + } + goto tr125 + st1715: + if p++; p == pe { + goto _test_eof1715 + } + st_case_1715: + switch { + case data[p] < 171: + if 159 <= data[p] && data[p] <= 170 { + goto tr1485 + } + case data[p] > 175: + switch { + case data[p] > 185: + if 186 <= data[p] { + goto tr125 + } + case data[p] >= 176: + goto tr126 + } + default: + goto tr125 + } + goto tr148 + st1716: + if p++; p == pe { + goto _test_eof1716 + } + st_case_1716: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto tr1485 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr1485 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1717: + if p++; p == pe { + goto _test_eof1717 + } + st_case_1717: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr1485 + } + switch { + case data[p] < 157: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr1485 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr1485 + } + default: + goto tr1485 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr1485 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr1485 + } + default: + goto tr1485 + } + default: + goto tr148 + } + goto tr125 + st1718: + if p++; p == pe { + goto _test_eof1718 + } + st_case_1718: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr1485 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st1719: + if p++; p == pe { + goto _test_eof1719 + } + st_case_1719: + if data[p] == 134 { + goto tr125 + } + switch { + case data[p] < 136: + if 132 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] { + goto tr125 + } + case data[p] >= 144: + goto tr126 + } + default: + goto tr125 + } + goto tr1485 + st1720: + if p++; p == pe { + goto _test_eof1720 + } + st_case_1720: + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 181: + if 184 <= data[p] { + goto tr1485 + } + default: + goto tr1485 + } + goto tr125 + st1721: + if p++; p == pe { + goto _test_eof1721 + } + st_case_1721: + switch { + case data[p] < 152: + if 129 <= data[p] && data[p] <= 151 { + goto tr125 + } + case data[p] > 155: + if 158 <= data[p] { + goto tr125 + } + default: + goto tr148 + } + goto tr1485 + st1722: + if p++; p == pe { + goto _test_eof1722 + } + st_case_1722: + if data[p] == 132 { + goto tr148 + } + switch { + case data[p] < 144: + if 129 <= data[p] && data[p] <= 143 { + goto tr125 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr125 + } + default: + goto tr126 + } + goto tr1485 + st1723: + if p++; p == pe { + goto _test_eof1723 + } + st_case_1723: + switch { + case data[p] > 170: + if 171 <= data[p] && data[p] <= 183 { + goto tr1485 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st1724: + if p++; p == pe { + goto _test_eof1724 + } + st_case_1724: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + goto tr2 + st1725: + if p++; p == pe { + goto _test_eof1725 + } + st_case_1725: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + case data[p] >= 157: + goto tr1485 + } + goto tr125 + st1726: + if p++; p == pe { + goto _test_eof1726 + } + st_case_1726: + switch { + case data[p] < 170: + if 160 <= data[p] && data[p] <= 169 { + goto tr126 + } + case data[p] > 190: + if 192 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st1727: + if p++; p == pe { + goto _test_eof1727 + } + st_case_1727: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st1728 + case 171: + goto st1729 + case 172: + goto st1730 + case 173: + goto st1731 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st1732 + case 190: + goto st1733 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr125 + st1728: + if p++; p == pe { + goto _test_eof1728 + } + st_case_1728: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 169 { + goto tr126 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st1729: + if p++; p == pe { + goto _test_eof1729 + } + st_case_1729: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto tr1485 + } + case data[p] >= 144: + goto tr148 + } + goto tr125 + st1730: + if p++; p == pe { + goto _test_eof1730 + } + st_case_1730: + switch { + case data[p] > 175: + if 176 <= data[p] && data[p] <= 182 { + goto tr1485 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st1731: + if p++; p == pe { + goto _test_eof1731 + } + st_case_1731: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 131 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 183: + if 189 <= data[p] { + goto tr148 + } + case data[p] >= 163: + goto tr148 + } + default: + goto tr126 + } + goto tr2 + st1732: + if p++; p == pe { + goto _test_eof1732 + } + st_case_1732: + switch { + case data[p] < 145: + if 133 <= data[p] && data[p] <= 143 { + goto tr125 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr125 + } + default: + goto tr1485 + } + goto tr148 + st1733: + if p++; p == pe { + goto _test_eof1733 + } + st_case_1733: + switch { + case data[p] > 146: + if 147 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 143: + goto tr1485 + } + goto tr125 + st1734: + if p++; p == pe { + goto _test_eof1734 + } + st_case_1734: + switch data[p] { + case 128: + goto st1224 + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st1735 + } + goto tr125 + st1735: + if p++; p == pe { + goto _test_eof1735 + } + st_case_1735: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr1485 + } + case data[p] >= 157: + goto tr1485 + } + default: + goto tr148 + } + goto tr125 + st1736: + if p++; p == pe { + goto _test_eof1736 + } + st_case_1736: + switch data[p] { + case 133: + goto st1737 + case 134: + goto st1738 + case 137: + goto st1739 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st1740 + case 168: + goto st1741 + case 169: + goto st1742 + case 170: + goto st1743 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr125 + st1737: + if p++; p == pe { + goto _test_eof1737 + } + st_case_1737: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr1485 + } + case data[p] >= 165: + goto tr1485 + } + goto tr125 + st1738: + if p++; p == pe { + goto _test_eof1738 + } + st_case_1738: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr125 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr125 + } + default: + goto tr125 + } + goto tr1485 + st1739: + if p++; p == pe { + goto _test_eof1739 + } + st_case_1739: + if 130 <= data[p] && data[p] <= 132 { + goto tr1485 + } + goto tr125 + st1740: + if p++; p == pe { + goto _test_eof1740 + } + st_case_1740: + if data[p] == 131 { + goto tr2 + } + switch { + case data[p] < 142: + if 140 <= data[p] && data[p] <= 141 { + goto tr2 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr2 + } + default: + goto tr126 + } + goto tr148 + st1741: + if p++; p == pe { + goto _test_eof1741 + } + st_case_1741: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr1485 + } + case data[p] >= 128: + goto tr1485 + } + goto tr125 + st1742: + if p++; p == pe { + goto _test_eof1742 + } + st_case_1742: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr125 + } + case data[p] >= 173: + goto tr125 + } + goto tr1485 + st1743: + if p++; p == pe { + goto _test_eof1743 + } + st_case_1743: + if data[p] == 132 { + goto tr1485 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr1485 + } + case data[p] >= 155: + goto tr1485 + } + goto tr125 + st1744: + if p++; p == pe { + goto _test_eof1744 + } + st_case_1744: + switch data[p] { + case 160: + goto st147 + case 163: + goto st1745 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr125 + st1745: + if p++; p == pe { + goto _test_eof1745 + } + st_case_1745: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr125 + } + case data[p] > 150: + if 151 <= data[p] { + goto tr125 + } + default: + goto tr1485 + } + goto tr148 + st1746: + if p++; p == pe { + goto _test_eof1746 + } + st_case_1746: + if data[p] == 160 { + goto st1747 + } + goto tr125 + st1747: + if p++; p == pe { + goto _test_eof1747 + } + st_case_1747: + switch data[p] { + case 128: + goto st1748 + case 129: + goto st1749 + case 132: + goto st1593 + case 135: + goto st1751 + } + if 133 <= data[p] && data[p] <= 134 { + goto st1750 + } + goto tr125 + st1748: + if p++; p == pe { + goto _test_eof1748 + } + st_case_1748: + if data[p] == 129 { + goto tr1485 + } + if 160 <= data[p] { + goto tr1485 + } + goto tr125 + st1749: + if p++; p == pe { + goto _test_eof1749 + } + st_case_1749: + if 192 <= data[p] { + goto tr125 + } + goto tr1485 + st1750: + if p++; p == pe { + goto _test_eof1750 + } + st_case_1750: + goto tr1485 + st1751: + if p++; p == pe { + goto _test_eof1751 + } + st_case_1751: + if 176 <= data[p] { + goto tr125 + } + goto tr1485 + st1752: + if p++; p == pe { + goto _test_eof1752 + } + st_case_1752: + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr126 + case 181: + goto tr148 + case 186: + goto tr148 + } + goto tr125 + st1753: + if p++; p == pe { + goto _test_eof1753 + } + st_case_1753: + if 128 <= data[p] { + goto tr126 + } + goto tr125 + st1754: + if p++; p == pe { + goto _test_eof1754 + } + st_case_1754: + switch data[p] { + case 181: + goto tr125 + case 190: + goto st141 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr125 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr125 + } + goto tr126 + st1755: + if p++; p == pe { + goto _test_eof1755 + } + st_case_1755: + if data[p] == 130 { + goto tr125 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr126 + } + goto tr148 + st1756: + if p++; p == pe { + goto _test_eof1756 + } + st_case_1756: + switch data[p] { + case 137: + goto st141 + case 190: + goto tr125 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr125 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr125 + } + default: + goto tr126 + } + goto tr148 + st1757: + if p++; p == pe { + goto _test_eof1757 + } + st_case_1757: + switch data[p] { + case 135: + goto tr126 + case 179: + goto tr148 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr126 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr126 + } + goto tr125 + st1758: + if p++; p == pe { + goto _test_eof1758 + } + st_case_1758: + if data[p] == 156 { + goto tr126 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 133 { + goto tr126 + } + case data[p] > 141: + switch { + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + case data[p] >= 144: + goto tr126 + } + default: + goto st141 + } + goto tr125 + st1759: + if p++; p == pe { + goto _test_eof1759 + } + st_case_1759: + switch data[p] { + case 171: + goto tr126 + case 172: + goto st141 + case 176: + goto tr126 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + default: + goto tr126 + } + goto tr125 + st1760: + if p++; p == pe { + goto _test_eof1760 + } + st_case_1760: + switch data[p] { + case 148: + goto tr125 + case 158: + goto tr125 + case 169: + goto tr125 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr126 + } + case data[p] >= 150: + goto tr126 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr125 + } + case data[p] >= 189: + goto tr125 + } + default: + goto tr126 + } + goto tr148 + st1761: + if p++; p == pe { + goto _test_eof1761 + } + st_case_1761: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto tr126 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr126 + } + default: + goto tr148 + } + goto tr125 + st1762: + if p++; p == pe { + goto _test_eof1762 + } + st_case_1762: + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr125 + } + goto tr126 + st1763: + if p++; p == pe { + goto _test_eof1763 + } + st_case_1763: + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr125 + } + case data[p] >= 166: + goto tr126 + } + goto tr148 + st1764: + if p++; p == pe { + goto _test_eof1764 + } + st_case_1764: + switch data[p] { + case 184: + goto st141 + case 186: + goto tr148 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 170: + switch { + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 171: + goto tr126 + } + default: + goto tr148 + } + goto tr125 + st1765: + if p++; p == pe { + goto _test_eof1765 + } + st_case_1765: + switch data[p] { + case 160: + goto st1766 + case 161: + goto st1767 + case 162: + goto st168 + case 163: + goto st1768 + case 164: + goto st1769 + case 165: + goto st1770 + case 166: + goto st1771 + case 167: + goto st1772 + case 168: + goto st1773 + case 169: + goto st1774 + case 170: + goto st1775 + case 171: + goto st1776 + case 172: + goto st1777 + case 173: + goto st1778 + case 174: + goto st1779 + case 175: + goto st1780 + case 176: + goto st1781 + case 177: + goto st1782 + case 178: + goto st1783 + case 179: + goto st1784 + case 180: + goto st1785 + case 181: + goto st1786 + case 182: + goto st1787 + case 183: + goto st1788 + case 184: + goto st1789 + case 185: + goto st1790 + case 186: + goto st1791 + case 187: + goto st1792 + case 188: + goto st1793 + case 189: + goto st1794 + case 190: + goto st1795 + case 191: + goto st1796 + } + goto tr125 + st1766: + if p++; p == pe { + goto _test_eof1766 + } + st_case_1766: + switch data[p] { + case 154: + goto tr148 + case 164: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] > 149: + if 150 <= data[p] && data[p] <= 173 { + goto tr126 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st1767: + if p++; p == pe { + goto _test_eof1767 + } + st_case_1767: + switch { + case data[p] > 152: + if 153 <= data[p] && data[p] <= 155 { + goto tr126 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st1768: + if p++; p == pe { + goto _test_eof1768 + } + st_case_1768: + if 163 <= data[p] { + goto tr126 + } + goto tr125 + st1769: + if p++; p == pe { + goto _test_eof1769 + } + st_case_1769: + if data[p] == 189 { + goto tr148 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr148 + } + goto tr126 + st1770: + if p++; p == pe { + goto _test_eof1770 + } + st_case_1770: + switch data[p] { + case 144: + goto tr148 + case 176: + goto tr125 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + if 177 <= data[p] { + goto tr148 + } + default: + goto tr125 + } + goto tr126 + st1771: + if p++; p == pe { + goto _test_eof1771 + } + st_case_1771: + switch data[p] { + case 132: + goto tr125 + case 169: + goto tr125 + case 177: + goto tr125 + case 188: + goto tr126 + } + switch { + case data[p] < 145: + switch { + case data[p] > 131: + if 141 <= data[p] && data[p] <= 142 { + goto tr125 + } + case data[p] >= 129: + goto tr126 + } + case data[p] > 146: + switch { + case data[p] < 186: + if 179 <= data[p] && data[p] <= 181 { + goto tr125 + } + case data[p] > 187: + if 190 <= data[p] { + goto tr126 + } + default: + goto tr125 + } + default: + goto tr125 + } + goto tr148 + st1772: + if p++; p == pe { + goto _test_eof1772 + } + st_case_1772: + switch data[p] { + case 142: + goto tr148 + case 158: + goto tr125 + } + switch { + case data[p] < 152: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr125 + } + case data[p] > 138: + if 143 <= data[p] && data[p] <= 150 { + goto tr125 + } + default: + goto tr125 + } + case data[p] > 155: + switch { + case data[p] < 164: + if 156 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr125 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr125 + } + default: + goto tr125 + } + goto tr126 + st1773: + if p++; p == pe { + goto _test_eof1773 + } + st_case_1773: + if data[p] == 188 { + goto tr126 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr126 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto tr126 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1774: + if p++; p == pe { + goto _test_eof1774 + } + st_case_1774: + if data[p] == 157 { + goto tr125 + } + switch { + case data[p] < 146: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr125 + } + case data[p] > 138: + if 142 <= data[p] && data[p] <= 144 { + goto tr125 + } + default: + goto tr125 + } + case data[p] > 152: + switch { + case data[p] < 159: + if 153 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 165: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr125 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr125 + } + default: + goto tr125 + } + goto tr126 + st1775: + if p++; p == pe { + goto _test_eof1775 + } + st_case_1775: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr126 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto tr126 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1776: + if p++; p == pe { + goto _test_eof1776 + } + st_case_1776: + switch data[p] { + case 134: + goto tr125 + case 138: + goto tr125 + case 144: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 160: + if 142 <= data[p] && data[p] <= 159 { + goto tr125 + } + case data[p] > 161: + switch { + case data[p] > 165: + if 176 <= data[p] { + goto tr125 + } + case data[p] >= 164: + goto tr125 + } + default: + goto tr148 + } + goto tr126 + st1777: + if p++; p == pe { + goto _test_eof1777 + } + st_case_1777: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr126 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr126 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1778: + if p++; p == pe { + goto _test_eof1778 + } + st_case_1778: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr126 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr126 + } + default: + goto tr126 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 161: + switch { + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] >= 162: + goto tr126 + } + default: + goto tr148 + } + default: + goto tr126 + } + goto tr125 + st1779: + if p++; p == pe { + goto _test_eof1779 + } + st_case_1779: + switch data[p] { + case 130: + goto tr126 + case 131: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 158: + switch { + case data[p] < 142: + if 133 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 149: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] < 168: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto tr126 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1780: + if p++; p == pe { + goto _test_eof1780 + } + st_case_1780: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr126 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr126 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] >= 138: + goto tr126 + } + default: + goto tr126 + } + goto tr125 + st1781: + if p++; p == pe { + goto _test_eof1781 + } + st_case_1781: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto tr126 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 190 <= data[p] { + goto tr126 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1782: + if p++; p == pe { + goto _test_eof1782 + } + st_case_1782: + switch data[p] { + case 133: + goto tr125 + case 137: + goto tr125 + case 151: + goto tr125 + } + switch { + case data[p] < 155: + switch { + case data[p] > 148: + if 152 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 142: + goto tr125 + } + case data[p] > 159: + switch { + case data[p] < 164: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + if 176 <= data[p] { + goto tr125 + } + default: + goto tr125 + } + default: + goto tr125 + } + goto tr126 + st1783: + if p++; p == pe { + goto _test_eof1783 + } + st_case_1783: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr126 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr126 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1784: + if p++; p == pe { + goto _test_eof1784 + } + st_case_1784: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr126 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr126 + } + default: + goto tr126 + } + case data[p] > 150: + switch { + case data[p] < 162: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 163: + switch { + case data[p] > 175: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr126 + } + default: + goto tr126 + } + goto tr125 + st1785: + if p++; p == pe { + goto _test_eof1785 + } + st_case_1785: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto tr126 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto tr126 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1786: + if p++; p == pe { + goto _test_eof1786 + } + st_case_1786: + switch data[p] { + case 133: + goto tr125 + case 137: + goto tr125 + case 142: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 150 { + goto tr125 + } + case data[p] > 158: + if 159 <= data[p] && data[p] <= 161 { + goto tr148 + } + default: + goto tr125 + } + case data[p] > 165: + switch { + case data[p] < 186: + if 176 <= data[p] && data[p] <= 185 { + goto tr125 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr125 + } + default: + goto tr148 + } + default: + goto tr125 + } + goto tr126 + st1787: + if p++; p == pe { + goto _test_eof1787 + } + st_case_1787: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr126 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1788: + if p++; p == pe { + goto _test_eof1788 + } + st_case_1788: + switch data[p] { + case 138: + goto tr126 + case 150: + goto tr126 + } + switch { + case data[p] < 152: + switch { + case data[p] > 134: + if 143 <= data[p] && data[p] <= 148 { + goto tr126 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto tr126 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr126 + } + goto tr125 + st1789: + if p++; p == pe { + goto _test_eof1789 + } + st_case_1789: + if data[p] == 177 { + goto tr126 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr126 + } + goto tr125 + st1790: + if p++; p == pe { + goto _test_eof1790 + } + st_case_1790: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 135: + goto tr126 + } + goto tr125 + st1791: + if p++; p == pe { + goto _test_eof1791 + } + st_case_1791: + if data[p] == 177 { + goto tr126 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr126 + } + case data[p] >= 180: + goto tr126 + } + goto tr125 + st1792: + if p++; p == pe { + goto _test_eof1792 + } + st_case_1792: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 136: + goto tr126 + } + goto tr125 + st1793: + if p++; p == pe { + goto _test_eof1793 + } + st_case_1793: + switch data[p] { + case 128: + goto tr148 + case 181: + goto tr126 + case 183: + goto tr126 + case 185: + goto tr126 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto tr126 + } + default: + goto tr126 + } + goto tr125 + st1794: + if p++; p == pe { + goto _test_eof1794 + } + st_case_1794: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto tr126 + } + default: + goto tr148 + } + goto tr125 + st1795: + if p++; p == pe { + goto _test_eof1795 + } + st_case_1795: + switch { + case data[p] < 136: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 135 { + goto tr126 + } + case data[p] >= 128: + goto tr126 + } + case data[p] > 140: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr126 + } + case data[p] >= 141: + goto tr126 + } + default: + goto tr148 + } + goto tr125 + st1796: + if p++; p == pe { + goto _test_eof1796 + } + st_case_1796: + if data[p] == 134 { + goto tr126 + } + goto tr125 + st1797: + if p++; p == pe { + goto _test_eof1797 + } + st_case_1797: + switch data[p] { + case 128: + goto st1798 + case 129: + goto st1799 + case 130: + goto st1800 + case 131: + goto st202 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st1801 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st1802 + case 157: + goto st1803 + case 158: + goto st1804 + case 159: + goto st1805 + case 160: + goto st1806 + case 161: + goto st219 + case 162: + goto st1807 + case 163: + goto st221 + case 164: + goto st1808 + case 165: + goto st1649 + case 167: + goto st1650 + case 168: + goto st1809 + case 169: + goto st1810 + case 170: + goto st1811 + case 172: + goto st1812 + case 173: + goto st1813 + case 174: + goto st1814 + case 175: + goto st1815 + case 176: + goto st1816 + case 177: + goto st1659 + case 179: + goto st1817 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st1818 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + } + switch { + case data[p] < 180: + if 132 <= data[p] && data[p] <= 152 { + goto st145 + } + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + default: + goto st147 + } + goto tr125 + st1798: + if p++; p == pe { + goto _test_eof1798 + } + st_case_1798: + if 171 <= data[p] && data[p] <= 190 { + goto tr126 + } + goto tr125 + st1799: + if p++; p == pe { + goto _test_eof1799 + } + st_case_1799: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 128: + goto tr126 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto tr126 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr126 + } + default: + goto tr126 + } + default: + goto tr126 + } + goto tr125 + st1800: + if p++; p == pe { + goto _test_eof1800 + } + st_case_1800: + switch { + case data[p] < 143: + if 130 <= data[p] && data[p] <= 141 { + goto tr126 + } + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr126 + } + goto tr125 + st1801: + if p++; p == pe { + goto _test_eof1801 + } + st_case_1801: + switch { + case data[p] < 157: + if 155 <= data[p] && data[p] <= 156 { + goto tr125 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr125 + } + default: + goto tr126 + } + goto tr148 + st1802: + if p++; p == pe { + goto _test_eof1802 + } + st_case_1802: + switch { + case data[p] < 146: + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 177: + if 178 <= data[p] && data[p] <= 180 { + goto tr126 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr126 + } + goto tr125 + st1803: + if p++; p == pe { + goto _test_eof1803 + } + st_case_1803: + switch { + case data[p] < 160: + switch { + case data[p] > 145: + if 146 <= data[p] && data[p] <= 147 { + goto tr126 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto tr126 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1804: + if p++; p == pe { + goto _test_eof1804 + } + st_case_1804: + if 180 <= data[p] { + goto tr126 + } + goto tr125 + st1805: + if p++; p == pe { + goto _test_eof1805 + } + st_case_1805: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr125 + } + case data[p] > 159: + if 170 <= data[p] { + goto tr125 + } + default: + goto tr125 + } + goto tr126 + st1806: + if p++; p == pe { + goto _test_eof1806 + } + st_case_1806: + switch { + case data[p] < 144: + if 139 <= data[p] && data[p] <= 142 { + goto tr126 + } + case data[p] > 153: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr126 + } + goto tr125 + st1807: + if p++; p == pe { + goto _test_eof1807 + } + st_case_1807: + if data[p] == 169 { + goto tr126 + } + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st1808: + if p++; p == pe { + goto _test_eof1808 + } + st_case_1808: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr126 + } + default: + goto tr126 + } + goto tr125 + st1809: + if p++; p == pe { + goto _test_eof1809 + } + st_case_1809: + switch { + case data[p] > 150: + if 151 <= data[p] && data[p] <= 155 { + goto tr126 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st1810: + if p++; p == pe { + goto _test_eof1810 + } + st_case_1810: + if data[p] == 191 { + goto tr126 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr126 + } + case data[p] >= 149: + goto tr126 + } + goto tr125 + st1811: + if p++; p == pe { + goto _test_eof1811 + } + st_case_1811: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto tr126 + } + default: + goto tr126 + } + goto tr125 + st1812: + if p++; p == pe { + goto _test_eof1812 + } + st_case_1812: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 132 { + goto tr126 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr126 + } + default: + goto tr148 + } + goto tr125 + st1813: + if p++; p == pe { + goto _test_eof1813 + } + st_case_1813: + switch { + case data[p] < 140: + if 133 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 143: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr125 + } + case data[p] >= 154: + goto tr125 + } + default: + goto tr125 + } + goto tr126 + st1814: + if p++; p == pe { + goto _test_eof1814 + } + st_case_1814: + switch { + case data[p] < 161: + switch { + case data[p] > 130: + if 131 <= data[p] && data[p] <= 160 { + goto tr148 + } + case data[p] >= 128: + goto tr126 + } + case data[p] > 173: + switch { + case data[p] < 176: + if 174 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr148 + } + default: + goto tr126 + } + default: + goto tr126 + } + goto tr125 + st1815: + if p++; p == pe { + goto _test_eof1815 + } + st_case_1815: + switch { + case data[p] > 179: + if 180 <= data[p] { + goto tr125 + } + case data[p] >= 166: + goto tr126 + } + goto tr148 + st1816: + if p++; p == pe { + goto _test_eof1816 + } + st_case_1816: + switch { + case data[p] > 163: + if 164 <= data[p] && data[p] <= 183 { + goto tr126 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st1817: + if p++; p == pe { + goto _test_eof1817 + } + st_case_1817: + if data[p] == 173 { + goto tr126 + } + switch { + case data[p] < 169: + switch { + case data[p] > 146: + if 148 <= data[p] && data[p] <= 168 { + goto tr126 + } + case data[p] >= 144: + goto tr126 + } + case data[p] > 177: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 180 { + goto tr126 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto tr126 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1818: + if p++; p == pe { + goto _test_eof1818 + } + st_case_1818: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr126 + } + case data[p] >= 128: + goto tr126 + } + goto tr125 + st1819: + if p++; p == pe { + goto _test_eof1819 + } + st_case_1819: + switch data[p] { + case 128: + goto st1820 + case 129: + goto st1821 + case 130: + goto st241 + case 131: + goto st1822 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st1823 + case 180: + goto st251 + case 181: + goto st1824 + case 182: + goto st253 + case 183: + goto st1825 + case 184: + goto st255 + } + goto tr125 + st1820: + if p++; p == pe { + goto _test_eof1820 + } + st_case_1820: + if data[p] == 164 { + goto st141 + } + switch { + case data[p] < 152: + if 140 <= data[p] && data[p] <= 143 { + goto tr126 + } + case data[p] > 153: + switch { + case data[p] > 174: + if 191 <= data[p] { + goto tr1485 + } + case data[p] >= 170: + goto tr126 + } + default: + goto st141 + } + goto tr125 + st1821: + if p++; p == pe { + goto _test_eof1821 + } + st_case_1821: + switch data[p] { + case 132: + goto st141 + case 165: + goto tr125 + case 177: + goto tr148 + case 191: + goto tr148 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr125 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr125 + } + case data[p] >= 160: + goto tr126 + } + default: + goto tr125 + } + goto tr1485 + st1822: + if p++; p == pe { + goto _test_eof1822 + } + st_case_1822: + if 144 <= data[p] && data[p] <= 176 { + goto tr126 + } + goto tr125 + st1823: + if p++; p == pe { + goto _test_eof1823 + } + st_case_1823: + switch { + case data[p] < 175: + if 165 <= data[p] && data[p] <= 170 { + goto tr125 + } + case data[p] > 177: + if 180 <= data[p] { + goto tr125 + } + default: + goto tr126 + } + goto tr148 + st1824: + if p++; p == pe { + goto _test_eof1824 + } + st_case_1824: + if data[p] == 191 { + goto tr126 + } + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr125 + } + case data[p] >= 168: + goto tr125 + } + goto tr148 + st1825: + if p++; p == pe { + goto _test_eof1825 + } + st_case_1825: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto tr126 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1826: + if p++; p == pe { + goto _test_eof1826 + } + st_case_1826: + switch data[p] { + case 128: + goto st1827 + case 130: + goto st1828 + case 132: + goto st259 + case 133: + goto st145 + case 134: + goto st260 + } + goto tr125 + st1827: + if p++; p == pe { + goto _test_eof1827 + } + st_case_1827: + if data[p] == 133 { + goto tr148 + } + switch { + case data[p] > 175: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + case data[p] >= 170: + goto tr126 + } + goto tr125 + st1828: + if p++; p == pe { + goto _test_eof1828 + } + st_case_1828: + if 153 <= data[p] && data[p] <= 154 { + goto tr126 + } + goto tr125 + st1829: + if p++; p == pe { + goto _test_eof1829 + } + st_case_1829: + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st1673 + case 153: + goto st1830 + case 154: + goto st1831 + case 155: + goto st1832 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st1833 + case 161: + goto st272 + case 162: + goto st1834 + case 163: + goto st1835 + case 164: + goto st1836 + case 165: + goto st1837 + case 166: + goto st1838 + case 167: + goto st1839 + case 168: + goto st1840 + case 169: + goto st1841 + case 170: + goto st1842 + case 171: + goto st1843 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st1844 + case 176: + goto st147 + } + if 129 <= data[p] { + goto st145 + } + goto tr125 + st1830: + if p++; p == pe { + goto _test_eof1830 + } + st_case_1830: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr126 + } + default: + goto tr126 + } + goto tr125 + st1831: + if p++; p == pe { + goto _test_eof1831 + } + st_case_1831: + switch { + case data[p] < 158: + if 128 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr126 + } + goto tr125 + st1832: + if p++; p == pe { + goto _test_eof1832 + } + st_case_1832: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr125 + } + case data[p] >= 176: + goto tr126 + } + goto tr148 + st1833: + if p++; p == pe { + goto _test_eof1833 + } + st_case_1833: + switch data[p] { + case 130: + goto tr126 + case 134: + goto tr126 + case 139: + goto tr126 + } + switch { + case data[p] > 167: + if 168 <= data[p] { + goto tr125 + } + case data[p] >= 163: + goto tr126 + } + goto tr148 + st1834: + if p++; p == pe { + goto _test_eof1834 + } + st_case_1834: + switch { + case data[p] < 130: + if 128 <= data[p] && data[p] <= 129 { + goto tr126 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr126 + } + default: + goto tr148 + } + goto tr125 + st1835: + if p++; p == pe { + goto _test_eof1835 + } + st_case_1835: + switch data[p] { + case 187: + goto tr148 + case 189: + goto tr148 + } + switch { + case data[p] < 154: + if 133 <= data[p] && data[p] <= 143 { + goto tr125 + } + case data[p] > 159: + switch { + case data[p] > 183: + if 184 <= data[p] { + goto tr125 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr125 + } + goto tr126 + st1836: + if p++; p == pe { + goto _test_eof1836 + } + st_case_1836: + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 165: + switch { + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr148 + } + goto tr125 + st1837: + if p++; p == pe { + goto _test_eof1837 + } + st_case_1837: + switch { + case data[p] < 148: + if 135 <= data[p] && data[p] <= 147 { + goto tr126 + } + case data[p] > 159: + if 189 <= data[p] { + goto tr125 + } + default: + goto tr125 + } + goto tr148 + st1838: + if p++; p == pe { + goto _test_eof1838 + } + st_case_1838: + switch { + case data[p] < 132: + if 128 <= data[p] && data[p] <= 131 { + goto tr126 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr126 + } + default: + goto tr148 + } + goto tr125 + st1839: + if p++; p == pe { + goto _test_eof1839 + } + st_case_1839: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] < 154: + if 129 <= data[p] && data[p] <= 142 { + goto tr125 + } + case data[p] > 164: + switch { + case data[p] > 175: + if 186 <= data[p] { + goto tr125 + } + case data[p] >= 166: + goto tr125 + } + default: + goto tr125 + } + goto tr126 + st1840: + if p++; p == pe { + goto _test_eof1840 + } + st_case_1840: + switch { + case data[p] > 168: + if 169 <= data[p] && data[p] <= 182 { + goto tr126 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st1841: + if p++; p == pe { + goto _test_eof1841 + } + st_case_1841: + if data[p] == 131 { + goto tr126 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 141: + switch { + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto tr126 + } + case data[p] >= 144: + goto tr126 + } + default: + goto tr126 + } + goto tr125 + st1842: + if p++; p == pe { + goto _test_eof1842 + } + st_case_1842: + if data[p] == 176 { + goto tr126 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr126 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr126 + } + default: + goto tr126 + } + goto tr125 + st1843: + if p++; p == pe { + goto _test_eof1843 + } + st_case_1843: + if data[p] == 129 { + goto tr126 + } + switch { + case data[p] < 171: + if 160 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 181 <= data[p] && data[p] <= 182 { + goto tr126 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr126 + } + goto tr125 + st1844: + if p++; p == pe { + goto _test_eof1844 + } + st_case_1844: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 162 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + case data[p] >= 172: + goto tr126 + } + default: + goto tr126 + } + goto tr125 + st1845: + if p++; p == pe { + goto _test_eof1845 + } + st_case_1845: + switch data[p] { + case 172: + goto st1846 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st1847 + case 185: + goto st1848 + case 187: + goto st1849 + case 188: + goto st1850 + case 189: + goto st303 + case 190: + goto st1851 + case 191: + goto st1852 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr125 + st1846: + if p++; p == pe { + goto _test_eof1846 + } + st_case_1846: + switch data[p] { + case 158: + goto tr126 + case 190: + goto tr572 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 170: + goto tr572 + } + default: + goto tr572 + } + goto tr125 + st1847: + if p++; p == pe { + goto _test_eof1847 + } + st_case_1847: + switch data[p] { + case 144: + goto st141 + case 148: + goto st141 + } + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr126 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr1485 + } + default: + goto tr126 + } + goto tr125 + st1848: + if p++; p == pe { + goto _test_eof1848 + } + st_case_1848: + switch data[p] { + case 144: + goto st141 + case 146: + goto st141 + case 148: + goto st141 + } + switch { + case data[p] < 176: + if 141 <= data[p] && data[p] <= 143 { + goto tr1485 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1849: + if p++; p == pe { + goto _test_eof1849 + } + st_case_1849: + if data[p] == 191 { + goto tr126 + } + if 189 <= data[p] { + goto tr125 + } + goto tr148 + st1850: + if p++; p == pe { + goto _test_eof1850 + } + st_case_1850: + switch data[p] { + case 135: + goto st141 + case 140: + goto st141 + case 142: + goto st141 + case 155: + goto st141 + case 191: + goto tr1485 + } + if 161 <= data[p] && data[p] <= 186 { + goto tr148 + } + goto tr125 + st1851: + if p++; p == pe { + goto _test_eof1851 + } + st_case_1851: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 190 { + goto tr148 + } + case data[p] >= 158: + goto tr126 + } + goto tr125 + st1852: + if p++; p == pe { + goto _test_eof1852 + } + st_case_1852: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] >= 130: + goto tr148 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr126 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1853: + if p++; p == pe { + goto _test_eof1853 + } + st_case_1853: + switch data[p] { + case 144: + goto st1854 + case 145: + goto st1860 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st1879 + case 155: + goto st1884 + case 157: + goto st1886 + case 158: + goto st1893 + case 159: + goto st403 + } + goto tr125 + st1854: + if p++; p == pe { + goto _test_eof1854 + } + st_case_1854: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st1855 + case 138: + goto st313 + case 139: + goto st1856 + case 140: + goto st315 + case 141: + goto st1857 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st1702 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st1858 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st1859 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr125 + st1855: + if p++; p == pe { + goto _test_eof1855 + } + st_case_1855: + if data[p] == 189 { + goto tr126 + } + goto tr125 + st1856: + if p++; p == pe { + goto _test_eof1856 + } + st_case_1856: + if data[p] == 160 { + goto tr126 + } + if 145 <= data[p] { + goto tr125 + } + goto tr148 + st1857: + if p++; p == pe { + goto _test_eof1857 + } + st_case_1857: + switch { + case data[p] < 182: + if 139 <= data[p] && data[p] <= 143 { + goto tr125 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr125 + } + default: + goto tr126 + } + goto tr148 + st1858: + if p++; p == pe { + goto _test_eof1858 + } + st_case_1858: + switch data[p] { + case 128: + goto tr148 + case 191: + goto tr126 + } + switch { + case data[p] < 144: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr126 + } + case data[p] > 134: + if 140 <= data[p] && data[p] <= 143 { + goto tr126 + } + default: + goto tr126 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto tr126 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1859: + if p++; p == pe { + goto _test_eof1859 + } + st_case_1859: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 164: + if 165 <= data[p] && data[p] <= 166 { + goto tr126 + } + default: + goto tr148 + } + goto tr125 + st1860: + if p++; p == pe { + goto _test_eof1860 + } + st_case_1860: + switch data[p] { + case 128: + goto st1861 + case 129: + goto st1862 + case 130: + goto st1863 + case 131: + goto st1709 + case 132: + goto st1864 + case 133: + goto st1865 + case 134: + goto st1866 + case 135: + goto st1867 + case 136: + goto st1868 + case 138: + goto st348 + case 139: + goto st1869 + case 140: + goto st1870 + case 141: + goto st1871 + case 146: + goto st1872 + case 147: + goto st1873 + case 150: + goto st1874 + case 151: + goto st1875 + case 152: + goto st1872 + case 153: + goto st1876 + case 154: + goto st1877 + case 155: + goto st1724 + case 156: + goto st1878 + case 162: + goto st359 + case 163: + goto st1726 + case 171: + goto st361 + } + goto tr125 + st1861: + if p++; p == pe { + goto _test_eof1861 + } + st_case_1861: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr126 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr126 + } + default: + goto tr148 + } + goto tr125 + st1862: + if p++; p == pe { + goto _test_eof1862 + } + st_case_1862: + switch { + case data[p] > 165: + if 176 <= data[p] && data[p] <= 190 { + goto tr125 + } + case data[p] >= 135: + goto tr125 + } + goto tr126 + st1863: + if p++; p == pe { + goto _test_eof1863 + } + st_case_1863: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr125 + } + default: + goto tr125 + } + goto tr126 + st1864: + if p++; p == pe { + goto _test_eof1864 + } + st_case_1864: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr126 + } + case data[p] > 166: + switch { + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr126 + } + case data[p] >= 167: + goto tr126 + } + default: + goto tr148 + } + goto tr125 + st1865: + if p++; p == pe { + goto _test_eof1865 + } + st_case_1865: + switch data[p] { + case 179: + goto tr126 + case 182: + goto tr148 + } + if 144 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr125 + st1866: + if p++; p == pe { + goto _test_eof1866 + } + st_case_1866: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr126 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr126 + } + default: + goto tr148 + } + goto tr125 + st1867: + if p++; p == pe { + goto _test_eof1867 + } + st_case_1867: + if data[p] == 155 { + goto tr125 + } + switch { + case data[p] < 141: + switch { + case data[p] > 132: + if 133 <= data[p] && data[p] <= 137 { + goto tr125 + } + case data[p] >= 129: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] > 156: + if 157 <= data[p] { + goto tr125 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr125 + } + goto tr126 + st1868: + if p++; p == pe { + goto _test_eof1868 + } + st_case_1868: + switch { + case data[p] < 147: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] > 171: + if 172 <= data[p] && data[p] <= 183 { + goto tr126 + } + default: + goto tr148 + } + goto tr125 + st1869: + if p++; p == pe { + goto _test_eof1869 + } + st_case_1869: + switch { + case data[p] < 171: + if 159 <= data[p] && data[p] <= 170 { + goto tr126 + } + case data[p] > 175: + switch { + case data[p] > 185: + if 186 <= data[p] { + goto tr125 + } + case data[p] >= 176: + goto tr126 + } + default: + goto tr125 + } + goto tr148 + st1870: + if p++; p == pe { + goto _test_eof1870 + } + st_case_1870: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto tr126 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr126 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st1871: + if p++; p == pe { + goto _test_eof1871 + } + st_case_1871: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr126 + } + switch { + case data[p] < 157: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr126 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr126 + } + default: + goto tr126 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr126 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr126 + } + default: + goto tr126 + } + default: + goto tr148 + } + goto tr125 + st1872: + if p++; p == pe { + goto _test_eof1872 + } + st_case_1872: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr126 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st1873: + if p++; p == pe { + goto _test_eof1873 + } + st_case_1873: + if data[p] == 134 { + goto tr125 + } + switch { + case data[p] < 136: + if 132 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 143: + if 154 <= data[p] { + goto tr125 + } + default: + goto tr125 + } + goto tr126 + st1874: + if p++; p == pe { + goto _test_eof1874 + } + st_case_1874: + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 181: + if 184 <= data[p] { + goto tr126 + } + default: + goto tr126 + } + goto tr125 + st1875: + if p++; p == pe { + goto _test_eof1875 + } + st_case_1875: + switch { + case data[p] < 152: + if 129 <= data[p] && data[p] <= 151 { + goto tr125 + } + case data[p] > 155: + if 158 <= data[p] { + goto tr125 + } + default: + goto tr148 + } + goto tr126 + st1876: + if p++; p == pe { + goto _test_eof1876 + } + st_case_1876: + if data[p] == 132 { + goto tr148 + } + switch { + case data[p] > 143: + if 154 <= data[p] { + goto tr125 + } + case data[p] >= 129: + goto tr125 + } + goto tr126 + st1877: + if p++; p == pe { + goto _test_eof1877 + } + st_case_1877: + switch { + case data[p] > 170: + if 171 <= data[p] && data[p] <= 183 { + goto tr126 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st1878: + if p++; p == pe { + goto _test_eof1878 + } + st_case_1878: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + case data[p] >= 157: + goto tr126 + } + goto tr125 + st1879: + if p++; p == pe { + goto _test_eof1879 + } + st_case_1879: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st1728 + case 171: + goto st1880 + case 172: + goto st1881 + case 173: + goto st1731 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st1882 + case 190: + goto st1883 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr125 + st1880: + if p++; p == pe { + goto _test_eof1880 + } + st_case_1880: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto tr126 + } + case data[p] >= 144: + goto tr148 + } + goto tr125 + st1881: + if p++; p == pe { + goto _test_eof1881 + } + st_case_1881: + switch { + case data[p] > 175: + if 176 <= data[p] && data[p] <= 182 { + goto tr126 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st1882: + if p++; p == pe { + goto _test_eof1882 + } + st_case_1882: + switch { + case data[p] < 145: + if 133 <= data[p] && data[p] <= 143 { + goto tr125 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr125 + } + default: + goto tr126 + } + goto tr148 + st1883: + if p++; p == pe { + goto _test_eof1883 + } + st_case_1883: + switch { + case data[p] > 146: + if 147 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 143: + goto tr126 + } + goto tr125 + st1884: + if p++; p == pe { + goto _test_eof1884 + } + st_case_1884: + switch data[p] { + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st1885 + } + goto tr125 + st1885: + if p++; p == pe { + goto _test_eof1885 + } + st_case_1885: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr126 + } + case data[p] >= 157: + goto tr126 + } + default: + goto tr148 + } + goto tr125 + st1886: + if p++; p == pe { + goto _test_eof1886 + } + st_case_1886: + switch data[p] { + case 133: + goto st1887 + case 134: + goto st1888 + case 137: + goto st1889 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st1740 + case 168: + goto st1890 + case 169: + goto st1891 + case 170: + goto st1892 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr125 + st1887: + if p++; p == pe { + goto _test_eof1887 + } + st_case_1887: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr126 + } + case data[p] >= 165: + goto tr126 + } + goto tr125 + st1888: + if p++; p == pe { + goto _test_eof1888 + } + st_case_1888: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr125 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr125 + } + default: + goto tr125 + } + goto tr126 + st1889: + if p++; p == pe { + goto _test_eof1889 + } + st_case_1889: + if 130 <= data[p] && data[p] <= 132 { + goto tr126 + } + goto tr125 + st1890: + if p++; p == pe { + goto _test_eof1890 + } + st_case_1890: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr126 + } + case data[p] >= 128: + goto tr126 + } + goto tr125 + st1891: + if p++; p == pe { + goto _test_eof1891 + } + st_case_1891: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr125 + } + case data[p] >= 173: + goto tr125 + } + goto tr126 + st1892: + if p++; p == pe { + goto _test_eof1892 + } + st_case_1892: + if data[p] == 132 { + goto tr126 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] >= 155: + goto tr126 + } + goto tr125 + st1893: + if p++; p == pe { + goto _test_eof1893 + } + st_case_1893: + switch data[p] { + case 160: + goto st147 + case 163: + goto st1894 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr125 + st1894: + if p++; p == pe { + goto _test_eof1894 + } + st_case_1894: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr125 + } + case data[p] > 150: + if 151 <= data[p] { + goto tr125 + } + default: + goto tr126 + } + goto tr148 + st1895: + if p++; p == pe { + goto _test_eof1895 + } + st_case_1895: + if data[p] == 160 { + goto st1896 + } + goto tr125 + st1896: + if p++; p == pe { + goto _test_eof1896 + } + st_case_1896: + switch data[p] { + case 128: + goto st1897 + case 129: + goto st1898 + case 132: + goto st1753 + case 135: + goto st1900 + } + if 133 <= data[p] && data[p] <= 134 { + goto st1899 + } + goto tr125 + st1897: + if p++; p == pe { + goto _test_eof1897 + } + st_case_1897: + if data[p] == 129 { + goto tr126 + } + if 160 <= data[p] { + goto tr126 + } + goto tr125 + st1898: + if p++; p == pe { + goto _test_eof1898 + } + st_case_1898: + if 192 <= data[p] { + goto tr125 + } + goto tr126 + st1899: + if p++; p == pe { + goto _test_eof1899 + } + st_case_1899: + goto tr126 + st1900: + if p++; p == pe { + goto _test_eof1900 + } + st_case_1900: + if 176 <= data[p] { + goto tr125 + } + goto tr126 + st1901: + if p++; p == pe { + goto _test_eof1901 + } + st_case_1901: + if data[p] == 173 { + goto st141 + } + goto tr125 + st1902: + if p++; p == pe { + goto _test_eof1902 + } + st_case_1902: + if 128 <= data[p] { + goto st141 + } + goto tr125 + st1903: + if p++; p == pe { + goto _test_eof1903 + } + st_case_1903: + if 176 <= data[p] { + goto tr125 + } + goto st141 + st1904: + if p++; p == pe { + goto _test_eof1904 + } + st_case_1904: + if 131 <= data[p] && data[p] <= 137 { + goto st141 + } + goto tr125 + st1905: + if p++; p == pe { + goto _test_eof1905 + } + st_case_1905: + if data[p] == 191 { + goto st141 + } + if 145 <= data[p] && data[p] <= 189 { + goto st141 + } + goto tr125 + st1906: + if p++; p == pe { + goto _test_eof1906 + } + st_case_1906: + if data[p] == 135 { + goto st141 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto st141 + } + case data[p] >= 129: + goto st141 + } + goto tr125 + st1907: + if p++; p == pe { + goto _test_eof1907 + } + st_case_1907: + if data[p] == 156 { + goto st141 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto st141 + } + case data[p] >= 128: + goto st141 + } + goto tr125 + st1908: + if p++; p == pe { + goto _test_eof1908 + } + st_case_1908: + switch data[p] { + case 171: + goto tr126 + case 176: + goto st141 + } + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 169 { + goto tr126 + } + case data[p] >= 139: + goto st141 + } + goto tr125 + st1909: + if p++; p == pe { + goto _test_eof1909 + } + st_case_1909: + switch { + case data[p] < 167: + switch { + case data[p] > 157: + if 159 <= data[p] && data[p] <= 164 { + goto st141 + } + case data[p] >= 150: + goto st141 + } + case data[p] > 168: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + case data[p] >= 170: + goto st141 + } + default: + goto st141 + } + goto tr125 + st1910: + if p++; p == pe { + goto _test_eof1910 + } + st_case_1910: + switch data[p] { + case 143: + goto st141 + case 145: + goto st141 + } + if 176 <= data[p] { + goto st141 + } + goto tr125 + st1911: + if p++; p == pe { + goto _test_eof1911 + } + st_case_1911: + if 139 <= data[p] { + goto tr125 + } + goto st141 + st1912: + if p++; p == pe { + goto _test_eof1912 + } + st_case_1912: + if 166 <= data[p] && data[p] <= 176 { + goto st141 + } + goto tr125 + st1913: + if p++; p == pe { + goto _test_eof1913 + } + st_case_1913: + switch { + case data[p] > 137: + if 171 <= data[p] && data[p] <= 179 { + goto st141 + } + case data[p] >= 128: + goto tr126 + } + goto tr125 + st1914: + if p++; p == pe { + goto _test_eof1914 + } + st_case_1914: + switch data[p] { + case 160: + goto st1915 + case 161: + goto st1916 + case 163: + goto st1917 + case 164: + goto st1918 + case 165: + goto st1919 + case 167: + goto st1921 + case 169: + goto st1922 + case 171: + goto st1923 + case 173: + goto st1925 + case 174: + goto st1926 + case 175: + goto st1927 + case 176: + goto st1928 + case 177: + goto st1929 + case 179: + goto st1930 + case 180: + goto st1931 + case 181: + goto st1932 + case 182: + goto st1933 + case 183: + goto st1934 + case 184: + goto st1935 + case 185: + goto st1936 + case 186: + goto st1937 + case 187: + goto st1938 + case 188: + goto st1939 + case 189: + goto st1940 + case 190: + goto st1941 + case 191: + goto st1942 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto st1924 + } + case data[p] >= 166: + goto st1920 + } + goto tr125 + st1915: + if p++; p == pe { + goto _test_eof1915 + } + st_case_1915: + switch { + case data[p] < 155: + if 150 <= data[p] && data[p] <= 153 { + goto st141 + } + case data[p] > 163: + switch { + case data[p] > 167: + if 169 <= data[p] && data[p] <= 173 { + goto st141 + } + case data[p] >= 165: + goto st141 + } + default: + goto st141 + } + goto tr125 + st1916: + if p++; p == pe { + goto _test_eof1916 + } + st_case_1916: + if 153 <= data[p] && data[p] <= 155 { + goto st141 + } + goto tr125 + st1917: + if p++; p == pe { + goto _test_eof1917 + } + st_case_1917: + if 163 <= data[p] { + goto st141 + } + goto tr125 + st1918: + if p++; p == pe { + goto _test_eof1918 + } + st_case_1918: + if data[p] == 189 { + goto tr125 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr125 + } + goto st141 + st1919: + if p++; p == pe { + goto _test_eof1919 + } + st_case_1919: + if data[p] == 144 { + goto tr125 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr125 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr125 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr125 + } + goto st141 + st1920: + if p++; p == pe { + goto _test_eof1920 + } + st_case_1920: + if data[p] == 188 { + goto st141 + } + switch { + case data[p] > 131: + if 190 <= data[p] { + goto st141 + } + case data[p] >= 129: + goto st141 + } + goto tr125 + st1921: + if p++; p == pe { + goto _test_eof1921 + } + st_case_1921: + switch { + case data[p] < 152: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr125 + } + case data[p] > 138: + if 142 <= data[p] && data[p] <= 150 { + goto tr125 + } + default: + goto tr125 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr125 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr125 + } + default: + goto tr126 + } + default: + goto tr125 + } + goto st141 + st1922: + if p++; p == pe { + goto _test_eof1922 + } + st_case_1922: + switch { + case data[p] < 146: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr125 + } + case data[p] > 138: + if 142 <= data[p] && data[p] <= 144 { + goto tr125 + } + default: + goto tr125 + } + case data[p] > 165: + switch { + case data[p] < 178: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr125 + } + default: + goto tr125 + } + default: + goto tr125 + } + goto st141 + st1923: + if p++; p == pe { + goto _test_eof1923 + } + st_case_1923: + switch data[p] { + case 134: + goto tr125 + case 138: + goto tr125 + } + switch { + case data[p] < 164: + if 142 <= data[p] && data[p] <= 161 { + goto tr125 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr125 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr125 + } + goto st141 + st1924: + if p++; p == pe { + goto _test_eof1924 + } + st_case_1924: + if data[p] == 188 { + goto st141 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto st141 + } + case data[p] >= 129: + goto st141 + } + goto tr125 + st1925: + if p++; p == pe { + goto _test_eof1925 + } + st_case_1925: + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto st141 + } + case data[p] >= 128: + goto st141 + } + case data[p] > 141: + switch { + case data[p] < 162: + if 150 <= data[p] && data[p] <= 151 { + goto st141 + } + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + default: + goto st141 + } + default: + goto st141 + } + goto tr125 + st1926: + if p++; p == pe { + goto _test_eof1926 + } + st_case_1926: + if data[p] == 130 { + goto st141 + } + if 190 <= data[p] && data[p] <= 191 { + goto st141 + } + goto tr125 + st1927: + if p++; p == pe { + goto _test_eof1927 + } + st_case_1927: + if data[p] == 151 { + goto st141 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto st141 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] >= 138: + goto st141 + } + default: + goto st141 + } + goto tr125 + st1928: + if p++; p == pe { + goto _test_eof1928 + } + st_case_1928: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto st141 + } + case data[p] >= 128: + goto st141 + } + goto tr125 + st1929: + if p++; p == pe { + goto _test_eof1929 + } + st_case_1929: + switch data[p] { + case 133: + goto tr125 + case 137: + goto tr125 + } + switch { + case data[p] < 164: + switch { + case data[p] > 148: + if 151 <= data[p] && data[p] <= 161 { + goto tr125 + } + case data[p] >= 142: + goto tr125 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr125 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr125 + } + goto st141 + st1930: + if p++; p == pe { + goto _test_eof1930 + } + st_case_1930: + switch { + case data[p] < 138: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 136 { + goto st141 + } + case data[p] >= 128: + goto st141 + } + case data[p] > 141: + switch { + case data[p] < 162: + if 149 <= data[p] && data[p] <= 150 { + goto st141 + } + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + default: + goto st141 + } + default: + goto st141 + } + goto tr125 + st1931: + if p++; p == pe { + goto _test_eof1931 + } + st_case_1931: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto st141 + } + case data[p] >= 129: + goto st141 + } + goto tr125 + st1932: + if p++; p == pe { + goto _test_eof1932 + } + st_case_1932: + switch data[p] { + case 133: + goto tr125 + case 137: + goto tr125 + } + switch { + case data[p] < 164: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 161 { + goto tr125 + } + case data[p] >= 142: + goto tr125 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr125 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr125 + } + goto st141 + st1933: + if p++; p == pe { + goto _test_eof1933 + } + st_case_1933: + if 130 <= data[p] && data[p] <= 131 { + goto st141 + } + goto tr125 + st1934: + if p++; p == pe { + goto _test_eof1934 + } + st_case_1934: + switch data[p] { + case 138: + goto st141 + case 150: + goto st141 + } + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 148 { + goto st141 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto st141 + } + case data[p] >= 166: + goto tr126 + } + default: + goto st141 + } + goto tr125 + st1935: + if p++; p == pe { + goto _test_eof1935 + } + st_case_1935: + if data[p] == 177 { + goto st141 + } + if 180 <= data[p] && data[p] <= 186 { + goto st141 + } + goto tr125 + st1936: + if p++; p == pe { + goto _test_eof1936 + } + st_case_1936: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 135: + goto st141 + } + goto tr125 + st1937: + if p++; p == pe { + goto _test_eof1937 + } + st_case_1937: + if data[p] == 177 { + goto st141 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto st141 + } + case data[p] >= 180: + goto st141 + } + goto tr125 + st1938: + if p++; p == pe { + goto _test_eof1938 + } + st_case_1938: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 136: + goto st141 + } + goto tr125 + st1939: + if p++; p == pe { + goto _test_eof1939 + } + st_case_1939: + switch data[p] { + case 181: + goto st141 + case 183: + goto st141 + case 185: + goto st141 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto st141 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto st141 + } + default: + goto tr126 + } + goto tr125 + st1940: + if p++; p == pe { + goto _test_eof1940 + } + st_case_1940: + if 177 <= data[p] && data[p] <= 191 { + goto st141 + } + goto tr125 + st1941: + if p++; p == pe { + goto _test_eof1941 + } + st_case_1941: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto st141 + } + case data[p] > 135: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto st141 + } + case data[p] >= 141: + goto st141 + } + default: + goto st141 + } + goto tr125 + st1942: + if p++; p == pe { + goto _test_eof1942 + } + st_case_1942: + if data[p] == 134 { + goto st141 + } + goto tr125 + st1943: + if p++; p == pe { + goto _test_eof1943 + } + st_case_1943: + switch data[p] { + case 128: + goto st1944 + case 129: + goto st1945 + case 130: + goto st1946 + case 141: + goto st1947 + case 156: + goto st1948 + case 157: + goto st1949 + case 158: + goto st1950 + case 159: + goto st1951 + case 160: + goto st1952 + case 162: + goto st1953 + case 164: + goto st1954 + case 165: + goto st1649 + case 167: + goto st1650 + case 168: + goto st1955 + case 169: + goto st1956 + case 170: + goto st1957 + case 172: + goto st1958 + case 173: + goto st1959 + case 174: + goto st1960 + case 175: + goto st1961 + case 176: + goto st1962 + case 177: + goto st1963 + case 179: + goto st1964 + case 183: + goto st1965 + } + goto tr125 + st1944: + if p++; p == pe { + goto _test_eof1944 + } + st_case_1944: + if 171 <= data[p] && data[p] <= 190 { + goto st141 + } + goto tr125 + st1945: + if p++; p == pe { + goto _test_eof1945 + } + st_case_1945: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto st141 + } + case data[p] >= 128: + goto tr126 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto st141 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto st141 + } + default: + goto st141 + } + default: + goto st141 + } + goto tr125 + st1946: + if p++; p == pe { + goto _test_eof1946 + } + st_case_1946: + if data[p] == 143 { + goto st141 + } + switch { + case data[p] < 144: + if 130 <= data[p] && data[p] <= 141 { + goto st141 + } + case data[p] > 153: + if 154 <= data[p] && data[p] <= 157 { + goto st141 + } + default: + goto tr126 + } + goto tr125 + st1947: + if p++; p == pe { + goto _test_eof1947 + } + st_case_1947: + if 157 <= data[p] && data[p] <= 159 { + goto st141 + } + goto tr125 + st1948: + if p++; p == pe { + goto _test_eof1948 + } + st_case_1948: + switch { + case data[p] > 148: + if 178 <= data[p] && data[p] <= 180 { + goto st141 + } + case data[p] >= 146: + goto st141 + } + goto tr125 + st1949: + if p++; p == pe { + goto _test_eof1949 + } + st_case_1949: + switch { + case data[p] > 147: + if 178 <= data[p] && data[p] <= 179 { + goto st141 + } + case data[p] >= 146: + goto st141 + } + goto tr125 + st1950: + if p++; p == pe { + goto _test_eof1950 + } + st_case_1950: + if 180 <= data[p] { + goto st141 + } + goto tr125 + st1951: + if p++; p == pe { + goto _test_eof1951 + } + st_case_1951: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr125 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 170 <= data[p] { + goto tr125 + } + case data[p] >= 160: + goto tr126 + } + default: + goto tr125 + } + goto st141 + st1952: + if p++; p == pe { + goto _test_eof1952 + } + st_case_1952: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 139: + goto st141 + } + goto tr125 + st1953: + if p++; p == pe { + goto _test_eof1953 + } + st_case_1953: + if data[p] == 169 { + goto st141 + } + goto tr125 + st1954: + if p++; p == pe { + goto _test_eof1954 + } + st_case_1954: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto st141 + } + case data[p] >= 160: + goto st141 + } + goto tr125 + st1955: + if p++; p == pe { + goto _test_eof1955 + } + st_case_1955: + if 151 <= data[p] && data[p] <= 155 { + goto st141 + } + goto tr125 + st1956: + if p++; p == pe { + goto _test_eof1956 + } + st_case_1956: + if data[p] == 191 { + goto st141 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto st141 + } + case data[p] >= 149: + goto st141 + } + goto tr125 + st1957: + if p++; p == pe { + goto _test_eof1957 + } + st_case_1957: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto st141 + } + default: + goto tr126 + } + goto tr125 + st1958: + if p++; p == pe { + goto _test_eof1958 + } + st_case_1958: + switch { + case data[p] > 132: + if 180 <= data[p] { + goto st141 + } + case data[p] >= 128: + goto st141 + } + goto tr125 + st1959: + if p++; p == pe { + goto _test_eof1959 + } + st_case_1959: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr125 + } + case data[p] > 153: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr125 + } + case data[p] >= 154: + goto tr125 + } + default: + goto tr126 + } + goto st141 + st1960: + if p++; p == pe { + goto _test_eof1960 + } + st_case_1960: + switch { + case data[p] < 161: + if 128 <= data[p] && data[p] <= 130 { + goto st141 + } + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + default: + goto st141 + } + goto tr125 + st1961: + if p++; p == pe { + goto _test_eof1961 + } + st_case_1961: + if 166 <= data[p] && data[p] <= 179 { + goto st141 + } + goto tr125 + st1962: + if p++; p == pe { + goto _test_eof1962 + } + st_case_1962: + if 164 <= data[p] && data[p] <= 183 { + goto st141 + } + goto tr125 + st1963: + if p++; p == pe { + goto _test_eof1963 + } + st_case_1963: + switch { + case data[p] > 137: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 128: + goto tr126 + } + goto tr125 + st1964: + if p++; p == pe { + goto _test_eof1964 + } + st_case_1964: + if data[p] == 173 { + goto st141 + } + switch { + case data[p] < 148: + if 144 <= data[p] && data[p] <= 146 { + goto st141 + } + case data[p] > 168: + switch { + case data[p] > 180: + if 184 <= data[p] && data[p] <= 185 { + goto st141 + } + case data[p] >= 178: + goto st141 + } + default: + goto st141 + } + goto tr125 + st1965: + if p++; p == pe { + goto _test_eof1965 + } + st_case_1965: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto st141 + } + case data[p] >= 128: + goto st141 + } + goto tr125 + st1966: + if p++; p == pe { + goto _test_eof1966 + } + st_case_1966: + switch data[p] { + case 128: + goto st1967 + case 129: + goto st1968 + case 131: + goto st1969 + case 179: + goto st1970 + case 181: + goto st1971 + case 183: + goto st1972 + } + goto tr125 + st1967: + if p++; p == pe { + goto _test_eof1967 + } + st_case_1967: + switch { + case data[p] > 143: + if 170 <= data[p] && data[p] <= 174 { + goto st141 + } + case data[p] >= 140: + goto st141 + } + goto tr125 + st1968: + if p++; p == pe { + goto _test_eof1968 + } + st_case_1968: + switch { + case data[p] > 164: + if 166 <= data[p] && data[p] <= 175 { + goto st141 + } + case data[p] >= 160: + goto st141 + } + goto tr125 + st1969: + if p++; p == pe { + goto _test_eof1969 + } + st_case_1969: + if 144 <= data[p] && data[p] <= 176 { + goto st141 + } + goto tr125 + st1970: + if p++; p == pe { + goto _test_eof1970 + } + st_case_1970: + if 175 <= data[p] && data[p] <= 177 { + goto st141 + } + goto tr125 + st1971: + if p++; p == pe { + goto _test_eof1971 + } + st_case_1971: + if data[p] == 191 { + goto st141 + } + goto tr125 + st1972: + if p++; p == pe { + goto _test_eof1972 + } + st_case_1972: + if 160 <= data[p] && data[p] <= 191 { + goto st141 + } + goto tr125 + st1973: + if p++; p == pe { + goto _test_eof1973 + } + st_case_1973: + switch data[p] { + case 128: + goto st1974 + case 130: + goto st1975 + } + goto tr125 + st1974: + if p++; p == pe { + goto _test_eof1974 + } + st_case_1974: + if 170 <= data[p] && data[p] <= 175 { + goto st141 + } + goto tr125 + st1975: + if p++; p == pe { + goto _test_eof1975 + } + st_case_1975: + if 153 <= data[p] && data[p] <= 154 { + goto st141 + } + goto tr125 + st1976: + if p++; p == pe { + goto _test_eof1976 + } + st_case_1976: + switch data[p] { + case 152: + goto st1977 + case 153: + goto st1978 + case 154: + goto st1979 + case 155: + goto st1980 + case 160: + goto st1981 + case 162: + goto st1982 + case 163: + goto st1983 + case 164: + goto st1984 + case 165: + goto st1985 + case 166: + goto st1986 + case 167: + goto st1987 + case 168: + goto st1988 + case 169: + goto st1989 + case 170: + goto st1990 + case 171: + goto st1991 + case 175: + goto st1992 + } + goto tr125 + st1977: + if p++; p == pe { + goto _test_eof1977 + } + st_case_1977: + if 160 <= data[p] && data[p] <= 169 { + goto tr126 + } + goto tr125 + st1978: + if p++; p == pe { + goto _test_eof1978 + } + st_case_1978: + switch { + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto st141 + } + case data[p] >= 175: + goto st141 + } + goto tr125 + st1979: + if p++; p == pe { + goto _test_eof1979 + } + st_case_1979: + if 158 <= data[p] && data[p] <= 159 { + goto st141 + } + goto tr125 + st1980: + if p++; p == pe { + goto _test_eof1980 + } + st_case_1980: + if 176 <= data[p] && data[p] <= 177 { + goto st141 + } + goto tr125 + st1981: + if p++; p == pe { + goto _test_eof1981 + } + st_case_1981: + switch data[p] { + case 130: + goto st141 + case 134: + goto st141 + case 139: + goto st141 + } + if 163 <= data[p] && data[p] <= 167 { + goto st141 + } + goto tr125 + st1982: + if p++; p == pe { + goto _test_eof1982 + } + st_case_1982: + switch { + case data[p] > 129: + if 180 <= data[p] { + goto st141 + } + case data[p] >= 128: + goto st141 + } + goto tr125 + st1983: + if p++; p == pe { + goto _test_eof1983 + } + st_case_1983: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr125 + } + case data[p] > 153: + switch { + case data[p] > 159: + if 178 <= data[p] { + goto tr125 + } + case data[p] >= 154: + goto tr125 + } + default: + goto tr126 + } + goto st141 + st1984: + if p++; p == pe { + goto _test_eof1984 + } + st_case_1984: + switch { + case data[p] > 137: + if 166 <= data[p] && data[p] <= 173 { + goto st141 + } + case data[p] >= 128: + goto tr126 + } + goto tr125 + st1985: + if p++; p == pe { + goto _test_eof1985 + } + st_case_1985: + if 135 <= data[p] && data[p] <= 147 { + goto st141 + } + goto tr125 + st1986: + if p++; p == pe { + goto _test_eof1986 + } + st_case_1986: + switch { + case data[p] > 131: + if 179 <= data[p] { + goto st141 + } + case data[p] >= 128: + goto st141 + } + goto tr125 + st1987: + if p++; p == pe { + goto _test_eof1987 + } + st_case_1987: + switch { + case data[p] < 154: + switch { + case data[p] > 143: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 129: + goto tr125 + } + case data[p] > 164: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr125 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr125 + } + default: + goto tr126 + } + default: + goto tr125 + } + goto st141 + st1988: + if p++; p == pe { + goto _test_eof1988 + } + st_case_1988: + if 169 <= data[p] && data[p] <= 182 { + goto st141 + } + goto tr125 + st1989: + if p++; p == pe { + goto _test_eof1989 + } + st_case_1989: + if data[p] == 131 { + goto st141 + } + switch { + case data[p] < 144: + if 140 <= data[p] && data[p] <= 141 { + goto st141 + } + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto st141 + } + default: + goto tr126 + } + goto tr125 + st1990: + if p++; p == pe { + goto _test_eof1990 + } + st_case_1990: + if data[p] == 176 { + goto st141 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto st141 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto st141 + } + default: + goto st141 + } + goto tr125 + st1991: + if p++; p == pe { + goto _test_eof1991 + } + st_case_1991: + if data[p] == 129 { + goto st141 + } + switch { + case data[p] > 175: + if 181 <= data[p] && data[p] <= 182 { + goto st141 + } + case data[p] >= 171: + goto st141 + } + goto tr125 + st1992: + if p++; p == pe { + goto _test_eof1992 + } + st_case_1992: + switch { + case data[p] < 172: + if 163 <= data[p] && data[p] <= 170 { + goto st141 + } + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + default: + goto st141 + } + goto tr125 + st1993: + if p++; p == pe { + goto _test_eof1993 + } + st_case_1993: + switch data[p] { + case 172: + goto st1994 + case 184: + goto st1995 + case 187: + goto st1971 + case 190: + goto st1979 + case 191: + goto st1996 + } + goto tr125 + st1994: + if p++; p == pe { + goto _test_eof1994 + } + st_case_1994: + if data[p] == 158 { + goto st141 + } + goto tr125 + st1995: + if p++; p == pe { + goto _test_eof1995 + } + st_case_1995: + switch { + case data[p] > 143: + if 160 <= data[p] && data[p] <= 175 { + goto st141 + } + case data[p] >= 128: + goto st141 + } + goto tr125 + st1996: + if p++; p == pe { + goto _test_eof1996 + } + st_case_1996: + if 185 <= data[p] && data[p] <= 187 { + goto st141 + } + goto tr125 + st1997: + if p++; p == pe { + goto _test_eof1997 + } + st_case_1997: + switch data[p] { + case 144: + goto st1998 + case 145: + goto st2004 + case 150: + goto st2024 + case 155: + goto st2029 + case 157: + goto st2031 + case 158: + goto st2039 + } + goto tr125 + st1998: + if p++; p == pe { + goto _test_eof1998 + } + st_case_1998: + switch data[p] { + case 135: + goto st1999 + case 139: + goto st2000 + case 141: + goto st2001 + case 146: + goto st1977 + case 168: + goto st2002 + case 171: + goto st2003 + } + goto tr125 + st1999: + if p++; p == pe { + goto _test_eof1999 + } + st_case_1999: + if data[p] == 189 { + goto st141 + } + goto tr125 + st2000: + if p++; p == pe { + goto _test_eof2000 + } + st_case_2000: + if data[p] == 160 { + goto st141 + } + goto tr125 + st2001: + if p++; p == pe { + goto _test_eof2001 + } + st_case_2001: + if 182 <= data[p] && data[p] <= 186 { + goto st141 + } + goto tr125 + st2002: + if p++; p == pe { + goto _test_eof2002 + } + st_case_2002: + if data[p] == 191 { + goto st141 + } + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto st141 + } + case data[p] > 134: + switch { + case data[p] > 143: + if 184 <= data[p] && data[p] <= 186 { + goto st141 + } + case data[p] >= 140: + goto st141 + } + default: + goto st141 + } + goto tr125 + st2003: + if p++; p == pe { + goto _test_eof2003 + } + st_case_2003: + if 165 <= data[p] && data[p] <= 166 { + goto st141 + } + goto tr125 + st2004: + if p++; p == pe { + goto _test_eof2004 + } + st_case_2004: + switch data[p] { + case 128: + goto st2005 + case 129: + goto st2006 + case 130: + goto st2007 + case 131: + goto st2008 + case 132: + goto st2009 + case 133: + goto st2010 + case 134: + goto st2011 + case 135: + goto st2012 + case 136: + goto st2013 + case 139: + goto st2014 + case 140: + goto st2015 + case 141: + goto st2016 + case 146: + goto st2017 + case 147: + goto st2018 + case 150: + goto st2019 + case 151: + goto st2020 + case 152: + goto st2017 + case 153: + goto st2021 + case 154: + goto st2022 + case 155: + goto st1724 + case 156: + goto st2023 + case 163: + goto st1977 + } + goto tr125 + st2005: + if p++; p == pe { + goto _test_eof2005 + } + st_case_2005: + switch { + case data[p] > 130: + if 184 <= data[p] { + goto st141 + } + case data[p] >= 128: + goto st141 + } + goto tr125 + st2006: + if p++; p == pe { + goto _test_eof2006 + } + st_case_2006: + switch { + case data[p] < 166: + if 135 <= data[p] && data[p] <= 165 { + goto tr125 + } + case data[p] > 175: + if 176 <= data[p] && data[p] <= 190 { + goto tr125 + } + default: + goto tr126 + } + goto st141 + st2007: + if p++; p == pe { + goto _test_eof2007 + } + st_case_2007: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr125 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr125 + } + default: + goto tr125 + } + goto st141 + st2008: + if p++; p == pe { + goto _test_eof2008 + } + st_case_2008: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + goto tr125 + st2009: + if p++; p == pe { + goto _test_eof2009 + } + st_case_2009: + switch { + case data[p] < 167: + if 128 <= data[p] && data[p] <= 130 { + goto st141 + } + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr126 + } + default: + goto st141 + } + goto tr125 + st2010: + if p++; p == pe { + goto _test_eof2010 + } + st_case_2010: + if data[p] == 179 { + goto st141 + } + goto tr125 + st2011: + if p++; p == pe { + goto _test_eof2011 + } + st_case_2011: + switch { + case data[p] > 130: + if 179 <= data[p] { + goto st141 + } + case data[p] >= 128: + goto st141 + } + goto tr125 + st2012: + if p++; p == pe { + goto _test_eof2012 + } + st_case_2012: + switch { + case data[p] < 141: + if 129 <= data[p] && data[p] <= 137 { + goto tr125 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] { + goto tr125 + } + case data[p] >= 144: + goto tr126 + } + default: + goto tr125 + } + goto st141 + st2013: + if p++; p == pe { + goto _test_eof2013 + } + st_case_2013: + if 172 <= data[p] && data[p] <= 183 { + goto st141 + } + goto tr125 + st2014: + if p++; p == pe { + goto _test_eof2014 + } + st_case_2014: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + case data[p] >= 159: + goto st141 + } + goto tr125 + st2015: + if p++; p == pe { + goto _test_eof2015 + } + st_case_2015: + if data[p] == 188 { + goto st141 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto st141 + } + case data[p] >= 128: + goto st141 + } + goto tr125 + st2016: + if p++; p == pe { + goto _test_eof2016 + } + st_case_2016: + if data[p] == 151 { + goto st141 + } + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto st141 + } + case data[p] >= 128: + goto st141 + } + case data[p] > 141: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto st141 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto st141 + } + default: + goto st141 + } + default: + goto st141 + } + goto tr125 + st2017: + if p++; p == pe { + goto _test_eof2017 + } + st_case_2017: + if 176 <= data[p] { + goto st141 + } + goto tr125 + st2018: + if p++; p == pe { + goto _test_eof2018 + } + st_case_2018: + switch { + case data[p] < 144: + if 132 <= data[p] && data[p] <= 143 { + goto tr125 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr125 + } + default: + goto tr126 + } + goto st141 + st2019: + if p++; p == pe { + goto _test_eof2019 + } + st_case_2019: + switch { + case data[p] > 181: + if 184 <= data[p] { + goto st141 + } + case data[p] >= 175: + goto st141 + } + goto tr125 + st2020: + if p++; p == pe { + goto _test_eof2020 + } + st_case_2020: + switch { + case data[p] > 155: + if 158 <= data[p] { + goto tr125 + } + case data[p] >= 129: + goto tr125 + } + goto st141 + st2021: + if p++; p == pe { + goto _test_eof2021 + } + st_case_2021: + switch { + case data[p] < 144: + if 129 <= data[p] && data[p] <= 143 { + goto tr125 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr125 + } + default: + goto tr126 + } + goto st141 + st2022: + if p++; p == pe { + goto _test_eof2022 + } + st_case_2022: + if 171 <= data[p] && data[p] <= 183 { + goto st141 + } + goto tr125 + st2023: + if p++; p == pe { + goto _test_eof2023 + } + st_case_2023: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + case data[p] >= 157: + goto st141 + } + goto tr125 + st2024: + if p++; p == pe { + goto _test_eof2024 + } + st_case_2024: + switch data[p] { + case 169: + goto st1977 + case 171: + goto st2025 + case 172: + goto st2026 + case 173: + goto st1650 + case 189: + goto st2027 + case 190: + goto st2028 + } + goto tr125 + st2025: + if p++; p == pe { + goto _test_eof2025 + } + st_case_2025: + if 176 <= data[p] && data[p] <= 180 { + goto st141 + } + goto tr125 + st2026: + if p++; p == pe { + goto _test_eof2026 + } + st_case_2026: + if 176 <= data[p] && data[p] <= 182 { + goto st141 + } + goto tr125 + st2027: + if p++; p == pe { + goto _test_eof2027 + } + st_case_2027: + if 145 <= data[p] && data[p] <= 190 { + goto st141 + } + goto tr125 + st2028: + if p++; p == pe { + goto _test_eof2028 + } + st_case_2028: + if 143 <= data[p] && data[p] <= 146 { + goto st141 + } + goto tr125 + st2029: + if p++; p == pe { + goto _test_eof2029 + } + st_case_2029: + if data[p] == 178 { + goto st2030 + } + goto tr125 + st2030: + if p++; p == pe { + goto _test_eof2030 + } + st_case_2030: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto st141 + } + case data[p] >= 157: + goto st141 + } + goto tr125 + st2031: + if p++; p == pe { + goto _test_eof2031 + } + st_case_2031: + switch data[p] { + case 133: + goto st2032 + case 134: + goto st2033 + case 137: + goto st2034 + case 159: + goto st2035 + case 168: + goto st2036 + case 169: + goto st2037 + case 170: + goto st2038 + } + goto tr125 + st2032: + if p++; p == pe { + goto _test_eof2032 + } + st_case_2032: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto st141 + } + case data[p] >= 165: + goto st141 + } + goto tr125 + st2033: + if p++; p == pe { + goto _test_eof2033 + } + st_case_2033: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr125 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr125 + } + default: + goto tr125 + } + goto st141 + st2034: + if p++; p == pe { + goto _test_eof2034 + } + st_case_2034: + if 130 <= data[p] && data[p] <= 132 { + goto st141 + } + goto tr125 + st2035: + if p++; p == pe { + goto _test_eof2035 + } + st_case_2035: + if 142 <= data[p] && data[p] <= 191 { + goto tr126 + } + goto tr125 + st2036: + if p++; p == pe { + goto _test_eof2036 + } + st_case_2036: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto st141 + } + case data[p] >= 128: + goto st141 + } + goto tr125 + st2037: + if p++; p == pe { + goto _test_eof2037 + } + st_case_2037: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr125 + } + case data[p] >= 173: + goto tr125 + } + goto st141 + st2038: + if p++; p == pe { + goto _test_eof2038 + } + st_case_2038: + if data[p] == 132 { + goto st141 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto st141 + } + case data[p] >= 155: + goto st141 + } + goto tr125 + st2039: + if p++; p == pe { + goto _test_eof2039 + } + st_case_2039: + if data[p] == 163 { + goto st2040 + } + goto tr125 + st2040: + if p++; p == pe { + goto _test_eof2040 + } + st_case_2040: + if 144 <= data[p] && data[p] <= 150 { + goto st141 + } + goto tr125 + st2041: + if p++; p == pe { + goto _test_eof2041 + } + st_case_2041: + if data[p] == 160 { + goto st2042 + } + goto tr125 + st2042: + if p++; p == pe { + goto _test_eof2042 + } + st_case_2042: + switch data[p] { + case 128: + goto st2043 + case 129: + goto st2044 + case 132: + goto st1902 + case 135: + goto st1903 + } + if 133 <= data[p] && data[p] <= 134 { + goto st2045 + } + goto tr125 + st2043: + if p++; p == pe { + goto _test_eof2043 + } + st_case_2043: + if data[p] == 129 { + goto st141 + } + if 160 <= data[p] { + goto st141 + } + goto tr125 + st2044: + if p++; p == pe { + goto _test_eof2044 + } + st_case_2044: + if 192 <= data[p] { + goto tr125 + } + goto st141 + st2045: + if p++; p == pe { + goto _test_eof2045 + } + st_case_2045: + goto st141 + st2046: + if p++; p == pe { + goto _test_eof2046 + } + st_case_2046: + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr1880 + case 181: + goto tr148 + case 186: + goto tr148 + } + goto tr125 + st2047: + if p++; p == pe { + goto _test_eof2047 + } + st_case_2047: + if data[p] <= 127 { + goto tr125 + } + goto tr1880 + st2048: + if p++; p == pe { + goto _test_eof2048 + } + st_case_2048: + switch data[p] { + case 181: + goto tr125 + case 190: + goto st141 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr125 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr125 + } + goto tr1880 + st2049: + if p++; p == pe { + goto _test_eof2049 + } + st_case_2049: + if data[p] == 130 { + goto tr125 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr1880 + } + goto tr148 + st2050: + if p++; p == pe { + goto _test_eof2050 + } + st_case_2050: + switch data[p] { + case 137: + goto st141 + case 190: + goto tr125 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr125 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr125 + } + default: + goto tr1880 + } + goto tr148 + st2051: + if p++; p == pe { + goto _test_eof2051 + } + st_case_2051: + switch data[p] { + case 135: + goto tr1880 + case 179: + goto tr148 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr1880 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr1880 + } + goto tr125 + st2052: + if p++; p == pe { + goto _test_eof2052 + } + st_case_2052: + if data[p] == 156 { + goto tr1880 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 133 { + goto tr1880 + } + case data[p] > 141: + switch { + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + case data[p] >= 144: + goto tr1880 + } + default: + goto st141 + } + goto tr125 + st2053: + if p++; p == pe { + goto _test_eof2053 + } + st_case_2053: + switch data[p] { + case 171: + goto tr126 + case 172: + goto st141 + case 176: + goto tr1880 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + case data[p] >= 160: + goto tr126 + } + default: + goto tr1880 + } + goto tr125 + st2054: + if p++; p == pe { + goto _test_eof2054 + } + st_case_2054: + switch data[p] { + case 148: + goto tr125 + case 158: + goto tr125 + case 169: + goto tr125 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr1880 + } + case data[p] >= 150: + goto tr1880 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr125 + } + case data[p] >= 189: + goto tr125 + } + default: + goto tr126 + } + goto tr148 + st2055: + if p++; p == pe { + goto _test_eof2055 + } + st_case_2055: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto tr1880 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr1880 + } + default: + goto tr148 + } + goto tr125 + st2056: + if p++; p == pe { + goto _test_eof2056 + } + st_case_2056: + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr125 + } + goto tr1880 + st2057: + if p++; p == pe { + goto _test_eof2057 + } + st_case_2057: + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr125 + } + case data[p] >= 166: + goto tr1880 + } + goto tr148 + st2058: + if p++; p == pe { + goto _test_eof2058 + } + st_case_2058: + switch data[p] { + case 184: + goto st141 + case 186: + goto tr148 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 170: + switch { + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 171: + goto tr1880 + } + default: + goto tr148 + } + goto tr125 + st2059: + if p++; p == pe { + goto _test_eof2059 + } + st_case_2059: + switch data[p] { + case 160: + goto st2060 + case 161: + goto st2061 + case 162: + goto st168 + case 163: + goto st2062 + case 164: + goto st2063 + case 165: + goto st2064 + case 166: + goto st2065 + case 167: + goto st2066 + case 168: + goto st2067 + case 169: + goto st2068 + case 170: + goto st2069 + case 171: + goto st2070 + case 172: + goto st2071 + case 173: + goto st2072 + case 174: + goto st2073 + case 175: + goto st2074 + case 176: + goto st2075 + case 177: + goto st2076 + case 178: + goto st2077 + case 179: + goto st2078 + case 180: + goto st2079 + case 181: + goto st2080 + case 182: + goto st2081 + case 183: + goto st2082 + case 184: + goto st2083 + case 185: + goto st2084 + case 186: + goto st2085 + case 187: + goto st2086 + case 188: + goto st2087 + case 189: + goto st2088 + case 190: + goto st2089 + case 191: + goto st2090 + } + goto tr125 + st2060: + if p++; p == pe { + goto _test_eof2060 + } + st_case_2060: + switch data[p] { + case 154: + goto tr148 + case 164: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] > 149: + if 150 <= data[p] && data[p] <= 173 { + goto tr1880 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st2061: + if p++; p == pe { + goto _test_eof2061 + } + st_case_2061: + switch { + case data[p] > 152: + if 153 <= data[p] && data[p] <= 155 { + goto tr1880 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st2062: + if p++; p == pe { + goto _test_eof2062 + } + st_case_2062: + if 163 <= data[p] { + goto tr1880 + } + goto tr125 + st2063: + if p++; p == pe { + goto _test_eof2063 + } + st_case_2063: + if data[p] == 189 { + goto tr148 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr148 + } + goto tr1880 + st2064: + if p++; p == pe { + goto _test_eof2064 + } + st_case_2064: + switch data[p] { + case 144: + goto tr148 + case 176: + goto tr125 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 177 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr125 + } + goto tr1880 + st2065: + if p++; p == pe { + goto _test_eof2065 + } + st_case_2065: + switch data[p] { + case 132: + goto tr125 + case 169: + goto tr125 + case 177: + goto tr125 + case 188: + goto tr1880 + } + switch { + case data[p] < 145: + switch { + case data[p] > 131: + if 141 <= data[p] && data[p] <= 142 { + goto tr125 + } + case data[p] >= 129: + goto tr1880 + } + case data[p] > 146: + switch { + case data[p] < 186: + if 179 <= data[p] && data[p] <= 181 { + goto tr125 + } + case data[p] > 187: + if 190 <= data[p] { + goto tr1880 + } + default: + goto tr125 + } + default: + goto tr125 + } + goto tr148 + st2066: + if p++; p == pe { + goto _test_eof2066 + } + st_case_2066: + switch data[p] { + case 142: + goto tr148 + case 158: + goto tr125 + } + switch { + case data[p] < 156: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr125 + } + case data[p] > 138: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 155 { + goto tr125 + } + case data[p] >= 143: + goto tr125 + } + default: + goto tr125 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr125 + } + case data[p] > 175: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr125 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr126 + } + default: + goto tr148 + } + goto tr1880 + st2067: + if p++; p == pe { + goto _test_eof2067 + } + st_case_2067: + if data[p] == 188 { + goto tr1880 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr1880 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto tr1880 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st2068: + if p++; p == pe { + goto _test_eof2068 + } + st_case_2068: + if data[p] == 157 { + goto tr125 + } + switch { + case data[p] < 153: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr125 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 146 <= data[p] && data[p] <= 152 { + goto tr125 + } + case data[p] >= 142: + goto tr125 + } + default: + goto tr125 + } + case data[p] > 158: + switch { + case data[p] < 166: + if 159 <= data[p] && data[p] <= 165 { + goto tr125 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr125 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr126 + } + default: + goto tr148 + } + goto tr1880 + st2069: + if p++; p == pe { + goto _test_eof2069 + } + st_case_2069: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr1880 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto tr1880 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st2070: + if p++; p == pe { + goto _test_eof2070 + } + st_case_2070: + switch data[p] { + case 134: + goto tr125 + case 138: + goto tr125 + case 144: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] >= 142: + goto tr125 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr125 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr125 + } + goto tr1880 + st2071: + if p++; p == pe { + goto _test_eof2071 + } + st_case_2071: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr1880 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr1880 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st2072: + if p++; p == pe { + goto _test_eof2072 + } + st_case_2072: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr1880 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr1880 + } + default: + goto tr1880 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 161: + switch { + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] >= 162: + goto tr1880 + } + default: + goto tr148 + } + default: + goto tr1880 + } + goto tr125 + st2073: + if p++; p == pe { + goto _test_eof2073 + } + st_case_2073: + switch data[p] { + case 130: + goto tr1880 + case 131: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 158: + switch { + case data[p] < 142: + if 133 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 149: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] < 168: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto tr1880 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st2074: + if p++; p == pe { + goto _test_eof2074 + } + st_case_2074: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr1880 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr1880 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] >= 138: + goto tr1880 + } + default: + goto tr1880 + } + goto tr125 + st2075: + if p++; p == pe { + goto _test_eof2075 + } + st_case_2075: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto tr1880 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 190 <= data[p] { + goto tr1880 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st2076: + if p++; p == pe { + goto _test_eof2076 + } + st_case_2076: + switch data[p] { + case 133: + goto tr125 + case 137: + goto tr125 + case 151: + goto tr125 + } + switch { + case data[p] < 160: + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 148 { + goto tr125 + } + case data[p] > 154: + if 155 <= data[p] && data[p] <= 159 { + goto tr125 + } + default: + goto tr148 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr125 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr125 + } + default: + goto tr126 + } + default: + goto tr148 + } + goto tr1880 + st2077: + if p++; p == pe { + goto _test_eof2077 + } + st_case_2077: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr1880 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr1880 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st2078: + if p++; p == pe { + goto _test_eof2078 + } + st_case_2078: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr1880 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr1880 + } + default: + goto tr1880 + } + case data[p] > 150: + switch { + case data[p] < 162: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 163: + switch { + case data[p] > 175: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr1880 + } + default: + goto tr1880 + } + goto tr125 + st2079: + if p++; p == pe { + goto _test_eof2079 + } + st_case_2079: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto tr1880 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto tr1880 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st2080: + if p++; p == pe { + goto _test_eof2080 + } + st_case_2080: + switch data[p] { + case 133: + goto tr125 + case 137: + goto tr125 + case 142: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 150 { + goto tr125 + } + case data[p] > 158: + if 159 <= data[p] && data[p] <= 161 { + goto tr148 + } + default: + goto tr125 + } + case data[p] > 165: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr125 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr125 + } + default: + goto tr125 + } + goto tr1880 + st2081: + if p++; p == pe { + goto _test_eof2081 + } + st_case_2081: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr1880 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st2082: + if p++; p == pe { + goto _test_eof2082 + } + st_case_2082: + switch data[p] { + case 138: + goto tr1880 + case 150: + goto tr1880 + } + switch { + case data[p] < 152: + switch { + case data[p] > 134: + if 143 <= data[p] && data[p] <= 148 { + goto tr1880 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto tr1880 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr1880 + } + goto tr125 + st2083: + if p++; p == pe { + goto _test_eof2083 + } + st_case_2083: + if data[p] == 177 { + goto tr1880 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr1880 + } + goto tr125 + st2084: + if p++; p == pe { + goto _test_eof2084 + } + st_case_2084: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 135: + goto tr1880 + } + goto tr125 + st2085: + if p++; p == pe { + goto _test_eof2085 + } + st_case_2085: + if data[p] == 177 { + goto tr1880 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr1880 + } + case data[p] >= 180: + goto tr1880 + } + goto tr125 + st2086: + if p++; p == pe { + goto _test_eof2086 + } + st_case_2086: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 136: + goto tr1880 + } + goto tr125 + st2087: + if p++; p == pe { + goto _test_eof2087 + } + st_case_2087: + switch data[p] { + case 128: + goto tr148 + case 181: + goto tr1880 + case 183: + goto tr1880 + case 185: + goto tr1880 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto tr1880 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto tr1880 + } + default: + goto tr126 + } + goto tr125 + st2088: + if p++; p == pe { + goto _test_eof2088 + } + st_case_2088: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto tr1880 + } + default: + goto tr148 + } + goto tr125 + st2089: + if p++; p == pe { + goto _test_eof2089 + } + st_case_2089: + switch { + case data[p] < 136: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 135 { + goto tr1880 + } + case data[p] >= 128: + goto tr1880 + } + case data[p] > 140: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr1880 + } + case data[p] >= 141: + goto tr1880 + } + default: + goto tr148 + } + goto tr125 + st2090: + if p++; p == pe { + goto _test_eof2090 + } + st_case_2090: + if data[p] == 134 { + goto tr1880 + } + goto tr125 + st2091: + if p++; p == pe { + goto _test_eof2091 + } + st_case_2091: + switch data[p] { + case 128: + goto st2092 + case 129: + goto st2093 + case 130: + goto st2094 + case 131: + goto st202 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st2095 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st2096 + case 157: + goto st2097 + case 158: + goto st2098 + case 159: + goto st2099 + case 160: + goto st2100 + case 161: + goto st219 + case 162: + goto st2101 + case 163: + goto st221 + case 164: + goto st2102 + case 165: + goto st1649 + case 167: + goto st1650 + case 168: + goto st2103 + case 169: + goto st2104 + case 170: + goto st2105 + case 172: + goto st2106 + case 173: + goto st2107 + case 174: + goto st2108 + case 175: + goto st2109 + case 176: + goto st2110 + case 177: + goto st1659 + case 179: + goto st2111 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st2112 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + } + switch { + case data[p] < 180: + if 132 <= data[p] && data[p] <= 152 { + goto st145 + } + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + default: + goto st147 + } + goto tr125 + st2092: + if p++; p == pe { + goto _test_eof2092 + } + st_case_2092: + if 171 <= data[p] && data[p] <= 190 { + goto tr1880 + } + goto tr125 + st2093: + if p++; p == pe { + goto _test_eof2093 + } + st_case_2093: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto tr1880 + } + case data[p] >= 128: + goto tr126 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto tr1880 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr1880 + } + default: + goto tr1880 + } + default: + goto tr1880 + } + goto tr125 + st2094: + if p++; p == pe { + goto _test_eof2094 + } + st_case_2094: + if data[p] == 143 { + goto tr1880 + } + switch { + case data[p] < 144: + if 130 <= data[p] && data[p] <= 141 { + goto tr1880 + } + case data[p] > 153: + switch { + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 154: + goto tr1880 + } + default: + goto tr126 + } + goto tr125 + st2095: + if p++; p == pe { + goto _test_eof2095 + } + st_case_2095: + switch { + case data[p] < 157: + if 155 <= data[p] && data[p] <= 156 { + goto tr125 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr125 + } + default: + goto tr1880 + } + goto tr148 + st2096: + if p++; p == pe { + goto _test_eof2096 + } + st_case_2096: + switch { + case data[p] < 146: + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 177: + if 178 <= data[p] && data[p] <= 180 { + goto tr1880 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr1880 + } + goto tr125 + st2097: + if p++; p == pe { + goto _test_eof2097 + } + st_case_2097: + switch { + case data[p] < 160: + switch { + case data[p] > 145: + if 146 <= data[p] && data[p] <= 147 { + goto tr1880 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto tr1880 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st2098: + if p++; p == pe { + goto _test_eof2098 + } + st_case_2098: + if 180 <= data[p] { + goto tr1880 + } + goto tr125 + st2099: + if p++; p == pe { + goto _test_eof2099 + } + st_case_2099: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr125 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 170 <= data[p] { + goto tr125 + } + case data[p] >= 160: + goto tr126 + } + default: + goto tr125 + } + goto tr1880 + st2100: + if p++; p == pe { + goto _test_eof2100 + } + st_case_2100: + switch { + case data[p] < 144: + if 139 <= data[p] && data[p] <= 142 { + goto tr1880 + } + case data[p] > 153: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr126 + } + goto tr125 + st2101: + if p++; p == pe { + goto _test_eof2101 + } + st_case_2101: + if data[p] == 169 { + goto tr1880 + } + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st2102: + if p++; p == pe { + goto _test_eof2102 + } + st_case_2102: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr1880 + } + default: + goto tr1880 + } + goto tr125 + st2103: + if p++; p == pe { + goto _test_eof2103 + } + st_case_2103: + switch { + case data[p] > 150: + if 151 <= data[p] && data[p] <= 155 { + goto tr1880 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st2104: + if p++; p == pe { + goto _test_eof2104 + } + st_case_2104: + if data[p] == 191 { + goto tr1880 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr1880 + } + case data[p] >= 149: + goto tr1880 + } + goto tr125 + st2105: + if p++; p == pe { + goto _test_eof2105 + } + st_case_2105: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto tr1880 + } + default: + goto tr126 + } + goto tr125 + st2106: + if p++; p == pe { + goto _test_eof2106 + } + st_case_2106: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 132 { + goto tr1880 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr1880 + } + default: + goto tr148 + } + goto tr125 + st2107: + if p++; p == pe { + goto _test_eof2107 + } + st_case_2107: + switch { + case data[p] < 144: + switch { + case data[p] > 139: + if 140 <= data[p] && data[p] <= 143 { + goto tr125 + } + case data[p] >= 133: + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr125 + } + case data[p] >= 154: + goto tr125 + } + default: + goto tr126 + } + goto tr1880 + st2108: + if p++; p == pe { + goto _test_eof2108 + } + st_case_2108: + switch { + case data[p] < 161: + switch { + case data[p] > 130: + if 131 <= data[p] && data[p] <= 160 { + goto tr148 + } + case data[p] >= 128: + goto tr1880 + } + case data[p] > 173: + switch { + case data[p] < 176: + if 174 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr148 + } + default: + goto tr126 + } + default: + goto tr1880 + } + goto tr125 + st2109: + if p++; p == pe { + goto _test_eof2109 + } + st_case_2109: + switch { + case data[p] > 179: + if 180 <= data[p] { + goto tr125 + } + case data[p] >= 166: + goto tr1880 + } + goto tr148 + st2110: + if p++; p == pe { + goto _test_eof2110 + } + st_case_2110: + switch { + case data[p] > 163: + if 164 <= data[p] && data[p] <= 183 { + goto tr1880 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st2111: + if p++; p == pe { + goto _test_eof2111 + } + st_case_2111: + if data[p] == 173 { + goto tr1880 + } + switch { + case data[p] < 169: + switch { + case data[p] > 146: + if 148 <= data[p] && data[p] <= 168 { + goto tr1880 + } + case data[p] >= 144: + goto tr1880 + } + case data[p] > 177: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 180 { + goto tr1880 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto tr1880 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st2112: + if p++; p == pe { + goto _test_eof2112 + } + st_case_2112: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr1880 + } + case data[p] >= 128: + goto tr1880 + } + goto tr125 + st2113: + if p++; p == pe { + goto _test_eof2113 + } + st_case_2113: + switch data[p] { + case 128: + goto st2114 + case 129: + goto st2115 + case 130: + goto st241 + case 131: + goto st2116 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st2117 + case 180: + goto st251 + case 181: + goto st2118 + case 182: + goto st253 + case 183: + goto st2119 + case 184: + goto st255 + } + goto tr125 + st2114: + if p++; p == pe { + goto _test_eof2114 + } + st_case_2114: + if data[p] == 164 { + goto st141 + } + switch { + case data[p] < 152: + if 140 <= data[p] && data[p] <= 143 { + goto tr1880 + } + case data[p] > 153: + switch { + case data[p] > 174: + if 191 <= data[p] { + goto tr1485 + } + case data[p] >= 170: + goto tr1880 + } + default: + goto st141 + } + goto tr125 + st2115: + if p++; p == pe { + goto _test_eof2115 + } + st_case_2115: + switch data[p] { + case 132: + goto st141 + case 165: + goto tr125 + case 177: + goto tr148 + case 191: + goto tr148 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr125 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr125 + } + case data[p] >= 160: + goto tr1880 + } + default: + goto tr125 + } + goto tr1485 + st2116: + if p++; p == pe { + goto _test_eof2116 + } + st_case_2116: + if 144 <= data[p] && data[p] <= 176 { + goto tr1880 + } + goto tr125 + st2117: + if p++; p == pe { + goto _test_eof2117 + } + st_case_2117: + switch { + case data[p] < 175: + if 165 <= data[p] && data[p] <= 170 { + goto tr125 + } + case data[p] > 177: + if 180 <= data[p] { + goto tr125 + } + default: + goto tr1880 + } + goto tr148 + st2118: + if p++; p == pe { + goto _test_eof2118 + } + st_case_2118: + if data[p] == 191 { + goto tr1880 + } + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr125 + } + case data[p] >= 168: + goto tr125 + } + goto tr148 + st2119: + if p++; p == pe { + goto _test_eof2119 + } + st_case_2119: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto tr1880 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st2120: + if p++; p == pe { + goto _test_eof2120 + } + st_case_2120: + switch data[p] { + case 128: + goto st2121 + case 130: + goto st2122 + case 132: + goto st259 + case 133: + goto st145 + case 134: + goto st260 + } + goto tr125 + st2121: + if p++; p == pe { + goto _test_eof2121 + } + st_case_2121: + if data[p] == 133 { + goto tr148 + } + switch { + case data[p] > 175: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + case data[p] >= 170: + goto tr1880 + } + goto tr125 + st2122: + if p++; p == pe { + goto _test_eof2122 + } + st_case_2122: + if 153 <= data[p] && data[p] <= 154 { + goto tr1880 + } + goto tr125 + st2123: + if p++; p == pe { + goto _test_eof2123 + } + st_case_2123: + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st1673 + case 153: + goto st2124 + case 154: + goto st2125 + case 155: + goto st2126 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st2127 + case 161: + goto st272 + case 162: + goto st2128 + case 163: + goto st2129 + case 164: + goto st2130 + case 165: + goto st2131 + case 166: + goto st2132 + case 167: + goto st2133 + case 168: + goto st2134 + case 169: + goto st2135 + case 170: + goto st2136 + case 171: + goto st2137 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st2138 + case 176: + goto st147 + } + if 129 <= data[p] { + goto st145 + } + goto tr125 + st2124: + if p++; p == pe { + goto _test_eof2124 + } + st_case_2124: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr1880 + } + default: + goto tr1880 + } + goto tr125 + st2125: + if p++; p == pe { + goto _test_eof2125 + } + st_case_2125: + switch { + case data[p] < 158: + if 128 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr1880 + } + goto tr125 + st2126: + if p++; p == pe { + goto _test_eof2126 + } + st_case_2126: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr125 + } + case data[p] >= 176: + goto tr1880 + } + goto tr148 + st2127: + if p++; p == pe { + goto _test_eof2127 + } + st_case_2127: + switch data[p] { + case 130: + goto tr1880 + case 134: + goto tr1880 + case 139: + goto tr1880 + } + switch { + case data[p] > 167: + if 168 <= data[p] { + goto tr125 + } + case data[p] >= 163: + goto tr1880 + } + goto tr148 + st2128: + if p++; p == pe { + goto _test_eof2128 + } + st_case_2128: + switch { + case data[p] < 130: + if 128 <= data[p] && data[p] <= 129 { + goto tr1880 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr1880 + } + default: + goto tr148 + } + goto tr125 + st2129: + if p++; p == pe { + goto _test_eof2129 + } + st_case_2129: + switch data[p] { + case 187: + goto tr148 + case 189: + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 143: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 133: + goto tr125 + } + case data[p] > 159: + switch { + case data[p] > 183: + if 184 <= data[p] { + goto tr125 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr125 + } + goto tr1880 + st2130: + if p++; p == pe { + goto _test_eof2130 + } + st_case_2130: + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 165: + switch { + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr1880 + } + default: + goto tr148 + } + goto tr125 + st2131: + if p++; p == pe { + goto _test_eof2131 + } + st_case_2131: + switch { + case data[p] < 148: + if 135 <= data[p] && data[p] <= 147 { + goto tr1880 + } + case data[p] > 159: + if 189 <= data[p] { + goto tr125 + } + default: + goto tr125 + } + goto tr148 + st2132: + if p++; p == pe { + goto _test_eof2132 + } + st_case_2132: + switch { + case data[p] < 132: + if 128 <= data[p] && data[p] <= 131 { + goto tr1880 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr1880 + } + default: + goto tr148 + } + goto tr125 + st2133: + if p++; p == pe { + goto _test_eof2133 + } + st_case_2133: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 129: + goto tr125 + } + case data[p] > 164: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr125 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr125 + } + default: + goto tr126 + } + default: + goto tr125 + } + goto tr1880 + st2134: + if p++; p == pe { + goto _test_eof2134 + } + st_case_2134: + switch { + case data[p] > 168: + if 169 <= data[p] && data[p] <= 182 { + goto tr1880 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st2135: + if p++; p == pe { + goto _test_eof2135 + } + st_case_2135: + if data[p] == 131 { + goto tr1880 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 141: + switch { + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto tr1880 + } + case data[p] >= 144: + goto tr126 + } + default: + goto tr1880 + } + goto tr125 + st2136: + if p++; p == pe { + goto _test_eof2136 + } + st_case_2136: + if data[p] == 176 { + goto tr1880 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr1880 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr1880 + } + default: + goto tr1880 + } + goto tr125 + st2137: + if p++; p == pe { + goto _test_eof2137 + } + st_case_2137: + if data[p] == 129 { + goto tr1880 + } + switch { + case data[p] < 171: + if 160 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 181 <= data[p] && data[p] <= 182 { + goto tr1880 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr1880 + } + goto tr125 + st2138: + if p++; p == pe { + goto _test_eof2138 + } + st_case_2138: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 162 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + case data[p] >= 172: + goto tr1880 + } + default: + goto tr1880 + } + goto tr125 + st2139: + if p++; p == pe { + goto _test_eof2139 + } + st_case_2139: + switch data[p] { + case 172: + goto st2140 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st2141 + case 185: + goto st1848 + case 187: + goto st2142 + case 188: + goto st1850 + case 189: + goto st303 + case 190: + goto st2143 + case 191: + goto st2144 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr125 + st2140: + if p++; p == pe { + goto _test_eof2140 + } + st_case_2140: + switch data[p] { + case 158: + goto tr1880 + case 190: + goto tr572 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 170: + goto tr572 + } + default: + goto tr572 + } + goto tr125 + st2141: + if p++; p == pe { + goto _test_eof2141 + } + st_case_2141: + switch data[p] { + case 144: + goto st141 + case 148: + goto st141 + } + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr1880 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr1485 + } + default: + goto tr1880 + } + goto tr125 + st2142: + if p++; p == pe { + goto _test_eof2142 + } + st_case_2142: + if data[p] == 191 { + goto tr1880 + } + if 189 <= data[p] { + goto tr125 + } + goto tr148 + st2143: + if p++; p == pe { + goto _test_eof2143 + } + st_case_2143: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 190 { + goto tr148 + } + case data[p] >= 158: + goto tr1880 + } + goto tr125 + st2144: + if p++; p == pe { + goto _test_eof2144 + } + st_case_2144: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] >= 130: + goto tr148 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr1880 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st2145: + if p++; p == pe { + goto _test_eof2145 + } + st_case_2145: + switch data[p] { + case 144: + goto st2146 + case 145: + goto st2152 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st2171 + case 155: + goto st2176 + case 157: + goto st2178 + case 158: + goto st2185 + case 159: + goto st403 + } + goto tr125 + st2146: + if p++; p == pe { + goto _test_eof2146 + } + st_case_2146: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st2147 + case 138: + goto st313 + case 139: + goto st2148 + case 140: + goto st315 + case 141: + goto st2149 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st1702 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st2150 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st2151 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr125 + st2147: + if p++; p == pe { + goto _test_eof2147 + } + st_case_2147: + if data[p] == 189 { + goto tr1880 + } + goto tr125 + st2148: + if p++; p == pe { + goto _test_eof2148 + } + st_case_2148: + if data[p] == 160 { + goto tr1880 + } + if 145 <= data[p] { + goto tr125 + } + goto tr148 + st2149: + if p++; p == pe { + goto _test_eof2149 + } + st_case_2149: + switch { + case data[p] < 182: + if 139 <= data[p] && data[p] <= 143 { + goto tr125 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr125 + } + default: + goto tr1880 + } + goto tr148 + st2150: + if p++; p == pe { + goto _test_eof2150 + } + st_case_2150: + switch data[p] { + case 128: + goto tr148 + case 191: + goto tr1880 + } + switch { + case data[p] < 144: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr1880 + } + case data[p] > 134: + if 140 <= data[p] && data[p] <= 143 { + goto tr1880 + } + default: + goto tr1880 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto tr1880 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st2151: + if p++; p == pe { + goto _test_eof2151 + } + st_case_2151: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 164: + if 165 <= data[p] && data[p] <= 166 { + goto tr1880 + } + default: + goto tr148 + } + goto tr125 + st2152: + if p++; p == pe { + goto _test_eof2152 + } + st_case_2152: + switch data[p] { + case 128: + goto st2153 + case 129: + goto st2154 + case 130: + goto st2155 + case 131: + goto st1709 + case 132: + goto st2156 + case 133: + goto st2157 + case 134: + goto st2158 + case 135: + goto st2159 + case 136: + goto st2160 + case 138: + goto st348 + case 139: + goto st2161 + case 140: + goto st2162 + case 141: + goto st2163 + case 146: + goto st2164 + case 147: + goto st2165 + case 150: + goto st2166 + case 151: + goto st2167 + case 152: + goto st2164 + case 153: + goto st2168 + case 154: + goto st2169 + case 155: + goto st1724 + case 156: + goto st2170 + case 162: + goto st359 + case 163: + goto st1726 + case 171: + goto st361 + } + goto tr125 + st2153: + if p++; p == pe { + goto _test_eof2153 + } + st_case_2153: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr1880 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr1880 + } + default: + goto tr148 + } + goto tr125 + st2154: + if p++; p == pe { + goto _test_eof2154 + } + st_case_2154: + switch { + case data[p] < 166: + if 135 <= data[p] && data[p] <= 165 { + goto tr125 + } + case data[p] > 175: + if 176 <= data[p] && data[p] <= 190 { + goto tr125 + } + default: + goto tr126 + } + goto tr1880 + st2155: + if p++; p == pe { + goto _test_eof2155 + } + st_case_2155: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr125 + } + default: + goto tr125 + } + goto tr1880 + st2156: + if p++; p == pe { + goto _test_eof2156 + } + st_case_2156: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr1880 + } + case data[p] > 166: + switch { + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr126 + } + case data[p] >= 167: + goto tr1880 + } + default: + goto tr148 + } + goto tr125 + st2157: + if p++; p == pe { + goto _test_eof2157 + } + st_case_2157: + switch data[p] { + case 179: + goto tr1880 + case 182: + goto tr148 + } + if 144 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr125 + st2158: + if p++; p == pe { + goto _test_eof2158 + } + st_case_2158: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr1880 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr1880 + } + default: + goto tr148 + } + goto tr125 + st2159: + if p++; p == pe { + goto _test_eof2159 + } + st_case_2159: + if data[p] == 155 { + goto tr125 + } + switch { + case data[p] < 141: + switch { + case data[p] > 132: + if 133 <= data[p] && data[p] <= 137 { + goto tr125 + } + case data[p] >= 129: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] < 154: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] > 156: + if 157 <= data[p] { + goto tr125 + } + default: + goto tr148 + } + default: + goto tr125 + } + goto tr1880 + st2160: + if p++; p == pe { + goto _test_eof2160 + } + st_case_2160: + switch { + case data[p] < 147: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] > 171: + if 172 <= data[p] && data[p] <= 183 { + goto tr1880 + } + default: + goto tr148 + } + goto tr125 + st2161: + if p++; p == pe { + goto _test_eof2161 + } + st_case_2161: + switch { + case data[p] < 171: + if 159 <= data[p] && data[p] <= 170 { + goto tr1880 + } + case data[p] > 175: + switch { + case data[p] > 185: + if 186 <= data[p] { + goto tr125 + } + case data[p] >= 176: + goto tr126 + } + default: + goto tr125 + } + goto tr148 + st2162: + if p++; p == pe { + goto _test_eof2162 + } + st_case_2162: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto tr1880 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr1880 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr125 + st2163: + if p++; p == pe { + goto _test_eof2163 + } + st_case_2163: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr1880 + } + switch { + case data[p] < 157: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr1880 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr1880 + } + default: + goto tr1880 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr1880 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr1880 + } + default: + goto tr1880 + } + default: + goto tr148 + } + goto tr125 + st2164: + if p++; p == pe { + goto _test_eof2164 + } + st_case_2164: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr1880 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st2165: + if p++; p == pe { + goto _test_eof2165 + } + st_case_2165: + if data[p] == 134 { + goto tr125 + } + switch { + case data[p] < 136: + if 132 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] { + goto tr125 + } + case data[p] >= 144: + goto tr126 + } + default: + goto tr125 + } + goto tr1880 + st2166: + if p++; p == pe { + goto _test_eof2166 + } + st_case_2166: + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 181: + if 184 <= data[p] { + goto tr1880 + } + default: + goto tr1880 + } + goto tr125 + st2167: + if p++; p == pe { + goto _test_eof2167 + } + st_case_2167: + switch { + case data[p] < 152: + if 129 <= data[p] && data[p] <= 151 { + goto tr125 + } + case data[p] > 155: + if 158 <= data[p] { + goto tr125 + } + default: + goto tr148 + } + goto tr1880 + st2168: + if p++; p == pe { + goto _test_eof2168 + } + st_case_2168: + if data[p] == 132 { + goto tr148 + } + switch { + case data[p] < 144: + if 129 <= data[p] && data[p] <= 143 { + goto tr125 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr125 + } + default: + goto tr126 + } + goto tr1880 + st2169: + if p++; p == pe { + goto _test_eof2169 + } + st_case_2169: + switch { + case data[p] > 170: + if 171 <= data[p] && data[p] <= 183 { + goto tr1880 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st2170: + if p++; p == pe { + goto _test_eof2170 + } + st_case_2170: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + case data[p] >= 157: + goto tr1880 + } + goto tr125 + st2171: + if p++; p == pe { + goto _test_eof2171 + } + st_case_2171: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st1728 + case 171: + goto st2172 + case 172: + goto st2173 + case 173: + goto st1731 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st2174 + case 190: + goto st2175 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr125 + st2172: + if p++; p == pe { + goto _test_eof2172 + } + st_case_2172: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto tr1880 + } + case data[p] >= 144: + goto tr148 + } + goto tr125 + st2173: + if p++; p == pe { + goto _test_eof2173 + } + st_case_2173: + switch { + case data[p] > 175: + if 176 <= data[p] && data[p] <= 182 { + goto tr1880 + } + case data[p] >= 128: + goto tr148 + } + goto tr125 + st2174: + if p++; p == pe { + goto _test_eof2174 + } + st_case_2174: + switch { + case data[p] < 145: + if 133 <= data[p] && data[p] <= 143 { + goto tr125 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr125 + } + default: + goto tr1880 + } + goto tr148 + st2175: + if p++; p == pe { + goto _test_eof2175 + } + st_case_2175: + switch { + case data[p] > 146: + if 147 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 143: + goto tr1880 + } + goto tr125 + st2176: + if p++; p == pe { + goto _test_eof2176 + } + st_case_2176: + switch data[p] { + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st2177 + } + goto tr125 + st2177: + if p++; p == pe { + goto _test_eof2177 + } + st_case_2177: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr1880 + } + case data[p] >= 157: + goto tr1880 + } + default: + goto tr148 + } + goto tr125 + st2178: + if p++; p == pe { + goto _test_eof2178 + } + st_case_2178: + switch data[p] { + case 133: + goto st2179 + case 134: + goto st2180 + case 137: + goto st2181 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st1740 + case 168: + goto st2182 + case 169: + goto st2183 + case 170: + goto st2184 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr125 + st2179: + if p++; p == pe { + goto _test_eof2179 + } + st_case_2179: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr1880 + } + case data[p] >= 165: + goto tr1880 + } + goto tr125 + st2180: + if p++; p == pe { + goto _test_eof2180 + } + st_case_2180: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr125 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr125 + } + default: + goto tr125 + } + goto tr1880 + st2181: + if p++; p == pe { + goto _test_eof2181 + } + st_case_2181: + if 130 <= data[p] && data[p] <= 132 { + goto tr1880 + } + goto tr125 + st2182: + if p++; p == pe { + goto _test_eof2182 + } + st_case_2182: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr1880 + } + case data[p] >= 128: + goto tr1880 + } + goto tr125 + st2183: + if p++; p == pe { + goto _test_eof2183 + } + st_case_2183: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr125 + } + case data[p] >= 173: + goto tr125 + } + goto tr1880 + st2184: + if p++; p == pe { + goto _test_eof2184 + } + st_case_2184: + if data[p] == 132 { + goto tr1880 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr1880 + } + case data[p] >= 155: + goto tr1880 + } + goto tr125 + st2185: + if p++; p == pe { + goto _test_eof2185 + } + st_case_2185: + switch data[p] { + case 160: + goto st147 + case 163: + goto st2186 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr125 + st2186: + if p++; p == pe { + goto _test_eof2186 + } + st_case_2186: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr125 + } + case data[p] > 150: + if 151 <= data[p] { + goto tr125 + } + default: + goto tr1880 + } + goto tr148 + st2187: + if p++; p == pe { + goto _test_eof2187 + } + st_case_2187: + if data[p] == 160 { + goto st2188 + } + goto tr125 + st2188: + if p++; p == pe { + goto _test_eof2188 + } + st_case_2188: + switch data[p] { + case 128: + goto st2189 + case 129: + goto st2190 + case 132: + goto st2047 + case 135: + goto st2192 + } + if 133 <= data[p] && data[p] <= 134 { + goto st2191 + } + goto tr125 + st2189: + if p++; p == pe { + goto _test_eof2189 + } + st_case_2189: + if data[p] == 129 { + goto tr1880 + } + if 160 <= data[p] { + goto tr1880 + } + goto tr125 + st2190: + if p++; p == pe { + goto _test_eof2190 + } + st_case_2190: + if 192 <= data[p] { + goto tr125 + } + goto tr1880 + st2191: + if p++; p == pe { + goto _test_eof2191 + } + st_case_2191: + goto tr1880 + st2192: + if p++; p == pe { + goto _test_eof2192 + } + st_case_2192: + if 176 <= data[p] { + goto tr125 + } + goto tr1880 +tr2008: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4874 +tr4462: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4874 + st4874: + if p++; p == pe { + goto _test_eof4874 + } + st_case_4874: +//line segment_words_prod.go:58452 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st2193 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st2194 + case 205: + goto st2195 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st2196 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st2197 + case 215: + goto st2198 + case 216: + goto st2199 + case 217: + goto st2200 + case 219: + goto st2201 + case 220: + goto st2202 + case 221: + goto st2203 + case 222: + goto st2204 + case 223: + goto st2205 + case 224: + goto st2206 + case 225: + goto st2238 + case 226: + goto st2260 + case 227: + goto st2267 + case 234: + goto st2270 + case 237: + goto st287 + case 239: + goto st2286 + case 240: + goto st2292 + case 243: + goto st2334 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 + st2193: + if p++; p == pe { + goto _test_eof2193 + } + st_case_2193: + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr2008 + case 181: + goto tr148 + case 183: + goto st142 + case 186: + goto tr148 + } + goto tr420 + st2194: + if p++; p == pe { + goto _test_eof2194 + } + st_case_2194: + if data[p] <= 127 { + goto tr420 + } + goto tr2008 + st2195: + if p++; p == pe { + goto _test_eof2195 + } + st_case_2195: + switch data[p] { + case 181: + goto tr420 + case 190: + goto tr420 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + goto tr2008 + st2196: + if p++; p == pe { + goto _test_eof2196 + } + st_case_2196: + if data[p] == 130 { + goto tr420 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr2008 + } + goto tr148 + st2197: + if p++; p == pe { + goto _test_eof2197 + } + st_case_2197: + if data[p] == 190 { + goto tr420 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr420 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + default: + goto tr2008 + } + goto tr148 + st2198: + if p++; p == pe { + goto _test_eof2198 + } + st_case_2198: + switch data[p] { + case 135: + goto tr2008 + case 179: + goto tr148 + case 180: + goto st142 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr2008 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr2008 + } + goto tr420 + st2199: + if p++; p == pe { + goto _test_eof2199 + } + st_case_2199: + if data[p] == 156 { + goto tr2008 + } + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 133 { + goto tr2008 + } + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr2008 + } + goto tr420 + st2200: + if p++; p == pe { + goto _test_eof2200 + } + st_case_2200: + switch data[p] { + case 171: + goto tr421 + case 176: + goto tr2008 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr2008 + } + goto tr420 + st2201: + if p++; p == pe { + goto _test_eof2201 + } + st_case_2201: + switch data[p] { + case 148: + goto tr420 + case 158: + goto tr420 + case 169: + goto tr420 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr2008 + } + case data[p] >= 150: + goto tr2008 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 189: + goto tr420 + } + default: + goto tr421 + } + goto tr148 + st2202: + if p++; p == pe { + goto _test_eof2202 + } + st_case_2202: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto tr2008 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr2008 + } + default: + goto tr148 + } + goto tr420 + st2203: + if p++; p == pe { + goto _test_eof2203 + } + st_case_2203: + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr420 + } + goto tr2008 + st2204: + if p++; p == pe { + goto _test_eof2204 + } + st_case_2204: + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr2008 + } + goto tr148 + st2205: + if p++; p == pe { + goto _test_eof2205 + } + st_case_2205: + if data[p] == 186 { + goto tr148 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 170: + switch { + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 171: + goto tr2008 + } + default: + goto tr148 + } + goto tr420 + st2206: + if p++; p == pe { + goto _test_eof2206 + } + st_case_2206: + switch data[p] { + case 160: + goto st2207 + case 161: + goto st2208 + case 162: + goto st168 + case 163: + goto st2209 + case 164: + goto st2210 + case 165: + goto st2211 + case 166: + goto st2212 + case 167: + goto st2213 + case 168: + goto st2214 + case 169: + goto st2215 + case 170: + goto st2216 + case 171: + goto st2217 + case 172: + goto st2218 + case 173: + goto st2219 + case 174: + goto st2220 + case 175: + goto st2221 + case 176: + goto st2222 + case 177: + goto st2223 + case 178: + goto st2224 + case 179: + goto st2225 + case 180: + goto st2226 + case 181: + goto st2227 + case 182: + goto st2228 + case 183: + goto st2229 + case 184: + goto st2230 + case 185: + goto st2231 + case 186: + goto st2232 + case 187: + goto st2233 + case 188: + goto st2234 + case 189: + goto st2235 + case 190: + goto st2236 + case 191: + goto st2237 + } + goto tr420 + st2207: + if p++; p == pe { + goto _test_eof2207 + } + st_case_2207: + switch data[p] { + case 154: + goto tr148 + case 164: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] > 149: + if 150 <= data[p] && data[p] <= 173 { + goto tr2008 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2208: + if p++; p == pe { + goto _test_eof2208 + } + st_case_2208: + switch { + case data[p] > 152: + if 153 <= data[p] && data[p] <= 155 { + goto tr2008 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2209: + if p++; p == pe { + goto _test_eof2209 + } + st_case_2209: + if 163 <= data[p] { + goto tr2008 + } + goto tr420 + st2210: + if p++; p == pe { + goto _test_eof2210 + } + st_case_2210: + if data[p] == 189 { + goto tr148 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr148 + } + goto tr2008 + st2211: + if p++; p == pe { + goto _test_eof2211 + } + st_case_2211: + switch data[p] { + case 144: + goto tr148 + case 176: + goto tr420 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 177 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr420 + } + goto tr2008 + st2212: + if p++; p == pe { + goto _test_eof2212 + } + st_case_2212: + switch data[p] { + case 132: + goto tr420 + case 169: + goto tr420 + case 177: + goto tr420 + case 188: + goto tr2008 + } + switch { + case data[p] < 145: + switch { + case data[p] > 131: + if 141 <= data[p] && data[p] <= 142 { + goto tr420 + } + case data[p] >= 129: + goto tr2008 + } + case data[p] > 146: + switch { + case data[p] < 186: + if 179 <= data[p] && data[p] <= 181 { + goto tr420 + } + case data[p] > 187: + if 190 <= data[p] { + goto tr2008 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st2213: + if p++; p == pe { + goto _test_eof2213 + } + st_case_2213: + switch data[p] { + case 142: + goto tr148 + case 158: + goto tr420 + } + switch { + case data[p] < 156: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 155 { + goto tr420 + } + case data[p] >= 143: + goto tr420 + } + default: + goto tr420 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr2008 + st2214: + if p++; p == pe { + goto _test_eof2214 + } + st_case_2214: + if data[p] == 188 { + goto tr2008 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2008 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto tr2008 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2215: + if p++; p == pe { + goto _test_eof2215 + } + st_case_2215: + if data[p] == 157 { + goto tr420 + } + switch { + case data[p] < 153: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 146 <= data[p] && data[p] <= 152 { + goto tr420 + } + case data[p] >= 142: + goto tr420 + } + default: + goto tr420 + } + case data[p] > 158: + switch { + case data[p] < 166: + if 159 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr2008 + st2216: + if p++; p == pe { + goto _test_eof2216 + } + st_case_2216: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2008 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto tr2008 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2217: + if p++; p == pe { + goto _test_eof2217 + } + st_case_2217: + switch data[p] { + case 134: + goto tr420 + case 138: + goto tr420 + case 144: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] >= 142: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr420 + } + goto tr2008 + st2218: + if p++; p == pe { + goto _test_eof2218 + } + st_case_2218: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2008 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2008 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2219: + if p++; p == pe { + goto _test_eof2219 + } + st_case_2219: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr2008 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 161: + switch { + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 162: + goto tr2008 + } + default: + goto tr148 + } + default: + goto tr2008 + } + goto tr420 + st2220: + if p++; p == pe { + goto _test_eof2220 + } + st_case_2220: + switch data[p] { + case 130: + goto tr2008 + case 131: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 158: + switch { + case data[p] < 142: + if 133 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 149: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] < 168: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto tr2008 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2221: + if p++; p == pe { + goto _test_eof2221 + } + st_case_2221: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr2008 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr2008 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 138: + goto tr2008 + } + default: + goto tr2008 + } + goto tr420 + st2222: + if p++; p == pe { + goto _test_eof2222 + } + st_case_2222: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto tr2008 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 190 <= data[p] { + goto tr2008 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2223: + if p++; p == pe { + goto _test_eof2223 + } + st_case_2223: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 151: + goto tr420 + } + switch { + case data[p] < 160: + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 148 { + goto tr420 + } + case data[p] > 154: + if 155 <= data[p] && data[p] <= 159 { + goto tr420 + } + default: + goto tr148 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr2008 + st2224: + if p++; p == pe { + goto _test_eof2224 + } + st_case_2224: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2008 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2008 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2225: + if p++; p == pe { + goto _test_eof2225 + } + st_case_2225: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr2008 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 150: + switch { + case data[p] < 162: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 163: + switch { + case data[p] > 175: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr2008 + } + default: + goto tr2008 + } + goto tr420 + st2226: + if p++; p == pe { + goto _test_eof2226 + } + st_case_2226: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto tr2008 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto tr2008 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2227: + if p++; p == pe { + goto _test_eof2227 + } + st_case_2227: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 142: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 150 { + goto tr420 + } + case data[p] > 158: + if 159 <= data[p] && data[p] <= 161 { + goto tr148 + } + default: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr2008 + st2228: + if p++; p == pe { + goto _test_eof2228 + } + st_case_2228: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr2008 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2229: + if p++; p == pe { + goto _test_eof2229 + } + st_case_2229: + switch data[p] { + case 138: + goto tr2008 + case 150: + goto tr2008 + } + switch { + case data[p] < 152: + switch { + case data[p] > 134: + if 143 <= data[p] && data[p] <= 148 { + goto tr2008 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto tr2008 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr2008 + } + goto tr420 + st2230: + if p++; p == pe { + goto _test_eof2230 + } + st_case_2230: + if data[p] == 177 { + goto tr2008 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr2008 + } + goto tr420 + st2231: + if p++; p == pe { + goto _test_eof2231 + } + st_case_2231: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 135: + goto tr2008 + } + goto tr420 + st2232: + if p++; p == pe { + goto _test_eof2232 + } + st_case_2232: + if data[p] == 177 { + goto tr2008 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr2008 + } + case data[p] >= 180: + goto tr2008 + } + goto tr420 + st2233: + if p++; p == pe { + goto _test_eof2233 + } + st_case_2233: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 136: + goto tr2008 + } + goto tr420 + st2234: + if p++; p == pe { + goto _test_eof2234 + } + st_case_2234: + switch data[p] { + case 128: + goto tr148 + case 181: + goto tr2008 + case 183: + goto tr2008 + case 185: + goto tr2008 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto tr2008 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto tr2008 + } + default: + goto tr421 + } + goto tr420 + st2235: + if p++; p == pe { + goto _test_eof2235 + } + st_case_2235: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto tr2008 + } + default: + goto tr148 + } + goto tr420 + st2236: + if p++; p == pe { + goto _test_eof2236 + } + st_case_2236: + switch { + case data[p] < 136: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 135 { + goto tr2008 + } + case data[p] >= 128: + goto tr2008 + } + case data[p] > 140: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr2008 + } + case data[p] >= 141: + goto tr2008 + } + default: + goto tr148 + } + goto tr420 + st2237: + if p++; p == pe { + goto _test_eof2237 + } + st_case_2237: + if data[p] == 134 { + goto tr2008 + } + goto tr420 + st2238: + if p++; p == pe { + goto _test_eof2238 + } + st_case_2238: + switch data[p] { + case 128: + goto st2239 + case 129: + goto st2240 + case 130: + goto st2241 + case 131: + goto st202 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st2242 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st2243 + case 157: + goto st2244 + case 158: + goto st2245 + case 159: + goto st2246 + case 160: + goto st2247 + case 161: + goto st219 + case 162: + goto st2248 + case 163: + goto st221 + case 164: + goto st2249 + case 165: + goto st468 + case 167: + goto st469 + case 168: + goto st2250 + case 169: + goto st2251 + case 170: + goto st2252 + case 172: + goto st2253 + case 173: + goto st2254 + case 174: + goto st2255 + case 175: + goto st2256 + case 176: + goto st2257 + case 177: + goto st640 + case 179: + goto st2258 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st2259 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + } + switch { + case data[p] < 180: + if 132 <= data[p] && data[p] <= 152 { + goto st145 + } + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + default: + goto st147 + } + goto tr420 + st2239: + if p++; p == pe { + goto _test_eof2239 + } + st_case_2239: + if 171 <= data[p] && data[p] <= 190 { + goto tr2008 + } + goto tr420 + st2240: + if p++; p == pe { + goto _test_eof2240 + } + st_case_2240: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto tr2008 + } + case data[p] >= 128: + goto tr421 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto tr2008 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr2008 + } + default: + goto tr2008 + } + default: + goto tr2008 + } + goto tr420 + st2241: + if p++; p == pe { + goto _test_eof2241 + } + st_case_2241: + if data[p] == 143 { + goto tr2008 + } + switch { + case data[p] < 144: + if 130 <= data[p] && data[p] <= 141 { + goto tr2008 + } + case data[p] > 153: + switch { + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 154: + goto tr2008 + } + default: + goto tr421 + } + goto tr420 + st2242: + if p++; p == pe { + goto _test_eof2242 + } + st_case_2242: + switch { + case data[p] < 157: + if 155 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr420 + } + default: + goto tr2008 + } + goto tr148 + st2243: + if p++; p == pe { + goto _test_eof2243 + } + st_case_2243: + switch { + case data[p] < 146: + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 177: + if 178 <= data[p] && data[p] <= 180 { + goto tr2008 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr2008 + } + goto tr420 + st2244: + if p++; p == pe { + goto _test_eof2244 + } + st_case_2244: + switch { + case data[p] < 160: + switch { + case data[p] > 145: + if 146 <= data[p] && data[p] <= 147 { + goto tr2008 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto tr2008 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2245: + if p++; p == pe { + goto _test_eof2245 + } + st_case_2245: + if 180 <= data[p] { + goto tr2008 + } + goto tr420 + st2246: + if p++; p == pe { + goto _test_eof2246 + } + st_case_2246: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 170 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr420 + } + goto tr2008 + st2247: + if p++; p == pe { + goto _test_eof2247 + } + st_case_2247: + switch { + case data[p] < 144: + if 139 <= data[p] && data[p] <= 142 { + goto tr2008 + } + case data[p] > 153: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + goto tr420 + st2248: + if p++; p == pe { + goto _test_eof2248 + } + st_case_2248: + if data[p] == 169 { + goto tr2008 + } + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2249: + if p++; p == pe { + goto _test_eof2249 + } + st_case_2249: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr2008 + } + default: + goto tr2008 + } + goto tr420 + st2250: + if p++; p == pe { + goto _test_eof2250 + } + st_case_2250: + switch { + case data[p] > 150: + if 151 <= data[p] && data[p] <= 155 { + goto tr2008 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2251: + if p++; p == pe { + goto _test_eof2251 + } + st_case_2251: + if data[p] == 191 { + goto tr2008 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr2008 + } + case data[p] >= 149: + goto tr2008 + } + goto tr420 + st2252: + if p++; p == pe { + goto _test_eof2252 + } + st_case_2252: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto tr2008 + } + default: + goto tr421 + } + goto tr420 + st2253: + if p++; p == pe { + goto _test_eof2253 + } + st_case_2253: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 132 { + goto tr2008 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr2008 + } + default: + goto tr148 + } + goto tr420 + st2254: + if p++; p == pe { + goto _test_eof2254 + } + st_case_2254: + switch { + case data[p] < 144: + switch { + case data[p] > 139: + if 140 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] >= 133: + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 154: + goto tr420 + } + default: + goto tr421 + } + goto tr2008 + st2255: + if p++; p == pe { + goto _test_eof2255 + } + st_case_2255: + switch { + case data[p] < 161: + switch { + case data[p] > 130: + if 131 <= data[p] && data[p] <= 160 { + goto tr148 + } + case data[p] >= 128: + goto tr2008 + } + case data[p] > 173: + switch { + case data[p] < 176: + if 174 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + default: + goto tr2008 + } + goto tr420 + st2256: + if p++; p == pe { + goto _test_eof2256 + } + st_case_2256: + switch { + case data[p] > 179: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr2008 + } + goto tr148 + st2257: + if p++; p == pe { + goto _test_eof2257 + } + st_case_2257: + switch { + case data[p] > 163: + if 164 <= data[p] && data[p] <= 183 { + goto tr2008 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2258: + if p++; p == pe { + goto _test_eof2258 + } + st_case_2258: + if data[p] == 173 { + goto tr2008 + } + switch { + case data[p] < 169: + switch { + case data[p] > 146: + if 148 <= data[p] && data[p] <= 168 { + goto tr2008 + } + case data[p] >= 144: + goto tr2008 + } + case data[p] > 177: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 180 { + goto tr2008 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto tr2008 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2259: + if p++; p == pe { + goto _test_eof2259 + } + st_case_2259: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr2008 + } + case data[p] >= 128: + goto tr2008 + } + goto tr420 + st2260: + if p++; p == pe { + goto _test_eof2260 + } + st_case_2260: + switch data[p] { + case 128: + goto st2261 + case 129: + goto st2262 + case 130: + goto st241 + case 131: + goto st2263 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st2264 + case 180: + goto st251 + case 181: + goto st2265 + case 182: + goto st253 + case 183: + goto st2266 + case 184: + goto st255 + } + goto tr420 + st2261: + if p++; p == pe { + goto _test_eof2261 + } + st_case_2261: + switch data[p] { + case 164: + goto st142 + case 167: + goto st142 + } + switch { + case data[p] < 152: + if 140 <= data[p] && data[p] <= 143 { + goto tr2008 + } + case data[p] > 153: + switch { + case data[p] > 174: + if 191 <= data[p] { + goto tr571 + } + case data[p] >= 170: + goto tr2008 + } + default: + goto st142 + } + goto tr420 + st2262: + if p++; p == pe { + goto _test_eof2262 + } + st_case_2262: + switch data[p] { + case 165: + goto tr420 + case 177: + goto tr148 + case 191: + goto tr148 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr2008 + } + default: + goto tr420 + } + goto tr571 + st2263: + if p++; p == pe { + goto _test_eof2263 + } + st_case_2263: + if 144 <= data[p] && data[p] <= 176 { + goto tr2008 + } + goto tr420 + st2264: + if p++; p == pe { + goto _test_eof2264 + } + st_case_2264: + switch { + case data[p] < 175: + if 165 <= data[p] && data[p] <= 170 { + goto tr420 + } + case data[p] > 177: + if 180 <= data[p] { + goto tr420 + } + default: + goto tr2008 + } + goto tr148 + st2265: + if p++; p == pe { + goto _test_eof2265 + } + st_case_2265: + if data[p] == 191 { + goto tr2008 + } + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 168: + goto tr420 + } + goto tr148 + st2266: + if p++; p == pe { + goto _test_eof2266 + } + st_case_2266: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto tr2008 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2267: + if p++; p == pe { + goto _test_eof2267 + } + st_case_2267: + switch data[p] { + case 128: + goto st2268 + case 130: + goto st2269 + case 132: + goto st259 + case 133: + goto st145 + case 134: + goto st260 + } + goto tr420 + st2268: + if p++; p == pe { + goto _test_eof2268 + } + st_case_2268: + if data[p] == 133 { + goto tr148 + } + switch { + case data[p] > 175: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + case data[p] >= 170: + goto tr2008 + } + goto tr420 + st2269: + if p++; p == pe { + goto _test_eof2269 + } + st_case_2269: + if 153 <= data[p] && data[p] <= 154 { + goto tr2008 + } + goto tr420 + st2270: + if p++; p == pe { + goto _test_eof2270 + } + st_case_2270: + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st654 + case 153: + goto st2271 + case 154: + goto st2272 + case 155: + goto st2273 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st2274 + case 161: + goto st272 + case 162: + goto st2275 + case 163: + goto st2276 + case 164: + goto st2277 + case 165: + goto st2278 + case 166: + goto st2279 + case 167: + goto st2280 + case 168: + goto st2281 + case 169: + goto st2282 + case 170: + goto st2283 + case 171: + goto st2284 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st2285 + case 176: + goto st147 + } + if 129 <= data[p] { + goto st145 + } + goto tr420 + st2271: + if p++; p == pe { + goto _test_eof2271 + } + st_case_2271: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr2008 + } + default: + goto tr2008 + } + goto tr420 + st2272: + if p++; p == pe { + goto _test_eof2272 + } + st_case_2272: + switch { + case data[p] < 158: + if 128 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr2008 + } + goto tr420 + st2273: + if p++; p == pe { + goto _test_eof2273 + } + st_case_2273: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr2008 + } + goto tr148 + st2274: + if p++; p == pe { + goto _test_eof2274 + } + st_case_2274: + switch data[p] { + case 130: + goto tr2008 + case 134: + goto tr2008 + case 139: + goto tr2008 + } + switch { + case data[p] > 167: + if 168 <= data[p] { + goto tr420 + } + case data[p] >= 163: + goto tr2008 + } + goto tr148 + st2275: + if p++; p == pe { + goto _test_eof2275 + } + st_case_2275: + switch { + case data[p] < 130: + if 128 <= data[p] && data[p] <= 129 { + goto tr2008 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr2008 + } + default: + goto tr148 + } + goto tr420 + st2276: + if p++; p == pe { + goto _test_eof2276 + } + st_case_2276: + switch data[p] { + case 187: + goto tr148 + case 189: + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 143: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 133: + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 183: + if 184 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr420 + } + goto tr2008 + st2277: + if p++; p == pe { + goto _test_eof2277 + } + st_case_2277: + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 165: + switch { + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr2008 + } + default: + goto tr148 + } + goto tr420 + st2278: + if p++; p == pe { + goto _test_eof2278 + } + st_case_2278: + switch { + case data[p] < 148: + if 135 <= data[p] && data[p] <= 147 { + goto tr2008 + } + case data[p] > 159: + if 189 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st2279: + if p++; p == pe { + goto _test_eof2279 + } + st_case_2279: + switch { + case data[p] < 132: + if 128 <= data[p] && data[p] <= 131 { + goto tr2008 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr2008 + } + default: + goto tr148 + } + goto tr420 + st2280: + if p++; p == pe { + goto _test_eof2280 + } + st_case_2280: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 129: + goto tr420 + } + case data[p] > 164: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr420 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + default: + goto tr420 + } + goto tr2008 + st2281: + if p++; p == pe { + goto _test_eof2281 + } + st_case_2281: + switch { + case data[p] > 168: + if 169 <= data[p] && data[p] <= 182 { + goto tr2008 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2282: + if p++; p == pe { + goto _test_eof2282 + } + st_case_2282: + if data[p] == 131 { + goto tr2008 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 141: + switch { + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto tr2008 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr2008 + } + goto tr420 + st2283: + if p++; p == pe { + goto _test_eof2283 + } + st_case_2283: + if data[p] == 176 { + goto tr2008 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr2008 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr2008 + } + default: + goto tr2008 + } + goto tr420 + st2284: + if p++; p == pe { + goto _test_eof2284 + } + st_case_2284: + if data[p] == 129 { + goto tr2008 + } + switch { + case data[p] < 171: + if 160 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 181 <= data[p] && data[p] <= 182 { + goto tr2008 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr2008 + } + goto tr420 + st2285: + if p++; p == pe { + goto _test_eof2285 + } + st_case_2285: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 162 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 172: + goto tr2008 + } + default: + goto tr2008 + } + goto tr420 + st2286: + if p++; p == pe { + goto _test_eof2286 + } + st_case_2286: + switch data[p] { + case 172: + goto st2287 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st2288 + case 185: + goto st967 + case 187: + goto st2289 + case 188: + goto st969 + case 189: + goto st303 + case 190: + goto st2290 + case 191: + goto st2291 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr420 + st2287: + if p++; p == pe { + goto _test_eof2287 + } + st_case_2287: + switch data[p] { + case 158: + goto tr2008 + case 190: + goto tr572 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 170: + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st2288: + if p++; p == pe { + goto _test_eof2288 + } + st_case_2288: + if data[p] == 147 { + goto st142 + } + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr2008 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr571 + } + default: + goto tr2008 + } + goto tr420 + st2289: + if p++; p == pe { + goto _test_eof2289 + } + st_case_2289: + if data[p] == 191 { + goto tr2008 + } + if 189 <= data[p] { + goto tr420 + } + goto tr148 + st2290: + if p++; p == pe { + goto _test_eof2290 + } + st_case_2290: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 190 { + goto tr148 + } + case data[p] >= 158: + goto tr2008 + } + goto tr420 + st2291: + if p++; p == pe { + goto _test_eof2291 + } + st_case_2291: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] >= 130: + goto tr148 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr2008 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2292: + if p++; p == pe { + goto _test_eof2292 + } + st_case_2292: + switch data[p] { + case 144: + goto st2293 + case 145: + goto st2299 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st2318 + case 155: + goto st2323 + case 157: + goto st2325 + case 158: + goto st2332 + case 159: + goto st403 + } + goto tr420 + st2293: + if p++; p == pe { + goto _test_eof2293 + } + st_case_2293: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st2294 + case 138: + goto st313 + case 139: + goto st2295 + case 140: + goto st315 + case 141: + goto st2296 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st684 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st2297 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st2298 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr420 + st2294: + if p++; p == pe { + goto _test_eof2294 + } + st_case_2294: + if data[p] == 189 { + goto tr2008 + } + goto tr420 + st2295: + if p++; p == pe { + goto _test_eof2295 + } + st_case_2295: + if data[p] == 160 { + goto tr2008 + } + if 145 <= data[p] { + goto tr420 + } + goto tr148 + st2296: + if p++; p == pe { + goto _test_eof2296 + } + st_case_2296: + switch { + case data[p] < 182: + if 139 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr420 + } + default: + goto tr2008 + } + goto tr148 + st2297: + if p++; p == pe { + goto _test_eof2297 + } + st_case_2297: + switch data[p] { + case 128: + goto tr148 + case 191: + goto tr2008 + } + switch { + case data[p] < 144: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2008 + } + case data[p] > 134: + if 140 <= data[p] && data[p] <= 143 { + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto tr2008 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2298: + if p++; p == pe { + goto _test_eof2298 + } + st_case_2298: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 164: + if 165 <= data[p] && data[p] <= 166 { + goto tr2008 + } + default: + goto tr148 + } + goto tr420 + st2299: + if p++; p == pe { + goto _test_eof2299 + } + st_case_2299: + switch data[p] { + case 128: + goto st2300 + case 129: + goto st2301 + case 130: + goto st2302 + case 131: + goto st691 + case 132: + goto st2303 + case 133: + goto st2304 + case 134: + goto st2305 + case 135: + goto st2306 + case 136: + goto st2307 + case 138: + goto st348 + case 139: + goto st2308 + case 140: + goto st2309 + case 141: + goto st2310 + case 146: + goto st2311 + case 147: + goto st2312 + case 150: + goto st2313 + case 151: + goto st2314 + case 152: + goto st2311 + case 153: + goto st2315 + case 154: + goto st2316 + case 155: + goto st538 + case 156: + goto st2317 + case 162: + goto st359 + case 163: + goto st707 + case 171: + goto st361 + } + goto tr420 + st2300: + if p++; p == pe { + goto _test_eof2300 + } + st_case_2300: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2008 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr2008 + } + default: + goto tr148 + } + goto tr420 + st2301: + if p++; p == pe { + goto _test_eof2301 + } + st_case_2301: + switch { + case data[p] < 166: + if 135 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] && data[p] <= 190 { + goto tr420 + } + default: + goto tr421 + } + goto tr2008 + st2302: + if p++; p == pe { + goto _test_eof2302 + } + st_case_2302: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr2008 + st2303: + if p++; p == pe { + goto _test_eof2303 + } + st_case_2303: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2008 + } + case data[p] > 166: + switch { + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr421 + } + case data[p] >= 167: + goto tr2008 + } + default: + goto tr148 + } + goto tr420 + st2304: + if p++; p == pe { + goto _test_eof2304 + } + st_case_2304: + switch data[p] { + case 179: + goto tr2008 + case 182: + goto tr148 + } + if 144 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr420 + st2305: + if p++; p == pe { + goto _test_eof2305 + } + st_case_2305: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2008 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr2008 + } + default: + goto tr148 + } + goto tr420 + st2306: + if p++; p == pe { + goto _test_eof2306 + } + st_case_2306: + if data[p] == 155 { + goto tr420 + } + switch { + case data[p] < 141: + switch { + case data[p] > 132: + if 133 <= data[p] && data[p] <= 137 { + goto tr420 + } + case data[p] >= 129: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] < 154: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] > 156: + if 157 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + default: + goto tr420 + } + goto tr2008 + st2307: + if p++; p == pe { + goto _test_eof2307 + } + st_case_2307: + switch { + case data[p] < 147: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] > 171: + if 172 <= data[p] && data[p] <= 183 { + goto tr2008 + } + default: + goto tr148 + } + goto tr420 + st2308: + if p++; p == pe { + goto _test_eof2308 + } + st_case_2308: + switch { + case data[p] < 171: + if 159 <= data[p] && data[p] <= 170 { + goto tr2008 + } + case data[p] > 175: + switch { + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr421 + } + default: + goto tr420 + } + goto tr148 + st2309: + if p++; p == pe { + goto _test_eof2309 + } + st_case_2309: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto tr2008 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2008 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2310: + if p++; p == pe { + goto _test_eof2310 + } + st_case_2310: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr2008 + } + switch { + case data[p] < 157: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr2008 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr2008 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr2008 + } + default: + goto tr2008 + } + default: + goto tr148 + } + goto tr420 + st2311: + if p++; p == pe { + goto _test_eof2311 + } + st_case_2311: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr2008 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2312: + if p++; p == pe { + goto _test_eof2312 + } + st_case_2312: + if data[p] == 134 { + goto tr420 + } + switch { + case data[p] < 136: + if 132 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr420 + } + goto tr2008 + st2313: + if p++; p == pe { + goto _test_eof2313 + } + st_case_2313: + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 181: + if 184 <= data[p] { + goto tr2008 + } + default: + goto tr2008 + } + goto tr420 + st2314: + if p++; p == pe { + goto _test_eof2314 + } + st_case_2314: + switch { + case data[p] < 152: + if 129 <= data[p] && data[p] <= 151 { + goto tr420 + } + case data[p] > 155: + if 158 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + goto tr2008 + st2315: + if p++; p == pe { + goto _test_eof2315 + } + st_case_2315: + if data[p] == 132 { + goto tr148 + } + switch { + case data[p] < 144: + if 129 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + goto tr2008 + st2316: + if p++; p == pe { + goto _test_eof2316 + } + st_case_2316: + switch { + case data[p] > 170: + if 171 <= data[p] && data[p] <= 183 { + goto tr2008 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2317: + if p++; p == pe { + goto _test_eof2317 + } + st_case_2317: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 157: + goto tr2008 + } + goto tr420 + st2318: + if p++; p == pe { + goto _test_eof2318 + } + st_case_2318: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st709 + case 171: + goto st2319 + case 172: + goto st2320 + case 173: + goto st712 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st2321 + case 190: + goto st2322 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr420 + st2319: + if p++; p == pe { + goto _test_eof2319 + } + st_case_2319: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto tr2008 + } + case data[p] >= 144: + goto tr148 + } + goto tr420 + st2320: + if p++; p == pe { + goto _test_eof2320 + } + st_case_2320: + switch { + case data[p] > 175: + if 176 <= data[p] && data[p] <= 182 { + goto tr2008 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2321: + if p++; p == pe { + goto _test_eof2321 + } + st_case_2321: + switch { + case data[p] < 145: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr420 + } + default: + goto tr2008 + } + goto tr148 + st2322: + if p++; p == pe { + goto _test_eof2322 + } + st_case_2322: + switch { + case data[p] > 146: + if 147 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 143: + goto tr2008 + } + goto tr420 + st2323: + if p++; p == pe { + goto _test_eof2323 + } + st_case_2323: + switch data[p] { + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st2324 + } + goto tr420 + st2324: + if p++; p == pe { + goto _test_eof2324 + } + st_case_2324: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr2008 + } + case data[p] >= 157: + goto tr2008 + } + default: + goto tr148 + } + goto tr420 + st2325: + if p++; p == pe { + goto _test_eof2325 + } + st_case_2325: + switch data[p] { + case 133: + goto st2326 + case 134: + goto st2327 + case 137: + goto st2328 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st721 + case 168: + goto st2329 + case 169: + goto st2330 + case 170: + goto st2331 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr420 + st2326: + if p++; p == pe { + goto _test_eof2326 + } + st_case_2326: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr2008 + } + case data[p] >= 165: + goto tr2008 + } + goto tr420 + st2327: + if p++; p == pe { + goto _test_eof2327 + } + st_case_2327: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr420 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr2008 + st2328: + if p++; p == pe { + goto _test_eof2328 + } + st_case_2328: + if 130 <= data[p] && data[p] <= 132 { + goto tr2008 + } + goto tr420 + st2329: + if p++; p == pe { + goto _test_eof2329 + } + st_case_2329: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr2008 + } + case data[p] >= 128: + goto tr2008 + } + goto tr420 + st2330: + if p++; p == pe { + goto _test_eof2330 + } + st_case_2330: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 173: + goto tr420 + } + goto tr2008 + st2331: + if p++; p == pe { + goto _test_eof2331 + } + st_case_2331: + if data[p] == 132 { + goto tr2008 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr2008 + } + case data[p] >= 155: + goto tr2008 + } + goto tr420 + st2332: + if p++; p == pe { + goto _test_eof2332 + } + st_case_2332: + switch data[p] { + case 160: + goto st147 + case 163: + goto st2333 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr420 + st2333: + if p++; p == pe { + goto _test_eof2333 + } + st_case_2333: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 150: + if 151 <= data[p] { + goto tr420 + } + default: + goto tr2008 + } + goto tr148 + st2334: + if p++; p == pe { + goto _test_eof2334 + } + st_case_2334: + if data[p] == 160 { + goto st2335 + } + goto tr420 + st2335: + if p++; p == pe { + goto _test_eof2335 + } + st_case_2335: + switch data[p] { + case 128: + goto st2336 + case 129: + goto st2337 + case 132: + goto st2194 + case 135: + goto st2339 + } + if 133 <= data[p] && data[p] <= 134 { + goto st2338 + } + goto tr420 + st2336: + if p++; p == pe { + goto _test_eof2336 + } + st_case_2336: + if data[p] == 129 { + goto tr2008 + } + if 160 <= data[p] { + goto tr2008 + } + goto tr420 + st2337: + if p++; p == pe { + goto _test_eof2337 + } + st_case_2337: + if 192 <= data[p] { + goto tr420 + } + goto tr2008 + st2338: + if p++; p == pe { + goto _test_eof2338 + } + st_case_2338: + goto tr2008 + st2339: + if p++; p == pe { + goto _test_eof2339 + } + st_case_2339: + if 176 <= data[p] { + goto tr420 + } + goto tr2008 +tr2266: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4875 +tr4463: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4875 + st4875: + if p++; p == pe { + goto _test_eof4875 + } + st_case_4875: +//line segment_words_prod.go:62239 + switch data[p] { + case 95: + goto tr2136 + case 194: + goto st2489 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st148 + case 204: + goto st2490 + case 205: + goto st2491 + case 206: + goto st151 + case 207: + goto st152 + case 210: + goto st2492 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st2493 + case 215: + goto st2494 + case 216: + goto st2495 + case 217: + goto st2496 + case 219: + goto st2497 + case 220: + goto st2498 + case 221: + goto st2499 + case 222: + goto st2500 + case 223: + goto st2501 + case 224: + goto st2502 + case 225: + goto st2534 + case 226: + goto st2556 + case 227: + goto st2563 + case 234: + goto st2566 + case 237: + goto st287 + case 239: + goto st2582 + case 240: + goto st2588 + case 243: + goto st2630 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr126 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2136: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4876 + st4876: + if p++; p == pe { + goto _test_eof4876 + } + st_case_4876: +//line segment_words_prod.go:62343 + switch data[p] { + case 95: + goto tr2136 + case 194: + goto st2340 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st148 + case 204: + goto st2341 + case 205: + goto st2342 + case 206: + goto st151 + case 207: + goto st152 + case 210: + goto st2343 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st2344 + case 215: + goto st2345 + case 216: + goto st2346 + case 217: + goto st2347 + case 219: + goto st2348 + case 220: + goto st2349 + case 221: + goto st2350 + case 222: + goto st2351 + case 223: + goto st2352 + case 224: + goto st2353 + case 225: + goto st2385 + case 226: + goto st2407 + case 227: + goto st2414 + case 234: + goto st2417 + case 237: + goto st287 + case 239: + goto st2433 + case 240: + goto st2441 + case 243: + goto st2483 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr126 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 + st2340: + if p++; p == pe { + goto _test_eof2340 + } + st_case_2340: + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr2136 + case 181: + goto tr148 + case 186: + goto tr148 + } + goto tr420 + st2341: + if p++; p == pe { + goto _test_eof2341 + } + st_case_2341: + if data[p] <= 127 { + goto tr420 + } + goto tr2136 + st2342: + if p++; p == pe { + goto _test_eof2342 + } + st_case_2342: + switch data[p] { + case 181: + goto tr420 + case 190: + goto tr420 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + goto tr2136 + st2343: + if p++; p == pe { + goto _test_eof2343 + } + st_case_2343: + if data[p] == 130 { + goto tr420 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr2136 + } + goto tr148 + st2344: + if p++; p == pe { + goto _test_eof2344 + } + st_case_2344: + if data[p] == 190 { + goto tr420 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr420 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + default: + goto tr2136 + } + goto tr148 + st2345: + if p++; p == pe { + goto _test_eof2345 + } + st_case_2345: + switch data[p] { + case 135: + goto tr2136 + case 179: + goto tr148 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr2136 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr2136 + } + goto tr420 + st2346: + if p++; p == pe { + goto _test_eof2346 + } + st_case_2346: + if data[p] == 156 { + goto tr2136 + } + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 133 { + goto tr2136 + } + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr2136 + } + goto tr420 + st2347: + if p++; p == pe { + goto _test_eof2347 + } + st_case_2347: + switch data[p] { + case 171: + goto tr126 + case 176: + goto tr2136 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + case data[p] >= 160: + goto tr126 + } + default: + goto tr2136 + } + goto tr420 + st2348: + if p++; p == pe { + goto _test_eof2348 + } + st_case_2348: + switch data[p] { + case 148: + goto tr420 + case 158: + goto tr420 + case 169: + goto tr420 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr2136 + } + case data[p] >= 150: + goto tr2136 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 189: + goto tr420 + } + default: + goto tr126 + } + goto tr148 + st2349: + if p++; p == pe { + goto _test_eof2349 + } + st_case_2349: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto tr2136 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr2136 + } + default: + goto tr148 + } + goto tr420 + st2350: + if p++; p == pe { + goto _test_eof2350 + } + st_case_2350: + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr420 + } + goto tr2136 + st2351: + if p++; p == pe { + goto _test_eof2351 + } + st_case_2351: + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr2136 + } + goto tr148 + st2352: + if p++; p == pe { + goto _test_eof2352 + } + st_case_2352: + if data[p] == 186 { + goto tr148 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 170: + switch { + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 171: + goto tr2136 + } + default: + goto tr148 + } + goto tr420 + st2353: + if p++; p == pe { + goto _test_eof2353 + } + st_case_2353: + switch data[p] { + case 160: + goto st2354 + case 161: + goto st2355 + case 162: + goto st168 + case 163: + goto st2356 + case 164: + goto st2357 + case 165: + goto st2358 + case 166: + goto st2359 + case 167: + goto st2360 + case 168: + goto st2361 + case 169: + goto st2362 + case 170: + goto st2363 + case 171: + goto st2364 + case 172: + goto st2365 + case 173: + goto st2366 + case 174: + goto st2367 + case 175: + goto st2368 + case 176: + goto st2369 + case 177: + goto st2370 + case 178: + goto st2371 + case 179: + goto st2372 + case 180: + goto st2373 + case 181: + goto st2374 + case 182: + goto st2375 + case 183: + goto st2376 + case 184: + goto st2377 + case 185: + goto st2378 + case 186: + goto st2379 + case 187: + goto st2380 + case 188: + goto st2381 + case 189: + goto st2382 + case 190: + goto st2383 + case 191: + goto st2384 + } + goto tr420 + st2354: + if p++; p == pe { + goto _test_eof2354 + } + st_case_2354: + switch data[p] { + case 154: + goto tr148 + case 164: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] > 149: + if 150 <= data[p] && data[p] <= 173 { + goto tr2136 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2355: + if p++; p == pe { + goto _test_eof2355 + } + st_case_2355: + switch { + case data[p] > 152: + if 153 <= data[p] && data[p] <= 155 { + goto tr2136 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2356: + if p++; p == pe { + goto _test_eof2356 + } + st_case_2356: + if 163 <= data[p] { + goto tr2136 + } + goto tr420 + st2357: + if p++; p == pe { + goto _test_eof2357 + } + st_case_2357: + if data[p] == 189 { + goto tr148 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr148 + } + goto tr2136 + st2358: + if p++; p == pe { + goto _test_eof2358 + } + st_case_2358: + switch data[p] { + case 144: + goto tr148 + case 176: + goto tr420 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 177 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr420 + } + goto tr2136 + st2359: + if p++; p == pe { + goto _test_eof2359 + } + st_case_2359: + switch data[p] { + case 132: + goto tr420 + case 169: + goto tr420 + case 177: + goto tr420 + case 188: + goto tr2136 + } + switch { + case data[p] < 145: + switch { + case data[p] > 131: + if 141 <= data[p] && data[p] <= 142 { + goto tr420 + } + case data[p] >= 129: + goto tr2136 + } + case data[p] > 146: + switch { + case data[p] < 186: + if 179 <= data[p] && data[p] <= 181 { + goto tr420 + } + case data[p] > 187: + if 190 <= data[p] { + goto tr2136 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st2360: + if p++; p == pe { + goto _test_eof2360 + } + st_case_2360: + switch data[p] { + case 142: + goto tr148 + case 158: + goto tr420 + } + switch { + case data[p] < 156: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 155 { + goto tr420 + } + case data[p] >= 143: + goto tr420 + } + default: + goto tr420 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr126 + } + default: + goto tr148 + } + goto tr2136 + st2361: + if p++; p == pe { + goto _test_eof2361 + } + st_case_2361: + if data[p] == 188 { + goto tr2136 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2136 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto tr2136 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2362: + if p++; p == pe { + goto _test_eof2362 + } + st_case_2362: + if data[p] == 157 { + goto tr420 + } + switch { + case data[p] < 153: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 146 <= data[p] && data[p] <= 152 { + goto tr420 + } + case data[p] >= 142: + goto tr420 + } + default: + goto tr420 + } + case data[p] > 158: + switch { + case data[p] < 166: + if 159 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr126 + } + default: + goto tr148 + } + goto tr2136 + st2363: + if p++; p == pe { + goto _test_eof2363 + } + st_case_2363: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2136 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto tr2136 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2364: + if p++; p == pe { + goto _test_eof2364 + } + st_case_2364: + switch data[p] { + case 134: + goto tr420 + case 138: + goto tr420 + case 144: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] >= 142: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr420 + } + goto tr2136 + st2365: + if p++; p == pe { + goto _test_eof2365 + } + st_case_2365: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2136 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2136 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2366: + if p++; p == pe { + goto _test_eof2366 + } + st_case_2366: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr2136 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr2136 + } + default: + goto tr2136 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 161: + switch { + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] >= 162: + goto tr2136 + } + default: + goto tr148 + } + default: + goto tr2136 + } + goto tr420 + st2367: + if p++; p == pe { + goto _test_eof2367 + } + st_case_2367: + switch data[p] { + case 130: + goto tr2136 + case 131: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 158: + switch { + case data[p] < 142: + if 133 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 149: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] < 168: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto tr2136 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2368: + if p++; p == pe { + goto _test_eof2368 + } + st_case_2368: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr2136 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr2136 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] >= 138: + goto tr2136 + } + default: + goto tr2136 + } + goto tr420 + st2369: + if p++; p == pe { + goto _test_eof2369 + } + st_case_2369: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto tr2136 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 190 <= data[p] { + goto tr2136 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2370: + if p++; p == pe { + goto _test_eof2370 + } + st_case_2370: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 151: + goto tr420 + } + switch { + case data[p] < 160: + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 148 { + goto tr420 + } + case data[p] > 154: + if 155 <= data[p] && data[p] <= 159 { + goto tr420 + } + default: + goto tr148 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + default: + goto tr126 + } + default: + goto tr148 + } + goto tr2136 + st2371: + if p++; p == pe { + goto _test_eof2371 + } + st_case_2371: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2136 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2136 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2372: + if p++; p == pe { + goto _test_eof2372 + } + st_case_2372: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr2136 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr2136 + } + default: + goto tr2136 + } + case data[p] > 150: + switch { + case data[p] < 162: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 163: + switch { + case data[p] > 175: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr2136 + } + default: + goto tr2136 + } + goto tr420 + st2373: + if p++; p == pe { + goto _test_eof2373 + } + st_case_2373: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto tr2136 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto tr2136 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2374: + if p++; p == pe { + goto _test_eof2374 + } + st_case_2374: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 142: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 150 { + goto tr420 + } + case data[p] > 158: + if 159 <= data[p] && data[p] <= 161 { + goto tr148 + } + default: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr2136 + st2375: + if p++; p == pe { + goto _test_eof2375 + } + st_case_2375: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr2136 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2376: + if p++; p == pe { + goto _test_eof2376 + } + st_case_2376: + switch data[p] { + case 138: + goto tr2136 + case 150: + goto tr2136 + } + switch { + case data[p] < 152: + switch { + case data[p] > 134: + if 143 <= data[p] && data[p] <= 148 { + goto tr2136 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto tr2136 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr2136 + } + goto tr420 + st2377: + if p++; p == pe { + goto _test_eof2377 + } + st_case_2377: + if data[p] == 177 { + goto tr2136 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr2136 + } + goto tr420 + st2378: + if p++; p == pe { + goto _test_eof2378 + } + st_case_2378: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 135: + goto tr2136 + } + goto tr420 + st2379: + if p++; p == pe { + goto _test_eof2379 + } + st_case_2379: + if data[p] == 177 { + goto tr2136 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr2136 + } + case data[p] >= 180: + goto tr2136 + } + goto tr420 + st2380: + if p++; p == pe { + goto _test_eof2380 + } + st_case_2380: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 136: + goto tr2136 + } + goto tr420 + st2381: + if p++; p == pe { + goto _test_eof2381 + } + st_case_2381: + switch data[p] { + case 128: + goto tr148 + case 181: + goto tr2136 + case 183: + goto tr2136 + case 185: + goto tr2136 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto tr2136 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto tr2136 + } + default: + goto tr126 + } + goto tr420 + st2382: + if p++; p == pe { + goto _test_eof2382 + } + st_case_2382: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto tr2136 + } + default: + goto tr148 + } + goto tr420 + st2383: + if p++; p == pe { + goto _test_eof2383 + } + st_case_2383: + switch { + case data[p] < 136: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 135 { + goto tr2136 + } + case data[p] >= 128: + goto tr2136 + } + case data[p] > 140: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr2136 + } + case data[p] >= 141: + goto tr2136 + } + default: + goto tr148 + } + goto tr420 + st2384: + if p++; p == pe { + goto _test_eof2384 + } + st_case_2384: + if data[p] == 134 { + goto tr2136 + } + goto tr420 + st2385: + if p++; p == pe { + goto _test_eof2385 + } + st_case_2385: + switch data[p] { + case 128: + goto st2386 + case 129: + goto st2387 + case 130: + goto st2388 + case 131: + goto st202 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st2389 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st2390 + case 157: + goto st2391 + case 158: + goto st2392 + case 159: + goto st2393 + case 160: + goto st2394 + case 161: + goto st219 + case 162: + goto st2395 + case 163: + goto st221 + case 164: + goto st2396 + case 165: + goto st1649 + case 167: + goto st1650 + case 168: + goto st2397 + case 169: + goto st2398 + case 170: + goto st2399 + case 172: + goto st2400 + case 173: + goto st2401 + case 174: + goto st2402 + case 175: + goto st2403 + case 176: + goto st2404 + case 177: + goto st1659 + case 179: + goto st2405 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st2406 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + } + switch { + case data[p] < 180: + if 132 <= data[p] && data[p] <= 152 { + goto st145 + } + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + default: + goto st147 + } + goto tr420 + st2386: + if p++; p == pe { + goto _test_eof2386 + } + st_case_2386: + if 171 <= data[p] && data[p] <= 190 { + goto tr2136 + } + goto tr420 + st2387: + if p++; p == pe { + goto _test_eof2387 + } + st_case_2387: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto tr2136 + } + case data[p] >= 128: + goto tr126 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto tr2136 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr2136 + } + default: + goto tr2136 + } + default: + goto tr2136 + } + goto tr420 + st2388: + if p++; p == pe { + goto _test_eof2388 + } + st_case_2388: + if data[p] == 143 { + goto tr2136 + } + switch { + case data[p] < 144: + if 130 <= data[p] && data[p] <= 141 { + goto tr2136 + } + case data[p] > 153: + switch { + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 154: + goto tr2136 + } + default: + goto tr126 + } + goto tr420 + st2389: + if p++; p == pe { + goto _test_eof2389 + } + st_case_2389: + switch { + case data[p] < 157: + if 155 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr420 + } + default: + goto tr2136 + } + goto tr148 + st2390: + if p++; p == pe { + goto _test_eof2390 + } + st_case_2390: + switch { + case data[p] < 146: + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 177: + if 178 <= data[p] && data[p] <= 180 { + goto tr2136 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr2136 + } + goto tr420 + st2391: + if p++; p == pe { + goto _test_eof2391 + } + st_case_2391: + switch { + case data[p] < 160: + switch { + case data[p] > 145: + if 146 <= data[p] && data[p] <= 147 { + goto tr2136 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto tr2136 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2392: + if p++; p == pe { + goto _test_eof2392 + } + st_case_2392: + if 180 <= data[p] { + goto tr2136 + } + goto tr420 + st2393: + if p++; p == pe { + goto _test_eof2393 + } + st_case_2393: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 170 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr126 + } + default: + goto tr420 + } + goto tr2136 + st2394: + if p++; p == pe { + goto _test_eof2394 + } + st_case_2394: + switch { + case data[p] < 144: + if 139 <= data[p] && data[p] <= 142 { + goto tr2136 + } + case data[p] > 153: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr126 + } + goto tr420 + st2395: + if p++; p == pe { + goto _test_eof2395 + } + st_case_2395: + if data[p] == 169 { + goto tr2136 + } + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2396: + if p++; p == pe { + goto _test_eof2396 + } + st_case_2396: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr2136 + } + default: + goto tr2136 + } + goto tr420 + st2397: + if p++; p == pe { + goto _test_eof2397 + } + st_case_2397: + switch { + case data[p] > 150: + if 151 <= data[p] && data[p] <= 155 { + goto tr2136 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2398: + if p++; p == pe { + goto _test_eof2398 + } + st_case_2398: + if data[p] == 191 { + goto tr2136 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr2136 + } + case data[p] >= 149: + goto tr2136 + } + goto tr420 + st2399: + if p++; p == pe { + goto _test_eof2399 + } + st_case_2399: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto tr2136 + } + default: + goto tr126 + } + goto tr420 + st2400: + if p++; p == pe { + goto _test_eof2400 + } + st_case_2400: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 132 { + goto tr2136 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr2136 + } + default: + goto tr148 + } + goto tr420 + st2401: + if p++; p == pe { + goto _test_eof2401 + } + st_case_2401: + switch { + case data[p] < 144: + switch { + case data[p] > 139: + if 140 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] >= 133: + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 154: + goto tr420 + } + default: + goto tr126 + } + goto tr2136 + st2402: + if p++; p == pe { + goto _test_eof2402 + } + st_case_2402: + switch { + case data[p] < 161: + switch { + case data[p] > 130: + if 131 <= data[p] && data[p] <= 160 { + goto tr148 + } + case data[p] >= 128: + goto tr2136 + } + case data[p] > 173: + switch { + case data[p] < 176: + if 174 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr148 + } + default: + goto tr126 + } + default: + goto tr2136 + } + goto tr420 + st2403: + if p++; p == pe { + goto _test_eof2403 + } + st_case_2403: + switch { + case data[p] > 179: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr2136 + } + goto tr148 + st2404: + if p++; p == pe { + goto _test_eof2404 + } + st_case_2404: + switch { + case data[p] > 163: + if 164 <= data[p] && data[p] <= 183 { + goto tr2136 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2405: + if p++; p == pe { + goto _test_eof2405 + } + st_case_2405: + if data[p] == 173 { + goto tr2136 + } + switch { + case data[p] < 169: + switch { + case data[p] > 146: + if 148 <= data[p] && data[p] <= 168 { + goto tr2136 + } + case data[p] >= 144: + goto tr2136 + } + case data[p] > 177: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 180 { + goto tr2136 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto tr2136 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2406: + if p++; p == pe { + goto _test_eof2406 + } + st_case_2406: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr2136 + } + case data[p] >= 128: + goto tr2136 + } + goto tr420 + st2407: + if p++; p == pe { + goto _test_eof2407 + } + st_case_2407: + switch data[p] { + case 128: + goto st2408 + case 129: + goto st2409 + case 130: + goto st241 + case 131: + goto st2410 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st2411 + case 180: + goto st251 + case 181: + goto st2412 + case 182: + goto st253 + case 183: + goto st2413 + case 184: + goto st255 + } + goto tr420 + st2408: + if p++; p == pe { + goto _test_eof2408 + } + st_case_2408: + switch { + case data[p] < 170: + if 140 <= data[p] && data[p] <= 143 { + goto tr2136 + } + case data[p] > 174: + if 191 <= data[p] { + goto tr2136 + } + default: + goto tr2136 + } + goto tr420 + st2409: + if p++; p == pe { + goto _test_eof2409 + } + st_case_2409: + switch data[p] { + case 165: + goto tr420 + case 177: + goto tr148 + case 191: + goto tr148 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr420 + } + case data[p] > 159: + if 176 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr2136 + st2410: + if p++; p == pe { + goto _test_eof2410 + } + st_case_2410: + if 144 <= data[p] && data[p] <= 176 { + goto tr2136 + } + goto tr420 + st2411: + if p++; p == pe { + goto _test_eof2411 + } + st_case_2411: + switch { + case data[p] < 175: + if 165 <= data[p] && data[p] <= 170 { + goto tr420 + } + case data[p] > 177: + if 180 <= data[p] { + goto tr420 + } + default: + goto tr2136 + } + goto tr148 + st2412: + if p++; p == pe { + goto _test_eof2412 + } + st_case_2412: + if data[p] == 191 { + goto tr2136 + } + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 168: + goto tr420 + } + goto tr148 + st2413: + if p++; p == pe { + goto _test_eof2413 + } + st_case_2413: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto tr2136 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2414: + if p++; p == pe { + goto _test_eof2414 + } + st_case_2414: + switch data[p] { + case 128: + goto st2415 + case 130: + goto st2416 + case 131: + goto st1164 + case 132: + goto st259 + case 133: + goto st145 + case 134: + goto st260 + case 135: + goto st1165 + case 139: + goto st1166 + case 140: + goto st1091 + case 141: + goto st1167 + } + goto tr420 + st2415: + if p++; p == pe { + goto _test_eof2415 + } + st_case_2415: + if data[p] == 133 { + goto tr148 + } + switch { + case data[p] < 177: + if 170 <= data[p] && data[p] <= 175 { + goto tr2136 + } + case data[p] > 181: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + default: + goto tr1049 + } + goto tr420 + st2416: + if p++; p == pe { + goto _test_eof2416 + } + st_case_2416: + switch { + case data[p] < 155: + if 153 <= data[p] && data[p] <= 154 { + goto tr2136 + } + case data[p] > 156: + if 160 <= data[p] { + goto tr1049 + } + default: + goto tr1049 + } + goto tr420 + st2417: + if p++; p == pe { + goto _test_eof2417 + } + st_case_2417: + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st1673 + case 153: + goto st2418 + case 154: + goto st2419 + case 155: + goto st2420 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st2421 + case 161: + goto st272 + case 162: + goto st2422 + case 163: + goto st2423 + case 164: + goto st2424 + case 165: + goto st2425 + case 166: + goto st2426 + case 167: + goto st2427 + case 168: + goto st2428 + case 169: + goto st2429 + case 170: + goto st2430 + case 171: + goto st2431 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st2432 + case 176: + goto st147 + } + if 129 <= data[p] { + goto st145 + } + goto tr420 + st2418: + if p++; p == pe { + goto _test_eof2418 + } + st_case_2418: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr2136 + } + default: + goto tr2136 + } + goto tr420 + st2419: + if p++; p == pe { + goto _test_eof2419 + } + st_case_2419: + switch { + case data[p] < 158: + if 128 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr2136 + } + goto tr420 + st2420: + if p++; p == pe { + goto _test_eof2420 + } + st_case_2420: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr2136 + } + goto tr148 + st2421: + if p++; p == pe { + goto _test_eof2421 + } + st_case_2421: + switch data[p] { + case 130: + goto tr2136 + case 134: + goto tr2136 + case 139: + goto tr2136 + } + switch { + case data[p] > 167: + if 168 <= data[p] { + goto tr420 + } + case data[p] >= 163: + goto tr2136 + } + goto tr148 + st2422: + if p++; p == pe { + goto _test_eof2422 + } + st_case_2422: + switch { + case data[p] < 130: + if 128 <= data[p] && data[p] <= 129 { + goto tr2136 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr2136 + } + default: + goto tr148 + } + goto tr420 + st2423: + if p++; p == pe { + goto _test_eof2423 + } + st_case_2423: + switch data[p] { + case 187: + goto tr148 + case 189: + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 143: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 133: + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 183: + if 184 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr420 + } + goto tr2136 + st2424: + if p++; p == pe { + goto _test_eof2424 + } + st_case_2424: + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 165: + switch { + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr2136 + } + default: + goto tr148 + } + goto tr420 + st2425: + if p++; p == pe { + goto _test_eof2425 + } + st_case_2425: + switch { + case data[p] < 148: + if 135 <= data[p] && data[p] <= 147 { + goto tr2136 + } + case data[p] > 159: + if 189 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st2426: + if p++; p == pe { + goto _test_eof2426 + } + st_case_2426: + switch { + case data[p] < 132: + if 128 <= data[p] && data[p] <= 131 { + goto tr2136 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr2136 + } + default: + goto tr148 + } + goto tr420 + st2427: + if p++; p == pe { + goto _test_eof2427 + } + st_case_2427: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 129: + goto tr420 + } + case data[p] > 164: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr420 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + default: + goto tr126 + } + default: + goto tr420 + } + goto tr2136 + st2428: + if p++; p == pe { + goto _test_eof2428 + } + st_case_2428: + switch { + case data[p] > 168: + if 169 <= data[p] && data[p] <= 182 { + goto tr2136 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2429: + if p++; p == pe { + goto _test_eof2429 + } + st_case_2429: + if data[p] == 131 { + goto tr2136 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 141: + switch { + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto tr2136 + } + case data[p] >= 144: + goto tr126 + } + default: + goto tr2136 + } + goto tr420 + st2430: + if p++; p == pe { + goto _test_eof2430 + } + st_case_2430: + if data[p] == 176 { + goto tr2136 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr2136 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr2136 + } + default: + goto tr2136 + } + goto tr420 + st2431: + if p++; p == pe { + goto _test_eof2431 + } + st_case_2431: + if data[p] == 129 { + goto tr2136 + } + switch { + case data[p] < 171: + if 160 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 181 <= data[p] && data[p] <= 182 { + goto tr2136 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr2136 + } + goto tr420 + st2432: + if p++; p == pe { + goto _test_eof2432 + } + st_case_2432: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 162 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + case data[p] >= 172: + goto tr2136 + } + default: + goto tr2136 + } + goto tr420 + st2433: + if p++; p == pe { + goto _test_eof2433 + } + st_case_2433: + switch data[p] { + case 172: + goto st2434 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st2435 + case 185: + goto st2436 + case 187: + goto st2437 + case 188: + goto st2438 + case 189: + goto st1261 + case 190: + goto st2439 + case 191: + goto st2440 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr420 + st2434: + if p++; p == pe { + goto _test_eof2434 + } + st_case_2434: + switch data[p] { + case 158: + goto tr2136 + case 190: + goto tr572 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 170: + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st2435: + if p++; p == pe { + goto _test_eof2435 + } + st_case_2435: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr2136 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr2136 + } + default: + goto tr2136 + } + goto tr420 + st2436: + if p++; p == pe { + goto _test_eof2436 + } + st_case_2436: + switch { + case data[p] < 176: + if 141 <= data[p] && data[p] <= 143 { + goto tr2136 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st2437: + if p++; p == pe { + goto _test_eof2437 + } + st_case_2437: + if data[p] == 191 { + goto tr2136 + } + if 189 <= data[p] { + goto tr420 + } + goto tr148 + st2438: + if p++; p == pe { + goto _test_eof2438 + } + st_case_2438: + if data[p] == 191 { + goto tr2136 + } + if 161 <= data[p] && data[p] <= 186 { + goto tr148 + } + goto tr2 + st2439: + if p++; p == pe { + goto _test_eof2439 + } + st_case_2439: + switch { + case data[p] < 160: + if 158 <= data[p] && data[p] <= 159 { + goto tr2136 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + goto tr1049 + st2440: + if p++; p == pe { + goto _test_eof2440 + } + st_case_2440: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] >= 130: + goto tr148 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr2136 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2441: + if p++; p == pe { + goto _test_eof2441 + } + st_case_2441: + switch data[p] { + case 144: + goto st2442 + case 145: + goto st2448 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st2467 + case 155: + goto st2472 + case 157: + goto st2474 + case 158: + goto st2481 + case 159: + goto st403 + } + goto tr420 + st2442: + if p++; p == pe { + goto _test_eof2442 + } + st_case_2442: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st2443 + case 138: + goto st313 + case 139: + goto st2444 + case 140: + goto st315 + case 141: + goto st2445 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st1702 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st2446 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st2447 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr420 + st2443: + if p++; p == pe { + goto _test_eof2443 + } + st_case_2443: + if data[p] == 189 { + goto tr2136 + } + goto tr420 + st2444: + if p++; p == pe { + goto _test_eof2444 + } + st_case_2444: + if data[p] == 160 { + goto tr2136 + } + if 145 <= data[p] { + goto tr420 + } + goto tr148 + st2445: + if p++; p == pe { + goto _test_eof2445 + } + st_case_2445: + switch { + case data[p] < 182: + if 139 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr420 + } + default: + goto tr2136 + } + goto tr148 + st2446: + if p++; p == pe { + goto _test_eof2446 + } + st_case_2446: + switch data[p] { + case 128: + goto tr148 + case 191: + goto tr2136 + } + switch { + case data[p] < 144: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2136 + } + case data[p] > 134: + if 140 <= data[p] && data[p] <= 143 { + goto tr2136 + } + default: + goto tr2136 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto tr2136 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2447: + if p++; p == pe { + goto _test_eof2447 + } + st_case_2447: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 164: + if 165 <= data[p] && data[p] <= 166 { + goto tr2136 + } + default: + goto tr148 + } + goto tr420 + st2448: + if p++; p == pe { + goto _test_eof2448 + } + st_case_2448: + switch data[p] { + case 128: + goto st2449 + case 129: + goto st2450 + case 130: + goto st2451 + case 131: + goto st1709 + case 132: + goto st2452 + case 133: + goto st2453 + case 134: + goto st2454 + case 135: + goto st2455 + case 136: + goto st2456 + case 138: + goto st348 + case 139: + goto st2457 + case 140: + goto st2458 + case 141: + goto st2459 + case 146: + goto st2460 + case 147: + goto st2461 + case 150: + goto st2462 + case 151: + goto st2463 + case 152: + goto st2460 + case 153: + goto st2464 + case 154: + goto st2465 + case 155: + goto st1724 + case 156: + goto st2466 + case 162: + goto st359 + case 163: + goto st1726 + case 171: + goto st361 + } + goto tr420 + st2449: + if p++; p == pe { + goto _test_eof2449 + } + st_case_2449: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2136 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr2136 + } + default: + goto tr148 + } + goto tr420 + st2450: + if p++; p == pe { + goto _test_eof2450 + } + st_case_2450: + switch { + case data[p] < 166: + if 135 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] && data[p] <= 190 { + goto tr420 + } + default: + goto tr126 + } + goto tr2136 + st2451: + if p++; p == pe { + goto _test_eof2451 + } + st_case_2451: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr2136 + st2452: + if p++; p == pe { + goto _test_eof2452 + } + st_case_2452: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2136 + } + case data[p] > 166: + switch { + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr126 + } + case data[p] >= 167: + goto tr2136 + } + default: + goto tr148 + } + goto tr420 + st2453: + if p++; p == pe { + goto _test_eof2453 + } + st_case_2453: + switch data[p] { + case 179: + goto tr2136 + case 182: + goto tr148 + } + if 144 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr420 + st2454: + if p++; p == pe { + goto _test_eof2454 + } + st_case_2454: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2136 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr2136 + } + default: + goto tr148 + } + goto tr420 + st2455: + if p++; p == pe { + goto _test_eof2455 + } + st_case_2455: + if data[p] == 155 { + goto tr420 + } + switch { + case data[p] < 141: + switch { + case data[p] > 132: + if 133 <= data[p] && data[p] <= 137 { + goto tr420 + } + case data[p] >= 129: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] < 154: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] > 156: + if 157 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + default: + goto tr420 + } + goto tr2136 + st2456: + if p++; p == pe { + goto _test_eof2456 + } + st_case_2456: + switch { + case data[p] < 147: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] > 171: + if 172 <= data[p] && data[p] <= 183 { + goto tr2136 + } + default: + goto tr148 + } + goto tr420 + st2457: + if p++; p == pe { + goto _test_eof2457 + } + st_case_2457: + switch { + case data[p] < 171: + if 159 <= data[p] && data[p] <= 170 { + goto tr2136 + } + case data[p] > 175: + switch { + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr126 + } + default: + goto tr420 + } + goto tr148 + st2458: + if p++; p == pe { + goto _test_eof2458 + } + st_case_2458: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto tr2136 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2136 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2459: + if p++; p == pe { + goto _test_eof2459 + } + st_case_2459: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr2136 + } + switch { + case data[p] < 157: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr2136 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr2136 + } + default: + goto tr2136 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr2136 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr2136 + } + default: + goto tr2136 + } + default: + goto tr148 + } + goto tr420 + st2460: + if p++; p == pe { + goto _test_eof2460 + } + st_case_2460: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr2136 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2461: + if p++; p == pe { + goto _test_eof2461 + } + st_case_2461: + if data[p] == 134 { + goto tr420 + } + switch { + case data[p] < 136: + if 132 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + case data[p] >= 144: + goto tr126 + } + default: + goto tr420 + } + goto tr2136 + st2462: + if p++; p == pe { + goto _test_eof2462 + } + st_case_2462: + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 181: + if 184 <= data[p] { + goto tr2136 + } + default: + goto tr2136 + } + goto tr420 + st2463: + if p++; p == pe { + goto _test_eof2463 + } + st_case_2463: + switch { + case data[p] < 152: + if 129 <= data[p] && data[p] <= 151 { + goto tr420 + } + case data[p] > 155: + if 158 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + goto tr2136 + st2464: + if p++; p == pe { + goto _test_eof2464 + } + st_case_2464: + if data[p] == 132 { + goto tr148 + } + switch { + case data[p] < 144: + if 129 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + default: + goto tr126 + } + goto tr2136 + st2465: + if p++; p == pe { + goto _test_eof2465 + } + st_case_2465: + switch { + case data[p] > 170: + if 171 <= data[p] && data[p] <= 183 { + goto tr2136 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2466: + if p++; p == pe { + goto _test_eof2466 + } + st_case_2466: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + case data[p] >= 157: + goto tr2136 + } + goto tr420 + st2467: + if p++; p == pe { + goto _test_eof2467 + } + st_case_2467: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st1728 + case 171: + goto st2468 + case 172: + goto st2469 + case 173: + goto st1731 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st2470 + case 190: + goto st2471 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr420 + st2468: + if p++; p == pe { + goto _test_eof2468 + } + st_case_2468: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto tr2136 + } + case data[p] >= 144: + goto tr148 + } + goto tr420 + st2469: + if p++; p == pe { + goto _test_eof2469 + } + st_case_2469: + switch { + case data[p] > 175: + if 176 <= data[p] && data[p] <= 182 { + goto tr2136 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2470: + if p++; p == pe { + goto _test_eof2470 + } + st_case_2470: + switch { + case data[p] < 145: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr420 + } + default: + goto tr2136 + } + goto tr148 + st2471: + if p++; p == pe { + goto _test_eof2471 + } + st_case_2471: + switch { + case data[p] > 146: + if 147 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 143: + goto tr2136 + } + goto tr420 + st2472: + if p++; p == pe { + goto _test_eof2472 + } + st_case_2472: + switch data[p] { + case 128: + goto st1224 + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st2473 + } + goto tr420 + st2473: + if p++; p == pe { + goto _test_eof2473 + } + st_case_2473: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr2136 + } + case data[p] >= 157: + goto tr2136 + } + default: + goto tr148 + } + goto tr420 + st2474: + if p++; p == pe { + goto _test_eof2474 + } + st_case_2474: + switch data[p] { + case 133: + goto st2475 + case 134: + goto st2476 + case 137: + goto st2477 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st1740 + case 168: + goto st2478 + case 169: + goto st2479 + case 170: + goto st2480 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr420 + st2475: + if p++; p == pe { + goto _test_eof2475 + } + st_case_2475: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr2136 + } + case data[p] >= 165: + goto tr2136 + } + goto tr420 + st2476: + if p++; p == pe { + goto _test_eof2476 + } + st_case_2476: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr420 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr2136 + st2477: + if p++; p == pe { + goto _test_eof2477 + } + st_case_2477: + if 130 <= data[p] && data[p] <= 132 { + goto tr2136 + } + goto tr420 + st2478: + if p++; p == pe { + goto _test_eof2478 + } + st_case_2478: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr2136 + } + case data[p] >= 128: + goto tr2136 + } + goto tr420 + st2479: + if p++; p == pe { + goto _test_eof2479 + } + st_case_2479: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 173: + goto tr420 + } + goto tr2136 + st2480: + if p++; p == pe { + goto _test_eof2480 + } + st_case_2480: + if data[p] == 132 { + goto tr2136 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr2136 + } + case data[p] >= 155: + goto tr2136 + } + goto tr420 + st2481: + if p++; p == pe { + goto _test_eof2481 + } + st_case_2481: + switch data[p] { + case 160: + goto st147 + case 163: + goto st2482 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr420 + st2482: + if p++; p == pe { + goto _test_eof2482 + } + st_case_2482: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 150: + if 151 <= data[p] { + goto tr420 + } + default: + goto tr2136 + } + goto tr148 + st2483: + if p++; p == pe { + goto _test_eof2483 + } + st_case_2483: + if data[p] == 160 { + goto st2484 + } + goto tr420 + st2484: + if p++; p == pe { + goto _test_eof2484 + } + st_case_2484: + switch data[p] { + case 128: + goto st2485 + case 129: + goto st2486 + case 132: + goto st2341 + case 135: + goto st2488 + } + if 133 <= data[p] && data[p] <= 134 { + goto st2487 + } + goto tr420 + st2485: + if p++; p == pe { + goto _test_eof2485 + } + st_case_2485: + if data[p] == 129 { + goto tr2136 + } + if 160 <= data[p] { + goto tr2136 + } + goto tr420 + st2486: + if p++; p == pe { + goto _test_eof2486 + } + st_case_2486: + if 192 <= data[p] { + goto tr420 + } + goto tr2136 + st2487: + if p++; p == pe { + goto _test_eof2487 + } + st_case_2487: + goto tr2136 + st2488: + if p++; p == pe { + goto _test_eof2488 + } + st_case_2488: + if 176 <= data[p] { + goto tr420 + } + goto tr2136 + st2489: + if p++; p == pe { + goto _test_eof2489 + } + st_case_2489: + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr2266 + case 181: + goto tr148 + case 186: + goto tr148 + } + goto tr420 + st2490: + if p++; p == pe { + goto _test_eof2490 + } + st_case_2490: + if data[p] <= 127 { + goto tr420 + } + goto tr2266 + st2491: + if p++; p == pe { + goto _test_eof2491 + } + st_case_2491: + switch data[p] { + case 181: + goto tr420 + case 190: + goto tr420 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + goto tr2266 + st2492: + if p++; p == pe { + goto _test_eof2492 + } + st_case_2492: + if data[p] == 130 { + goto tr420 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr2266 + } + goto tr148 + st2493: + if p++; p == pe { + goto _test_eof2493 + } + st_case_2493: + if data[p] == 190 { + goto tr420 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr420 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + default: + goto tr2266 + } + goto tr148 + st2494: + if p++; p == pe { + goto _test_eof2494 + } + st_case_2494: + switch data[p] { + case 135: + goto tr2266 + case 179: + goto tr148 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr2266 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr2266 + } + goto tr420 + st2495: + if p++; p == pe { + goto _test_eof2495 + } + st_case_2495: + if data[p] == 156 { + goto tr2266 + } + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 133 { + goto tr2266 + } + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr2266 + } + goto tr420 + st2496: + if p++; p == pe { + goto _test_eof2496 + } + st_case_2496: + switch data[p] { + case 171: + goto tr126 + case 176: + goto tr2266 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + case data[p] >= 160: + goto tr126 + } + default: + goto tr2266 + } + goto tr420 + st2497: + if p++; p == pe { + goto _test_eof2497 + } + st_case_2497: + switch data[p] { + case 148: + goto tr420 + case 158: + goto tr420 + case 169: + goto tr420 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr2266 + } + case data[p] >= 150: + goto tr2266 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 189: + goto tr420 + } + default: + goto tr126 + } + goto tr148 + st2498: + if p++; p == pe { + goto _test_eof2498 + } + st_case_2498: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto tr2266 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr2266 + } + default: + goto tr148 + } + goto tr420 + st2499: + if p++; p == pe { + goto _test_eof2499 + } + st_case_2499: + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr420 + } + goto tr2266 + st2500: + if p++; p == pe { + goto _test_eof2500 + } + st_case_2500: + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr2266 + } + goto tr148 + st2501: + if p++; p == pe { + goto _test_eof2501 + } + st_case_2501: + if data[p] == 186 { + goto tr148 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 170: + switch { + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 171: + goto tr2266 + } + default: + goto tr148 + } + goto tr420 + st2502: + if p++; p == pe { + goto _test_eof2502 + } + st_case_2502: + switch data[p] { + case 160: + goto st2503 + case 161: + goto st2504 + case 162: + goto st168 + case 163: + goto st2505 + case 164: + goto st2506 + case 165: + goto st2507 + case 166: + goto st2508 + case 167: + goto st2509 + case 168: + goto st2510 + case 169: + goto st2511 + case 170: + goto st2512 + case 171: + goto st2513 + case 172: + goto st2514 + case 173: + goto st2515 + case 174: + goto st2516 + case 175: + goto st2517 + case 176: + goto st2518 + case 177: + goto st2519 + case 178: + goto st2520 + case 179: + goto st2521 + case 180: + goto st2522 + case 181: + goto st2523 + case 182: + goto st2524 + case 183: + goto st2525 + case 184: + goto st2526 + case 185: + goto st2527 + case 186: + goto st2528 + case 187: + goto st2529 + case 188: + goto st2530 + case 189: + goto st2531 + case 190: + goto st2532 + case 191: + goto st2533 + } + goto tr420 + st2503: + if p++; p == pe { + goto _test_eof2503 + } + st_case_2503: + switch data[p] { + case 154: + goto tr148 + case 164: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] > 149: + if 150 <= data[p] && data[p] <= 173 { + goto tr2266 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2504: + if p++; p == pe { + goto _test_eof2504 + } + st_case_2504: + switch { + case data[p] > 152: + if 153 <= data[p] && data[p] <= 155 { + goto tr2266 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2505: + if p++; p == pe { + goto _test_eof2505 + } + st_case_2505: + if 163 <= data[p] { + goto tr2266 + } + goto tr420 + st2506: + if p++; p == pe { + goto _test_eof2506 + } + st_case_2506: + if data[p] == 189 { + goto tr148 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr148 + } + goto tr2266 + st2507: + if p++; p == pe { + goto _test_eof2507 + } + st_case_2507: + switch data[p] { + case 144: + goto tr148 + case 176: + goto tr420 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 177 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr420 + } + goto tr2266 + st2508: + if p++; p == pe { + goto _test_eof2508 + } + st_case_2508: + switch data[p] { + case 132: + goto tr420 + case 169: + goto tr420 + case 177: + goto tr420 + case 188: + goto tr2266 + } + switch { + case data[p] < 145: + switch { + case data[p] > 131: + if 141 <= data[p] && data[p] <= 142 { + goto tr420 + } + case data[p] >= 129: + goto tr2266 + } + case data[p] > 146: + switch { + case data[p] < 186: + if 179 <= data[p] && data[p] <= 181 { + goto tr420 + } + case data[p] > 187: + if 190 <= data[p] { + goto tr2266 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st2509: + if p++; p == pe { + goto _test_eof2509 + } + st_case_2509: + switch data[p] { + case 142: + goto tr148 + case 158: + goto tr420 + } + switch { + case data[p] < 156: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 155 { + goto tr420 + } + case data[p] >= 143: + goto tr420 + } + default: + goto tr420 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr126 + } + default: + goto tr148 + } + goto tr2266 + st2510: + if p++; p == pe { + goto _test_eof2510 + } + st_case_2510: + if data[p] == 188 { + goto tr2266 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2266 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto tr2266 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2511: + if p++; p == pe { + goto _test_eof2511 + } + st_case_2511: + if data[p] == 157 { + goto tr420 + } + switch { + case data[p] < 153: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 146 <= data[p] && data[p] <= 152 { + goto tr420 + } + case data[p] >= 142: + goto tr420 + } + default: + goto tr420 + } + case data[p] > 158: + switch { + case data[p] < 166: + if 159 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr126 + } + default: + goto tr148 + } + goto tr2266 + st2512: + if p++; p == pe { + goto _test_eof2512 + } + st_case_2512: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2266 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto tr2266 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2513: + if p++; p == pe { + goto _test_eof2513 + } + st_case_2513: + switch data[p] { + case 134: + goto tr420 + case 138: + goto tr420 + case 144: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] >= 142: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr420 + } + goto tr2266 + st2514: + if p++; p == pe { + goto _test_eof2514 + } + st_case_2514: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2266 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2266 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2515: + if p++; p == pe { + goto _test_eof2515 + } + st_case_2515: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr2266 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr2266 + } + default: + goto tr2266 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 161: + switch { + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] >= 162: + goto tr2266 + } + default: + goto tr148 + } + default: + goto tr2266 + } + goto tr420 + st2516: + if p++; p == pe { + goto _test_eof2516 + } + st_case_2516: + switch data[p] { + case 130: + goto tr2266 + case 131: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 158: + switch { + case data[p] < 142: + if 133 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 149: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] < 168: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto tr2266 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2517: + if p++; p == pe { + goto _test_eof2517 + } + st_case_2517: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr2266 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr2266 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] >= 138: + goto tr2266 + } + default: + goto tr2266 + } + goto tr420 + st2518: + if p++; p == pe { + goto _test_eof2518 + } + st_case_2518: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto tr2266 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 190 <= data[p] { + goto tr2266 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2519: + if p++; p == pe { + goto _test_eof2519 + } + st_case_2519: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 151: + goto tr420 + } + switch { + case data[p] < 160: + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 148 { + goto tr420 + } + case data[p] > 154: + if 155 <= data[p] && data[p] <= 159 { + goto tr420 + } + default: + goto tr148 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + default: + goto tr126 + } + default: + goto tr148 + } + goto tr2266 + st2520: + if p++; p == pe { + goto _test_eof2520 + } + st_case_2520: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2266 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2266 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2521: + if p++; p == pe { + goto _test_eof2521 + } + st_case_2521: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr2266 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr2266 + } + default: + goto tr2266 + } + case data[p] > 150: + switch { + case data[p] < 162: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 163: + switch { + case data[p] > 175: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr2266 + } + default: + goto tr2266 + } + goto tr420 + st2522: + if p++; p == pe { + goto _test_eof2522 + } + st_case_2522: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto tr2266 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto tr2266 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2523: + if p++; p == pe { + goto _test_eof2523 + } + st_case_2523: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 142: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 150 { + goto tr420 + } + case data[p] > 158: + if 159 <= data[p] && data[p] <= 161 { + goto tr148 + } + default: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr2266 + st2524: + if p++; p == pe { + goto _test_eof2524 + } + st_case_2524: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr2266 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2525: + if p++; p == pe { + goto _test_eof2525 + } + st_case_2525: + switch data[p] { + case 138: + goto tr2266 + case 150: + goto tr2266 + } + switch { + case data[p] < 152: + switch { + case data[p] > 134: + if 143 <= data[p] && data[p] <= 148 { + goto tr2266 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto tr2266 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr2266 + } + goto tr420 + st2526: + if p++; p == pe { + goto _test_eof2526 + } + st_case_2526: + if data[p] == 177 { + goto tr2266 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr2266 + } + goto tr420 + st2527: + if p++; p == pe { + goto _test_eof2527 + } + st_case_2527: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 135: + goto tr2266 + } + goto tr420 + st2528: + if p++; p == pe { + goto _test_eof2528 + } + st_case_2528: + if data[p] == 177 { + goto tr2266 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr2266 + } + case data[p] >= 180: + goto tr2266 + } + goto tr420 + st2529: + if p++; p == pe { + goto _test_eof2529 + } + st_case_2529: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 136: + goto tr2266 + } + goto tr420 + st2530: + if p++; p == pe { + goto _test_eof2530 + } + st_case_2530: + switch data[p] { + case 128: + goto tr148 + case 181: + goto tr2266 + case 183: + goto tr2266 + case 185: + goto tr2266 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto tr2266 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto tr2266 + } + default: + goto tr126 + } + goto tr420 + st2531: + if p++; p == pe { + goto _test_eof2531 + } + st_case_2531: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto tr2266 + } + default: + goto tr148 + } + goto tr420 + st2532: + if p++; p == pe { + goto _test_eof2532 + } + st_case_2532: + switch { + case data[p] < 136: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 135 { + goto tr2266 + } + case data[p] >= 128: + goto tr2266 + } + case data[p] > 140: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr2266 + } + case data[p] >= 141: + goto tr2266 + } + default: + goto tr148 + } + goto tr420 + st2533: + if p++; p == pe { + goto _test_eof2533 + } + st_case_2533: + if data[p] == 134 { + goto tr2266 + } + goto tr420 + st2534: + if p++; p == pe { + goto _test_eof2534 + } + st_case_2534: + switch data[p] { + case 128: + goto st2535 + case 129: + goto st2536 + case 130: + goto st2537 + case 131: + goto st202 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st2538 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st2539 + case 157: + goto st2540 + case 158: + goto st2541 + case 159: + goto st2542 + case 160: + goto st2543 + case 161: + goto st219 + case 162: + goto st2544 + case 163: + goto st221 + case 164: + goto st2545 + case 165: + goto st1649 + case 167: + goto st1650 + case 168: + goto st2546 + case 169: + goto st2547 + case 170: + goto st2548 + case 172: + goto st2549 + case 173: + goto st2550 + case 174: + goto st2551 + case 175: + goto st2552 + case 176: + goto st2553 + case 177: + goto st1659 + case 179: + goto st2554 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st2555 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + } + switch { + case data[p] < 180: + if 132 <= data[p] && data[p] <= 152 { + goto st145 + } + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + default: + goto st147 + } + goto tr420 + st2535: + if p++; p == pe { + goto _test_eof2535 + } + st_case_2535: + if 171 <= data[p] && data[p] <= 190 { + goto tr2266 + } + goto tr420 + st2536: + if p++; p == pe { + goto _test_eof2536 + } + st_case_2536: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto tr2266 + } + case data[p] >= 128: + goto tr126 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto tr2266 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr2266 + } + default: + goto tr2266 + } + default: + goto tr2266 + } + goto tr420 + st2537: + if p++; p == pe { + goto _test_eof2537 + } + st_case_2537: + if data[p] == 143 { + goto tr2266 + } + switch { + case data[p] < 144: + if 130 <= data[p] && data[p] <= 141 { + goto tr2266 + } + case data[p] > 153: + switch { + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 154: + goto tr2266 + } + default: + goto tr126 + } + goto tr420 + st2538: + if p++; p == pe { + goto _test_eof2538 + } + st_case_2538: + switch { + case data[p] < 157: + if 155 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr420 + } + default: + goto tr2266 + } + goto tr148 + st2539: + if p++; p == pe { + goto _test_eof2539 + } + st_case_2539: + switch { + case data[p] < 146: + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 177: + if 178 <= data[p] && data[p] <= 180 { + goto tr2266 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr2266 + } + goto tr420 + st2540: + if p++; p == pe { + goto _test_eof2540 + } + st_case_2540: + switch { + case data[p] < 160: + switch { + case data[p] > 145: + if 146 <= data[p] && data[p] <= 147 { + goto tr2266 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto tr2266 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2541: + if p++; p == pe { + goto _test_eof2541 + } + st_case_2541: + if 180 <= data[p] { + goto tr2266 + } + goto tr420 + st2542: + if p++; p == pe { + goto _test_eof2542 + } + st_case_2542: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 170 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr126 + } + default: + goto tr420 + } + goto tr2266 + st2543: + if p++; p == pe { + goto _test_eof2543 + } + st_case_2543: + switch { + case data[p] < 144: + if 139 <= data[p] && data[p] <= 142 { + goto tr2266 + } + case data[p] > 153: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr126 + } + goto tr420 + st2544: + if p++; p == pe { + goto _test_eof2544 + } + st_case_2544: + if data[p] == 169 { + goto tr2266 + } + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2545: + if p++; p == pe { + goto _test_eof2545 + } + st_case_2545: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr2266 + } + default: + goto tr2266 + } + goto tr420 + st2546: + if p++; p == pe { + goto _test_eof2546 + } + st_case_2546: + switch { + case data[p] > 150: + if 151 <= data[p] && data[p] <= 155 { + goto tr2266 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2547: + if p++; p == pe { + goto _test_eof2547 + } + st_case_2547: + if data[p] == 191 { + goto tr2266 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr2266 + } + case data[p] >= 149: + goto tr2266 + } + goto tr420 + st2548: + if p++; p == pe { + goto _test_eof2548 + } + st_case_2548: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto tr2266 + } + default: + goto tr126 + } + goto tr420 + st2549: + if p++; p == pe { + goto _test_eof2549 + } + st_case_2549: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 132 { + goto tr2266 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr2266 + } + default: + goto tr148 + } + goto tr420 + st2550: + if p++; p == pe { + goto _test_eof2550 + } + st_case_2550: + switch { + case data[p] < 144: + switch { + case data[p] > 139: + if 140 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] >= 133: + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 154: + goto tr420 + } + default: + goto tr126 + } + goto tr2266 + st2551: + if p++; p == pe { + goto _test_eof2551 + } + st_case_2551: + switch { + case data[p] < 161: + switch { + case data[p] > 130: + if 131 <= data[p] && data[p] <= 160 { + goto tr148 + } + case data[p] >= 128: + goto tr2266 + } + case data[p] > 173: + switch { + case data[p] < 176: + if 174 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr148 + } + default: + goto tr126 + } + default: + goto tr2266 + } + goto tr420 + st2552: + if p++; p == pe { + goto _test_eof2552 + } + st_case_2552: + switch { + case data[p] > 179: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr2266 + } + goto tr148 + st2553: + if p++; p == pe { + goto _test_eof2553 + } + st_case_2553: + switch { + case data[p] > 163: + if 164 <= data[p] && data[p] <= 183 { + goto tr2266 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2554: + if p++; p == pe { + goto _test_eof2554 + } + st_case_2554: + if data[p] == 173 { + goto tr2266 + } + switch { + case data[p] < 169: + switch { + case data[p] > 146: + if 148 <= data[p] && data[p] <= 168 { + goto tr2266 + } + case data[p] >= 144: + goto tr2266 + } + case data[p] > 177: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 180 { + goto tr2266 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto tr2266 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2555: + if p++; p == pe { + goto _test_eof2555 + } + st_case_2555: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr2266 + } + case data[p] >= 128: + goto tr2266 + } + goto tr420 + st2556: + if p++; p == pe { + goto _test_eof2556 + } + st_case_2556: + switch data[p] { + case 128: + goto st2557 + case 129: + goto st2558 + case 130: + goto st241 + case 131: + goto st2559 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st2560 + case 180: + goto st251 + case 181: + goto st2561 + case 182: + goto st253 + case 183: + goto st2562 + case 184: + goto st255 + } + goto tr420 + st2557: + if p++; p == pe { + goto _test_eof2557 + } + st_case_2557: + switch { + case data[p] < 170: + if 140 <= data[p] && data[p] <= 143 { + goto tr2266 + } + case data[p] > 174: + if 191 <= data[p] { + goto tr2136 + } + default: + goto tr2266 + } + goto tr420 + st2558: + if p++; p == pe { + goto _test_eof2558 + } + st_case_2558: + switch data[p] { + case 165: + goto tr420 + case 177: + goto tr148 + case 191: + goto tr148 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr2266 + } + default: + goto tr420 + } + goto tr2136 + st2559: + if p++; p == pe { + goto _test_eof2559 + } + st_case_2559: + if 144 <= data[p] && data[p] <= 176 { + goto tr2266 + } + goto tr420 + st2560: + if p++; p == pe { + goto _test_eof2560 + } + st_case_2560: + switch { + case data[p] < 175: + if 165 <= data[p] && data[p] <= 170 { + goto tr420 + } + case data[p] > 177: + if 180 <= data[p] { + goto tr420 + } + default: + goto tr2266 + } + goto tr148 + st2561: + if p++; p == pe { + goto _test_eof2561 + } + st_case_2561: + if data[p] == 191 { + goto tr2266 + } + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 168: + goto tr420 + } + goto tr148 + st2562: + if p++; p == pe { + goto _test_eof2562 + } + st_case_2562: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto tr2266 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2563: + if p++; p == pe { + goto _test_eof2563 + } + st_case_2563: + switch data[p] { + case 128: + goto st2564 + case 130: + goto st2565 + case 131: + goto st1164 + case 132: + goto st259 + case 133: + goto st145 + case 134: + goto st260 + case 135: + goto st1165 + case 139: + goto st1166 + case 140: + goto st1091 + case 141: + goto st1167 + } + goto tr420 + st2564: + if p++; p == pe { + goto _test_eof2564 + } + st_case_2564: + if data[p] == 133 { + goto tr148 + } + switch { + case data[p] < 177: + if 170 <= data[p] && data[p] <= 175 { + goto tr2266 + } + case data[p] > 181: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + default: + goto tr1049 + } + goto tr420 + st2565: + if p++; p == pe { + goto _test_eof2565 + } + st_case_2565: + switch { + case data[p] < 155: + if 153 <= data[p] && data[p] <= 154 { + goto tr2266 + } + case data[p] > 156: + if 160 <= data[p] { + goto tr1049 + } + default: + goto tr1049 + } + goto tr420 + st2566: + if p++; p == pe { + goto _test_eof2566 + } + st_case_2566: + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st1673 + case 153: + goto st2567 + case 154: + goto st2568 + case 155: + goto st2569 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st2570 + case 161: + goto st272 + case 162: + goto st2571 + case 163: + goto st2572 + case 164: + goto st2573 + case 165: + goto st2574 + case 166: + goto st2575 + case 167: + goto st2576 + case 168: + goto st2577 + case 169: + goto st2578 + case 170: + goto st2579 + case 171: + goto st2580 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st2581 + case 176: + goto st147 + } + if 129 <= data[p] { + goto st145 + } + goto tr420 + st2567: + if p++; p == pe { + goto _test_eof2567 + } + st_case_2567: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr2266 + } + default: + goto tr2266 + } + goto tr420 + st2568: + if p++; p == pe { + goto _test_eof2568 + } + st_case_2568: + switch { + case data[p] < 158: + if 128 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr2266 + } + goto tr420 + st2569: + if p++; p == pe { + goto _test_eof2569 + } + st_case_2569: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr2266 + } + goto tr148 + st2570: + if p++; p == pe { + goto _test_eof2570 + } + st_case_2570: + switch data[p] { + case 130: + goto tr2266 + case 134: + goto tr2266 + case 139: + goto tr2266 + } + switch { + case data[p] > 167: + if 168 <= data[p] { + goto tr420 + } + case data[p] >= 163: + goto tr2266 + } + goto tr148 + st2571: + if p++; p == pe { + goto _test_eof2571 + } + st_case_2571: + switch { + case data[p] < 130: + if 128 <= data[p] && data[p] <= 129 { + goto tr2266 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr2266 + } + default: + goto tr148 + } + goto tr420 + st2572: + if p++; p == pe { + goto _test_eof2572 + } + st_case_2572: + switch data[p] { + case 187: + goto tr148 + case 189: + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 143: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 133: + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 183: + if 184 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr420 + } + goto tr2266 + st2573: + if p++; p == pe { + goto _test_eof2573 + } + st_case_2573: + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 165: + switch { + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr2266 + } + default: + goto tr148 + } + goto tr420 + st2574: + if p++; p == pe { + goto _test_eof2574 + } + st_case_2574: + switch { + case data[p] < 148: + if 135 <= data[p] && data[p] <= 147 { + goto tr2266 + } + case data[p] > 159: + if 189 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st2575: + if p++; p == pe { + goto _test_eof2575 + } + st_case_2575: + switch { + case data[p] < 132: + if 128 <= data[p] && data[p] <= 131 { + goto tr2266 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr2266 + } + default: + goto tr148 + } + goto tr420 + st2576: + if p++; p == pe { + goto _test_eof2576 + } + st_case_2576: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 129: + goto tr420 + } + case data[p] > 164: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr420 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + default: + goto tr126 + } + default: + goto tr420 + } + goto tr2266 + st2577: + if p++; p == pe { + goto _test_eof2577 + } + st_case_2577: + switch { + case data[p] > 168: + if 169 <= data[p] && data[p] <= 182 { + goto tr2266 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2578: + if p++; p == pe { + goto _test_eof2578 + } + st_case_2578: + if data[p] == 131 { + goto tr2266 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 141: + switch { + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto tr2266 + } + case data[p] >= 144: + goto tr126 + } + default: + goto tr2266 + } + goto tr420 + st2579: + if p++; p == pe { + goto _test_eof2579 + } + st_case_2579: + if data[p] == 176 { + goto tr2266 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr2266 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr2266 + } + default: + goto tr2266 + } + goto tr420 + st2580: + if p++; p == pe { + goto _test_eof2580 + } + st_case_2580: + if data[p] == 129 { + goto tr2266 + } + switch { + case data[p] < 171: + if 160 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 181 <= data[p] && data[p] <= 182 { + goto tr2266 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr2266 + } + goto tr420 + st2581: + if p++; p == pe { + goto _test_eof2581 + } + st_case_2581: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 162 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + case data[p] >= 172: + goto tr2266 + } + default: + goto tr2266 + } + goto tr420 + st2582: + if p++; p == pe { + goto _test_eof2582 + } + st_case_2582: + switch data[p] { + case 172: + goto st2583 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st2584 + case 185: + goto st2436 + case 187: + goto st2585 + case 188: + goto st2438 + case 189: + goto st1261 + case 190: + goto st2586 + case 191: + goto st2587 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr420 + st2583: + if p++; p == pe { + goto _test_eof2583 + } + st_case_2583: + switch data[p] { + case 158: + goto tr2266 + case 190: + goto tr572 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 170: + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st2584: + if p++; p == pe { + goto _test_eof2584 + } + st_case_2584: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr2266 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr2136 + } + default: + goto tr2266 + } + goto tr420 + st2585: + if p++; p == pe { + goto _test_eof2585 + } + st_case_2585: + if data[p] == 191 { + goto tr2266 + } + if 189 <= data[p] { + goto tr420 + } + goto tr148 + st2586: + if p++; p == pe { + goto _test_eof2586 + } + st_case_2586: + switch { + case data[p] < 160: + if 158 <= data[p] && data[p] <= 159 { + goto tr2266 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + goto tr1049 + st2587: + if p++; p == pe { + goto _test_eof2587 + } + st_case_2587: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] >= 130: + goto tr148 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr2266 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2588: + if p++; p == pe { + goto _test_eof2588 + } + st_case_2588: + switch data[p] { + case 144: + goto st2589 + case 145: + goto st2595 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st2614 + case 155: + goto st2619 + case 157: + goto st2621 + case 158: + goto st2628 + case 159: + goto st403 + } + goto tr420 + st2589: + if p++; p == pe { + goto _test_eof2589 + } + st_case_2589: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st2590 + case 138: + goto st313 + case 139: + goto st2591 + case 140: + goto st315 + case 141: + goto st2592 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st1702 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st2593 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st2594 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr420 + st2590: + if p++; p == pe { + goto _test_eof2590 + } + st_case_2590: + if data[p] == 189 { + goto tr2266 + } + goto tr420 + st2591: + if p++; p == pe { + goto _test_eof2591 + } + st_case_2591: + if data[p] == 160 { + goto tr2266 + } + if 145 <= data[p] { + goto tr420 + } + goto tr148 + st2592: + if p++; p == pe { + goto _test_eof2592 + } + st_case_2592: + switch { + case data[p] < 182: + if 139 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr420 + } + default: + goto tr2266 + } + goto tr148 + st2593: + if p++; p == pe { + goto _test_eof2593 + } + st_case_2593: + switch data[p] { + case 128: + goto tr148 + case 191: + goto tr2266 + } + switch { + case data[p] < 144: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2266 + } + case data[p] > 134: + if 140 <= data[p] && data[p] <= 143 { + goto tr2266 + } + default: + goto tr2266 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto tr2266 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2594: + if p++; p == pe { + goto _test_eof2594 + } + st_case_2594: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 164: + if 165 <= data[p] && data[p] <= 166 { + goto tr2266 + } + default: + goto tr148 + } + goto tr420 + st2595: + if p++; p == pe { + goto _test_eof2595 + } + st_case_2595: + switch data[p] { + case 128: + goto st2596 + case 129: + goto st2597 + case 130: + goto st2598 + case 131: + goto st1709 + case 132: + goto st2599 + case 133: + goto st2600 + case 134: + goto st2601 + case 135: + goto st2602 + case 136: + goto st2603 + case 138: + goto st348 + case 139: + goto st2604 + case 140: + goto st2605 + case 141: + goto st2606 + case 146: + goto st2607 + case 147: + goto st2608 + case 150: + goto st2609 + case 151: + goto st2610 + case 152: + goto st2607 + case 153: + goto st2611 + case 154: + goto st2612 + case 155: + goto st1724 + case 156: + goto st2613 + case 162: + goto st359 + case 163: + goto st1726 + case 171: + goto st361 + } + goto tr420 + st2596: + if p++; p == pe { + goto _test_eof2596 + } + st_case_2596: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2266 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr2266 + } + default: + goto tr148 + } + goto tr420 + st2597: + if p++; p == pe { + goto _test_eof2597 + } + st_case_2597: + switch { + case data[p] < 166: + if 135 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] && data[p] <= 190 { + goto tr420 + } + default: + goto tr126 + } + goto tr2266 + st2598: + if p++; p == pe { + goto _test_eof2598 + } + st_case_2598: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr2266 + st2599: + if p++; p == pe { + goto _test_eof2599 + } + st_case_2599: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2266 + } + case data[p] > 166: + switch { + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr126 + } + case data[p] >= 167: + goto tr2266 + } + default: + goto tr148 + } + goto tr420 + st2600: + if p++; p == pe { + goto _test_eof2600 + } + st_case_2600: + switch data[p] { + case 179: + goto tr2266 + case 182: + goto tr148 + } + if 144 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr420 + st2601: + if p++; p == pe { + goto _test_eof2601 + } + st_case_2601: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2266 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr2266 + } + default: + goto tr148 + } + goto tr420 + st2602: + if p++; p == pe { + goto _test_eof2602 + } + st_case_2602: + if data[p] == 155 { + goto tr420 + } + switch { + case data[p] < 141: + switch { + case data[p] > 132: + if 133 <= data[p] && data[p] <= 137 { + goto tr420 + } + case data[p] >= 129: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] < 154: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] > 156: + if 157 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + default: + goto tr420 + } + goto tr2266 + st2603: + if p++; p == pe { + goto _test_eof2603 + } + st_case_2603: + switch { + case data[p] < 147: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] > 171: + if 172 <= data[p] && data[p] <= 183 { + goto tr2266 + } + default: + goto tr148 + } + goto tr420 + st2604: + if p++; p == pe { + goto _test_eof2604 + } + st_case_2604: + switch { + case data[p] < 171: + if 159 <= data[p] && data[p] <= 170 { + goto tr2266 + } + case data[p] > 175: + switch { + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr126 + } + default: + goto tr420 + } + goto tr148 + st2605: + if p++; p == pe { + goto _test_eof2605 + } + st_case_2605: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto tr2266 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2266 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2606: + if p++; p == pe { + goto _test_eof2606 + } + st_case_2606: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr2266 + } + switch { + case data[p] < 157: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr2266 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr2266 + } + default: + goto tr2266 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr2266 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr2266 + } + default: + goto tr2266 + } + default: + goto tr148 + } + goto tr420 + st2607: + if p++; p == pe { + goto _test_eof2607 + } + st_case_2607: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr2266 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2608: + if p++; p == pe { + goto _test_eof2608 + } + st_case_2608: + if data[p] == 134 { + goto tr420 + } + switch { + case data[p] < 136: + if 132 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + case data[p] >= 144: + goto tr126 + } + default: + goto tr420 + } + goto tr2266 + st2609: + if p++; p == pe { + goto _test_eof2609 + } + st_case_2609: + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 181: + if 184 <= data[p] { + goto tr2266 + } + default: + goto tr2266 + } + goto tr420 + st2610: + if p++; p == pe { + goto _test_eof2610 + } + st_case_2610: + switch { + case data[p] < 152: + if 129 <= data[p] && data[p] <= 151 { + goto tr420 + } + case data[p] > 155: + if 158 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + goto tr2266 + st2611: + if p++; p == pe { + goto _test_eof2611 + } + st_case_2611: + if data[p] == 132 { + goto tr148 + } + switch { + case data[p] < 144: + if 129 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + default: + goto tr126 + } + goto tr2266 + st2612: + if p++; p == pe { + goto _test_eof2612 + } + st_case_2612: + switch { + case data[p] > 170: + if 171 <= data[p] && data[p] <= 183 { + goto tr2266 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2613: + if p++; p == pe { + goto _test_eof2613 + } + st_case_2613: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + case data[p] >= 157: + goto tr2266 + } + goto tr420 + st2614: + if p++; p == pe { + goto _test_eof2614 + } + st_case_2614: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st1728 + case 171: + goto st2615 + case 172: + goto st2616 + case 173: + goto st1731 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st2617 + case 190: + goto st2618 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr420 + st2615: + if p++; p == pe { + goto _test_eof2615 + } + st_case_2615: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto tr2266 + } + case data[p] >= 144: + goto tr148 + } + goto tr420 + st2616: + if p++; p == pe { + goto _test_eof2616 + } + st_case_2616: + switch { + case data[p] > 175: + if 176 <= data[p] && data[p] <= 182 { + goto tr2266 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2617: + if p++; p == pe { + goto _test_eof2617 + } + st_case_2617: + switch { + case data[p] < 145: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr420 + } + default: + goto tr2266 + } + goto tr148 + st2618: + if p++; p == pe { + goto _test_eof2618 + } + st_case_2618: + switch { + case data[p] > 146: + if 147 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 143: + goto tr2266 + } + goto tr420 + st2619: + if p++; p == pe { + goto _test_eof2619 + } + st_case_2619: + switch data[p] { + case 128: + goto st1224 + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st2620 + } + goto tr420 + st2620: + if p++; p == pe { + goto _test_eof2620 + } + st_case_2620: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr2266 + } + case data[p] >= 157: + goto tr2266 + } + default: + goto tr148 + } + goto tr420 + st2621: + if p++; p == pe { + goto _test_eof2621 + } + st_case_2621: + switch data[p] { + case 133: + goto st2622 + case 134: + goto st2623 + case 137: + goto st2624 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st1740 + case 168: + goto st2625 + case 169: + goto st2626 + case 170: + goto st2627 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr420 + st2622: + if p++; p == pe { + goto _test_eof2622 + } + st_case_2622: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr2266 + } + case data[p] >= 165: + goto tr2266 + } + goto tr420 + st2623: + if p++; p == pe { + goto _test_eof2623 + } + st_case_2623: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr420 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr2266 + st2624: + if p++; p == pe { + goto _test_eof2624 + } + st_case_2624: + if 130 <= data[p] && data[p] <= 132 { + goto tr2266 + } + goto tr420 + st2625: + if p++; p == pe { + goto _test_eof2625 + } + st_case_2625: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr2266 + } + case data[p] >= 128: + goto tr2266 + } + goto tr420 + st2626: + if p++; p == pe { + goto _test_eof2626 + } + st_case_2626: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 173: + goto tr420 + } + goto tr2266 + st2627: + if p++; p == pe { + goto _test_eof2627 + } + st_case_2627: + if data[p] == 132 { + goto tr2266 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr2266 + } + case data[p] >= 155: + goto tr2266 + } + goto tr420 + st2628: + if p++; p == pe { + goto _test_eof2628 + } + st_case_2628: + switch data[p] { + case 160: + goto st147 + case 163: + goto st2629 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr420 + st2629: + if p++; p == pe { + goto _test_eof2629 + } + st_case_2629: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 150: + if 151 <= data[p] { + goto tr420 + } + default: + goto tr2266 + } + goto tr148 + st2630: + if p++; p == pe { + goto _test_eof2630 + } + st_case_2630: + if data[p] == 160 { + goto st2631 + } + goto tr420 + st2631: + if p++; p == pe { + goto _test_eof2631 + } + st_case_2631: + switch data[p] { + case 128: + goto st2632 + case 129: + goto st2633 + case 132: + goto st2490 + case 135: + goto st2635 + } + if 133 <= data[p] && data[p] <= 134 { + goto st2634 + } + goto tr420 + st2632: + if p++; p == pe { + goto _test_eof2632 + } + st_case_2632: + if data[p] == 129 { + goto tr2266 + } + if 160 <= data[p] { + goto tr2266 + } + goto tr420 + st2633: + if p++; p == pe { + goto _test_eof2633 + } + st_case_2633: + if 192 <= data[p] { + goto tr420 + } + goto tr2266 + st2634: + if p++; p == pe { + goto _test_eof2634 + } + st_case_2634: + goto tr2266 + st2635: + if p++; p == pe { + goto _test_eof2635 + } + st_case_2635: + if 176 <= data[p] { + goto tr420 + } + goto tr2266 +tr4464: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4877 + st4877: + if p++; p == pe { + goto _test_eof4877 + } + st_case_4877: +//line segment_words_prod.go:69822 + switch data[p] { + case 133: + goto tr3249 + case 170: + goto tr148 + case 173: + goto tr2395 + case 181: + goto tr148 + case 186: + goto tr148 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr2395: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st4878 + st4878: + if p++; p == pe { + goto _test_eof4878 + } + st_case_4878: +//line segment_words_prod.go:69894 + switch data[p] { + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + goto tr4763 + st2636: + if p++; p == pe { + goto _test_eof2636 + } + st_case_2636: + if data[p] == 173 { + goto tr2395 + } + goto tr2394 + st2637: + if p++; p == pe { + goto _test_eof2637 + } + st_case_2637: + if 128 <= data[p] { + goto tr2395 + } + goto tr2 + st2638: + if p++; p == pe { + goto _test_eof2638 + } + st_case_2638: + if 176 <= data[p] { + goto tr2 + } + goto tr2395 + st2639: + if p++; p == pe { + goto _test_eof2639 + } + st_case_2639: + if 131 <= data[p] && data[p] <= 137 { + goto tr2395 + } + goto tr2394 + st2640: + if p++; p == pe { + goto _test_eof2640 + } + st_case_2640: + if data[p] == 191 { + goto tr2395 + } + if 145 <= data[p] && data[p] <= 189 { + goto tr2395 + } + goto tr2394 + st2641: + if p++; p == pe { + goto _test_eof2641 + } + st_case_2641: + if data[p] == 135 { + goto tr2395 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto tr2395 + } + case data[p] >= 129: + goto tr2395 + } + goto tr2394 + st2642: + if p++; p == pe { + goto _test_eof2642 + } + st_case_2642: + if data[p] == 156 { + goto tr2395 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto tr2395 + } + case data[p] >= 128: + goto tr2395 + } + goto tr2394 + st2643: + if p++; p == pe { + goto _test_eof2643 + } + st_case_2643: + if data[p] == 176 { + goto tr2395 + } + if 139 <= data[p] && data[p] <= 159 { + goto tr2395 + } + goto tr2394 + st2644: + if p++; p == pe { + goto _test_eof2644 + } + st_case_2644: + switch { + case data[p] < 159: + if 150 <= data[p] && data[p] <= 157 { + goto tr2395 + } + case data[p] > 164: + switch { + case data[p] > 168: + if 170 <= data[p] && data[p] <= 173 { + goto tr2395 + } + case data[p] >= 167: + goto tr2395 + } + default: + goto tr2395 + } + goto tr2394 + st2645: + if p++; p == pe { + goto _test_eof2645 + } + st_case_2645: + switch data[p] { + case 143: + goto tr2395 + case 145: + goto tr2395 + } + if 176 <= data[p] { + goto tr2395 + } + goto tr2394 + st2646: + if p++; p == pe { + goto _test_eof2646 + } + st_case_2646: + if 139 <= data[p] { + goto tr2394 + } + goto tr2395 + st2647: + if p++; p == pe { + goto _test_eof2647 + } + st_case_2647: + if 166 <= data[p] && data[p] <= 176 { + goto tr2395 + } + goto tr2394 + st2648: + if p++; p == pe { + goto _test_eof2648 + } + st_case_2648: + if 171 <= data[p] && data[p] <= 179 { + goto tr2395 + } + goto tr2394 + st2649: + if p++; p == pe { + goto _test_eof2649 + } + st_case_2649: + switch data[p] { + case 160: + goto st2650 + case 161: + goto st2651 + case 163: + goto st2652 + case 164: + goto st2653 + case 165: + goto st2654 + case 167: + goto st2656 + case 169: + goto st2657 + case 171: + goto st2658 + case 173: + goto st2660 + case 174: + goto st2661 + case 175: + goto st2662 + case 176: + goto st2663 + case 177: + goto st2664 + case 179: + goto st2665 + case 180: + goto st2666 + case 181: + goto st2667 + case 182: + goto st2668 + case 183: + goto st2669 + case 184: + goto st2670 + case 185: + goto st2671 + case 186: + goto st2672 + case 187: + goto st2673 + case 188: + goto st2674 + case 189: + goto st2675 + case 190: + goto st2676 + case 191: + goto st2677 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto st2659 + } + case data[p] >= 166: + goto st2655 + } + goto tr2394 + st2650: + if p++; p == pe { + goto _test_eof2650 + } + st_case_2650: + switch { + case data[p] < 155: + if 150 <= data[p] && data[p] <= 153 { + goto tr2395 + } + case data[p] > 163: + switch { + case data[p] > 167: + if 169 <= data[p] && data[p] <= 173 { + goto tr2395 + } + case data[p] >= 165: + goto tr2395 + } + default: + goto tr2395 + } + goto tr2 + st2651: + if p++; p == pe { + goto _test_eof2651 + } + st_case_2651: + if 153 <= data[p] && data[p] <= 155 { + goto tr2395 + } + goto tr2 + st2652: + if p++; p == pe { + goto _test_eof2652 + } + st_case_2652: + if 163 <= data[p] { + goto tr2395 + } + goto tr2 + st2653: + if p++; p == pe { + goto _test_eof2653 + } + st_case_2653: + if data[p] == 189 { + goto tr2 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr2 + } + goto tr2395 + st2654: + if p++; p == pe { + goto _test_eof2654 + } + st_case_2654: + if data[p] == 144 { + goto tr2 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr2 + } + case data[p] >= 152: + goto tr2 + } + goto tr2395 + st2655: + if p++; p == pe { + goto _test_eof2655 + } + st_case_2655: + if data[p] == 188 { + goto tr2395 + } + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr2395 + } + case data[p] >= 129: + goto tr2395 + } + goto tr2 + st2656: + if p++; p == pe { + goto _test_eof2656 + } + st_case_2656: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr2 + } + case data[p] >= 133: + goto tr2 + } + case data[p] > 150: + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr2 + } + case data[p] >= 152: + goto tr2 + } + default: + goto tr2 + } + goto tr2395 + st2657: + if p++; p == pe { + goto _test_eof2657 + } + st_case_2657: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr2 + } + case data[p] >= 131: + goto tr2 + } + case data[p] > 144: + switch { + case data[p] < 178: + if 146 <= data[p] && data[p] <= 175 { + goto tr2 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + default: + goto tr2 + } + goto tr2395 + st2658: + if p++; p == pe { + goto _test_eof2658 + } + st_case_2658: + switch data[p] { + case 134: + goto tr2 + case 138: + goto tr2 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr2 + } + case data[p] >= 142: + goto tr2 + } + goto tr2395 + st2659: + if p++; p == pe { + goto _test_eof2659 + } + st_case_2659: + if data[p] == 188 { + goto tr2395 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr2395 + } + case data[p] >= 129: + goto tr2395 + } + goto tr2 + st2660: + if p++; p == pe { + goto _test_eof2660 + } + st_case_2660: + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr2395 + } + case data[p] >= 128: + goto tr2395 + } + case data[p] > 141: + switch { + case data[p] > 151: + if 162 <= data[p] && data[p] <= 163 { + goto tr2395 + } + case data[p] >= 150: + goto tr2395 + } + default: + goto tr2395 + } + goto tr2 + st2661: + if p++; p == pe { + goto _test_eof2661 + } + st_case_2661: + if data[p] == 130 { + goto tr2395 + } + if 190 <= data[p] && data[p] <= 191 { + goto tr2395 + } + goto tr2 + st2662: + if p++; p == pe { + goto _test_eof2662 + } + st_case_2662: + if data[p] == 151 { + goto tr2395 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr2395 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr2395 + } + default: + goto tr2395 + } + goto tr2 + st2663: + if p++; p == pe { + goto _test_eof2663 + } + st_case_2663: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr2395 + } + case data[p] >= 128: + goto tr2395 + } + goto tr2 + st2664: + if p++; p == pe { + goto _test_eof2664 + } + st_case_2664: + switch data[p] { + case 133: + goto tr2 + case 137: + goto tr2 + } + switch { + case data[p] < 151: + if 142 <= data[p] && data[p] <= 148 { + goto tr2 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr2395 + st2665: + if p++; p == pe { + goto _test_eof2665 + } + st_case_2665: + switch { + case data[p] < 138: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 136 { + goto tr2395 + } + case data[p] >= 128: + goto tr2395 + } + case data[p] > 141: + switch { + case data[p] > 150: + if 162 <= data[p] && data[p] <= 163 { + goto tr2395 + } + case data[p] >= 149: + goto tr2395 + } + default: + goto tr2395 + } + goto tr2 + st2666: + if p++; p == pe { + goto _test_eof2666 + } + st_case_2666: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr2395 + } + case data[p] >= 129: + goto tr2395 + } + goto tr2 + st2667: + if p++; p == pe { + goto _test_eof2667 + } + st_case_2667: + switch data[p] { + case 133: + goto tr2 + case 137: + goto tr2 + } + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 150 { + goto tr2 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr2395 + st2668: + if p++; p == pe { + goto _test_eof2668 + } + st_case_2668: + if 130 <= data[p] && data[p] <= 131 { + goto tr2395 + } + goto tr2 + st2669: + if p++; p == pe { + goto _test_eof2669 + } + st_case_2669: + switch data[p] { + case 138: + goto tr2395 + case 150: + goto tr2395 + } + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 148 { + goto tr2395 + } + case data[p] > 159: + if 178 <= data[p] && data[p] <= 179 { + goto tr2395 + } + default: + goto tr2395 + } + goto tr2 + st2670: + if p++; p == pe { + goto _test_eof2670 + } + st_case_2670: + if data[p] == 177 { + goto tr2395 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr2395 + } + goto tr2 + st2671: + if p++; p == pe { + goto _test_eof2671 + } + st_case_2671: + if 135 <= data[p] && data[p] <= 142 { + goto tr2395 + } + goto tr2 + st2672: + if p++; p == pe { + goto _test_eof2672 + } + st_case_2672: + if data[p] == 177 { + goto tr2395 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr2395 + } + case data[p] >= 180: + goto tr2395 + } + goto tr2 + st2673: + if p++; p == pe { + goto _test_eof2673 + } + st_case_2673: + if 136 <= data[p] && data[p] <= 141 { + goto tr2395 + } + goto tr2 + st2674: + if p++; p == pe { + goto _test_eof2674 + } + st_case_2674: + switch data[p] { + case 181: + goto tr2395 + case 183: + goto tr2395 + case 185: + goto tr2395 + } + switch { + case data[p] > 153: + if 190 <= data[p] && data[p] <= 191 { + goto tr2395 + } + case data[p] >= 152: + goto tr2395 + } + goto tr2 + st2675: + if p++; p == pe { + goto _test_eof2675 + } + st_case_2675: + if 177 <= data[p] && data[p] <= 191 { + goto tr2395 + } + goto tr2 + st2676: + if p++; p == pe { + goto _test_eof2676 + } + st_case_2676: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr2395 + } + case data[p] > 135: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr2395 + } + case data[p] >= 141: + goto tr2395 + } + default: + goto tr2395 + } + goto tr2 + st2677: + if p++; p == pe { + goto _test_eof2677 + } + st_case_2677: + if data[p] == 134 { + goto tr2395 + } + goto tr2 + st2678: + if p++; p == pe { + goto _test_eof2678 + } + st_case_2678: + switch data[p] { + case 128: + goto st2679 + case 129: + goto st2680 + case 130: + goto st2681 + case 141: + goto st2682 + case 156: + goto st2683 + case 157: + goto st2684 + case 158: + goto st2685 + case 159: + goto st2686 + case 160: + goto st2687 + case 162: + goto st2688 + case 164: + goto st2689 + case 168: + goto st2690 + case 169: + goto st2691 + case 170: + goto st2692 + case 172: + goto st2693 + case 173: + goto st2694 + case 174: + goto st2695 + case 175: + goto st2696 + case 176: + goto st2697 + case 179: + goto st2698 + case 183: + goto st2699 + } + goto tr2394 + st2679: + if p++; p == pe { + goto _test_eof2679 + } + st_case_2679: + if 171 <= data[p] && data[p] <= 190 { + goto tr2395 + } + goto tr2 + st2680: + if p++; p == pe { + goto _test_eof2680 + } + st_case_2680: + switch { + case data[p] < 162: + switch { + case data[p] > 153: + if 158 <= data[p] && data[p] <= 160 { + goto tr2395 + } + case data[p] >= 150: + goto tr2395 + } + case data[p] > 164: + switch { + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr2395 + } + case data[p] >= 167: + goto tr2395 + } + default: + goto tr2395 + } + goto tr2 + st2681: + if p++; p == pe { + goto _test_eof2681 + } + st_case_2681: + if data[p] == 143 { + goto tr2395 + } + switch { + case data[p] > 141: + if 154 <= data[p] && data[p] <= 157 { + goto tr2395 + } + case data[p] >= 130: + goto tr2395 + } + goto tr2 + st2682: + if p++; p == pe { + goto _test_eof2682 + } + st_case_2682: + if 157 <= data[p] && data[p] <= 159 { + goto tr2395 + } + goto tr2 + st2683: + if p++; p == pe { + goto _test_eof2683 + } + st_case_2683: + switch { + case data[p] > 148: + if 178 <= data[p] && data[p] <= 180 { + goto tr2395 + } + case data[p] >= 146: + goto tr2395 + } + goto tr2 + st2684: + if p++; p == pe { + goto _test_eof2684 + } + st_case_2684: + switch { + case data[p] > 147: + if 178 <= data[p] && data[p] <= 179 { + goto tr2395 + } + case data[p] >= 146: + goto tr2395 + } + goto tr2 + st2685: + if p++; p == pe { + goto _test_eof2685 + } + st_case_2685: + if 180 <= data[p] { + goto tr2395 + } + goto tr2 + st2686: + if p++; p == pe { + goto _test_eof2686 + } + st_case_2686: + switch { + case data[p] > 156: + if 158 <= data[p] { + goto tr2 + } + case data[p] >= 148: + goto tr2 + } + goto tr2395 + st2687: + if p++; p == pe { + goto _test_eof2687 + } + st_case_2687: + if 139 <= data[p] && data[p] <= 142 { + goto tr2395 + } + goto tr2 + st2688: + if p++; p == pe { + goto _test_eof2688 + } + st_case_2688: + if data[p] == 169 { + goto tr2395 + } + goto tr2 + st2689: + if p++; p == pe { + goto _test_eof2689 + } + st_case_2689: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr2395 + } + case data[p] >= 160: + goto tr2395 + } + goto tr2 + st2690: + if p++; p == pe { + goto _test_eof2690 + } + st_case_2690: + if 151 <= data[p] && data[p] <= 155 { + goto tr2395 + } + goto tr2 + st2691: + if p++; p == pe { + goto _test_eof2691 + } + st_case_2691: + if data[p] == 191 { + goto tr2395 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr2395 + } + case data[p] >= 149: + goto tr2395 + } + goto tr2 + st2692: + if p++; p == pe { + goto _test_eof2692 + } + st_case_2692: + if 176 <= data[p] && data[p] <= 190 { + goto tr2395 + } + goto tr2 + st2693: + if p++; p == pe { + goto _test_eof2693 + } + st_case_2693: + switch { + case data[p] > 132: + if 180 <= data[p] { + goto tr2395 + } + case data[p] >= 128: + goto tr2395 + } + goto tr2 + st2694: + if p++; p == pe { + goto _test_eof2694 + } + st_case_2694: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr2 + } + case data[p] >= 133: + goto tr2 + } + goto tr2395 + st2695: + if p++; p == pe { + goto _test_eof2695 + } + st_case_2695: + switch { + case data[p] > 130: + if 161 <= data[p] && data[p] <= 173 { + goto tr2395 + } + case data[p] >= 128: + goto tr2395 + } + goto tr2 + st2696: + if p++; p == pe { + goto _test_eof2696 + } + st_case_2696: + if 166 <= data[p] && data[p] <= 179 { + goto tr2395 + } + goto tr2 + st2697: + if p++; p == pe { + goto _test_eof2697 + } + st_case_2697: + if 164 <= data[p] && data[p] <= 183 { + goto tr2395 + } + goto tr2 + st2698: + if p++; p == pe { + goto _test_eof2698 + } + st_case_2698: + if data[p] == 173 { + goto tr2395 + } + switch { + case data[p] < 148: + if 144 <= data[p] && data[p] <= 146 { + goto tr2395 + } + case data[p] > 168: + switch { + case data[p] > 180: + if 184 <= data[p] && data[p] <= 185 { + goto tr2395 + } + case data[p] >= 178: + goto tr2395 + } + default: + goto tr2395 + } + goto tr2 + st2699: + if p++; p == pe { + goto _test_eof2699 + } + st_case_2699: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr2395 + } + case data[p] >= 128: + goto tr2395 + } + goto tr2 + st2700: + if p++; p == pe { + goto _test_eof2700 + } + st_case_2700: + switch data[p] { + case 128: + goto st2701 + case 129: + goto st2702 + case 131: + goto st2703 + case 179: + goto st2704 + case 181: + goto st2705 + case 183: + goto st2706 + } + goto tr2394 + st2701: + if p++; p == pe { + goto _test_eof2701 + } + st_case_2701: + switch { + case data[p] > 143: + if 170 <= data[p] && data[p] <= 174 { + goto tr2395 + } + case data[p] >= 140: + goto tr2395 + } + goto tr2 + st2702: + if p++; p == pe { + goto _test_eof2702 + } + st_case_2702: + switch { + case data[p] > 164: + if 166 <= data[p] && data[p] <= 175 { + goto tr2395 + } + case data[p] >= 160: + goto tr2395 + } + goto tr2 + st2703: + if p++; p == pe { + goto _test_eof2703 + } + st_case_2703: + if 144 <= data[p] && data[p] <= 176 { + goto tr2395 + } + goto tr2 + st2704: + if p++; p == pe { + goto _test_eof2704 + } + st_case_2704: + if 175 <= data[p] && data[p] <= 177 { + goto tr2395 + } + goto tr2 + st2705: + if p++; p == pe { + goto _test_eof2705 + } + st_case_2705: + if data[p] == 191 { + goto tr2395 + } + goto tr2 + st2706: + if p++; p == pe { + goto _test_eof2706 + } + st_case_2706: + if 160 <= data[p] && data[p] <= 191 { + goto tr2395 + } + goto tr2 + st2707: + if p++; p == pe { + goto _test_eof2707 + } + st_case_2707: + switch data[p] { + case 128: + goto st2708 + case 130: + goto st2709 + } + goto tr2394 + st2708: + if p++; p == pe { + goto _test_eof2708 + } + st_case_2708: + if 170 <= data[p] && data[p] <= 175 { + goto tr2395 + } + goto tr2 + st2709: + if p++; p == pe { + goto _test_eof2709 + } + st_case_2709: + if 153 <= data[p] && data[p] <= 154 { + goto tr2395 + } + goto tr2 + st2710: + if p++; p == pe { + goto _test_eof2710 + } + st_case_2710: + switch data[p] { + case 153: + goto st2711 + case 154: + goto st2712 + case 155: + goto st2713 + case 160: + goto st2714 + case 162: + goto st2715 + case 163: + goto st2716 + case 164: + goto st2717 + case 165: + goto st2718 + case 166: + goto st2719 + case 167: + goto st2720 + case 168: + goto st2721 + case 169: + goto st2722 + case 170: + goto st2723 + case 171: + goto st2724 + case 175: + goto st2725 + } + goto tr2394 + st2711: + if p++; p == pe { + goto _test_eof2711 + } + st_case_2711: + switch { + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr2395 + } + case data[p] >= 175: + goto tr2395 + } + goto tr2 + st2712: + if p++; p == pe { + goto _test_eof2712 + } + st_case_2712: + if 158 <= data[p] && data[p] <= 159 { + goto tr2395 + } + goto tr2 + st2713: + if p++; p == pe { + goto _test_eof2713 + } + st_case_2713: + if 176 <= data[p] && data[p] <= 177 { + goto tr2395 + } + goto tr2 + st2714: + if p++; p == pe { + goto _test_eof2714 + } + st_case_2714: + switch data[p] { + case 130: + goto tr2395 + case 134: + goto tr2395 + case 139: + goto tr2395 + } + if 163 <= data[p] && data[p] <= 167 { + goto tr2395 + } + goto tr2 + st2715: + if p++; p == pe { + goto _test_eof2715 + } + st_case_2715: + switch { + case data[p] > 129: + if 180 <= data[p] { + goto tr2395 + } + case data[p] >= 128: + goto tr2395 + } + goto tr2 + st2716: + if p++; p == pe { + goto _test_eof2716 + } + st_case_2716: + switch { + case data[p] > 159: + if 178 <= data[p] { + goto tr2 + } + case data[p] >= 133: + goto tr2 + } + goto tr2395 + st2717: + if p++; p == pe { + goto _test_eof2717 + } + st_case_2717: + if 166 <= data[p] && data[p] <= 173 { + goto tr2395 + } + goto tr2 + st2718: + if p++; p == pe { + goto _test_eof2718 + } + st_case_2718: + if 135 <= data[p] && data[p] <= 147 { + goto tr2395 + } + goto tr2 + st2719: + if p++; p == pe { + goto _test_eof2719 + } + st_case_2719: + switch { + case data[p] > 131: + if 179 <= data[p] { + goto tr2395 + } + case data[p] >= 128: + goto tr2395 + } + goto tr2 + st2720: + if p++; p == pe { + goto _test_eof2720 + } + st_case_2720: + switch { + case data[p] > 164: + if 166 <= data[p] { + goto tr2 + } + case data[p] >= 129: + goto tr2 + } + goto tr2395 + st2721: + if p++; p == pe { + goto _test_eof2721 + } + st_case_2721: + if 169 <= data[p] && data[p] <= 182 { + goto tr2395 + } + goto tr2 + st2722: + if p++; p == pe { + goto _test_eof2722 + } + st_case_2722: + if data[p] == 131 { + goto tr2395 + } + switch { + case data[p] > 141: + if 187 <= data[p] && data[p] <= 189 { + goto tr2395 + } + case data[p] >= 140: + goto tr2395 + } + goto tr2 + st2723: + if p++; p == pe { + goto _test_eof2723 + } + st_case_2723: + if data[p] == 176 { + goto tr2395 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr2395 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr2395 + } + default: + goto tr2395 + } + goto tr2 + st2724: + if p++; p == pe { + goto _test_eof2724 + } + st_case_2724: + if data[p] == 129 { + goto tr2395 + } + switch { + case data[p] > 175: + if 181 <= data[p] && data[p] <= 182 { + goto tr2395 + } + case data[p] >= 171: + goto tr2395 + } + goto tr2 + st2725: + if p++; p == pe { + goto _test_eof2725 + } + st_case_2725: + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 173 { + goto tr2395 + } + case data[p] >= 163: + goto tr2395 + } + goto tr2 + st2726: + if p++; p == pe { + goto _test_eof2726 + } + st_case_2726: + switch data[p] { + case 172: + goto st2727 + case 184: + goto st2728 + case 187: + goto st2705 + case 190: + goto st2712 + case 191: + goto st2729 + } + goto tr2394 + st2727: + if p++; p == pe { + goto _test_eof2727 + } + st_case_2727: + if data[p] == 158 { + goto tr2395 + } + goto tr2 + st2728: + if p++; p == pe { + goto _test_eof2728 + } + st_case_2728: + switch { + case data[p] > 143: + if 160 <= data[p] && data[p] <= 175 { + goto tr2395 + } + case data[p] >= 128: + goto tr2395 + } + goto tr2 + st2729: + if p++; p == pe { + goto _test_eof2729 + } + st_case_2729: + if 185 <= data[p] && data[p] <= 187 { + goto tr2395 + } + goto tr2 + st2730: + if p++; p == pe { + goto _test_eof2730 + } + st_case_2730: + switch data[p] { + case 144: + goto st2731 + case 145: + goto st2737 + case 150: + goto st2756 + case 155: + goto st2761 + case 157: + goto st2763 + case 158: + goto st2770 + } + goto tr2394 + st2731: + if p++; p == pe { + goto _test_eof2731 + } + st_case_2731: + switch data[p] { + case 135: + goto st2732 + case 139: + goto st2733 + case 141: + goto st2734 + case 168: + goto st2735 + case 171: + goto st2736 + } + goto tr2 + st2732: + if p++; p == pe { + goto _test_eof2732 + } + st_case_2732: + if data[p] == 189 { + goto tr2395 + } + goto tr2 + st2733: + if p++; p == pe { + goto _test_eof2733 + } + st_case_2733: + if data[p] == 160 { + goto tr2395 + } + goto tr2 + st2734: + if p++; p == pe { + goto _test_eof2734 + } + st_case_2734: + if 182 <= data[p] && data[p] <= 186 { + goto tr2395 + } + goto tr2 + st2735: + if p++; p == pe { + goto _test_eof2735 + } + st_case_2735: + if data[p] == 191 { + goto tr2395 + } + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2395 + } + case data[p] > 134: + switch { + case data[p] > 143: + if 184 <= data[p] && data[p] <= 186 { + goto tr2395 + } + case data[p] >= 140: + goto tr2395 + } + default: + goto tr2395 + } + goto tr2 + st2736: + if p++; p == pe { + goto _test_eof2736 + } + st_case_2736: + if 165 <= data[p] && data[p] <= 166 { + goto tr2395 + } + goto tr2 + st2737: + if p++; p == pe { + goto _test_eof2737 + } + st_case_2737: + switch data[p] { + case 128: + goto st2738 + case 129: + goto st2739 + case 130: + goto st2740 + case 132: + goto st2741 + case 133: + goto st2742 + case 134: + goto st2743 + case 135: + goto st2744 + case 136: + goto st2745 + case 139: + goto st2746 + case 140: + goto st2747 + case 141: + goto st2748 + case 146: + goto st2749 + case 147: + goto st2750 + case 150: + goto st2751 + case 151: + goto st2752 + case 152: + goto st2749 + case 153: + goto st2753 + case 154: + goto st2754 + case 156: + goto st2755 + } + goto tr2 + st2738: + if p++; p == pe { + goto _test_eof2738 + } + st_case_2738: + switch { + case data[p] > 130: + if 184 <= data[p] { + goto tr2395 + } + case data[p] >= 128: + goto tr2395 + } + goto tr2 + st2739: + if p++; p == pe { + goto _test_eof2739 + } + st_case_2739: + if 135 <= data[p] && data[p] <= 190 { + goto tr2 + } + goto tr2395 + st2740: + if p++; p == pe { + goto _test_eof2740 + } + st_case_2740: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr2 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr2395 + st2741: + if p++; p == pe { + goto _test_eof2741 + } + st_case_2741: + switch { + case data[p] > 130: + if 167 <= data[p] && data[p] <= 180 { + goto tr2395 + } + case data[p] >= 128: + goto tr2395 + } + goto tr2 + st2742: + if p++; p == pe { + goto _test_eof2742 + } + st_case_2742: + if data[p] == 179 { + goto tr2395 + } + goto tr2 + st2743: + if p++; p == pe { + goto _test_eof2743 + } + st_case_2743: + switch { + case data[p] > 130: + if 179 <= data[p] { + goto tr2395 + } + case data[p] >= 128: + goto tr2395 + } + goto tr2 + st2744: + if p++; p == pe { + goto _test_eof2744 + } + st_case_2744: + switch { + case data[p] > 137: + if 141 <= data[p] { + goto tr2 + } + case data[p] >= 129: + goto tr2 + } + goto tr2395 + st2745: + if p++; p == pe { + goto _test_eof2745 + } + st_case_2745: + if 172 <= data[p] && data[p] <= 183 { + goto tr2395 + } + goto tr2 + st2746: + if p++; p == pe { + goto _test_eof2746 + } + st_case_2746: + if 159 <= data[p] && data[p] <= 170 { + goto tr2395 + } + goto tr2 + st2747: + if p++; p == pe { + goto _test_eof2747 + } + st_case_2747: + if data[p] == 188 { + goto tr2395 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr2395 + } + case data[p] >= 128: + goto tr2395 + } + goto tr2 + st2748: + if p++; p == pe { + goto _test_eof2748 + } + st_case_2748: + if data[p] == 151 { + goto tr2395 + } + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr2395 + } + case data[p] >= 128: + goto tr2395 + } + case data[p] > 141: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr2395 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr2395 + } + default: + goto tr2395 + } + default: + goto tr2395 + } + goto tr2 + st2749: + if p++; p == pe { + goto _test_eof2749 + } + st_case_2749: + if 176 <= data[p] { + goto tr2395 + } + goto tr2 + st2750: + if p++; p == pe { + goto _test_eof2750 + } + st_case_2750: + if 132 <= data[p] { + goto tr2 + } + goto tr2395 + st2751: + if p++; p == pe { + goto _test_eof2751 + } + st_case_2751: + switch { + case data[p] > 181: + if 184 <= data[p] { + goto tr2395 + } + case data[p] >= 175: + goto tr2395 + } + goto tr2 + st2752: + if p++; p == pe { + goto _test_eof2752 + } + st_case_2752: + switch { + case data[p] > 155: + if 158 <= data[p] { + goto tr2 + } + case data[p] >= 129: + goto tr2 + } + goto tr2395 + st2753: + if p++; p == pe { + goto _test_eof2753 + } + st_case_2753: + if 129 <= data[p] { + goto tr2 + } + goto tr2395 + st2754: + if p++; p == pe { + goto _test_eof2754 + } + st_case_2754: + if 171 <= data[p] && data[p] <= 183 { + goto tr2395 + } + goto tr2 + st2755: + if p++; p == pe { + goto _test_eof2755 + } + st_case_2755: + if 157 <= data[p] && data[p] <= 171 { + goto tr2395 + } + goto tr2 + st2756: + if p++; p == pe { + goto _test_eof2756 + } + st_case_2756: + switch data[p] { + case 171: + goto st2757 + case 172: + goto st2758 + case 189: + goto st2759 + case 190: + goto st2760 + } + goto tr2 + st2757: + if p++; p == pe { + goto _test_eof2757 + } + st_case_2757: + if 176 <= data[p] && data[p] <= 180 { + goto tr2395 + } + goto tr2 + st2758: + if p++; p == pe { + goto _test_eof2758 + } + st_case_2758: + if 176 <= data[p] && data[p] <= 182 { + goto tr2395 + } + goto tr2 + st2759: + if p++; p == pe { + goto _test_eof2759 + } + st_case_2759: + if 145 <= data[p] && data[p] <= 190 { + goto tr2395 + } + goto tr2 + st2760: + if p++; p == pe { + goto _test_eof2760 + } + st_case_2760: + if 143 <= data[p] && data[p] <= 146 { + goto tr2395 + } + goto tr2 + st2761: + if p++; p == pe { + goto _test_eof2761 + } + st_case_2761: + if data[p] == 178 { + goto st2762 + } + goto tr2 + st2762: + if p++; p == pe { + goto _test_eof2762 + } + st_case_2762: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr2395 + } + case data[p] >= 157: + goto tr2395 + } + goto tr2 + st2763: + if p++; p == pe { + goto _test_eof2763 + } + st_case_2763: + switch data[p] { + case 133: + goto st2764 + case 134: + goto st2765 + case 137: + goto st2766 + case 168: + goto st2767 + case 169: + goto st2768 + case 170: + goto st2769 + } + goto tr2 + st2764: + if p++; p == pe { + goto _test_eof2764 + } + st_case_2764: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr2395 + } + case data[p] >= 165: + goto tr2395 + } + goto tr2 + st2765: + if p++; p == pe { + goto _test_eof2765 + } + st_case_2765: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr2 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr2395 + st2766: + if p++; p == pe { + goto _test_eof2766 + } + st_case_2766: + if 130 <= data[p] && data[p] <= 132 { + goto tr2395 + } + goto tr2 + st2767: + if p++; p == pe { + goto _test_eof2767 + } + st_case_2767: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr2395 + } + case data[p] >= 128: + goto tr2395 + } + goto tr2 + st2768: + if p++; p == pe { + goto _test_eof2768 + } + st_case_2768: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr2 + } + case data[p] >= 173: + goto tr2 + } + goto tr2395 + st2769: + if p++; p == pe { + goto _test_eof2769 + } + st_case_2769: + if data[p] == 132 { + goto tr2395 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr2395 + } + case data[p] >= 155: + goto tr2395 + } + goto tr2 + st2770: + if p++; p == pe { + goto _test_eof2770 + } + st_case_2770: + if data[p] == 163 { + goto st2771 + } + goto tr2 + st2771: + if p++; p == pe { + goto _test_eof2771 + } + st_case_2771: + if 144 <= data[p] && data[p] <= 150 { + goto tr2395 + } + goto tr2 + st2772: + if p++; p == pe { + goto _test_eof2772 + } + st_case_2772: + if data[p] == 160 { + goto st2773 + } + goto tr2394 + st2773: + if p++; p == pe { + goto _test_eof2773 + } + st_case_2773: + switch data[p] { + case 128: + goto st2774 + case 129: + goto st2775 + case 132: + goto st2637 + case 135: + goto st2638 + } + if 133 <= data[p] && data[p] <= 134 { + goto st2776 + } + goto tr2 + st2774: + if p++; p == pe { + goto _test_eof2774 + } + st_case_2774: + if data[p] == 129 { + goto tr2395 + } + if 160 <= data[p] { + goto tr2395 + } + goto tr2 + st2775: + if p++; p == pe { + goto _test_eof2775 + } + st_case_2775: + if 192 <= data[p] { + goto tr2 + } + goto tr2395 + st2776: + if p++; p == pe { + goto _test_eof2776 + } + st_case_2776: + goto tr2395 +tr4805: +//line segment_words.rl:72 + + endPos = p + + goto st4879 +tr4465: +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + + goto st4879 + st4879: + if p++; p == pe { + goto _test_eof4879 + } + st_case_4879: +//line segment_words_prod.go:72049 + switch data[p] { + case 194: + goto tr4783 + case 204: + goto tr4784 + case 205: + goto tr4785 + case 210: + goto tr4786 + case 214: + goto tr4787 + case 215: + goto tr4788 + case 216: + goto tr4789 + case 217: + goto tr4790 + case 219: + goto tr4791 + case 220: + goto tr4792 + case 221: + goto tr4793 + case 222: + goto tr4794 + case 223: + goto tr4795 + case 224: + goto tr4796 + case 225: + goto tr4797 + case 226: + goto tr4798 + case 227: + goto tr4799 + case 234: + goto tr4800 + case 239: + goto tr4801 + case 240: + goto tr4802 + case 243: + goto tr4803 + } + switch { + case data[p] < 152: + if 128 <= data[p] && data[p] <= 150 { + goto tr148 + } + case data[p] > 182: + if 184 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + goto tr4499 +tr4783: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4880 + st4880: + if p++; p == pe { + goto _test_eof4880 + } + st_case_4880: +//line segment_words_prod.go:72123 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 173: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr4784: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4881 + st4881: + if p++; p == pe { + goto _test_eof4881 + } + st_case_4881: +//line segment_words_prod.go:72235 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto tr4804 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr4808 + case 205: + goto tr4810 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr4813 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr4816 + case 215: + goto tr4817 + case 216: + goto tr4818 + case 217: + goto tr4819 + case 219: + goto tr4820 + case 220: + goto tr4821 + case 221: + goto tr4822 + case 222: + goto tr4823 + case 223: + goto tr4824 + case 224: + goto tr4825 + case 225: + goto tr4826 + case 226: + goto tr4827 + case 227: + goto tr4828 + case 234: + goto tr4829 + case 237: + goto tr4831 + case 239: + goto tr4832 + case 240: + goto tr4833 + case 243: + goto tr4834 + } + switch { + case data[p] < 91: + switch { + case data[p] < 48: + if data[p] <= 47 { + goto tr4562 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 59: + goto tr4562 + } + default: + goto tr421 + } + case data[p] > 96: + switch { + case data[p] < 123: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + case data[p] > 127: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto tr4830 + } + case data[p] >= 196: + goto tr4806 + } + default: + goto tr4562 + } + default: + goto tr4562 + } + goto tr1 +tr4804: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4882 + st4882: + if p++; p == pe { + goto _test_eof4882 + } + st_case_4882: +//line segment_words_prod.go:72363 + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr148 + case 181: + goto tr148 + case 183: + goto st142 + case 186: + goto tr148 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr4806: +//line segment_words.rl:72 + + endPos = p + + goto st4883 +tr4466: +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + + goto st4883 + st4883: + if p++; p == pe { + goto _test_eof4883 + } + st_case_4883: +//line segment_words_prod.go:72440 + switch data[p] { + case 194: + goto tr4783 + case 204: + goto tr4784 + case 205: + goto tr4785 + case 210: + goto tr4786 + case 214: + goto tr4787 + case 215: + goto tr4788 + case 216: + goto tr4789 + case 217: + goto tr4790 + case 219: + goto tr4791 + case 220: + goto tr4792 + case 221: + goto tr4793 + case 222: + goto tr4794 + case 223: + goto tr4795 + case 224: + goto tr4796 + case 225: + goto tr4797 + case 226: + goto tr4798 + case 227: + goto tr4799 + case 234: + goto tr4800 + case 239: + goto tr4801 + case 240: + goto tr4802 + case 243: + goto tr4803 + } + goto tr148 +tr4785: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4884 + st4884: + if p++; p == pe { + goto _test_eof4884 + } + st_case_4884: +//line segment_words_prod.go:72502 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 176: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr2646 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto st145 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr4562 + } + case data[p] >= 235: + goto st286 + } + default: + goto tr4562 + } + default: + goto tr4562 + } + goto tr1 +tr2518: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4885 + st4885: + if p++; p == pe { + goto _test_eof4885 + } + st_case_4885: +//line segment_words_prod.go:72625 + switch data[p] { + case 194: + goto st2777 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st148 + case 204: + goto st2778 + case 205: + goto st2779 + case 206: + goto st151 + case 207: + goto st152 + case 210: + goto st2780 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st2781 + case 215: + goto st2782 + case 216: + goto st2783 + case 217: + goto st2784 + case 219: + goto st2785 + case 220: + goto st2786 + case 221: + goto st2787 + case 222: + goto st2788 + case 223: + goto st2789 + case 224: + goto st2790 + case 225: + goto st2822 + case 226: + goto st2844 + case 227: + goto st2851 + case 234: + goto st2854 + case 237: + goto st287 + case 239: + goto st2870 + case 240: + goto st2876 + case 243: + goto st2918 + } + switch { + case data[p] < 97: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4499 + st2777: + if p++; p == pe { + goto _test_eof2777 + } + st_case_2777: + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr2518 + case 181: + goto tr148 + case 186: + goto tr148 + } + goto tr0 + st2778: + if p++; p == pe { + goto _test_eof2778 + } + st_case_2778: + if 128 <= data[p] { + goto tr2518 + } + goto tr0 + st2779: + if p++; p == pe { + goto _test_eof2779 + } + st_case_2779: + switch data[p] { + case 181: + goto tr0 + case 190: + goto tr0 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr0 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr0 + } + goto tr2518 + st2780: + if p++; p == pe { + goto _test_eof2780 + } + st_case_2780: + if data[p] == 130 { + goto tr0 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr2518 + } + goto tr148 + st2781: + if p++; p == pe { + goto _test_eof2781 + } + st_case_2781: + if data[p] == 190 { + goto tr0 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr0 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr0 + } + default: + goto tr2518 + } + goto tr148 + st2782: + if p++; p == pe { + goto _test_eof2782 + } + st_case_2782: + if data[p] == 135 { + goto tr2518 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr2518 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] >= 144: + goto tr148 + } + default: + goto tr2518 + } + goto tr0 + st2783: + if p++; p == pe { + goto _test_eof2783 + } + st_case_2783: + if data[p] == 156 { + goto tr2518 + } + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 133 { + goto tr2518 + } + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr2518 + } + goto tr0 + st2784: + if p++; p == pe { + goto _test_eof2784 + } + st_case_2784: + if data[p] == 176 { + goto tr2518 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 159: + if 174 <= data[p] { + goto tr148 + } + default: + goto tr2518 + } + goto tr0 + st2785: + if p++; p == pe { + goto _test_eof2785 + } + st_case_2785: + switch data[p] { + case 148: + goto tr0 + case 158: + goto tr0 + case 169: + goto tr0 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr2518 + } + case data[p] >= 150: + goto tr2518 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr0 + } + case data[p] >= 189: + goto tr0 + } + default: + goto tr0 + } + goto tr148 + st2786: + if p++; p == pe { + goto _test_eof2786 + } + st_case_2786: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto tr2518 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr2518 + } + default: + goto tr148 + } + goto tr0 + st2787: + if p++; p == pe { + goto _test_eof2787 + } + st_case_2787: + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr0 + } + goto tr2518 + st2788: + if p++; p == pe { + goto _test_eof2788 + } + st_case_2788: + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr0 + } + case data[p] >= 166: + goto tr2518 + } + goto tr148 + st2789: + if p++; p == pe { + goto _test_eof2789 + } + st_case_2789: + if data[p] == 186 { + goto tr148 + } + switch { + case data[p] < 171: + if 138 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + default: + goto tr2518 + } + goto tr0 + st2790: + if p++; p == pe { + goto _test_eof2790 + } + st_case_2790: + switch data[p] { + case 160: + goto st2791 + case 161: + goto st2792 + case 162: + goto st168 + case 163: + goto st2793 + case 164: + goto st2794 + case 165: + goto st2795 + case 166: + goto st2796 + case 167: + goto st2797 + case 168: + goto st2798 + case 169: + goto st2799 + case 170: + goto st2800 + case 171: + goto st2801 + case 172: + goto st2802 + case 173: + goto st2803 + case 174: + goto st2804 + case 175: + goto st2805 + case 176: + goto st2806 + case 177: + goto st2807 + case 178: + goto st2808 + case 179: + goto st2809 + case 180: + goto st2810 + case 181: + goto st2811 + case 182: + goto st2812 + case 183: + goto st2813 + case 184: + goto st2814 + case 185: + goto st2815 + case 186: + goto st2816 + case 187: + goto st2817 + case 188: + goto st2818 + case 189: + goto st2819 + case 190: + goto st2820 + case 191: + goto st2821 + } + goto tr0 + st2791: + if p++; p == pe { + goto _test_eof2791 + } + st_case_2791: + switch data[p] { + case 154: + goto tr148 + case 164: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] > 149: + if 150 <= data[p] && data[p] <= 173 { + goto tr2518 + } + case data[p] >= 128: + goto tr148 + } + goto tr0 + st2792: + if p++; p == pe { + goto _test_eof2792 + } + st_case_2792: + switch { + case data[p] > 152: + if 153 <= data[p] && data[p] <= 155 { + goto tr2518 + } + case data[p] >= 128: + goto tr148 + } + goto tr0 + st2793: + if p++; p == pe { + goto _test_eof2793 + } + st_case_2793: + if 163 <= data[p] { + goto tr2518 + } + goto tr0 + st2794: + if p++; p == pe { + goto _test_eof2794 + } + st_case_2794: + if data[p] == 189 { + goto tr148 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr148 + } + goto tr2518 + st2795: + if p++; p == pe { + goto _test_eof2795 + } + st_case_2795: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 176: + if 177 <= data[p] { + goto tr148 + } + default: + goto tr0 + } + goto tr2518 + st2796: + if p++; p == pe { + goto _test_eof2796 + } + st_case_2796: + switch data[p] { + case 132: + goto tr0 + case 169: + goto tr0 + case 177: + goto tr0 + case 188: + goto tr2518 + } + switch { + case data[p] < 145: + switch { + case data[p] > 131: + if 141 <= data[p] && data[p] <= 142 { + goto tr0 + } + case data[p] >= 129: + goto tr2518 + } + case data[p] > 146: + switch { + case data[p] < 186: + if 179 <= data[p] && data[p] <= 181 { + goto tr0 + } + case data[p] > 187: + if 190 <= data[p] { + goto tr2518 + } + default: + goto tr0 + } + default: + goto tr0 + } + goto tr148 + st2797: + if p++; p == pe { + goto _test_eof2797 + } + st_case_2797: + switch data[p] { + case 142: + goto tr148 + case 158: + goto tr0 + } + switch { + case data[p] < 152: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr0 + } + case data[p] > 138: + if 143 <= data[p] && data[p] <= 150 { + goto tr0 + } + default: + goto tr0 + } + case data[p] > 155: + switch { + case data[p] < 164: + if 156 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr0 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr0 + } + default: + goto tr0 + } + goto tr2518 + st2798: + if p++; p == pe { + goto _test_eof2798 + } + st_case_2798: + if data[p] == 188 { + goto tr2518 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2518 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto tr2518 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st2799: + if p++; p == pe { + goto _test_eof2799 + } + st_case_2799: + if data[p] == 157 { + goto tr0 + } + switch { + case data[p] < 146: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr0 + } + case data[p] > 138: + if 142 <= data[p] && data[p] <= 144 { + goto tr0 + } + default: + goto tr0 + } + case data[p] > 152: + switch { + case data[p] < 159: + if 153 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr0 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr0 + } + default: + goto tr0 + } + goto tr2518 + st2800: + if p++; p == pe { + goto _test_eof2800 + } + st_case_2800: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2518 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto tr2518 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st2801: + if p++; p == pe { + goto _test_eof2801 + } + st_case_2801: + switch data[p] { + case 134: + goto tr0 + case 138: + goto tr0 + case 144: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 160: + if 142 <= data[p] && data[p] <= 159 { + goto tr0 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr0 + } + default: + goto tr148 + } + goto tr2518 + st2802: + if p++; p == pe { + goto _test_eof2802 + } + st_case_2802: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2518 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2518 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st2803: + if p++; p == pe { + goto _test_eof2803 + } + st_case_2803: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr2518 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr2518 + } + default: + goto tr2518 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 161: + if 162 <= data[p] && data[p] <= 163 { + goto tr2518 + } + default: + goto tr148 + } + default: + goto tr2518 + } + goto tr0 + st2804: + if p++; p == pe { + goto _test_eof2804 + } + st_case_2804: + switch data[p] { + case 130: + goto tr2518 + case 131: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 158: + switch { + case data[p] < 142: + if 133 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 149: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] < 168: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto tr2518 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st2805: + if p++; p == pe { + goto _test_eof2805 + } + st_case_2805: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr2518 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr2518 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr2518 + } + default: + goto tr2518 + } + goto tr0 + st2806: + if p++; p == pe { + goto _test_eof2806 + } + st_case_2806: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto tr2518 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 190 <= data[p] { + goto tr2518 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st2807: + if p++; p == pe { + goto _test_eof2807 + } + st_case_2807: + switch data[p] { + case 133: + goto tr0 + case 137: + goto tr0 + case 151: + goto tr0 + } + switch { + case data[p] < 155: + switch { + case data[p] > 148: + if 152 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 142: + goto tr0 + } + case data[p] > 159: + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr0 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr0 + } + goto tr2518 + st2808: + if p++; p == pe { + goto _test_eof2808 + } + st_case_2808: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2518 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2518 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st2809: + if p++; p == pe { + goto _test_eof2809 + } + st_case_2809: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr2518 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr2518 + } + default: + goto tr2518 + } + case data[p] > 150: + switch { + case data[p] < 162: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 163: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + default: + goto tr2518 + } + default: + goto tr2518 + } + goto tr0 + st2810: + if p++; p == pe { + goto _test_eof2810 + } + st_case_2810: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto tr2518 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto tr2518 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st2811: + if p++; p == pe { + goto _test_eof2811 + } + st_case_2811: + switch data[p] { + case 133: + goto tr0 + case 137: + goto tr0 + case 142: + goto tr148 + } + switch { + case data[p] < 159: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 158 { + goto tr0 + } + case data[p] >= 143: + goto tr0 + } + case data[p] > 161: + switch { + case data[p] < 186: + if 164 <= data[p] && data[p] <= 185 { + goto tr0 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr0 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2518 + st2812: + if p++; p == pe { + goto _test_eof2812 + } + st_case_2812: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr2518 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st2813: + if p++; p == pe { + goto _test_eof2813 + } + st_case_2813: + switch data[p] { + case 138: + goto tr2518 + case 150: + goto tr2518 + } + switch { + case data[p] < 143: + if 128 <= data[p] && data[p] <= 134 { + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 159: + if 178 <= data[p] && data[p] <= 179 { + goto tr2518 + } + case data[p] >= 152: + goto tr2518 + } + default: + goto tr2518 + } + goto tr0 + st2814: + if p++; p == pe { + goto _test_eof2814 + } + st_case_2814: + if data[p] == 177 { + goto tr2518 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr2518 + } + goto tr0 + st2815: + if p++; p == pe { + goto _test_eof2815 + } + st_case_2815: + if 135 <= data[p] && data[p] <= 142 { + goto tr2518 + } + goto tr0 + st2816: + if p++; p == pe { + goto _test_eof2816 + } + st_case_2816: + if data[p] == 177 { + goto tr2518 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr2518 + } + case data[p] >= 180: + goto tr2518 + } + goto tr0 + st2817: + if p++; p == pe { + goto _test_eof2817 + } + st_case_2817: + if 136 <= data[p] && data[p] <= 141 { + goto tr2518 + } + goto tr0 + st2818: + if p++; p == pe { + goto _test_eof2818 + } + st_case_2818: + switch data[p] { + case 128: + goto tr148 + case 181: + goto tr2518 + case 183: + goto tr2518 + case 185: + goto tr2518 + } + switch { + case data[p] > 153: + if 190 <= data[p] && data[p] <= 191 { + goto tr2518 + } + case data[p] >= 152: + goto tr2518 + } + goto tr0 + st2819: + if p++; p == pe { + goto _test_eof2819 + } + st_case_2819: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto tr2518 + } + default: + goto tr148 + } + goto tr0 + st2820: + if p++; p == pe { + goto _test_eof2820 + } + st_case_2820: + switch { + case data[p] < 136: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 135 { + goto tr2518 + } + case data[p] >= 128: + goto tr2518 + } + case data[p] > 140: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr2518 + } + case data[p] >= 141: + goto tr2518 + } + default: + goto tr148 + } + goto tr0 + st2821: + if p++; p == pe { + goto _test_eof2821 + } + st_case_2821: + if data[p] == 134 { + goto tr2518 + } + goto tr0 + st2822: + if p++; p == pe { + goto _test_eof2822 + } + st_case_2822: + switch data[p] { + case 128: + goto st2823 + case 129: + goto st2824 + case 130: + goto st2825 + case 131: + goto st202 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st2826 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st2827 + case 157: + goto st2828 + case 158: + goto st2829 + case 159: + goto st2830 + case 160: + goto st2831 + case 161: + goto st219 + case 162: + goto st2832 + case 163: + goto st221 + case 164: + goto st2833 + case 168: + goto st2834 + case 169: + goto st2835 + case 170: + goto st2836 + case 172: + goto st2837 + case 173: + goto st2838 + case 174: + goto st2839 + case 175: + goto st2840 + case 176: + goto st2841 + case 177: + goto st231 + case 179: + goto st2842 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st2843 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + } + switch { + case data[p] < 180: + if 132 <= data[p] && data[p] <= 152 { + goto st145 + } + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + default: + goto st147 + } + goto tr0 + st2823: + if p++; p == pe { + goto _test_eof2823 + } + st_case_2823: + if 171 <= data[p] && data[p] <= 190 { + goto tr2518 + } + goto tr0 + st2824: + if p++; p == pe { + goto _test_eof2824 + } + st_case_2824: + switch { + case data[p] < 162: + switch { + case data[p] > 153: + if 158 <= data[p] && data[p] <= 160 { + goto tr2518 + } + case data[p] >= 150: + goto tr2518 + } + case data[p] > 164: + switch { + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr2518 + } + case data[p] >= 167: + goto tr2518 + } + default: + goto tr2518 + } + goto tr0 + st2825: + if p++; p == pe { + goto _test_eof2825 + } + st_case_2825: + if data[p] == 143 { + goto tr2518 + } + switch { + case data[p] < 154: + if 130 <= data[p] && data[p] <= 141 { + goto tr2518 + } + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr2518 + } + goto tr0 + st2826: + if p++; p == pe { + goto _test_eof2826 + } + st_case_2826: + switch { + case data[p] < 157: + if 155 <= data[p] && data[p] <= 156 { + goto tr0 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr0 + } + default: + goto tr2518 + } + goto tr148 + st2827: + if p++; p == pe { + goto _test_eof2827 + } + st_case_2827: + switch { + case data[p] < 146: + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 177: + if 178 <= data[p] && data[p] <= 180 { + goto tr2518 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr2518 + } + goto tr0 + st2828: + if p++; p == pe { + goto _test_eof2828 + } + st_case_2828: + switch { + case data[p] < 160: + switch { + case data[p] > 145: + if 146 <= data[p] && data[p] <= 147 { + goto tr2518 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto tr2518 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st2829: + if p++; p == pe { + goto _test_eof2829 + } + st_case_2829: + if 180 <= data[p] { + goto tr2518 + } + goto tr0 + st2830: + if p++; p == pe { + goto _test_eof2830 + } + st_case_2830: + switch { + case data[p] > 156: + if 158 <= data[p] { + goto tr0 + } + case data[p] >= 148: + goto tr0 + } + goto tr2518 + st2831: + if p++; p == pe { + goto _test_eof2831 + } + st_case_2831: + switch { + case data[p] > 142: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr2518 + } + goto tr0 + st2832: + if p++; p == pe { + goto _test_eof2832 + } + st_case_2832: + if data[p] == 169 { + goto tr2518 + } + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr0 + st2833: + if p++; p == pe { + goto _test_eof2833 + } + st_case_2833: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr2518 + } + default: + goto tr2518 + } + goto tr0 + st2834: + if p++; p == pe { + goto _test_eof2834 + } + st_case_2834: + switch { + case data[p] > 150: + if 151 <= data[p] && data[p] <= 155 { + goto tr2518 + } + case data[p] >= 128: + goto tr148 + } + goto tr0 + st2835: + if p++; p == pe { + goto _test_eof2835 + } + st_case_2835: + if data[p] == 191 { + goto tr2518 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr2518 + } + case data[p] >= 149: + goto tr2518 + } + goto tr0 + st2836: + if p++; p == pe { + goto _test_eof2836 + } + st_case_2836: + if 176 <= data[p] && data[p] <= 190 { + goto tr2518 + } + goto tr0 + st2837: + if p++; p == pe { + goto _test_eof2837 + } + st_case_2837: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 132 { + goto tr2518 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr2518 + } + default: + goto tr148 + } + goto tr0 + st2838: + if p++; p == pe { + goto _test_eof2838 + } + st_case_2838: + switch { + case data[p] < 140: + if 133 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 170: + if 180 <= data[p] { + goto tr0 + } + default: + goto tr0 + } + goto tr2518 + st2839: + if p++; p == pe { + goto _test_eof2839 + } + st_case_2839: + switch { + case data[p] < 161: + switch { + case data[p] > 130: + if 131 <= data[p] && data[p] <= 160 { + goto tr148 + } + case data[p] >= 128: + goto tr2518 + } + case data[p] > 173: + switch { + case data[p] > 175: + if 186 <= data[p] { + goto tr148 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr2518 + } + goto tr0 + st2840: + if p++; p == pe { + goto _test_eof2840 + } + st_case_2840: + switch { + case data[p] > 179: + if 180 <= data[p] { + goto tr0 + } + case data[p] >= 166: + goto tr2518 + } + goto tr148 + st2841: + if p++; p == pe { + goto _test_eof2841 + } + st_case_2841: + switch { + case data[p] > 163: + if 164 <= data[p] && data[p] <= 183 { + goto tr2518 + } + case data[p] >= 128: + goto tr148 + } + goto tr0 + st2842: + if p++; p == pe { + goto _test_eof2842 + } + st_case_2842: + if data[p] == 173 { + goto tr2518 + } + switch { + case data[p] < 169: + switch { + case data[p] > 146: + if 148 <= data[p] && data[p] <= 168 { + goto tr2518 + } + case data[p] >= 144: + goto tr2518 + } + case data[p] > 177: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 180 { + goto tr2518 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto tr2518 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st2843: + if p++; p == pe { + goto _test_eof2843 + } + st_case_2843: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr2518 + } + case data[p] >= 128: + goto tr2518 + } + goto tr0 + st2844: + if p++; p == pe { + goto _test_eof2844 + } + st_case_2844: + switch data[p] { + case 128: + goto st2845 + case 129: + goto st2846 + case 130: + goto st241 + case 131: + goto st2847 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st2848 + case 180: + goto st251 + case 181: + goto st2849 + case 182: + goto st253 + case 183: + goto st2850 + case 184: + goto st255 + } + goto tr0 + st2845: + if p++; p == pe { + goto _test_eof2845 + } + st_case_2845: + switch { + case data[p] > 143: + if 170 <= data[p] && data[p] <= 174 { + goto tr2518 + } + case data[p] >= 140: + goto tr2518 + } + goto tr0 + st2846: + if p++; p == pe { + goto _test_eof2846 + } + st_case_2846: + switch data[p] { + case 177: + goto tr148 + case 191: + goto tr148 + } + switch { + case data[p] > 164: + if 166 <= data[p] && data[p] <= 175 { + goto tr2518 + } + case data[p] >= 160: + goto tr2518 + } + goto tr0 + st2847: + if p++; p == pe { + goto _test_eof2847 + } + st_case_2847: + if 144 <= data[p] && data[p] <= 176 { + goto tr2518 + } + goto tr0 + st2848: + if p++; p == pe { + goto _test_eof2848 + } + st_case_2848: + switch { + case data[p] < 175: + if 165 <= data[p] && data[p] <= 170 { + goto tr0 + } + case data[p] > 177: + if 180 <= data[p] { + goto tr0 + } + default: + goto tr2518 + } + goto tr148 + st2849: + if p++; p == pe { + goto _test_eof2849 + } + st_case_2849: + if data[p] == 191 { + goto tr2518 + } + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr0 + } + case data[p] >= 168: + goto tr0 + } + goto tr148 + st2850: + if p++; p == pe { + goto _test_eof2850 + } + st_case_2850: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto tr2518 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st2851: + if p++; p == pe { + goto _test_eof2851 + } + st_case_2851: + switch data[p] { + case 128: + goto st2852 + case 130: + goto st2853 + case 132: + goto st259 + case 133: + goto st145 + case 134: + goto st260 + } + goto tr0 + st2852: + if p++; p == pe { + goto _test_eof2852 + } + st_case_2852: + if data[p] == 133 { + goto tr148 + } + switch { + case data[p] > 175: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + case data[p] >= 170: + goto tr2518 + } + goto tr0 + st2853: + if p++; p == pe { + goto _test_eof2853 + } + st_case_2853: + if 153 <= data[p] && data[p] <= 154 { + goto tr2518 + } + goto tr0 + st2854: + if p++; p == pe { + goto _test_eof2854 + } + st_case_2854: + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st264 + case 153: + goto st2855 + case 154: + goto st2856 + case 155: + goto st2857 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st2858 + case 161: + goto st272 + case 162: + goto st2859 + case 163: + goto st2860 + case 164: + goto st2861 + case 165: + goto st2862 + case 166: + goto st2863 + case 167: + goto st2864 + case 168: + goto st2865 + case 169: + goto st2866 + case 170: + goto st2867 + case 171: + goto st2868 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st2869 + case 176: + goto st147 + } + if 129 <= data[p] { + goto st145 + } + goto tr0 + st2855: + if p++; p == pe { + goto _test_eof2855 + } + st_case_2855: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr2518 + } + default: + goto tr2518 + } + goto tr0 + st2856: + if p++; p == pe { + goto _test_eof2856 + } + st_case_2856: + switch { + case data[p] < 158: + if 128 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr2518 + } + goto tr0 + st2857: + if p++; p == pe { + goto _test_eof2857 + } + st_case_2857: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr0 + } + case data[p] >= 176: + goto tr2518 + } + goto tr148 + st2858: + if p++; p == pe { + goto _test_eof2858 + } + st_case_2858: + switch data[p] { + case 130: + goto tr2518 + case 134: + goto tr2518 + case 139: + goto tr2518 + } + switch { + case data[p] > 167: + if 168 <= data[p] { + goto tr0 + } + case data[p] >= 163: + goto tr2518 + } + goto tr148 + st2859: + if p++; p == pe { + goto _test_eof2859 + } + st_case_2859: + switch { + case data[p] < 130: + if 128 <= data[p] && data[p] <= 129 { + goto tr2518 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr2518 + } + default: + goto tr148 + } + goto tr0 + st2860: + if p++; p == pe { + goto _test_eof2860 + } + st_case_2860: + switch data[p] { + case 187: + goto tr148 + case 189: + goto tr148 + } + switch { + case data[p] < 178: + if 133 <= data[p] && data[p] <= 159 { + goto tr0 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr0 + } + default: + goto tr148 + } + goto tr2518 + st2861: + if p++; p == pe { + goto _test_eof2861 + } + st_case_2861: + switch { + case data[p] < 166: + if 138 <= data[p] && data[p] <= 165 { + goto tr148 + } + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + default: + goto tr2518 + } + goto tr0 + st2862: + if p++; p == pe { + goto _test_eof2862 + } + st_case_2862: + switch { + case data[p] < 148: + if 135 <= data[p] && data[p] <= 147 { + goto tr2518 + } + case data[p] > 159: + if 189 <= data[p] { + goto tr0 + } + default: + goto tr0 + } + goto tr148 + st2863: + if p++; p == pe { + goto _test_eof2863 + } + st_case_2863: + switch { + case data[p] < 132: + if 128 <= data[p] && data[p] <= 131 { + goto tr2518 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr2518 + } + default: + goto tr148 + } + goto tr0 + st2864: + if p++; p == pe { + goto _test_eof2864 + } + st_case_2864: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] > 164: + if 166 <= data[p] { + goto tr0 + } + case data[p] >= 129: + goto tr0 + } + goto tr2518 + st2865: + if p++; p == pe { + goto _test_eof2865 + } + st_case_2865: + switch { + case data[p] > 168: + if 169 <= data[p] && data[p] <= 182 { + goto tr2518 + } + case data[p] >= 128: + goto tr148 + } + goto tr0 + st2866: + if p++; p == pe { + goto _test_eof2866 + } + st_case_2866: + if data[p] == 131 { + goto tr2518 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 141: + if 187 <= data[p] && data[p] <= 189 { + goto tr2518 + } + default: + goto tr2518 + } + goto tr0 + st2867: + if p++; p == pe { + goto _test_eof2867 + } + st_case_2867: + if data[p] == 176 { + goto tr2518 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr2518 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr2518 + } + default: + goto tr2518 + } + goto tr0 + st2868: + if p++; p == pe { + goto _test_eof2868 + } + st_case_2868: + if data[p] == 129 { + goto tr2518 + } + switch { + case data[p] < 171: + if 160 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 181 <= data[p] && data[p] <= 182 { + goto tr2518 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr2518 + } + goto tr0 + st2869: + if p++; p == pe { + goto _test_eof2869 + } + st_case_2869: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 162 { + goto tr148 + } + case data[p] > 170: + if 172 <= data[p] && data[p] <= 173 { + goto tr2518 + } + default: + goto tr2518 + } + goto tr0 + st2870: + if p++; p == pe { + goto _test_eof2870 + } + st_case_2870: + switch data[p] { + case 172: + goto st2871 + case 173: + goto st292 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st2872 + case 185: + goto st300 + case 187: + goto st2873 + case 188: + goto st302 + case 189: + goto st303 + case 190: + goto st2874 + case 191: + goto st2875 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr0 + st2871: + if p++; p == pe { + goto _test_eof2871 + } + st_case_2871: + switch data[p] { + case 158: + goto tr2518 + case 190: + goto tr148 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr148 + } + case data[p] >= 170: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st2872: + if p++; p == pe { + goto _test_eof2872 + } + st_case_2872: + switch { + case data[p] > 143: + if 160 <= data[p] && data[p] <= 175 { + goto tr2518 + } + case data[p] >= 128: + goto tr2518 + } + goto tr0 + st2873: + if p++; p == pe { + goto _test_eof2873 + } + st_case_2873: + if data[p] == 191 { + goto tr2518 + } + if 189 <= data[p] { + goto tr0 + } + goto tr148 + st2874: + if p++; p == pe { + goto _test_eof2874 + } + st_case_2874: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 190 { + goto tr148 + } + case data[p] >= 158: + goto tr2518 + } + goto tr0 + st2875: + if p++; p == pe { + goto _test_eof2875 + } + st_case_2875: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] >= 130: + goto tr148 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr2518 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st2876: + if p++; p == pe { + goto _test_eof2876 + } + st_case_2876: + switch data[p] { + case 144: + goto st2877 + case 145: + goto st2883 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st2902 + case 155: + goto st2907 + case 157: + goto st2909 + case 158: + goto st2916 + case 159: + goto st403 + } + goto tr0 + st2877: + if p++; p == pe { + goto _test_eof2877 + } + st_case_2877: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st2878 + case 138: + goto st313 + case 139: + goto st2879 + case 140: + goto st315 + case 141: + goto st2880 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st319 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st2881 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st2882 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr0 + st2878: + if p++; p == pe { + goto _test_eof2878 + } + st_case_2878: + if data[p] == 189 { + goto tr2518 + } + goto tr0 + st2879: + if p++; p == pe { + goto _test_eof2879 + } + st_case_2879: + if data[p] == 160 { + goto tr2518 + } + if 145 <= data[p] { + goto tr0 + } + goto tr148 + st2880: + if p++; p == pe { + goto _test_eof2880 + } + st_case_2880: + switch { + case data[p] < 182: + if 139 <= data[p] && data[p] <= 143 { + goto tr0 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr0 + } + default: + goto tr2518 + } + goto tr148 + st2881: + if p++; p == pe { + goto _test_eof2881 + } + st_case_2881: + switch data[p] { + case 128: + goto tr148 + case 191: + goto tr2518 + } + switch { + case data[p] < 144: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2518 + } + case data[p] > 134: + if 140 <= data[p] && data[p] <= 143 { + goto tr2518 + } + default: + goto tr2518 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto tr2518 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st2882: + if p++; p == pe { + goto _test_eof2882 + } + st_case_2882: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 164: + if 165 <= data[p] && data[p] <= 166 { + goto tr2518 + } + default: + goto tr148 + } + goto tr0 + st2883: + if p++; p == pe { + goto _test_eof2883 + } + st_case_2883: + switch data[p] { + case 128: + goto st2884 + case 129: + goto st2885 + case 130: + goto st2886 + case 131: + goto st342 + case 132: + goto st2887 + case 133: + goto st2888 + case 134: + goto st2889 + case 135: + goto st2890 + case 136: + goto st2891 + case 138: + goto st348 + case 139: + goto st2892 + case 140: + goto st2893 + case 141: + goto st2894 + case 146: + goto st2895 + case 147: + goto st2896 + case 150: + goto st2897 + case 151: + goto st2898 + case 152: + goto st2895 + case 153: + goto st2899 + case 154: + goto st2900 + case 156: + goto st2901 + case 162: + goto st359 + case 163: + goto st360 + case 171: + goto st361 + } + goto tr0 + st2884: + if p++; p == pe { + goto _test_eof2884 + } + st_case_2884: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2518 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr2518 + } + default: + goto tr148 + } + goto tr0 + st2885: + if p++; p == pe { + goto _test_eof2885 + } + st_case_2885: + if 135 <= data[p] && data[p] <= 190 { + goto tr0 + } + goto tr2518 + st2886: + if p++; p == pe { + goto _test_eof2886 + } + st_case_2886: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr0 + } + default: + goto tr0 + } + goto tr2518 + st2887: + if p++; p == pe { + goto _test_eof2887 + } + st_case_2887: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2518 + } + case data[p] > 166: + if 167 <= data[p] && data[p] <= 180 { + goto tr2518 + } + default: + goto tr148 + } + goto tr0 + st2888: + if p++; p == pe { + goto _test_eof2888 + } + st_case_2888: + switch data[p] { + case 179: + goto tr2518 + case 182: + goto tr148 + } + if 144 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr0 + st2889: + if p++; p == pe { + goto _test_eof2889 + } + st_case_2889: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2518 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr2518 + } + default: + goto tr148 + } + goto tr0 + st2890: + if p++; p == pe { + goto _test_eof2890 + } + st_case_2890: + switch data[p] { + case 154: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 132 { + goto tr148 + } + case data[p] > 137: + if 141 <= data[p] { + goto tr0 + } + default: + goto tr0 + } + goto tr2518 + st2891: + if p++; p == pe { + goto _test_eof2891 + } + st_case_2891: + switch { + case data[p] < 147: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] > 171: + if 172 <= data[p] && data[p] <= 183 { + goto tr2518 + } + default: + goto tr148 + } + goto tr0 + st2892: + if p++; p == pe { + goto _test_eof2892 + } + st_case_2892: + switch { + case data[p] > 170: + if 171 <= data[p] { + goto tr0 + } + case data[p] >= 159: + goto tr2518 + } + goto tr148 + st2893: + if p++; p == pe { + goto _test_eof2893 + } + st_case_2893: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto tr2518 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2518 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st2894: + if p++; p == pe { + goto _test_eof2894 + } + st_case_2894: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr2518 + } + switch { + case data[p] < 157: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr2518 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr2518 + } + default: + goto tr2518 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr2518 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr2518 + } + default: + goto tr2518 + } + default: + goto tr148 + } + goto tr0 + st2895: + if p++; p == pe { + goto _test_eof2895 + } + st_case_2895: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr2518 + } + case data[p] >= 128: + goto tr148 + } + goto tr0 + st2896: + if p++; p == pe { + goto _test_eof2896 + } + st_case_2896: + if data[p] == 134 { + goto tr0 + } + switch { + case data[p] > 135: + if 136 <= data[p] { + goto tr0 + } + case data[p] >= 132: + goto tr148 + } + goto tr2518 + st2897: + if p++; p == pe { + goto _test_eof2897 + } + st_case_2897: + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 181: + if 184 <= data[p] { + goto tr2518 + } + default: + goto tr2518 + } + goto tr0 + st2898: + if p++; p == pe { + goto _test_eof2898 + } + st_case_2898: + switch { + case data[p] < 152: + if 129 <= data[p] && data[p] <= 151 { + goto tr0 + } + case data[p] > 155: + if 158 <= data[p] { + goto tr0 + } + default: + goto tr148 + } + goto tr2518 + st2899: + if p++; p == pe { + goto _test_eof2899 + } + st_case_2899: + if data[p] == 132 { + goto tr148 + } + if 129 <= data[p] { + goto tr0 + } + goto tr2518 + st2900: + if p++; p == pe { + goto _test_eof2900 + } + st_case_2900: + switch { + case data[p] > 170: + if 171 <= data[p] && data[p] <= 183 { + goto tr2518 + } + case data[p] >= 128: + goto tr148 + } + goto tr0 + st2901: + if p++; p == pe { + goto _test_eof2901 + } + st_case_2901: + if 157 <= data[p] && data[p] <= 171 { + goto tr2518 + } + goto tr0 + st2902: + if p++; p == pe { + goto _test_eof2902 + } + st_case_2902: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st326 + case 171: + goto st2903 + case 172: + goto st2904 + case 173: + goto st373 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st2905 + case 190: + goto st2906 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr0 + st2903: + if p++; p == pe { + goto _test_eof2903 + } + st_case_2903: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto tr2518 + } + case data[p] >= 144: + goto tr148 + } + goto tr0 + st2904: + if p++; p == pe { + goto _test_eof2904 + } + st_case_2904: + switch { + case data[p] > 175: + if 176 <= data[p] && data[p] <= 182 { + goto tr2518 + } + case data[p] >= 128: + goto tr148 + } + goto tr0 + st2905: + if p++; p == pe { + goto _test_eof2905 + } + st_case_2905: + switch { + case data[p] < 145: + if 133 <= data[p] && data[p] <= 143 { + goto tr0 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr0 + } + default: + goto tr2518 + } + goto tr148 + st2906: + if p++; p == pe { + goto _test_eof2906 + } + st_case_2906: + switch { + case data[p] > 146: + if 147 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 143: + goto tr2518 + } + goto tr0 + st2907: + if p++; p == pe { + goto _test_eof2907 + } + st_case_2907: + switch data[p] { + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st2908 + } + goto tr0 + st2908: + if p++; p == pe { + goto _test_eof2908 + } + st_case_2908: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr2518 + } + case data[p] >= 157: + goto tr2518 + } + default: + goto tr148 + } + goto tr0 + st2909: + if p++; p == pe { + goto _test_eof2909 + } + st_case_2909: + switch data[p] { + case 133: + goto st2910 + case 134: + goto st2911 + case 137: + goto st2912 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st394 + case 168: + goto st2913 + case 169: + goto st2914 + case 170: + goto st2915 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr0 + st2910: + if p++; p == pe { + goto _test_eof2910 + } + st_case_2910: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr2518 + } + case data[p] >= 165: + goto tr2518 + } + goto tr0 + st2911: + if p++; p == pe { + goto _test_eof2911 + } + st_case_2911: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr0 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr0 + } + default: + goto tr0 + } + goto tr2518 + st2912: + if p++; p == pe { + goto _test_eof2912 + } + st_case_2912: + if 130 <= data[p] && data[p] <= 132 { + goto tr2518 + } + goto tr0 + st2913: + if p++; p == pe { + goto _test_eof2913 + } + st_case_2913: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr2518 + } + case data[p] >= 128: + goto tr2518 + } + goto tr0 + st2914: + if p++; p == pe { + goto _test_eof2914 + } + st_case_2914: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr0 + } + case data[p] >= 173: + goto tr0 + } + goto tr2518 + st2915: + if p++; p == pe { + goto _test_eof2915 + } + st_case_2915: + if data[p] == 132 { + goto tr2518 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr2518 + } + case data[p] >= 155: + goto tr2518 + } + goto tr0 + st2916: + if p++; p == pe { + goto _test_eof2916 + } + st_case_2916: + switch data[p] { + case 160: + goto st147 + case 163: + goto st2917 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr0 + st2917: + if p++; p == pe { + goto _test_eof2917 + } + st_case_2917: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr0 + } + case data[p] > 150: + if 151 <= data[p] { + goto tr0 + } + default: + goto tr2518 + } + goto tr148 + st2918: + if p++; p == pe { + goto _test_eof2918 + } + st_case_2918: + if data[p] == 160 { + goto st2919 + } + goto tr0 + st2919: + if p++; p == pe { + goto _test_eof2919 + } + st_case_2919: + switch data[p] { + case 128: + goto st2920 + case 129: + goto st2921 + case 132: + goto st2778 + case 135: + goto st2923 + } + if 133 <= data[p] && data[p] <= 134 { + goto st2922 + } + goto tr0 + st2920: + if p++; p == pe { + goto _test_eof2920 + } + st_case_2920: + if data[p] == 129 { + goto tr2518 + } + if 160 <= data[p] { + goto tr2518 + } + goto tr0 + st2921: + if p++; p == pe { + goto _test_eof2921 + } + st_case_2921: + if 192 <= data[p] { + goto tr0 + } + goto tr2518 + st2922: + if p++; p == pe { + goto _test_eof2922 + } + st_case_2922: + goto tr2518 + st2923: + if p++; p == pe { + goto _test_eof2923 + } + st_case_2923: + if 176 <= data[p] { + goto tr0 + } + goto tr2518 +tr2646: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4886 + st4886: + if p++; p == pe { + goto _test_eof4886 + } + st_case_4886: +//line segment_words_prod.go:76101 + switch data[p] { + case 39: + goto st413 + case 44: + goto st413 + case 46: + goto st413 + case 59: + goto st413 + case 95: + goto tr571 + case 194: + goto st2924 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st148 + case 204: + goto st2925 + case 205: + goto st2926 + case 206: + goto st151 + case 207: + goto st152 + case 210: + goto st2927 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st2928 + case 215: + goto st2929 + case 216: + goto st2930 + case 217: + goto st2931 + case 219: + goto st2932 + case 220: + goto st2933 + case 221: + goto st2934 + case 222: + goto st2935 + case 223: + goto st2936 + case 224: + goto st2937 + case 225: + goto st2969 + case 226: + goto st2991 + case 227: + goto st2998 + case 234: + goto st3001 + case 237: + goto st287 + case 239: + goto st3017 + case 240: + goto st3023 + case 243: + goto st3065 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 + st2924: + if p++; p == pe { + goto _test_eof2924 + } + st_case_2924: + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr2646 + case 181: + goto tr148 + case 186: + goto tr148 + } + goto tr420 + st2925: + if p++; p == pe { + goto _test_eof2925 + } + st_case_2925: + if data[p] <= 127 { + goto tr420 + } + goto tr2646 + st2926: + if p++; p == pe { + goto _test_eof2926 + } + st_case_2926: + switch data[p] { + case 181: + goto tr420 + case 190: + goto st413 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + goto tr2646 + st2927: + if p++; p == pe { + goto _test_eof2927 + } + st_case_2927: + if data[p] == 130 { + goto tr420 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr2646 + } + goto tr148 + st2928: + if p++; p == pe { + goto _test_eof2928 + } + st_case_2928: + switch data[p] { + case 137: + goto st413 + case 190: + goto tr420 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr420 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + default: + goto tr2646 + } + goto tr148 + st2929: + if p++; p == pe { + goto _test_eof2929 + } + st_case_2929: + switch data[p] { + case 135: + goto tr2646 + case 179: + goto tr148 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr2646 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr2646 + } + goto tr420 + st2930: + if p++; p == pe { + goto _test_eof2930 + } + st_case_2930: + if data[p] == 156 { + goto tr2646 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 133 { + goto tr2646 + } + case data[p] > 141: + switch { + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + case data[p] >= 144: + goto tr2646 + } + default: + goto st413 + } + goto tr420 + st2931: + if p++; p == pe { + goto _test_eof2931 + } + st_case_2931: + switch data[p] { + case 171: + goto tr421 + case 172: + goto st413 + case 176: + goto tr2646 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr2646 + } + goto tr420 + st2932: + if p++; p == pe { + goto _test_eof2932 + } + st_case_2932: + switch data[p] { + case 148: + goto tr420 + case 158: + goto tr420 + case 169: + goto tr420 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr2646 + } + case data[p] >= 150: + goto tr2646 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 189: + goto tr420 + } + default: + goto tr421 + } + goto tr148 + st2933: + if p++; p == pe { + goto _test_eof2933 + } + st_case_2933: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto tr2646 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr2646 + } + default: + goto tr148 + } + goto tr420 + st2934: + if p++; p == pe { + goto _test_eof2934 + } + st_case_2934: + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr420 + } + goto tr2646 + st2935: + if p++; p == pe { + goto _test_eof2935 + } + st_case_2935: + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr2646 + } + goto tr148 + st2936: + if p++; p == pe { + goto _test_eof2936 + } + st_case_2936: + switch data[p] { + case 184: + goto st413 + case 186: + goto tr148 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 170: + switch { + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 171: + goto tr2646 + } + default: + goto tr148 + } + goto tr420 + st2937: + if p++; p == pe { + goto _test_eof2937 + } + st_case_2937: + switch data[p] { + case 160: + goto st2938 + case 161: + goto st2939 + case 162: + goto st168 + case 163: + goto st2940 + case 164: + goto st2941 + case 165: + goto st2942 + case 166: + goto st2943 + case 167: + goto st2944 + case 168: + goto st2945 + case 169: + goto st2946 + case 170: + goto st2947 + case 171: + goto st2948 + case 172: + goto st2949 + case 173: + goto st2950 + case 174: + goto st2951 + case 175: + goto st2952 + case 176: + goto st2953 + case 177: + goto st2954 + case 178: + goto st2955 + case 179: + goto st2956 + case 180: + goto st2957 + case 181: + goto st2958 + case 182: + goto st2959 + case 183: + goto st2960 + case 184: + goto st2961 + case 185: + goto st2962 + case 186: + goto st2963 + case 187: + goto st2964 + case 188: + goto st2965 + case 189: + goto st2966 + case 190: + goto st2967 + case 191: + goto st2968 + } + goto tr420 + st2938: + if p++; p == pe { + goto _test_eof2938 + } + st_case_2938: + switch data[p] { + case 154: + goto tr148 + case 164: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] > 149: + if 150 <= data[p] && data[p] <= 173 { + goto tr2646 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2939: + if p++; p == pe { + goto _test_eof2939 + } + st_case_2939: + switch { + case data[p] > 152: + if 153 <= data[p] && data[p] <= 155 { + goto tr2646 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2940: + if p++; p == pe { + goto _test_eof2940 + } + st_case_2940: + if 163 <= data[p] { + goto tr2646 + } + goto tr420 + st2941: + if p++; p == pe { + goto _test_eof2941 + } + st_case_2941: + if data[p] == 189 { + goto tr148 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr148 + } + goto tr2646 + st2942: + if p++; p == pe { + goto _test_eof2942 + } + st_case_2942: + switch data[p] { + case 144: + goto tr148 + case 176: + goto tr420 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 177 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr420 + } + goto tr2646 + st2943: + if p++; p == pe { + goto _test_eof2943 + } + st_case_2943: + switch data[p] { + case 132: + goto tr420 + case 169: + goto tr420 + case 177: + goto tr420 + case 188: + goto tr2646 + } + switch { + case data[p] < 145: + switch { + case data[p] > 131: + if 141 <= data[p] && data[p] <= 142 { + goto tr420 + } + case data[p] >= 129: + goto tr2646 + } + case data[p] > 146: + switch { + case data[p] < 186: + if 179 <= data[p] && data[p] <= 181 { + goto tr420 + } + case data[p] > 187: + if 190 <= data[p] { + goto tr2646 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st2944: + if p++; p == pe { + goto _test_eof2944 + } + st_case_2944: + switch data[p] { + case 142: + goto tr148 + case 158: + goto tr420 + } + switch { + case data[p] < 156: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 155 { + goto tr420 + } + case data[p] >= 143: + goto tr420 + } + default: + goto tr420 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr2646 + st2945: + if p++; p == pe { + goto _test_eof2945 + } + st_case_2945: + if data[p] == 188 { + goto tr2646 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2646 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto tr2646 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2946: + if p++; p == pe { + goto _test_eof2946 + } + st_case_2946: + if data[p] == 157 { + goto tr420 + } + switch { + case data[p] < 153: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 146 <= data[p] && data[p] <= 152 { + goto tr420 + } + case data[p] >= 142: + goto tr420 + } + default: + goto tr420 + } + case data[p] > 158: + switch { + case data[p] < 166: + if 159 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr2646 + st2947: + if p++; p == pe { + goto _test_eof2947 + } + st_case_2947: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2646 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto tr2646 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2948: + if p++; p == pe { + goto _test_eof2948 + } + st_case_2948: + switch data[p] { + case 134: + goto tr420 + case 138: + goto tr420 + case 144: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] >= 142: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr420 + } + goto tr2646 + st2949: + if p++; p == pe { + goto _test_eof2949 + } + st_case_2949: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2646 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2646 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2950: + if p++; p == pe { + goto _test_eof2950 + } + st_case_2950: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr2646 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr2646 + } + default: + goto tr2646 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 161: + switch { + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 162: + goto tr2646 + } + default: + goto tr148 + } + default: + goto tr2646 + } + goto tr420 + st2951: + if p++; p == pe { + goto _test_eof2951 + } + st_case_2951: + switch data[p] { + case 130: + goto tr2646 + case 131: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 158: + switch { + case data[p] < 142: + if 133 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 149: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] < 168: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto tr2646 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2952: + if p++; p == pe { + goto _test_eof2952 + } + st_case_2952: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr2646 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr2646 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 138: + goto tr2646 + } + default: + goto tr2646 + } + goto tr420 + st2953: + if p++; p == pe { + goto _test_eof2953 + } + st_case_2953: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto tr2646 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 190 <= data[p] { + goto tr2646 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2954: + if p++; p == pe { + goto _test_eof2954 + } + st_case_2954: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 151: + goto tr420 + } + switch { + case data[p] < 160: + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 148 { + goto tr420 + } + case data[p] > 154: + if 155 <= data[p] && data[p] <= 159 { + goto tr420 + } + default: + goto tr148 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr2646 + st2955: + if p++; p == pe { + goto _test_eof2955 + } + st_case_2955: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2646 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2646 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2956: + if p++; p == pe { + goto _test_eof2956 + } + st_case_2956: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr2646 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr2646 + } + default: + goto tr2646 + } + case data[p] > 150: + switch { + case data[p] < 162: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 163: + switch { + case data[p] > 175: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr2646 + } + default: + goto tr2646 + } + goto tr420 + st2957: + if p++; p == pe { + goto _test_eof2957 + } + st_case_2957: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto tr2646 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto tr2646 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2958: + if p++; p == pe { + goto _test_eof2958 + } + st_case_2958: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 142: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 150 { + goto tr420 + } + case data[p] > 158: + if 159 <= data[p] && data[p] <= 161 { + goto tr148 + } + default: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr2646 + st2959: + if p++; p == pe { + goto _test_eof2959 + } + st_case_2959: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr2646 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2960: + if p++; p == pe { + goto _test_eof2960 + } + st_case_2960: + switch data[p] { + case 138: + goto tr2646 + case 150: + goto tr2646 + } + switch { + case data[p] < 152: + switch { + case data[p] > 134: + if 143 <= data[p] && data[p] <= 148 { + goto tr2646 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto tr2646 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr2646 + } + goto tr420 + st2961: + if p++; p == pe { + goto _test_eof2961 + } + st_case_2961: + if data[p] == 177 { + goto tr2646 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr2646 + } + goto tr420 + st2962: + if p++; p == pe { + goto _test_eof2962 + } + st_case_2962: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 135: + goto tr2646 + } + goto tr420 + st2963: + if p++; p == pe { + goto _test_eof2963 + } + st_case_2963: + if data[p] == 177 { + goto tr2646 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr2646 + } + case data[p] >= 180: + goto tr2646 + } + goto tr420 + st2964: + if p++; p == pe { + goto _test_eof2964 + } + st_case_2964: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 136: + goto tr2646 + } + goto tr420 + st2965: + if p++; p == pe { + goto _test_eof2965 + } + st_case_2965: + switch data[p] { + case 128: + goto tr148 + case 181: + goto tr2646 + case 183: + goto tr2646 + case 185: + goto tr2646 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto tr2646 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto tr2646 + } + default: + goto tr421 + } + goto tr420 + st2966: + if p++; p == pe { + goto _test_eof2966 + } + st_case_2966: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto tr2646 + } + default: + goto tr148 + } + goto tr420 + st2967: + if p++; p == pe { + goto _test_eof2967 + } + st_case_2967: + switch { + case data[p] < 136: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 135 { + goto tr2646 + } + case data[p] >= 128: + goto tr2646 + } + case data[p] > 140: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr2646 + } + case data[p] >= 141: + goto tr2646 + } + default: + goto tr148 + } + goto tr420 + st2968: + if p++; p == pe { + goto _test_eof2968 + } + st_case_2968: + if data[p] == 134 { + goto tr2646 + } + goto tr420 + st2969: + if p++; p == pe { + goto _test_eof2969 + } + st_case_2969: + switch data[p] { + case 128: + goto st2970 + case 129: + goto st2971 + case 130: + goto st2972 + case 131: + goto st202 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st2973 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st2974 + case 157: + goto st2975 + case 158: + goto st2976 + case 159: + goto st2977 + case 160: + goto st2978 + case 161: + goto st219 + case 162: + goto st2979 + case 163: + goto st221 + case 164: + goto st2980 + case 165: + goto st468 + case 167: + goto st469 + case 168: + goto st2981 + case 169: + goto st2982 + case 170: + goto st2983 + case 172: + goto st2984 + case 173: + goto st2985 + case 174: + goto st2986 + case 175: + goto st2987 + case 176: + goto st2988 + case 177: + goto st640 + case 179: + goto st2989 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st2990 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + } + switch { + case data[p] < 180: + if 132 <= data[p] && data[p] <= 152 { + goto st145 + } + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + default: + goto st147 + } + goto tr420 + st2970: + if p++; p == pe { + goto _test_eof2970 + } + st_case_2970: + if 171 <= data[p] && data[p] <= 190 { + goto tr2646 + } + goto tr420 + st2971: + if p++; p == pe { + goto _test_eof2971 + } + st_case_2971: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto tr2646 + } + case data[p] >= 128: + goto tr421 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto tr2646 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr2646 + } + default: + goto tr2646 + } + default: + goto tr2646 + } + goto tr420 + st2972: + if p++; p == pe { + goto _test_eof2972 + } + st_case_2972: + if data[p] == 143 { + goto tr2646 + } + switch { + case data[p] < 144: + if 130 <= data[p] && data[p] <= 141 { + goto tr2646 + } + case data[p] > 153: + switch { + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 154: + goto tr2646 + } + default: + goto tr421 + } + goto tr420 + st2973: + if p++; p == pe { + goto _test_eof2973 + } + st_case_2973: + switch { + case data[p] < 157: + if 155 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr420 + } + default: + goto tr2646 + } + goto tr148 + st2974: + if p++; p == pe { + goto _test_eof2974 + } + st_case_2974: + switch { + case data[p] < 146: + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 177: + if 178 <= data[p] && data[p] <= 180 { + goto tr2646 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr2646 + } + goto tr420 + st2975: + if p++; p == pe { + goto _test_eof2975 + } + st_case_2975: + switch { + case data[p] < 160: + switch { + case data[p] > 145: + if 146 <= data[p] && data[p] <= 147 { + goto tr2646 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto tr2646 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2976: + if p++; p == pe { + goto _test_eof2976 + } + st_case_2976: + if 180 <= data[p] { + goto tr2646 + } + goto tr420 + st2977: + if p++; p == pe { + goto _test_eof2977 + } + st_case_2977: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 170 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr420 + } + goto tr2646 + st2978: + if p++; p == pe { + goto _test_eof2978 + } + st_case_2978: + switch { + case data[p] < 144: + if 139 <= data[p] && data[p] <= 142 { + goto tr2646 + } + case data[p] > 153: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + goto tr420 + st2979: + if p++; p == pe { + goto _test_eof2979 + } + st_case_2979: + if data[p] == 169 { + goto tr2646 + } + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2980: + if p++; p == pe { + goto _test_eof2980 + } + st_case_2980: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr2646 + } + default: + goto tr2646 + } + goto tr420 + st2981: + if p++; p == pe { + goto _test_eof2981 + } + st_case_2981: + switch { + case data[p] > 150: + if 151 <= data[p] && data[p] <= 155 { + goto tr2646 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2982: + if p++; p == pe { + goto _test_eof2982 + } + st_case_2982: + if data[p] == 191 { + goto tr2646 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr2646 + } + case data[p] >= 149: + goto tr2646 + } + goto tr420 + st2983: + if p++; p == pe { + goto _test_eof2983 + } + st_case_2983: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto tr2646 + } + default: + goto tr421 + } + goto tr420 + st2984: + if p++; p == pe { + goto _test_eof2984 + } + st_case_2984: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 132 { + goto tr2646 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr2646 + } + default: + goto tr148 + } + goto tr420 + st2985: + if p++; p == pe { + goto _test_eof2985 + } + st_case_2985: + switch { + case data[p] < 144: + switch { + case data[p] > 139: + if 140 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] >= 133: + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 154: + goto tr420 + } + default: + goto tr421 + } + goto tr2646 + st2986: + if p++; p == pe { + goto _test_eof2986 + } + st_case_2986: + switch { + case data[p] < 161: + switch { + case data[p] > 130: + if 131 <= data[p] && data[p] <= 160 { + goto tr148 + } + case data[p] >= 128: + goto tr2646 + } + case data[p] > 173: + switch { + case data[p] < 176: + if 174 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + default: + goto tr2646 + } + goto tr420 + st2987: + if p++; p == pe { + goto _test_eof2987 + } + st_case_2987: + switch { + case data[p] > 179: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr2646 + } + goto tr148 + st2988: + if p++; p == pe { + goto _test_eof2988 + } + st_case_2988: + switch { + case data[p] > 163: + if 164 <= data[p] && data[p] <= 183 { + goto tr2646 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st2989: + if p++; p == pe { + goto _test_eof2989 + } + st_case_2989: + if data[p] == 173 { + goto tr2646 + } + switch { + case data[p] < 169: + switch { + case data[p] > 146: + if 148 <= data[p] && data[p] <= 168 { + goto tr2646 + } + case data[p] >= 144: + goto tr2646 + } + case data[p] > 177: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 180 { + goto tr2646 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto tr2646 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2990: + if p++; p == pe { + goto _test_eof2990 + } + st_case_2990: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr2646 + } + case data[p] >= 128: + goto tr2646 + } + goto tr420 + st2991: + if p++; p == pe { + goto _test_eof2991 + } + st_case_2991: + switch data[p] { + case 128: + goto st2992 + case 129: + goto st2993 + case 130: + goto st241 + case 131: + goto st2994 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st2995 + case 180: + goto st251 + case 181: + goto st2996 + case 182: + goto st253 + case 183: + goto st2997 + case 184: + goto st255 + } + goto tr420 + st2992: + if p++; p == pe { + goto _test_eof2992 + } + st_case_2992: + if data[p] == 164 { + goto st413 + } + switch { + case data[p] < 152: + if 140 <= data[p] && data[p] <= 143 { + goto tr2646 + } + case data[p] > 153: + switch { + case data[p] > 174: + if 191 <= data[p] { + goto tr571 + } + case data[p] >= 170: + goto tr2646 + } + default: + goto st413 + } + goto tr420 + st2993: + if p++; p == pe { + goto _test_eof2993 + } + st_case_2993: + switch data[p] { + case 132: + goto st413 + case 165: + goto tr420 + case 177: + goto tr148 + case 191: + goto tr148 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr2646 + } + default: + goto tr420 + } + goto tr571 + st2994: + if p++; p == pe { + goto _test_eof2994 + } + st_case_2994: + if 144 <= data[p] && data[p] <= 176 { + goto tr2646 + } + goto tr420 + st2995: + if p++; p == pe { + goto _test_eof2995 + } + st_case_2995: + switch { + case data[p] < 175: + if 165 <= data[p] && data[p] <= 170 { + goto tr420 + } + case data[p] > 177: + if 180 <= data[p] { + goto tr420 + } + default: + goto tr2646 + } + goto tr148 + st2996: + if p++; p == pe { + goto _test_eof2996 + } + st_case_2996: + if data[p] == 191 { + goto tr2646 + } + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 168: + goto tr420 + } + goto tr148 + st2997: + if p++; p == pe { + goto _test_eof2997 + } + st_case_2997: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto tr2646 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st2998: + if p++; p == pe { + goto _test_eof2998 + } + st_case_2998: + switch data[p] { + case 128: + goto st2999 + case 130: + goto st3000 + case 132: + goto st259 + case 133: + goto st145 + case 134: + goto st260 + } + goto tr420 + st2999: + if p++; p == pe { + goto _test_eof2999 + } + st_case_2999: + if data[p] == 133 { + goto tr148 + } + switch { + case data[p] > 175: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + case data[p] >= 170: + goto tr2646 + } + goto tr420 + st3000: + if p++; p == pe { + goto _test_eof3000 + } + st_case_3000: + if 153 <= data[p] && data[p] <= 154 { + goto tr2646 + } + goto tr420 + st3001: + if p++; p == pe { + goto _test_eof3001 + } + st_case_3001: + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st654 + case 153: + goto st3002 + case 154: + goto st3003 + case 155: + goto st3004 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st3005 + case 161: + goto st272 + case 162: + goto st3006 + case 163: + goto st3007 + case 164: + goto st3008 + case 165: + goto st3009 + case 166: + goto st3010 + case 167: + goto st3011 + case 168: + goto st3012 + case 169: + goto st3013 + case 170: + goto st3014 + case 171: + goto st3015 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st3016 + case 176: + goto st147 + } + if 129 <= data[p] { + goto st145 + } + goto tr420 + st3002: + if p++; p == pe { + goto _test_eof3002 + } + st_case_3002: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr2646 + } + default: + goto tr2646 + } + goto tr420 + st3003: + if p++; p == pe { + goto _test_eof3003 + } + st_case_3003: + switch { + case data[p] < 158: + if 128 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr2646 + } + goto tr420 + st3004: + if p++; p == pe { + goto _test_eof3004 + } + st_case_3004: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr2646 + } + goto tr148 + st3005: + if p++; p == pe { + goto _test_eof3005 + } + st_case_3005: + switch data[p] { + case 130: + goto tr2646 + case 134: + goto tr2646 + case 139: + goto tr2646 + } + switch { + case data[p] > 167: + if 168 <= data[p] { + goto tr420 + } + case data[p] >= 163: + goto tr2646 + } + goto tr148 + st3006: + if p++; p == pe { + goto _test_eof3006 + } + st_case_3006: + switch { + case data[p] < 130: + if 128 <= data[p] && data[p] <= 129 { + goto tr2646 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr2646 + } + default: + goto tr148 + } + goto tr420 + st3007: + if p++; p == pe { + goto _test_eof3007 + } + st_case_3007: + switch data[p] { + case 187: + goto tr148 + case 189: + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 143: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 133: + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 183: + if 184 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr420 + } + goto tr2646 + st3008: + if p++; p == pe { + goto _test_eof3008 + } + st_case_3008: + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 165: + switch { + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr2646 + } + default: + goto tr148 + } + goto tr420 + st3009: + if p++; p == pe { + goto _test_eof3009 + } + st_case_3009: + switch { + case data[p] < 148: + if 135 <= data[p] && data[p] <= 147 { + goto tr2646 + } + case data[p] > 159: + if 189 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st3010: + if p++; p == pe { + goto _test_eof3010 + } + st_case_3010: + switch { + case data[p] < 132: + if 128 <= data[p] && data[p] <= 131 { + goto tr2646 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr2646 + } + default: + goto tr148 + } + goto tr420 + st3011: + if p++; p == pe { + goto _test_eof3011 + } + st_case_3011: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 129: + goto tr420 + } + case data[p] > 164: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr420 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + default: + goto tr420 + } + goto tr2646 + st3012: + if p++; p == pe { + goto _test_eof3012 + } + st_case_3012: + switch { + case data[p] > 168: + if 169 <= data[p] && data[p] <= 182 { + goto tr2646 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3013: + if p++; p == pe { + goto _test_eof3013 + } + st_case_3013: + if data[p] == 131 { + goto tr2646 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 141: + switch { + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto tr2646 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr2646 + } + goto tr420 + st3014: + if p++; p == pe { + goto _test_eof3014 + } + st_case_3014: + if data[p] == 176 { + goto tr2646 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr2646 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr2646 + } + default: + goto tr2646 + } + goto tr420 + st3015: + if p++; p == pe { + goto _test_eof3015 + } + st_case_3015: + if data[p] == 129 { + goto tr2646 + } + switch { + case data[p] < 171: + if 160 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 181 <= data[p] && data[p] <= 182 { + goto tr2646 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr2646 + } + goto tr420 + st3016: + if p++; p == pe { + goto _test_eof3016 + } + st_case_3016: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 162 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 172: + goto tr2646 + } + default: + goto tr2646 + } + goto tr420 + st3017: + if p++; p == pe { + goto _test_eof3017 + } + st_case_3017: + switch data[p] { + case 172: + goto st3018 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st3019 + case 185: + goto st1408 + case 187: + goto st3020 + case 188: + goto st1410 + case 189: + goto st303 + case 190: + goto st3021 + case 191: + goto st3022 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr420 + st3018: + if p++; p == pe { + goto _test_eof3018 + } + st_case_3018: + switch data[p] { + case 158: + goto tr2646 + case 190: + goto tr572 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 170: + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st3019: + if p++; p == pe { + goto _test_eof3019 + } + st_case_3019: + switch data[p] { + case 144: + goto st413 + case 148: + goto st413 + } + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr2646 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr571 + } + default: + goto tr2646 + } + goto tr420 + st3020: + if p++; p == pe { + goto _test_eof3020 + } + st_case_3020: + if data[p] == 191 { + goto tr2646 + } + if 189 <= data[p] { + goto tr420 + } + goto tr148 + st3021: + if p++; p == pe { + goto _test_eof3021 + } + st_case_3021: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 190 { + goto tr148 + } + case data[p] >= 158: + goto tr2646 + } + goto tr420 + st3022: + if p++; p == pe { + goto _test_eof3022 + } + st_case_3022: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] >= 130: + goto tr148 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr2646 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3023: + if p++; p == pe { + goto _test_eof3023 + } + st_case_3023: + switch data[p] { + case 144: + goto st3024 + case 145: + goto st3030 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st3049 + case 155: + goto st3054 + case 157: + goto st3056 + case 158: + goto st3063 + case 159: + goto st403 + } + goto tr420 + st3024: + if p++; p == pe { + goto _test_eof3024 + } + st_case_3024: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st3025 + case 138: + goto st313 + case 139: + goto st3026 + case 140: + goto st315 + case 141: + goto st3027 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st684 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st3028 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st3029 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr420 + st3025: + if p++; p == pe { + goto _test_eof3025 + } + st_case_3025: + if data[p] == 189 { + goto tr2646 + } + goto tr420 + st3026: + if p++; p == pe { + goto _test_eof3026 + } + st_case_3026: + if data[p] == 160 { + goto tr2646 + } + if 145 <= data[p] { + goto tr420 + } + goto tr148 + st3027: + if p++; p == pe { + goto _test_eof3027 + } + st_case_3027: + switch { + case data[p] < 182: + if 139 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr420 + } + default: + goto tr2646 + } + goto tr148 + st3028: + if p++; p == pe { + goto _test_eof3028 + } + st_case_3028: + switch data[p] { + case 128: + goto tr148 + case 191: + goto tr2646 + } + switch { + case data[p] < 144: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2646 + } + case data[p] > 134: + if 140 <= data[p] && data[p] <= 143 { + goto tr2646 + } + default: + goto tr2646 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto tr2646 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3029: + if p++; p == pe { + goto _test_eof3029 + } + st_case_3029: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 164: + if 165 <= data[p] && data[p] <= 166 { + goto tr2646 + } + default: + goto tr148 + } + goto tr420 + st3030: + if p++; p == pe { + goto _test_eof3030 + } + st_case_3030: + switch data[p] { + case 128: + goto st3031 + case 129: + goto st3032 + case 130: + goto st3033 + case 131: + goto st691 + case 132: + goto st3034 + case 133: + goto st3035 + case 134: + goto st3036 + case 135: + goto st3037 + case 136: + goto st3038 + case 138: + goto st348 + case 139: + goto st3039 + case 140: + goto st3040 + case 141: + goto st3041 + case 146: + goto st3042 + case 147: + goto st3043 + case 150: + goto st3044 + case 151: + goto st3045 + case 152: + goto st3042 + case 153: + goto st3046 + case 154: + goto st3047 + case 155: + goto st538 + case 156: + goto st3048 + case 162: + goto st359 + case 163: + goto st707 + case 171: + goto st361 + } + goto tr420 + st3031: + if p++; p == pe { + goto _test_eof3031 + } + st_case_3031: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2646 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr2646 + } + default: + goto tr148 + } + goto tr420 + st3032: + if p++; p == pe { + goto _test_eof3032 + } + st_case_3032: + switch { + case data[p] < 166: + if 135 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] && data[p] <= 190 { + goto tr420 + } + default: + goto tr421 + } + goto tr2646 + st3033: + if p++; p == pe { + goto _test_eof3033 + } + st_case_3033: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr2646 + st3034: + if p++; p == pe { + goto _test_eof3034 + } + st_case_3034: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2646 + } + case data[p] > 166: + switch { + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr421 + } + case data[p] >= 167: + goto tr2646 + } + default: + goto tr148 + } + goto tr420 + st3035: + if p++; p == pe { + goto _test_eof3035 + } + st_case_3035: + switch data[p] { + case 179: + goto tr2646 + case 182: + goto tr148 + } + if 144 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr420 + st3036: + if p++; p == pe { + goto _test_eof3036 + } + st_case_3036: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2646 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr2646 + } + default: + goto tr148 + } + goto tr420 + st3037: + if p++; p == pe { + goto _test_eof3037 + } + st_case_3037: + if data[p] == 155 { + goto tr420 + } + switch { + case data[p] < 141: + switch { + case data[p] > 132: + if 133 <= data[p] && data[p] <= 137 { + goto tr420 + } + case data[p] >= 129: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] < 154: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] > 156: + if 157 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + default: + goto tr420 + } + goto tr2646 + st3038: + if p++; p == pe { + goto _test_eof3038 + } + st_case_3038: + switch { + case data[p] < 147: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] > 171: + if 172 <= data[p] && data[p] <= 183 { + goto tr2646 + } + default: + goto tr148 + } + goto tr420 + st3039: + if p++; p == pe { + goto _test_eof3039 + } + st_case_3039: + switch { + case data[p] < 171: + if 159 <= data[p] && data[p] <= 170 { + goto tr2646 + } + case data[p] > 175: + switch { + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr421 + } + default: + goto tr420 + } + goto tr148 + st3040: + if p++; p == pe { + goto _test_eof3040 + } + st_case_3040: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto tr2646 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2646 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3041: + if p++; p == pe { + goto _test_eof3041 + } + st_case_3041: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr2646 + } + switch { + case data[p] < 157: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr2646 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr2646 + } + default: + goto tr2646 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr2646 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr2646 + } + default: + goto tr2646 + } + default: + goto tr148 + } + goto tr420 + st3042: + if p++; p == pe { + goto _test_eof3042 + } + st_case_3042: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr2646 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3043: + if p++; p == pe { + goto _test_eof3043 + } + st_case_3043: + if data[p] == 134 { + goto tr420 + } + switch { + case data[p] < 136: + if 132 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr420 + } + goto tr2646 + st3044: + if p++; p == pe { + goto _test_eof3044 + } + st_case_3044: + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 181: + if 184 <= data[p] { + goto tr2646 + } + default: + goto tr2646 + } + goto tr420 + st3045: + if p++; p == pe { + goto _test_eof3045 + } + st_case_3045: + switch { + case data[p] < 152: + if 129 <= data[p] && data[p] <= 151 { + goto tr420 + } + case data[p] > 155: + if 158 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + goto tr2646 + st3046: + if p++; p == pe { + goto _test_eof3046 + } + st_case_3046: + if data[p] == 132 { + goto tr148 + } + switch { + case data[p] < 144: + if 129 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + goto tr2646 + st3047: + if p++; p == pe { + goto _test_eof3047 + } + st_case_3047: + switch { + case data[p] > 170: + if 171 <= data[p] && data[p] <= 183 { + goto tr2646 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3048: + if p++; p == pe { + goto _test_eof3048 + } + st_case_3048: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 157: + goto tr2646 + } + goto tr420 + st3049: + if p++; p == pe { + goto _test_eof3049 + } + st_case_3049: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st709 + case 171: + goto st3050 + case 172: + goto st3051 + case 173: + goto st712 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st3052 + case 190: + goto st3053 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr420 + st3050: + if p++; p == pe { + goto _test_eof3050 + } + st_case_3050: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto tr2646 + } + case data[p] >= 144: + goto tr148 + } + goto tr420 + st3051: + if p++; p == pe { + goto _test_eof3051 + } + st_case_3051: + switch { + case data[p] > 175: + if 176 <= data[p] && data[p] <= 182 { + goto tr2646 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3052: + if p++; p == pe { + goto _test_eof3052 + } + st_case_3052: + switch { + case data[p] < 145: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr420 + } + default: + goto tr2646 + } + goto tr148 + st3053: + if p++; p == pe { + goto _test_eof3053 + } + st_case_3053: + switch { + case data[p] > 146: + if 147 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 143: + goto tr2646 + } + goto tr420 + st3054: + if p++; p == pe { + goto _test_eof3054 + } + st_case_3054: + switch data[p] { + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st3055 + } + goto tr420 + st3055: + if p++; p == pe { + goto _test_eof3055 + } + st_case_3055: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr2646 + } + case data[p] >= 157: + goto tr2646 + } + default: + goto tr148 + } + goto tr420 + st3056: + if p++; p == pe { + goto _test_eof3056 + } + st_case_3056: + switch data[p] { + case 133: + goto st3057 + case 134: + goto st3058 + case 137: + goto st3059 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st721 + case 168: + goto st3060 + case 169: + goto st3061 + case 170: + goto st3062 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr420 + st3057: + if p++; p == pe { + goto _test_eof3057 + } + st_case_3057: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr2646 + } + case data[p] >= 165: + goto tr2646 + } + goto tr420 + st3058: + if p++; p == pe { + goto _test_eof3058 + } + st_case_3058: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr420 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr2646 + st3059: + if p++; p == pe { + goto _test_eof3059 + } + st_case_3059: + if 130 <= data[p] && data[p] <= 132 { + goto tr2646 + } + goto tr420 + st3060: + if p++; p == pe { + goto _test_eof3060 + } + st_case_3060: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr2646 + } + case data[p] >= 128: + goto tr2646 + } + goto tr420 + st3061: + if p++; p == pe { + goto _test_eof3061 + } + st_case_3061: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 173: + goto tr420 + } + goto tr2646 + st3062: + if p++; p == pe { + goto _test_eof3062 + } + st_case_3062: + if data[p] == 132 { + goto tr2646 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr2646 + } + case data[p] >= 155: + goto tr2646 + } + goto tr420 + st3063: + if p++; p == pe { + goto _test_eof3063 + } + st_case_3063: + switch data[p] { + case 160: + goto st147 + case 163: + goto st3064 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr420 + st3064: + if p++; p == pe { + goto _test_eof3064 + } + st_case_3064: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 150: + if 151 <= data[p] { + goto tr420 + } + default: + goto tr2646 + } + goto tr148 + st3065: + if p++; p == pe { + goto _test_eof3065 + } + st_case_3065: + if data[p] == 160 { + goto st3066 + } + goto tr420 + st3066: + if p++; p == pe { + goto _test_eof3066 + } + st_case_3066: + switch data[p] { + case 128: + goto st3067 + case 129: + goto st3068 + case 132: + goto st2925 + case 135: + goto st3070 + } + if 133 <= data[p] && data[p] <= 134 { + goto st3069 + } + goto tr420 + st3067: + if p++; p == pe { + goto _test_eof3067 + } + st_case_3067: + if data[p] == 129 { + goto tr2646 + } + if 160 <= data[p] { + goto tr2646 + } + goto tr420 + st3068: + if p++; p == pe { + goto _test_eof3068 + } + st_case_3068: + if 192 <= data[p] { + goto tr420 + } + goto tr2646 + st3069: + if p++; p == pe { + goto _test_eof3069 + } + st_case_3069: + goto tr2646 + st3070: + if p++; p == pe { + goto _test_eof3070 + } + st_case_3070: + if 176 <= data[p] { + goto tr420 + } + goto tr2646 +tr2774: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4887 + st4887: + if p++; p == pe { + goto _test_eof4887 + } + st_case_4887: +//line segment_words_prod.go:79886 + switch data[p] { + case 95: + goto tr571 + case 194: + goto st3071 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st148 + case 204: + goto st3072 + case 205: + goto st3073 + case 206: + goto st151 + case 207: + goto st152 + case 210: + goto st3074 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3075 + case 215: + goto st3076 + case 216: + goto st3077 + case 217: + goto st3078 + case 219: + goto st3079 + case 220: + goto st3080 + case 221: + goto st3081 + case 222: + goto st3082 + case 223: + goto st3083 + case 224: + goto st3084 + case 225: + goto st3116 + case 226: + goto st3138 + case 227: + goto st3145 + case 234: + goto st3148 + case 237: + goto st287 + case 239: + goto st3164 + case 240: + goto st3170 + case 243: + goto st3212 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 + st3071: + if p++; p == pe { + goto _test_eof3071 + } + st_case_3071: + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr2774 + case 181: + goto tr148 + case 186: + goto tr148 + } + goto tr420 + st3072: + if p++; p == pe { + goto _test_eof3072 + } + st_case_3072: + if data[p] <= 127 { + goto tr420 + } + goto tr2774 + st3073: + if p++; p == pe { + goto _test_eof3073 + } + st_case_3073: + switch data[p] { + case 181: + goto tr420 + case 190: + goto tr420 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + goto tr2774 + st3074: + if p++; p == pe { + goto _test_eof3074 + } + st_case_3074: + if data[p] == 130 { + goto tr420 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr2774 + } + goto tr148 + st3075: + if p++; p == pe { + goto _test_eof3075 + } + st_case_3075: + if data[p] == 190 { + goto tr420 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr420 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + default: + goto tr2774 + } + goto tr148 + st3076: + if p++; p == pe { + goto _test_eof3076 + } + st_case_3076: + switch data[p] { + case 135: + goto tr2774 + case 179: + goto tr148 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr2774 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr2774 + } + goto tr420 + st3077: + if p++; p == pe { + goto _test_eof3077 + } + st_case_3077: + if data[p] == 156 { + goto tr2774 + } + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 133 { + goto tr2774 + } + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr2774 + } + goto tr420 + st3078: + if p++; p == pe { + goto _test_eof3078 + } + st_case_3078: + switch data[p] { + case 171: + goto tr421 + case 176: + goto tr2774 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr2774 + } + goto tr420 + st3079: + if p++; p == pe { + goto _test_eof3079 + } + st_case_3079: + switch data[p] { + case 148: + goto tr420 + case 158: + goto tr420 + case 169: + goto tr420 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr2774 + } + case data[p] >= 150: + goto tr2774 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 189: + goto tr420 + } + default: + goto tr421 + } + goto tr148 + st3080: + if p++; p == pe { + goto _test_eof3080 + } + st_case_3080: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto tr2774 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr2774 + } + default: + goto tr148 + } + goto tr420 + st3081: + if p++; p == pe { + goto _test_eof3081 + } + st_case_3081: + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr420 + } + goto tr2774 + st3082: + if p++; p == pe { + goto _test_eof3082 + } + st_case_3082: + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr2774 + } + goto tr148 + st3083: + if p++; p == pe { + goto _test_eof3083 + } + st_case_3083: + if data[p] == 186 { + goto tr148 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 170: + switch { + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 171: + goto tr2774 + } + default: + goto tr148 + } + goto tr420 + st3084: + if p++; p == pe { + goto _test_eof3084 + } + st_case_3084: + switch data[p] { + case 160: + goto st3085 + case 161: + goto st3086 + case 162: + goto st168 + case 163: + goto st3087 + case 164: + goto st3088 + case 165: + goto st3089 + case 166: + goto st3090 + case 167: + goto st3091 + case 168: + goto st3092 + case 169: + goto st3093 + case 170: + goto st3094 + case 171: + goto st3095 + case 172: + goto st3096 + case 173: + goto st3097 + case 174: + goto st3098 + case 175: + goto st3099 + case 176: + goto st3100 + case 177: + goto st3101 + case 178: + goto st3102 + case 179: + goto st3103 + case 180: + goto st3104 + case 181: + goto st3105 + case 182: + goto st3106 + case 183: + goto st3107 + case 184: + goto st3108 + case 185: + goto st3109 + case 186: + goto st3110 + case 187: + goto st3111 + case 188: + goto st3112 + case 189: + goto st3113 + case 190: + goto st3114 + case 191: + goto st3115 + } + goto tr420 + st3085: + if p++; p == pe { + goto _test_eof3085 + } + st_case_3085: + switch data[p] { + case 154: + goto tr148 + case 164: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] > 149: + if 150 <= data[p] && data[p] <= 173 { + goto tr2774 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3086: + if p++; p == pe { + goto _test_eof3086 + } + st_case_3086: + switch { + case data[p] > 152: + if 153 <= data[p] && data[p] <= 155 { + goto tr2774 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3087: + if p++; p == pe { + goto _test_eof3087 + } + st_case_3087: + if 163 <= data[p] { + goto tr2774 + } + goto tr420 + st3088: + if p++; p == pe { + goto _test_eof3088 + } + st_case_3088: + if data[p] == 189 { + goto tr148 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr148 + } + goto tr2774 + st3089: + if p++; p == pe { + goto _test_eof3089 + } + st_case_3089: + switch data[p] { + case 144: + goto tr148 + case 176: + goto tr420 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 177 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr420 + } + goto tr2774 + st3090: + if p++; p == pe { + goto _test_eof3090 + } + st_case_3090: + switch data[p] { + case 132: + goto tr420 + case 169: + goto tr420 + case 177: + goto tr420 + case 188: + goto tr2774 + } + switch { + case data[p] < 145: + switch { + case data[p] > 131: + if 141 <= data[p] && data[p] <= 142 { + goto tr420 + } + case data[p] >= 129: + goto tr2774 + } + case data[p] > 146: + switch { + case data[p] < 186: + if 179 <= data[p] && data[p] <= 181 { + goto tr420 + } + case data[p] > 187: + if 190 <= data[p] { + goto tr2774 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st3091: + if p++; p == pe { + goto _test_eof3091 + } + st_case_3091: + switch data[p] { + case 142: + goto tr148 + case 158: + goto tr420 + } + switch { + case data[p] < 156: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 155 { + goto tr420 + } + case data[p] >= 143: + goto tr420 + } + default: + goto tr420 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr2774 + st3092: + if p++; p == pe { + goto _test_eof3092 + } + st_case_3092: + if data[p] == 188 { + goto tr2774 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2774 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto tr2774 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3093: + if p++; p == pe { + goto _test_eof3093 + } + st_case_3093: + if data[p] == 157 { + goto tr420 + } + switch { + case data[p] < 153: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 146 <= data[p] && data[p] <= 152 { + goto tr420 + } + case data[p] >= 142: + goto tr420 + } + default: + goto tr420 + } + case data[p] > 158: + switch { + case data[p] < 166: + if 159 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr2774 + st3094: + if p++; p == pe { + goto _test_eof3094 + } + st_case_3094: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2774 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto tr2774 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3095: + if p++; p == pe { + goto _test_eof3095 + } + st_case_3095: + switch data[p] { + case 134: + goto tr420 + case 138: + goto tr420 + case 144: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] >= 142: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr420 + } + goto tr2774 + st3096: + if p++; p == pe { + goto _test_eof3096 + } + st_case_3096: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2774 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2774 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3097: + if p++; p == pe { + goto _test_eof3097 + } + st_case_3097: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr2774 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr2774 + } + default: + goto tr2774 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 161: + switch { + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 162: + goto tr2774 + } + default: + goto tr148 + } + default: + goto tr2774 + } + goto tr420 + st3098: + if p++; p == pe { + goto _test_eof3098 + } + st_case_3098: + switch data[p] { + case 130: + goto tr2774 + case 131: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 158: + switch { + case data[p] < 142: + if 133 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 149: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] < 168: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto tr2774 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3099: + if p++; p == pe { + goto _test_eof3099 + } + st_case_3099: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr2774 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr2774 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 138: + goto tr2774 + } + default: + goto tr2774 + } + goto tr420 + st3100: + if p++; p == pe { + goto _test_eof3100 + } + st_case_3100: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto tr2774 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 190 <= data[p] { + goto tr2774 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3101: + if p++; p == pe { + goto _test_eof3101 + } + st_case_3101: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 151: + goto tr420 + } + switch { + case data[p] < 160: + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 148 { + goto tr420 + } + case data[p] > 154: + if 155 <= data[p] && data[p] <= 159 { + goto tr420 + } + default: + goto tr148 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr2774 + st3102: + if p++; p == pe { + goto _test_eof3102 + } + st_case_3102: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2774 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2774 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3103: + if p++; p == pe { + goto _test_eof3103 + } + st_case_3103: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr2774 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr2774 + } + default: + goto tr2774 + } + case data[p] > 150: + switch { + case data[p] < 162: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 163: + switch { + case data[p] > 175: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr2774 + } + default: + goto tr2774 + } + goto tr420 + st3104: + if p++; p == pe { + goto _test_eof3104 + } + st_case_3104: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto tr2774 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto tr2774 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3105: + if p++; p == pe { + goto _test_eof3105 + } + st_case_3105: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 142: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 150 { + goto tr420 + } + case data[p] > 158: + if 159 <= data[p] && data[p] <= 161 { + goto tr148 + } + default: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr2774 + st3106: + if p++; p == pe { + goto _test_eof3106 + } + st_case_3106: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr2774 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3107: + if p++; p == pe { + goto _test_eof3107 + } + st_case_3107: + switch data[p] { + case 138: + goto tr2774 + case 150: + goto tr2774 + } + switch { + case data[p] < 152: + switch { + case data[p] > 134: + if 143 <= data[p] && data[p] <= 148 { + goto tr2774 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto tr2774 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr2774 + } + goto tr420 + st3108: + if p++; p == pe { + goto _test_eof3108 + } + st_case_3108: + if data[p] == 177 { + goto tr2774 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr2774 + } + goto tr420 + st3109: + if p++; p == pe { + goto _test_eof3109 + } + st_case_3109: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 135: + goto tr2774 + } + goto tr420 + st3110: + if p++; p == pe { + goto _test_eof3110 + } + st_case_3110: + if data[p] == 177 { + goto tr2774 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr2774 + } + case data[p] >= 180: + goto tr2774 + } + goto tr420 + st3111: + if p++; p == pe { + goto _test_eof3111 + } + st_case_3111: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 136: + goto tr2774 + } + goto tr420 + st3112: + if p++; p == pe { + goto _test_eof3112 + } + st_case_3112: + switch data[p] { + case 128: + goto tr148 + case 181: + goto tr2774 + case 183: + goto tr2774 + case 185: + goto tr2774 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto tr2774 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto tr2774 + } + default: + goto tr421 + } + goto tr420 + st3113: + if p++; p == pe { + goto _test_eof3113 + } + st_case_3113: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto tr2774 + } + default: + goto tr148 + } + goto tr420 + st3114: + if p++; p == pe { + goto _test_eof3114 + } + st_case_3114: + switch { + case data[p] < 136: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 135 { + goto tr2774 + } + case data[p] >= 128: + goto tr2774 + } + case data[p] > 140: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr2774 + } + case data[p] >= 141: + goto tr2774 + } + default: + goto tr148 + } + goto tr420 + st3115: + if p++; p == pe { + goto _test_eof3115 + } + st_case_3115: + if data[p] == 134 { + goto tr2774 + } + goto tr420 + st3116: + if p++; p == pe { + goto _test_eof3116 + } + st_case_3116: + switch data[p] { + case 128: + goto st3117 + case 129: + goto st3118 + case 130: + goto st3119 + case 131: + goto st202 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st3120 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st3121 + case 157: + goto st3122 + case 158: + goto st3123 + case 159: + goto st3124 + case 160: + goto st3125 + case 161: + goto st219 + case 162: + goto st3126 + case 163: + goto st221 + case 164: + goto st3127 + case 165: + goto st468 + case 167: + goto st469 + case 168: + goto st3128 + case 169: + goto st3129 + case 170: + goto st3130 + case 172: + goto st3131 + case 173: + goto st3132 + case 174: + goto st3133 + case 175: + goto st3134 + case 176: + goto st3135 + case 177: + goto st640 + case 179: + goto st3136 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st3137 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + } + switch { + case data[p] < 180: + if 132 <= data[p] && data[p] <= 152 { + goto st145 + } + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + default: + goto st147 + } + goto tr420 + st3117: + if p++; p == pe { + goto _test_eof3117 + } + st_case_3117: + if 171 <= data[p] && data[p] <= 190 { + goto tr2774 + } + goto tr420 + st3118: + if p++; p == pe { + goto _test_eof3118 + } + st_case_3118: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto tr2774 + } + case data[p] >= 128: + goto tr421 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto tr2774 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr2774 + } + default: + goto tr2774 + } + default: + goto tr2774 + } + goto tr420 + st3119: + if p++; p == pe { + goto _test_eof3119 + } + st_case_3119: + if data[p] == 143 { + goto tr2774 + } + switch { + case data[p] < 144: + if 130 <= data[p] && data[p] <= 141 { + goto tr2774 + } + case data[p] > 153: + switch { + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 154: + goto tr2774 + } + default: + goto tr421 + } + goto tr420 + st3120: + if p++; p == pe { + goto _test_eof3120 + } + st_case_3120: + switch { + case data[p] < 157: + if 155 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr420 + } + default: + goto tr2774 + } + goto tr148 + st3121: + if p++; p == pe { + goto _test_eof3121 + } + st_case_3121: + switch { + case data[p] < 146: + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 177: + if 178 <= data[p] && data[p] <= 180 { + goto tr2774 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr2774 + } + goto tr420 + st3122: + if p++; p == pe { + goto _test_eof3122 + } + st_case_3122: + switch { + case data[p] < 160: + switch { + case data[p] > 145: + if 146 <= data[p] && data[p] <= 147 { + goto tr2774 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto tr2774 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3123: + if p++; p == pe { + goto _test_eof3123 + } + st_case_3123: + if 180 <= data[p] { + goto tr2774 + } + goto tr420 + st3124: + if p++; p == pe { + goto _test_eof3124 + } + st_case_3124: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 170 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr420 + } + goto tr2774 + st3125: + if p++; p == pe { + goto _test_eof3125 + } + st_case_3125: + switch { + case data[p] < 144: + if 139 <= data[p] && data[p] <= 142 { + goto tr2774 + } + case data[p] > 153: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + goto tr420 + st3126: + if p++; p == pe { + goto _test_eof3126 + } + st_case_3126: + if data[p] == 169 { + goto tr2774 + } + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3127: + if p++; p == pe { + goto _test_eof3127 + } + st_case_3127: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr2774 + } + default: + goto tr2774 + } + goto tr420 + st3128: + if p++; p == pe { + goto _test_eof3128 + } + st_case_3128: + switch { + case data[p] > 150: + if 151 <= data[p] && data[p] <= 155 { + goto tr2774 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3129: + if p++; p == pe { + goto _test_eof3129 + } + st_case_3129: + if data[p] == 191 { + goto tr2774 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr2774 + } + case data[p] >= 149: + goto tr2774 + } + goto tr420 + st3130: + if p++; p == pe { + goto _test_eof3130 + } + st_case_3130: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto tr2774 + } + default: + goto tr421 + } + goto tr420 + st3131: + if p++; p == pe { + goto _test_eof3131 + } + st_case_3131: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 132 { + goto tr2774 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr2774 + } + default: + goto tr148 + } + goto tr420 + st3132: + if p++; p == pe { + goto _test_eof3132 + } + st_case_3132: + switch { + case data[p] < 144: + switch { + case data[p] > 139: + if 140 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] >= 133: + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 154: + goto tr420 + } + default: + goto tr421 + } + goto tr2774 + st3133: + if p++; p == pe { + goto _test_eof3133 + } + st_case_3133: + switch { + case data[p] < 161: + switch { + case data[p] > 130: + if 131 <= data[p] && data[p] <= 160 { + goto tr148 + } + case data[p] >= 128: + goto tr2774 + } + case data[p] > 173: + switch { + case data[p] < 176: + if 174 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + default: + goto tr2774 + } + goto tr420 + st3134: + if p++; p == pe { + goto _test_eof3134 + } + st_case_3134: + switch { + case data[p] > 179: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr2774 + } + goto tr148 + st3135: + if p++; p == pe { + goto _test_eof3135 + } + st_case_3135: + switch { + case data[p] > 163: + if 164 <= data[p] && data[p] <= 183 { + goto tr2774 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3136: + if p++; p == pe { + goto _test_eof3136 + } + st_case_3136: + if data[p] == 173 { + goto tr2774 + } + switch { + case data[p] < 169: + switch { + case data[p] > 146: + if 148 <= data[p] && data[p] <= 168 { + goto tr2774 + } + case data[p] >= 144: + goto tr2774 + } + case data[p] > 177: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 180 { + goto tr2774 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto tr2774 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3137: + if p++; p == pe { + goto _test_eof3137 + } + st_case_3137: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr2774 + } + case data[p] >= 128: + goto tr2774 + } + goto tr420 + st3138: + if p++; p == pe { + goto _test_eof3138 + } + st_case_3138: + switch data[p] { + case 128: + goto st3139 + case 129: + goto st3140 + case 130: + goto st241 + case 131: + goto st3141 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st3142 + case 180: + goto st251 + case 181: + goto st3143 + case 182: + goto st253 + case 183: + goto st3144 + case 184: + goto st255 + } + goto tr420 + st3139: + if p++; p == pe { + goto _test_eof3139 + } + st_case_3139: + switch { + case data[p] < 170: + if 140 <= data[p] && data[p] <= 143 { + goto tr2774 + } + case data[p] > 174: + if 191 <= data[p] { + goto tr571 + } + default: + goto tr2774 + } + goto tr420 + st3140: + if p++; p == pe { + goto _test_eof3140 + } + st_case_3140: + switch data[p] { + case 165: + goto tr420 + case 177: + goto tr148 + case 191: + goto tr148 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr2774 + } + default: + goto tr420 + } + goto tr571 + st3141: + if p++; p == pe { + goto _test_eof3141 + } + st_case_3141: + if 144 <= data[p] && data[p] <= 176 { + goto tr2774 + } + goto tr420 + st3142: + if p++; p == pe { + goto _test_eof3142 + } + st_case_3142: + switch { + case data[p] < 175: + if 165 <= data[p] && data[p] <= 170 { + goto tr420 + } + case data[p] > 177: + if 180 <= data[p] { + goto tr420 + } + default: + goto tr2774 + } + goto tr148 + st3143: + if p++; p == pe { + goto _test_eof3143 + } + st_case_3143: + if data[p] == 191 { + goto tr2774 + } + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 168: + goto tr420 + } + goto tr148 + st3144: + if p++; p == pe { + goto _test_eof3144 + } + st_case_3144: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto tr2774 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3145: + if p++; p == pe { + goto _test_eof3145 + } + st_case_3145: + switch data[p] { + case 128: + goto st3146 + case 130: + goto st3147 + case 131: + goto st1164 + case 132: + goto st259 + case 133: + goto st145 + case 134: + goto st260 + case 135: + goto st1165 + case 139: + goto st1166 + case 140: + goto st1091 + case 141: + goto st1167 + } + goto tr420 + st3146: + if p++; p == pe { + goto _test_eof3146 + } + st_case_3146: + if data[p] == 133 { + goto tr148 + } + switch { + case data[p] < 177: + if 170 <= data[p] && data[p] <= 175 { + goto tr2774 + } + case data[p] > 181: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + default: + goto tr1049 + } + goto tr420 + st3147: + if p++; p == pe { + goto _test_eof3147 + } + st_case_3147: + switch { + case data[p] < 155: + if 153 <= data[p] && data[p] <= 154 { + goto tr2774 + } + case data[p] > 156: + if 160 <= data[p] { + goto tr1049 + } + default: + goto tr1049 + } + goto tr420 + st3148: + if p++; p == pe { + goto _test_eof3148 + } + st_case_3148: + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st654 + case 153: + goto st3149 + case 154: + goto st3150 + case 155: + goto st3151 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st3152 + case 161: + goto st272 + case 162: + goto st3153 + case 163: + goto st3154 + case 164: + goto st3155 + case 165: + goto st3156 + case 166: + goto st3157 + case 167: + goto st3158 + case 168: + goto st3159 + case 169: + goto st3160 + case 170: + goto st3161 + case 171: + goto st3162 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st3163 + case 176: + goto st147 + } + if 129 <= data[p] { + goto st145 + } + goto tr420 + st3149: + if p++; p == pe { + goto _test_eof3149 + } + st_case_3149: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr2774 + } + default: + goto tr2774 + } + goto tr420 + st3150: + if p++; p == pe { + goto _test_eof3150 + } + st_case_3150: + switch { + case data[p] < 158: + if 128 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr2774 + } + goto tr420 + st3151: + if p++; p == pe { + goto _test_eof3151 + } + st_case_3151: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr2774 + } + goto tr148 + st3152: + if p++; p == pe { + goto _test_eof3152 + } + st_case_3152: + switch data[p] { + case 130: + goto tr2774 + case 134: + goto tr2774 + case 139: + goto tr2774 + } + switch { + case data[p] > 167: + if 168 <= data[p] { + goto tr420 + } + case data[p] >= 163: + goto tr2774 + } + goto tr148 + st3153: + if p++; p == pe { + goto _test_eof3153 + } + st_case_3153: + switch { + case data[p] < 130: + if 128 <= data[p] && data[p] <= 129 { + goto tr2774 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr2774 + } + default: + goto tr148 + } + goto tr420 + st3154: + if p++; p == pe { + goto _test_eof3154 + } + st_case_3154: + switch data[p] { + case 187: + goto tr148 + case 189: + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 143: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 133: + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 183: + if 184 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr420 + } + goto tr2774 + st3155: + if p++; p == pe { + goto _test_eof3155 + } + st_case_3155: + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 165: + switch { + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr2774 + } + default: + goto tr148 + } + goto tr420 + st3156: + if p++; p == pe { + goto _test_eof3156 + } + st_case_3156: + switch { + case data[p] < 148: + if 135 <= data[p] && data[p] <= 147 { + goto tr2774 + } + case data[p] > 159: + if 189 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st3157: + if p++; p == pe { + goto _test_eof3157 + } + st_case_3157: + switch { + case data[p] < 132: + if 128 <= data[p] && data[p] <= 131 { + goto tr2774 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr2774 + } + default: + goto tr148 + } + goto tr420 + st3158: + if p++; p == pe { + goto _test_eof3158 + } + st_case_3158: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 129: + goto tr420 + } + case data[p] > 164: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr420 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + default: + goto tr420 + } + goto tr2774 + st3159: + if p++; p == pe { + goto _test_eof3159 + } + st_case_3159: + switch { + case data[p] > 168: + if 169 <= data[p] && data[p] <= 182 { + goto tr2774 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3160: + if p++; p == pe { + goto _test_eof3160 + } + st_case_3160: + if data[p] == 131 { + goto tr2774 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 141: + switch { + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto tr2774 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr2774 + } + goto tr420 + st3161: + if p++; p == pe { + goto _test_eof3161 + } + st_case_3161: + if data[p] == 176 { + goto tr2774 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr2774 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr2774 + } + default: + goto tr2774 + } + goto tr420 + st3162: + if p++; p == pe { + goto _test_eof3162 + } + st_case_3162: + if data[p] == 129 { + goto tr2774 + } + switch { + case data[p] < 171: + if 160 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 181 <= data[p] && data[p] <= 182 { + goto tr2774 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr2774 + } + goto tr420 + st3163: + if p++; p == pe { + goto _test_eof3163 + } + st_case_3163: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 162 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 172: + goto tr2774 + } + default: + goto tr2774 + } + goto tr420 + st3164: + if p++; p == pe { + goto _test_eof3164 + } + st_case_3164: + switch data[p] { + case 172: + goto st3165 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st3166 + case 185: + goto st674 + case 187: + goto st3167 + case 188: + goto st676 + case 189: + goto st1261 + case 190: + goto st3168 + case 191: + goto st3169 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr420 + st3165: + if p++; p == pe { + goto _test_eof3165 + } + st_case_3165: + switch data[p] { + case 158: + goto tr2774 + case 190: + goto tr572 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 170: + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st3166: + if p++; p == pe { + goto _test_eof3166 + } + st_case_3166: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr2774 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr571 + } + default: + goto tr2774 + } + goto tr420 + st3167: + if p++; p == pe { + goto _test_eof3167 + } + st_case_3167: + if data[p] == 191 { + goto tr2774 + } + if 189 <= data[p] { + goto tr420 + } + goto tr148 + st3168: + if p++; p == pe { + goto _test_eof3168 + } + st_case_3168: + switch { + case data[p] < 160: + if 158 <= data[p] && data[p] <= 159 { + goto tr2774 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + goto tr1049 + st3169: + if p++; p == pe { + goto _test_eof3169 + } + st_case_3169: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] >= 130: + goto tr148 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr2774 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3170: + if p++; p == pe { + goto _test_eof3170 + } + st_case_3170: + switch data[p] { + case 144: + goto st3171 + case 145: + goto st3177 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st3196 + case 155: + goto st3201 + case 157: + goto st3203 + case 158: + goto st3210 + case 159: + goto st403 + } + goto tr420 + st3171: + if p++; p == pe { + goto _test_eof3171 + } + st_case_3171: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st3172 + case 138: + goto st313 + case 139: + goto st3173 + case 140: + goto st315 + case 141: + goto st3174 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st684 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st3175 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st3176 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr420 + st3172: + if p++; p == pe { + goto _test_eof3172 + } + st_case_3172: + if data[p] == 189 { + goto tr2774 + } + goto tr420 + st3173: + if p++; p == pe { + goto _test_eof3173 + } + st_case_3173: + if data[p] == 160 { + goto tr2774 + } + if 145 <= data[p] { + goto tr420 + } + goto tr148 + st3174: + if p++; p == pe { + goto _test_eof3174 + } + st_case_3174: + switch { + case data[p] < 182: + if 139 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr420 + } + default: + goto tr2774 + } + goto tr148 + st3175: + if p++; p == pe { + goto _test_eof3175 + } + st_case_3175: + switch data[p] { + case 128: + goto tr148 + case 191: + goto tr2774 + } + switch { + case data[p] < 144: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2774 + } + case data[p] > 134: + if 140 <= data[p] && data[p] <= 143 { + goto tr2774 + } + default: + goto tr2774 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto tr2774 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3176: + if p++; p == pe { + goto _test_eof3176 + } + st_case_3176: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 164: + if 165 <= data[p] && data[p] <= 166 { + goto tr2774 + } + default: + goto tr148 + } + goto tr420 + st3177: + if p++; p == pe { + goto _test_eof3177 + } + st_case_3177: + switch data[p] { + case 128: + goto st3178 + case 129: + goto st3179 + case 130: + goto st3180 + case 131: + goto st691 + case 132: + goto st3181 + case 133: + goto st3182 + case 134: + goto st3183 + case 135: + goto st3184 + case 136: + goto st3185 + case 138: + goto st348 + case 139: + goto st3186 + case 140: + goto st3187 + case 141: + goto st3188 + case 146: + goto st3189 + case 147: + goto st3190 + case 150: + goto st3191 + case 151: + goto st3192 + case 152: + goto st3189 + case 153: + goto st3193 + case 154: + goto st3194 + case 155: + goto st538 + case 156: + goto st3195 + case 162: + goto st359 + case 163: + goto st707 + case 171: + goto st361 + } + goto tr420 + st3178: + if p++; p == pe { + goto _test_eof3178 + } + st_case_3178: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2774 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr2774 + } + default: + goto tr148 + } + goto tr420 + st3179: + if p++; p == pe { + goto _test_eof3179 + } + st_case_3179: + switch { + case data[p] < 166: + if 135 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] && data[p] <= 190 { + goto tr420 + } + default: + goto tr421 + } + goto tr2774 + st3180: + if p++; p == pe { + goto _test_eof3180 + } + st_case_3180: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr2774 + st3181: + if p++; p == pe { + goto _test_eof3181 + } + st_case_3181: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2774 + } + case data[p] > 166: + switch { + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr421 + } + case data[p] >= 167: + goto tr2774 + } + default: + goto tr148 + } + goto tr420 + st3182: + if p++; p == pe { + goto _test_eof3182 + } + st_case_3182: + switch data[p] { + case 179: + goto tr2774 + case 182: + goto tr148 + } + if 144 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr420 + st3183: + if p++; p == pe { + goto _test_eof3183 + } + st_case_3183: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2774 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr2774 + } + default: + goto tr148 + } + goto tr420 + st3184: + if p++; p == pe { + goto _test_eof3184 + } + st_case_3184: + if data[p] == 155 { + goto tr420 + } + switch { + case data[p] < 141: + switch { + case data[p] > 132: + if 133 <= data[p] && data[p] <= 137 { + goto tr420 + } + case data[p] >= 129: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] < 154: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] > 156: + if 157 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + default: + goto tr420 + } + goto tr2774 + st3185: + if p++; p == pe { + goto _test_eof3185 + } + st_case_3185: + switch { + case data[p] < 147: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] > 171: + if 172 <= data[p] && data[p] <= 183 { + goto tr2774 + } + default: + goto tr148 + } + goto tr420 + st3186: + if p++; p == pe { + goto _test_eof3186 + } + st_case_3186: + switch { + case data[p] < 171: + if 159 <= data[p] && data[p] <= 170 { + goto tr2774 + } + case data[p] > 175: + switch { + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr421 + } + default: + goto tr420 + } + goto tr148 + st3187: + if p++; p == pe { + goto _test_eof3187 + } + st_case_3187: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto tr2774 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2774 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3188: + if p++; p == pe { + goto _test_eof3188 + } + st_case_3188: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr2774 + } + switch { + case data[p] < 157: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr2774 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr2774 + } + default: + goto tr2774 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr2774 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr2774 + } + default: + goto tr2774 + } + default: + goto tr148 + } + goto tr420 + st3189: + if p++; p == pe { + goto _test_eof3189 + } + st_case_3189: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr2774 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3190: + if p++; p == pe { + goto _test_eof3190 + } + st_case_3190: + if data[p] == 134 { + goto tr420 + } + switch { + case data[p] < 136: + if 132 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr420 + } + goto tr2774 + st3191: + if p++; p == pe { + goto _test_eof3191 + } + st_case_3191: + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 181: + if 184 <= data[p] { + goto tr2774 + } + default: + goto tr2774 + } + goto tr420 + st3192: + if p++; p == pe { + goto _test_eof3192 + } + st_case_3192: + switch { + case data[p] < 152: + if 129 <= data[p] && data[p] <= 151 { + goto tr420 + } + case data[p] > 155: + if 158 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + goto tr2774 + st3193: + if p++; p == pe { + goto _test_eof3193 + } + st_case_3193: + if data[p] == 132 { + goto tr148 + } + switch { + case data[p] < 144: + if 129 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + goto tr2774 + st3194: + if p++; p == pe { + goto _test_eof3194 + } + st_case_3194: + switch { + case data[p] > 170: + if 171 <= data[p] && data[p] <= 183 { + goto tr2774 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3195: + if p++; p == pe { + goto _test_eof3195 + } + st_case_3195: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 157: + goto tr2774 + } + goto tr420 + st3196: + if p++; p == pe { + goto _test_eof3196 + } + st_case_3196: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st709 + case 171: + goto st3197 + case 172: + goto st3198 + case 173: + goto st712 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st3199 + case 190: + goto st3200 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr420 + st3197: + if p++; p == pe { + goto _test_eof3197 + } + st_case_3197: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto tr2774 + } + case data[p] >= 144: + goto tr148 + } + goto tr420 + st3198: + if p++; p == pe { + goto _test_eof3198 + } + st_case_3198: + switch { + case data[p] > 175: + if 176 <= data[p] && data[p] <= 182 { + goto tr2774 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3199: + if p++; p == pe { + goto _test_eof3199 + } + st_case_3199: + switch { + case data[p] < 145: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr420 + } + default: + goto tr2774 + } + goto tr148 + st3200: + if p++; p == pe { + goto _test_eof3200 + } + st_case_3200: + switch { + case data[p] > 146: + if 147 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 143: + goto tr2774 + } + goto tr420 + st3201: + if p++; p == pe { + goto _test_eof3201 + } + st_case_3201: + switch data[p] { + case 128: + goto st1224 + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st3202 + } + goto tr420 + st3202: + if p++; p == pe { + goto _test_eof3202 + } + st_case_3202: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr2774 + } + case data[p] >= 157: + goto tr2774 + } + default: + goto tr148 + } + goto tr420 + st3203: + if p++; p == pe { + goto _test_eof3203 + } + st_case_3203: + switch data[p] { + case 133: + goto st3204 + case 134: + goto st3205 + case 137: + goto st3206 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st721 + case 168: + goto st3207 + case 169: + goto st3208 + case 170: + goto st3209 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr420 + st3204: + if p++; p == pe { + goto _test_eof3204 + } + st_case_3204: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr2774 + } + case data[p] >= 165: + goto tr2774 + } + goto tr420 + st3205: + if p++; p == pe { + goto _test_eof3205 + } + st_case_3205: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr420 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr2774 + st3206: + if p++; p == pe { + goto _test_eof3206 + } + st_case_3206: + if 130 <= data[p] && data[p] <= 132 { + goto tr2774 + } + goto tr420 + st3207: + if p++; p == pe { + goto _test_eof3207 + } + st_case_3207: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr2774 + } + case data[p] >= 128: + goto tr2774 + } + goto tr420 + st3208: + if p++; p == pe { + goto _test_eof3208 + } + st_case_3208: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 173: + goto tr420 + } + goto tr2774 + st3209: + if p++; p == pe { + goto _test_eof3209 + } + st_case_3209: + if data[p] == 132 { + goto tr2774 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr2774 + } + case data[p] >= 155: + goto tr2774 + } + goto tr420 + st3210: + if p++; p == pe { + goto _test_eof3210 + } + st_case_3210: + switch data[p] { + case 160: + goto st147 + case 163: + goto st3211 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr420 + st3211: + if p++; p == pe { + goto _test_eof3211 + } + st_case_3211: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 150: + if 151 <= data[p] { + goto tr420 + } + default: + goto tr2774 + } + goto tr148 + st3212: + if p++; p == pe { + goto _test_eof3212 + } + st_case_3212: + if data[p] == 160 { + goto st3213 + } + goto tr420 + st3213: + if p++; p == pe { + goto _test_eof3213 + } + st_case_3213: + switch data[p] { + case 128: + goto st3214 + case 129: + goto st3215 + case 132: + goto st3072 + case 135: + goto st3217 + } + if 133 <= data[p] && data[p] <= 134 { + goto st3216 + } + goto tr420 + st3214: + if p++; p == pe { + goto _test_eof3214 + } + st_case_3214: + if data[p] == 129 { + goto tr2774 + } + if 160 <= data[p] { + goto tr2774 + } + goto tr420 + st3215: + if p++; p == pe { + goto _test_eof3215 + } + st_case_3215: + if 192 <= data[p] { + goto tr420 + } + goto tr2774 + st3216: + if p++; p == pe { + goto _test_eof3216 + } + st_case_3216: + goto tr2774 + st3217: + if p++; p == pe { + goto _test_eof3217 + } + st_case_3217: + if 176 <= data[p] { + goto tr420 + } + goto tr2774 +tr4786: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4888 + st4888: + if p++; p == pe { + goto _test_eof4888 + } + st_case_4888: +//line segment_words_prod.go:83663 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 131 <= data[p] && data[p] <= 137 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr4787: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4889 + st4889: + if p++; p == pe { + goto _test_eof4889 + } + st_case_4889: +//line segment_words_prod.go:83777 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 191: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 145 <= data[p] && data[p] <= 189 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr4788: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4890 + st4890: + if p++; p == pe { + goto _test_eof4890 + } + st_case_4890: +//line segment_words_prod.go:83893 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 135: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 129: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 130: + switch { + case data[p] < 196: + if 132 <= data[p] && data[p] <= 133 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 +tr4789: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4891 + st4891: + if p++; p == pe { + goto _test_eof4891 + } + st_case_4891: +//line segment_words_prod.go:84013 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 156: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 128: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 133: + switch { + case data[p] < 196: + if 144 <= data[p] && data[p] <= 154 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 +tr4790: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4892 + st4892: + if p++; p == pe { + goto _test_eof4892 + } + st_case_4892: +//line segment_words_prod.go:84133 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 176: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 139 <= data[p] && data[p] <= 159 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr4791: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4893 + st4893: + if p++; p == pe { + goto _test_eof4893 + } + st_case_4893: +//line segment_words_prod.go:84249 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 159: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 150 <= data[p] && data[p] <= 157 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 164: + switch { + case data[p] < 170: + if 167 <= data[p] && data[p] <= 168 { + goto tr1 + } + case data[p] > 173: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr4792: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4894 + st4894: + if p++; p == pe { + goto _test_eof4894 + } + st_case_4894: +//line segment_words_prod.go:84377 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 143: + goto tr1 + case 145: + goto tr1 + case 194: + goto tr4804 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr4808 + case 205: + goto tr4810 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr4813 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr4816 + case 215: + goto tr4817 + case 216: + goto tr4818 + case 217: + goto tr4819 + case 219: + goto tr4820 + case 220: + goto tr4821 + case 221: + goto tr4822 + case 222: + goto tr4823 + case 223: + goto tr4824 + case 224: + goto tr4825 + case 225: + goto tr4826 + case 226: + goto tr4827 + case 227: + goto tr4828 + case 234: + goto tr4829 + case 237: + goto tr4831 + case 239: + goto tr4832 + case 240: + goto tr4833 + case 243: + goto tr4834 + } + switch { + case data[p] < 176: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto tr4806 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr1 + } + case data[p] >= 235: + goto tr4830 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr4807: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4895 +tr4467: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4895 + st4895: + if p++; p == pe { + goto _test_eof4895 + } + st_case_4895: +//line segment_words_prod.go:84519 + switch data[p] { + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 192 <= data[p] { + goto tr4499 + } + goto tr148 +tr4808: +//line segment_words.rl:72 + + endPos = p + + goto st4896 +tr4468: +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + + goto st4896 + st4896: + if p++; p == pe { + goto _test_eof4896 + } + st_case_4896: +//line segment_words_prod.go:84589 + switch data[p] { + case 194: + goto tr4783 + case 204: + goto tr4784 + case 205: + goto tr4785 + case 210: + goto tr4786 + case 214: + goto tr4787 + case 215: + goto tr4788 + case 216: + goto tr4789 + case 217: + goto tr4790 + case 219: + goto tr4791 + case 220: + goto tr4792 + case 221: + goto tr4793 + case 222: + goto tr4794 + case 223: + goto tr4795 + case 224: + goto tr4796 + case 225: + goto tr4797 + case 226: + goto tr4798 + case 227: + goto tr4799 + case 234: + goto tr4800 + case 239: + goto tr4801 + case 240: + goto tr4802 + case 243: + goto tr4803 + } + if 128 <= data[p] { + goto tr148 + } + goto tr4499 +tr4793: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4897 + st4897: + if p++; p == pe { + goto _test_eof4897 + } + st_case_4897: +//line segment_words_prod.go:84654 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 91: + switch { + case data[p] < 48: + if data[p] <= 47 { + goto tr1 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 90 { + goto tr2008 + } + case data[p] >= 59: + goto tr1 + } + default: + goto tr2646 + } + case data[p] > 96: + switch { + case data[p] < 123: + if 97 <= data[p] && data[p] <= 122 { + goto tr2008 + } + case data[p] > 138: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr4794: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4898 + st4898: + if p++; p == pe { + goto _test_eof4898 + } + st_case_4898: +//line segment_words_prod.go:84782 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 166 <= data[p] && data[p] <= 176 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr4795: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4899 + st4899: + if p++; p == pe { + goto _test_eof4899 + } + st_case_4899: +//line segment_words_prod.go:84896 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 171 <= data[p] && data[p] <= 179 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr4796: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4900 + st4900: + if p++; p == pe { + goto _test_eof4900 + } + st_case_4900: +//line segment_words_prod.go:85010 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 160: + goto st14 + case 161: + goto st15 + case 163: + goto st16 + case 164: + goto st17 + case 165: + goto st18 + case 167: + goto st20 + case 169: + goto st21 + case 171: + goto st22 + case 173: + goto st24 + case 174: + goto st25 + case 175: + goto st26 + case 176: + goto st27 + case 177: + goto st28 + case 179: + goto st29 + case 180: + goto st30 + case 181: + goto st31 + case 182: + goto st32 + case 183: + goto st33 + case 184: + goto st34 + case 185: + goto st35 + case 186: + goto st36 + case 187: + goto st37 + case 188: + goto st38 + case 189: + goto st39 + case 190: + goto st40 + case 191: + goto st41 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 166: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 170: + switch { + case data[p] < 196: + if 172 <= data[p] && data[p] <= 178 { + goto st23 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto st19 + } + goto tr4562 +tr4797: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4901 + st4901: + if p++; p == pe { + goto _test_eof4901 + } + st_case_4901: +//line segment_words_prod.go:85180 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 128: + goto st43 + case 129: + goto st44 + case 130: + goto st45 + case 141: + goto st46 + case 156: + goto st47 + case 157: + goto st48 + case 158: + goto st49 + case 159: + goto st50 + case 160: + goto st51 + case 162: + goto st52 + case 164: + goto st53 + case 168: + goto st54 + case 169: + goto st55 + case 170: + goto st56 + case 172: + goto st57 + case 173: + goto st58 + case 174: + goto st59 + case 175: + goto st60 + case 176: + goto st61 + case 179: + goto st62 + case 183: + goto st63 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr4798: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4902 + st4902: + if p++; p == pe { + goto _test_eof4902 + } + st_case_4902: +//line segment_words_prod.go:85332 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 128: + goto st65 + case 129: + goto st66 + case 131: + goto st67 + case 179: + goto st68 + case 181: + goto st69 + case 183: + goto st70 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr4799: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4903 + st4903: + if p++; p == pe { + goto _test_eof4903 + } + st_case_4903: +//line segment_words_prod.go:85454 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 128: + goto st72 + case 130: + goto st73 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr4800: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4904 + st4904: + if p++; p == pe { + goto _test_eof4904 + } + st_case_4904: +//line segment_words_prod.go:85568 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 153: + goto st75 + case 154: + goto st76 + case 155: + goto st77 + case 160: + goto st78 + case 162: + goto st79 + case 163: + goto st80 + case 164: + goto st81 + case 165: + goto st82 + case 166: + goto st83 + case 167: + goto st84 + case 168: + goto st85 + case 169: + goto st86 + case 170: + goto st87 + case 171: + goto st88 + case 175: + goto st89 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr4801: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4905 + st4905: + if p++; p == pe { + goto _test_eof4905 + } + st_case_4905: +//line segment_words_prod.go:85708 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 172: + goto st91 + case 184: + goto st92 + case 187: + goto st69 + case 190: + goto st76 + case 191: + goto st93 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr4802: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4906 + st4906: + if p++; p == pe { + goto _test_eof4906 + } + st_case_4906: +//line segment_words_prod.go:85828 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 144: + goto st95 + case 145: + goto st101 + case 150: + goto st120 + case 155: + goto st125 + case 157: + goto st127 + case 158: + goto st134 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr4803: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4907 + st4907: + if p++; p == pe { + goto _test_eof4907 + } + st_case_4907: +//line segment_words_prod.go:85950 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 160: + goto st137 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr4809: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4908 + st4908: + if p++; p == pe { + goto _test_eof4908 + } + st_case_4908: +//line segment_words_prod.go:86062 + switch data[p] { + case 151: + goto st142 + case 173: + goto tr4499 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 146: + if 130 <= data[p] && data[p] <= 133 { + goto tr4499 + } + case data[p] > 159: + switch { + case data[p] > 171: + if 175 <= data[p] { + goto tr4499 + } + case data[p] >= 165: + goto tr4499 + } + default: + goto tr4499 + } + goto tr148 +tr4810: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4909 + st4909: + if p++; p == pe { + goto _test_eof4909 + } + st_case_4909: +//line segment_words_prod.go:86145 + switch data[p] { + case 181: + goto tr4499 + case 190: + goto tr4499 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] > 185: + if 192 <= data[p] { + goto tr4499 + } + case data[p] >= 184: + goto tr4499 + } + goto tr148 +tr4811: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4910 + st4910: + if p++; p == pe { + goto _test_eof4910 + } + st_case_4910: +//line segment_words_prod.go:86219 + switch data[p] { + case 135: + goto st142 + case 140: + goto tr148 + case 194: + goto tr4783 + case 204: + goto tr4784 + case 205: + goto tr4785 + case 210: + goto tr4786 + case 214: + goto tr4787 + case 215: + goto tr4788 + case 216: + goto tr4789 + case 217: + goto tr4790 + case 219: + goto tr4791 + case 220: + goto tr4792 + case 221: + goto tr4793 + case 222: + goto tr4794 + case 223: + goto tr4795 + case 224: + goto tr4796 + case 225: + goto tr4797 + case 226: + goto tr4798 + case 227: + goto tr4799 + case 234: + goto tr4800 + case 239: + goto tr4801 + case 240: + goto tr4802 + case 243: + goto tr4803 + } + switch { + case data[p] < 142: + if 134 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 161: + if 163 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + goto tr4499 +tr4812: +//line segment_words.rl:72 + + endPos = p + + goto st4911 +tr4473: +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + + goto st4911 + st4911: + if p++; p == pe { + goto _test_eof4911 + } + st_case_4911: +//line segment_words_prod.go:86302 + switch data[p] { + case 182: + goto tr4499 + case 194: + goto tr4783 + case 204: + goto tr4784 + case 205: + goto tr4785 + case 210: + goto tr4786 + case 214: + goto tr4787 + case 215: + goto tr4788 + case 216: + goto tr4789 + case 217: + goto tr4790 + case 219: + goto tr4791 + case 220: + goto tr4792 + case 221: + goto tr4793 + case 222: + goto tr4794 + case 223: + goto tr4795 + case 224: + goto tr4796 + case 225: + goto tr4797 + case 226: + goto tr4798 + case 227: + goto tr4799 + case 234: + goto tr4800 + case 239: + goto tr4801 + case 240: + goto tr4802 + case 243: + goto tr4803 + } + goto tr148 +tr4813: +//line segment_words.rl:72 + + endPos = p + + goto st4912 + st4912: + if p++; p == pe { + goto _test_eof4912 + } + st_case_4912: +//line segment_words_prod.go:86361 + switch data[p] { + case 130: + goto tr4499 + case 194: + goto tr4783 + case 204: + goto tr4784 + case 205: + goto tr4785 + case 210: + goto tr4786 + case 214: + goto tr4787 + case 215: + goto tr4788 + case 216: + goto tr4789 + case 217: + goto tr4790 + case 219: + goto tr4791 + case 220: + goto tr4792 + case 221: + goto tr4793 + case 222: + goto tr4794 + case 223: + goto tr4795 + case 224: + goto tr4796 + case 225: + goto tr4797 + case 226: + goto tr4798 + case 227: + goto tr4799 + case 234: + goto tr4800 + case 239: + goto tr4801 + case 240: + goto tr4802 + case 243: + goto tr4803 + } + goto tr148 +tr4814: +//line segment_words.rl:72 + + endPos = p + + goto st4913 +tr4475: +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + + goto st4913 + st4913: + if p++; p == pe { + goto _test_eof4913 + } + st_case_4913: +//line segment_words_prod.go:86430 + switch data[p] { + case 176: + goto tr4499 + case 194: + goto tr4783 + case 204: + goto tr4784 + case 205: + goto tr4785 + case 210: + goto tr4786 + case 214: + goto tr4787 + case 215: + goto tr4788 + case 216: + goto tr4789 + case 217: + goto tr4790 + case 219: + goto tr4791 + case 220: + goto tr4792 + case 221: + goto tr4793 + case 222: + goto tr4794 + case 223: + goto tr4795 + case 224: + goto tr4796 + case 225: + goto tr4797 + case 226: + goto tr4798 + case 227: + goto tr4799 + case 234: + goto tr4800 + case 239: + goto tr4801 + case 240: + goto tr4802 + case 243: + goto tr4803 + } + goto tr148 +tr4815: +//line segment_words.rl:72 + + endPos = p + + goto st4914 +tr4476: +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + + goto st4914 + st4914: + if p++; p == pe { + goto _test_eof4914 + } + st_case_4914: +//line segment_words_prod.go:86499 + switch data[p] { + case 194: + goto tr4783 + case 204: + goto tr4784 + case 205: + goto tr4785 + case 210: + goto tr4786 + case 214: + goto tr4787 + case 215: + goto tr4788 + case 216: + goto tr4789 + case 217: + goto tr4790 + case 219: + goto tr4791 + case 220: + goto tr4792 + case 221: + goto tr4793 + case 222: + goto tr4794 + case 223: + goto tr4795 + case 224: + goto tr4796 + case 225: + goto tr4797 + case 226: + goto tr4798 + case 227: + goto tr4799 + case 234: + goto tr4800 + case 239: + goto tr4801 + case 240: + goto tr4802 + case 243: + goto tr4803 + } + switch { + case data[p] > 152: + if 154 <= data[p] && data[p] <= 160 { + goto tr4499 + } + case data[p] >= 151: + goto tr4499 + } + goto tr148 +tr4816: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4915 + st4915: + if p++; p == pe { + goto _test_eof4915 + } + st_case_4915: +//line segment_words_prod.go:86569 + switch data[p] { + case 190: + goto tr4499 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] > 144: + if 192 <= data[p] { + goto tr4499 + } + case data[p] >= 136: + goto tr4499 + } + goto tr148 +tr4817: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4916 + st4916: + if p++; p == pe { + goto _test_eof4916 + } + st_case_4916: +//line segment_words_prod.go:86641 + switch data[p] { + case 135: + goto tr148 + case 179: + goto tr148 + case 180: + goto st142 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr148 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr148 + } + goto tr4499 +tr4818: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4917 + st4917: + if p++; p == pe { + goto _test_eof4917 + } + st_case_4917: +//line segment_words_prod.go:86726 + switch data[p] { + case 156: + goto tr148 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 133 { + goto tr148 + } + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr148 + } + goto tr4499 +tr4819: +//line segment_words.rl:72 + + endPos = p + + goto st4918 + st4918: + if p++; p == pe { + goto _test_eof4918 + } + st_case_4918: +//line segment_words_prod.go:86797 + switch data[p] { + case 171: + goto tr421 + case 194: + goto tr4783 + case 204: + goto tr4784 + case 205: + goto tr4785 + case 210: + goto tr4786 + case 214: + goto tr4787 + case 215: + goto tr4788 + case 216: + goto tr4789 + case 217: + goto tr4790 + case 219: + goto tr4791 + case 220: + goto tr4792 + case 221: + goto tr4793 + case 222: + goto tr4794 + case 223: + goto tr4795 + case 224: + goto tr4796 + case 225: + goto tr4797 + case 226: + goto tr4798 + case 227: + goto tr4799 + case 234: + goto tr4800 + case 239: + goto tr4801 + case 240: + goto tr4802 + case 243: + goto tr4803 + } + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + goto tr4499 +tr4820: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4919 + st4919: + if p++; p == pe { + goto _test_eof4919 + } + st_case_4919: +//line segment_words_prod.go:86873 + switch data[p] { + case 148: + goto tr4499 + case 158: + goto tr4499 + case 169: + goto tr4499 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 189: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] > 190: + if 192 <= data[p] { + goto tr4499 + } + default: + goto tr4499 + } + goto tr148 +tr4821: +//line segment_words.rl:72 + + endPos = p + + goto st4920 + st4920: + if p++; p == pe { + goto _test_eof4920 + } + st_case_4920: +//line segment_words_prod.go:86948 + switch data[p] { + case 194: + goto tr4783 + case 204: + goto tr4784 + case 205: + goto tr4785 + case 210: + goto tr4786 + case 214: + goto tr4787 + case 215: + goto tr4788 + case 216: + goto tr4789 + case 217: + goto tr4790 + case 219: + goto tr4791 + case 220: + goto tr4792 + case 221: + goto tr4793 + case 222: + goto tr4794 + case 223: + goto tr4795 + case 224: + goto tr4796 + case 225: + goto tr4797 + case 226: + goto tr4798 + case 227: + goto tr4799 + case 234: + goto tr4800 + case 239: + goto tr4801 + case 240: + goto tr4802 + case 243: + goto tr4803 + } + if 143 <= data[p] { + goto tr148 + } + goto tr4499 +tr4822: +//line segment_words.rl:72 + + endPos = p + + goto st4921 + st4921: + if p++; p == pe { + goto _test_eof4921 + } + st_case_4921: +//line segment_words_prod.go:87008 + switch data[p] { + case 194: + goto tr4783 + case 204: + goto tr4784 + case 205: + goto tr4785 + case 210: + goto tr4786 + case 214: + goto tr4787 + case 215: + goto tr4788 + case 216: + goto tr4789 + case 217: + goto tr4790 + case 219: + goto tr4791 + case 220: + goto tr4792 + case 221: + goto tr4793 + case 222: + goto tr4794 + case 223: + goto tr4795 + case 224: + goto tr4796 + case 225: + goto tr4797 + case 226: + goto tr4798 + case 227: + goto tr4799 + case 234: + goto tr4800 + case 239: + goto tr4801 + case 240: + goto tr4802 + case 243: + goto tr4803 + } + if 139 <= data[p] && data[p] <= 140 { + goto tr4499 + } + goto tr148 +tr4823: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4922 + st4922: + if p++; p == pe { + goto _test_eof4922 + } + st_case_4922: +//line segment_words_prod.go:87073 + switch data[p] { + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 178 <= data[p] { + goto tr4499 + } + goto tr148 +tr4824: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4923 + st4923: + if p++; p == pe { + goto _test_eof4923 + } + st_case_4923: +//line segment_words_prod.go:87138 + switch data[p] { + case 186: + goto tr148 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] > 137: + if 138 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 128: + goto tr421 + } + goto tr4499 +tr4825: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4924 + st4924: + if p++; p == pe { + goto _test_eof4924 + } + st_case_4924: +//line segment_words_prod.go:87210 + switch data[p] { + case 160: + goto st1473 + case 161: + goto st1474 + case 162: + goto st168 + case 163: + goto st1475 + case 164: + goto st145 + case 165: + goto st1476 + case 166: + goto st1477 + case 167: + goto st1478 + case 168: + goto st1479 + case 169: + goto st1480 + case 170: + goto st1481 + case 171: + goto st1482 + case 172: + goto st1483 + case 173: + goto st1484 + case 174: + goto st1485 + case 175: + goto st1486 + case 176: + goto st1487 + case 177: + goto st1488 + case 178: + goto st1489 + case 179: + goto st1490 + case 180: + goto st1491 + case 181: + goto st1492 + case 182: + goto st1493 + case 183: + goto st1494 + case 184: + goto st1495 + case 185: + goto st1496 + case 186: + goto st1497 + case 187: + goto st1498 + case 188: + goto st1499 + case 189: + goto st1500 + case 190: + goto st1501 + case 191: + goto st1502 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr4826: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4925 + st4925: + if p++; p == pe { + goto _test_eof4925 + } + st_case_4925: +//line segment_words_prod.go:87336 + switch data[p] { + case 128: + goto st1504 + case 129: + goto st1505 + case 130: + goto st1506 + case 131: + goto st202 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st1507 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st1508 + case 157: + goto st1509 + case 158: + goto st1510 + case 159: + goto st1511 + case 160: + goto st1512 + case 161: + goto st219 + case 162: + goto st1513 + case 163: + goto st221 + case 164: + goto st1514 + case 165: + goto st468 + case 167: + goto st469 + case 168: + goto st1474 + case 169: + goto st1515 + case 170: + goto st1516 + case 172: + goto st147 + case 173: + goto st1517 + case 174: + goto st1518 + case 175: + goto st1519 + case 176: + goto st1520 + case 177: + goto st640 + case 179: + goto st1521 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st1522 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 180: + if 132 <= data[p] && data[p] <= 152 { + goto st145 + } + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + default: + goto st147 + } + goto tr4499 +tr4827: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4926 + st4926: + if p++; p == pe { + goto _test_eof4926 + } + st_case_4926: +//line segment_words_prod.go:87496 + switch data[p] { + case 128: + goto st1524 + case 129: + goto st1525 + case 130: + goto st241 + case 131: + goto st1526 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st1527 + case 180: + goto st251 + case 181: + goto st1528 + case 182: + goto st253 + case 183: + goto st1529 + case 184: + goto st255 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr4828: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4927 + st4927: + if p++; p == pe { + goto _test_eof4927 + } + st_case_4927: +//line segment_words_prod.go:87594 + switch data[p] { + case 128: + goto st1531 + case 130: + goto st1532 + case 132: + goto st259 + case 133: + goto st145 + case 134: + goto st260 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr4829: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4928 + st4928: + if p++; p == pe { + goto _test_eof4928 + } + st_case_4928: +//line segment_words_prod.go:87666 + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st654 + case 153: + goto st1534 + case 154: + goto st147 + case 155: + goto st293 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st1535 + case 161: + goto st272 + case 162: + goto st147 + case 163: + goto st1536 + case 164: + goto st1537 + case 165: + goto st1538 + case 166: + goto st147 + case 167: + goto st1539 + case 168: + goto st1540 + case 169: + goto st1541 + case 170: + goto st1542 + case 171: + goto st1543 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st1544 + case 176: + goto st147 + case 194: + goto st3218 + case 204: + goto st3219 + case 205: + goto st3220 + case 210: + goto st3221 + case 214: + goto st3222 + case 215: + goto st3223 + case 216: + goto st3224 + case 217: + goto st3225 + case 219: + goto st3226 + case 220: + goto st3227 + case 221: + goto st3228 + case 222: + goto st3229 + case 223: + goto st3230 + case 224: + goto st3231 + case 225: + goto st3232 + case 226: + goto st3233 + case 227: + goto st3234 + case 234: + goto st3235 + case 239: + goto st3236 + case 240: + goto st3237 + case 243: + goto st3238 + } + if 129 <= data[p] { + goto st145 + } + goto tr4499 + st3218: + if p++; p == pe { + goto _test_eof3218 + } + st_case_3218: + if data[p] == 173 { + goto tr2008 + } + goto tr148 + st3219: + if p++; p == pe { + goto _test_eof3219 + } + st_case_3219: + if 128 <= data[p] { + goto tr2008 + } + goto tr148 + st3220: + if p++; p == pe { + goto _test_eof3220 + } + st_case_3220: + if 176 <= data[p] { + goto tr148 + } + goto tr2008 + st3221: + if p++; p == pe { + goto _test_eof3221 + } + st_case_3221: + if 131 <= data[p] && data[p] <= 137 { + goto tr2008 + } + goto tr148 + st3222: + if p++; p == pe { + goto _test_eof3222 + } + st_case_3222: + if data[p] == 191 { + goto tr2008 + } + if 145 <= data[p] && data[p] <= 189 { + goto tr2008 + } + goto tr148 + st3223: + if p++; p == pe { + goto _test_eof3223 + } + st_case_3223: + if data[p] == 135 { + goto tr2008 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto tr2008 + } + case data[p] >= 129: + goto tr2008 + } + goto tr148 + st3224: + if p++; p == pe { + goto _test_eof3224 + } + st_case_3224: + if data[p] == 156 { + goto tr2008 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto tr2008 + } + case data[p] >= 128: + goto tr2008 + } + goto tr148 + st3225: + if p++; p == pe { + goto _test_eof3225 + } + st_case_3225: + if data[p] == 176 { + goto tr2008 + } + if 139 <= data[p] && data[p] <= 159 { + goto tr2008 + } + goto tr148 + st3226: + if p++; p == pe { + goto _test_eof3226 + } + st_case_3226: + switch { + case data[p] < 159: + if 150 <= data[p] && data[p] <= 157 { + goto tr2008 + } + case data[p] > 164: + switch { + case data[p] > 168: + if 170 <= data[p] && data[p] <= 173 { + goto tr2008 + } + case data[p] >= 167: + goto tr2008 + } + default: + goto tr2008 + } + goto tr148 + st3227: + if p++; p == pe { + goto _test_eof3227 + } + st_case_3227: + switch data[p] { + case 143: + goto tr2008 + case 145: + goto tr2008 + } + if 176 <= data[p] { + goto tr2008 + } + goto tr148 + st3228: + if p++; p == pe { + goto _test_eof3228 + } + st_case_3228: + if 139 <= data[p] { + goto tr148 + } + goto tr2008 + st3229: + if p++; p == pe { + goto _test_eof3229 + } + st_case_3229: + if 166 <= data[p] && data[p] <= 176 { + goto tr2008 + } + goto tr148 + st3230: + if p++; p == pe { + goto _test_eof3230 + } + st_case_3230: + if 171 <= data[p] && data[p] <= 179 { + goto tr2008 + } + goto tr148 + st3231: + if p++; p == pe { + goto _test_eof3231 + } + st_case_3231: + switch data[p] { + case 160: + goto tr2902 + case 161: + goto tr2903 + case 163: + goto tr2904 + case 164: + goto tr2905 + case 165: + goto tr2906 + case 167: + goto tr2908 + case 169: + goto tr2909 + case 171: + goto tr2910 + case 173: + goto tr2912 + case 174: + goto tr2913 + case 175: + goto tr2914 + case 176: + goto tr2915 + case 177: + goto tr2916 + case 179: + goto tr2917 + case 180: + goto tr2918 + case 181: + goto tr2919 + case 182: + goto tr2920 + case 183: + goto tr2921 + case 184: + goto tr2922 + case 185: + goto tr2923 + case 186: + goto tr2924 + case 187: + goto tr2925 + case 188: + goto tr2926 + case 189: + goto tr2927 + case 190: + goto tr2928 + case 191: + goto tr2929 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto tr2911 + } + case data[p] >= 166: + goto tr2907 + } + goto tr148 +tr2902: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4929 + st4929: + if p++; p == pe { + goto _test_eof4929 + } + st_case_4929: +//line segment_words_prod.go:88014 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 155: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 150 <= data[p] && data[p] <= 153 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 163: + switch { + case data[p] < 169: + if 165 <= data[p] && data[p] <= 167 { + goto tr1 + } + case data[p] > 173: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr2903: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4930 + st4930: + if p++; p == pe { + goto _test_eof4930 + } + st_case_4930: +//line segment_words_prod.go:88142 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 153 <= data[p] && data[p] <= 155 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2904: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4931 + st4931: + if p++; p == pe { + goto _test_eof4931 + } + st_case_4931: +//line segment_words_prod.go:88256 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto tr4804 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr4808 + case 205: + goto tr4810 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr4813 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr4816 + case 215: + goto tr4817 + case 216: + goto tr4818 + case 217: + goto tr4819 + case 219: + goto tr4820 + case 220: + goto tr4821 + case 221: + goto tr4822 + case 222: + goto tr4823 + case 223: + goto tr4824 + case 224: + goto tr4825 + case 225: + goto tr4826 + case 226: + goto tr4827 + case 227: + goto tr4828 + case 234: + goto tr4829 + case 237: + goto tr4831 + case 239: + goto tr4832 + case 240: + goto tr4833 + case 243: + goto tr4834 + } + switch { + case data[p] < 163: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto tr4806 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr1 + } + case data[p] >= 235: + goto tr4830 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr4830: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4932 + st4932: + if p++; p == pe { + goto _test_eof4932 + } + st_case_4932: +//line segment_words_prod.go:88379 + switch data[p] { + case 194: + goto st3218 + case 204: + goto st3219 + case 205: + goto st3220 + case 210: + goto st3221 + case 214: + goto st3222 + case 215: + goto st3223 + case 216: + goto st3224 + case 217: + goto st3225 + case 219: + goto st3226 + case 220: + goto st3227 + case 221: + goto st3228 + case 222: + goto st3229 + case 223: + goto st3230 + case 224: + goto st3231 + case 225: + goto st3232 + case 226: + goto st3233 + case 227: + goto st3234 + case 234: + goto st3235 + case 239: + goto st3236 + case 240: + goto st3237 + case 243: + goto st3238 + } + goto st145 + st3232: + if p++; p == pe { + goto _test_eof3232 + } + st_case_3232: + switch data[p] { + case 128: + goto tr2930 + case 129: + goto tr2931 + case 130: + goto tr2932 + case 141: + goto tr2933 + case 156: + goto tr2934 + case 157: + goto tr2935 + case 158: + goto tr2936 + case 159: + goto tr2937 + case 160: + goto tr2938 + case 162: + goto tr2939 + case 164: + goto tr2940 + case 168: + goto tr2941 + case 169: + goto tr2942 + case 170: + goto tr2943 + case 172: + goto tr2944 + case 173: + goto tr2945 + case 174: + goto tr2946 + case 175: + goto tr2947 + case 176: + goto tr2948 + case 179: + goto tr2949 + case 183: + goto tr2950 + } + goto tr148 +tr2930: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4933 + st4933: + if p++; p == pe { + goto _test_eof4933 + } + st_case_4933: +//line segment_words_prod.go:88491 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 171 <= data[p] && data[p] <= 190 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2931: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4934 + st4934: + if p++; p == pe { + goto _test_eof4934 + } + st_case_4934: +//line segment_words_prod.go:88605 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 158: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 150 <= data[p] && data[p] <= 153 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 160: + switch { + case data[p] < 177: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr1 + } + case data[p] >= 162: + goto tr1 + } + case data[p] > 180: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr2932: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4935 + st4935: + if p++; p == pe { + goto _test_eof4935 + } + st_case_4935: +//line segment_words_prod.go:88738 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 143: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 130: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 141: + switch { + case data[p] < 196: + if 154 <= data[p] && data[p] <= 157 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 +tr2933: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4936 + st4936: + if p++; p == pe { + goto _test_eof4936 + } + st_case_4936: +//line segment_words_prod.go:88858 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 157 <= data[p] && data[p] <= 159 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2934: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4937 + st4937: + if p++; p == pe { + goto _test_eof4937 + } + st_case_4937: +//line segment_words_prod.go:88972 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 146: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] < 196: + if 178 <= data[p] && data[p] <= 180 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 +tr2935: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4938 + st4938: + if p++; p == pe { + goto _test_eof4938 + } + st_case_4938: +//line segment_words_prod.go:89090 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 146: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 147: + switch { + case data[p] < 196: + if 178 <= data[p] && data[p] <= 179 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 +tr2936: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4939 + st4939: + if p++; p == pe { + goto _test_eof4939 + } + st_case_4939: +//line segment_words_prod.go:89208 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto tr4804 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr4808 + case 205: + goto tr4810 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr4813 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr4816 + case 215: + goto tr4817 + case 216: + goto tr4818 + case 217: + goto tr4819 + case 219: + goto tr4820 + case 220: + goto tr4821 + case 221: + goto tr4822 + case 222: + goto tr4823 + case 223: + goto tr4824 + case 224: + goto tr4825 + case 225: + goto tr4826 + case 226: + goto tr4827 + case 227: + goto tr4828 + case 234: + goto tr4829 + case 237: + goto tr4831 + case 239: + goto tr4832 + case 240: + goto tr4833 + case 243: + goto tr4834 + } + switch { + case data[p] < 180: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto tr4806 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr1 + } + case data[p] >= 235: + goto tr4830 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr4831: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4940 + st4940: + if p++; p == pe { + goto _test_eof4940 + } + st_case_4940: +//line segment_words_prod.go:89331 + switch data[p] { + case 158: + goto st288 + case 159: + goto st289 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 160 <= data[p] { + goto tr4499 + } + goto st145 +tr4832: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4941 + st4941: + if p++; p == pe { + goto _test_eof4941 + } + st_case_4941: +//line segment_words_prod.go:89400 + switch data[p] { + case 172: + goto st1546 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st1547 + case 185: + goto st967 + case 187: + goto st1548 + case 188: + goto st969 + case 189: + goto st303 + case 190: + goto st1549 + case 191: + goto st1550 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr4499 +tr4833: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4942 + st4942: + if p++; p == pe { + goto _test_eof4942 + } + st_case_4942: +//line segment_words_prod.go:89495 + switch data[p] { + case 144: + goto st1552 + case 145: + goto st1558 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st1573 + case 155: + goto st1577 + case 157: + goto st1579 + case 158: + goto st1586 + case 159: + goto st403 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr4834: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st4943 + st4943: + if p++; p == pe { + goto _test_eof4943 + } + st_case_4943: +//line segment_words_prod.go:89577 + switch data[p] { + case 160: + goto st1589 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr2937: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4944 + st4944: + if p++; p == pe { + goto _test_eof4944 + } + st_case_4944: +//line segment_words_prod.go:89641 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 158: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr2646 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 148 <= data[p] && data[p] <= 156 { + goto tr4562 + } + case data[p] >= 97: + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto st145 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr4562 + } + case data[p] >= 235: + goto st286 + } + default: + goto tr4562 + } + default: + goto tr4562 + } + goto tr1 +tr2938: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4945 + st4945: + if p++; p == pe { + goto _test_eof4945 + } + st_case_4945: +//line segment_words_prod.go:89769 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 139 <= data[p] && data[p] <= 142 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2939: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4946 + st4946: + if p++; p == pe { + goto _test_eof4946 + } + st_case_4946: +//line segment_words_prod.go:89883 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 169: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2940: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4947 + st4947: + if p++; p == pe { + goto _test_eof4947 + } + st_case_4947: +//line segment_words_prod.go:89995 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 160: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 171: + switch { + case data[p] < 196: + if 176 <= data[p] && data[p] <= 187 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 +tr2941: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4948 + st4948: + if p++; p == pe { + goto _test_eof4948 + } + st_case_4948: +//line segment_words_prod.go:90113 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 151 <= data[p] && data[p] <= 155 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2942: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4949 + st4949: + if p++; p == pe { + goto _test_eof4949 + } + st_case_4949: +//line segment_words_prod.go:90227 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 191: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 149: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 158: + switch { + case data[p] < 196: + if 160 <= data[p] && data[p] <= 188 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 +tr2943: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4950 + st4950: + if p++; p == pe { + goto _test_eof4950 + } + st_case_4950: +//line segment_words_prod.go:90347 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 176 <= data[p] && data[p] <= 190 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2944: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4951 + st4951: + if p++; p == pe { + goto _test_eof4951 + } + st_case_4951: +//line segment_words_prod.go:90461 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto tr4804 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr4808 + case 205: + goto tr4810 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr4813 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr4816 + case 215: + goto tr4817 + case 216: + goto tr4818 + case 217: + goto tr4819 + case 219: + goto tr4820 + case 220: + goto tr4821 + case 221: + goto tr4822 + case 222: + goto tr4823 + case 223: + goto tr4824 + case 224: + goto tr4825 + case 225: + goto tr4826 + case 226: + goto tr4827 + case 227: + goto tr4828 + case 234: + goto tr4829 + case 237: + goto tr4831 + case 239: + goto tr4832 + case 240: + goto tr4833 + case 243: + goto tr4834 + } + switch { + case data[p] < 180: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 128 <= data[p] && data[p] <= 132 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto tr4806 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr1 + } + case data[p] >= 235: + goto tr4830 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr2945: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4952 + st4952: + if p++; p == pe { + goto _test_eof4952 + } + st_case_4952: +//line segment_words_prod.go:90589 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 180: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr2646 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 133 <= data[p] && data[p] <= 170 { + goto tr4562 + } + case data[p] >= 97: + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto st145 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr4562 + } + case data[p] >= 235: + goto st286 + } + default: + goto tr4562 + } + default: + goto tr4562 + } + goto tr1 +tr2946: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4953 + st4953: + if p++; p == pe { + goto _test_eof4953 + } + st_case_4953: +//line segment_words_prod.go:90717 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 128: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 130: + switch { + case data[p] < 196: + if 161 <= data[p] && data[p] <= 173 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 +tr2947: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4954 + st4954: + if p++; p == pe { + goto _test_eof4954 + } + st_case_4954: +//line segment_words_prod.go:90835 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 166 <= data[p] && data[p] <= 179 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2948: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4955 + st4955: + if p++; p == pe { + goto _test_eof4955 + } + st_case_4955: +//line segment_words_prod.go:90949 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 164 <= data[p] && data[p] <= 183 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2949: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4956 + st4956: + if p++; p == pe { + goto _test_eof4956 + } + st_case_4956: +//line segment_words_prod.go:91063 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 173: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 148: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 144 <= data[p] && data[p] <= 146 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 184: + if 178 <= data[p] && data[p] <= 180 { + goto tr1 + } + case data[p] > 185: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr2950: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4957 + st4957: + if p++; p == pe { + goto _test_eof4957 + } + st_case_4957: +//line segment_words_prod.go:91193 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 128: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 181: + switch { + case data[p] < 196: + if 188 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 + st3233: + if p++; p == pe { + goto _test_eof3233 + } + st_case_3233: + switch data[p] { + case 128: + goto tr2951 + case 129: + goto tr2952 + case 131: + goto tr2953 + case 179: + goto tr2954 + case 181: + goto tr2955 + case 183: + goto tr2956 + } + goto tr148 +tr2951: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4958 + st4958: + if p++; p == pe { + goto _test_eof4958 + } + st_case_4958: +//line segment_words_prod.go:91331 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 140: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] < 196: + if 170 <= data[p] && data[p] <= 174 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 +tr2952: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4959 + st4959: + if p++; p == pe { + goto _test_eof4959 + } + st_case_4959: +//line segment_words_prod.go:91449 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 160: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 164: + switch { + case data[p] < 196: + if 166 <= data[p] && data[p] <= 175 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 +tr2953: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4960 + st4960: + if p++; p == pe { + goto _test_eof4960 + } + st_case_4960: +//line segment_words_prod.go:91567 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 144 <= data[p] && data[p] <= 176 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2954: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4961 + st4961: + if p++; p == pe { + goto _test_eof4961 + } + st_case_4961: +//line segment_words_prod.go:91681 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 175 <= data[p] && data[p] <= 177 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2955: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4962 + st4962: + if p++; p == pe { + goto _test_eof4962 + } + st_case_4962: +//line segment_words_prod.go:91795 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 191: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2956: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4963 + st4963: + if p++; p == pe { + goto _test_eof4963 + } + st_case_4963: +//line segment_words_prod.go:91907 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 160 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 + st3234: + if p++; p == pe { + goto _test_eof3234 + } + st_case_3234: + switch data[p] { + case 128: + goto tr2957 + case 130: + goto tr2958 + } + goto tr148 +tr2957: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4964 + st4964: + if p++; p == pe { + goto _test_eof4964 + } + st_case_4964: +//line segment_words_prod.go:92033 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 170 <= data[p] && data[p] <= 175 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2958: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4965 + st4965: + if p++; p == pe { + goto _test_eof4965 + } + st_case_4965: +//line segment_words_prod.go:92147 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 153 <= data[p] && data[p] <= 154 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 + st3235: + if p++; p == pe { + goto _test_eof3235 + } + st_case_3235: + switch data[p] { + case 153: + goto tr2959 + case 154: + goto tr2960 + case 155: + goto tr2961 + case 160: + goto tr2962 + case 162: + goto tr2963 + case 163: + goto tr2964 + case 164: + goto tr2965 + case 165: + goto tr2966 + case 166: + goto tr2967 + case 167: + goto tr2968 + case 168: + goto tr2969 + case 169: + goto tr2970 + case 170: + goto tr2971 + case 171: + goto tr2972 + case 175: + goto tr2973 + } + goto tr148 +tr2959: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4966 + st4966: + if p++; p == pe { + goto _test_eof4966 + } + st_case_4966: +//line segment_words_prod.go:92299 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 175: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 178: + switch { + case data[p] < 196: + if 180 <= data[p] && data[p] <= 189 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 +tr2960: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4967 + st4967: + if p++; p == pe { + goto _test_eof4967 + } + st_case_4967: +//line segment_words_prod.go:92417 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 158 <= data[p] && data[p] <= 159 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2961: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4968 + st4968: + if p++; p == pe { + goto _test_eof4968 + } + st_case_4968: +//line segment_words_prod.go:92531 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 176 <= data[p] && data[p] <= 177 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2962: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4969 + st4969: + if p++; p == pe { + goto _test_eof4969 + } + st_case_4969: +//line segment_words_prod.go:92645 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 130: + goto tr1 + case 134: + goto tr1 + case 139: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 163 <= data[p] && data[p] <= 167 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2963: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4970 + st4970: + if p++; p == pe { + goto _test_eof4970 + } + st_case_4970: +//line segment_words_prod.go:92765 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto tr4804 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr4808 + case 205: + goto tr4810 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr4813 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr4816 + case 215: + goto tr4817 + case 216: + goto tr4818 + case 217: + goto tr4819 + case 219: + goto tr4820 + case 220: + goto tr4821 + case 221: + goto tr4822 + case 222: + goto tr4823 + case 223: + goto tr4824 + case 224: + goto tr4825 + case 225: + goto tr4826 + case 226: + goto tr4827 + case 227: + goto tr4828 + case 234: + goto tr4829 + case 237: + goto tr4831 + case 239: + goto tr4832 + case 240: + goto tr4833 + case 243: + goto tr4834 + } + switch { + case data[p] < 180: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 128 <= data[p] && data[p] <= 129 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto tr4806 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr1 + } + case data[p] >= 235: + goto tr4830 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr2964: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4971 + st4971: + if p++; p == pe { + goto _test_eof4971 + } + st_case_4971: +//line segment_words_prod.go:92893 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 178: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr2646 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 133 <= data[p] && data[p] <= 159 { + goto tr4562 + } + case data[p] >= 97: + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto st145 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr4562 + } + case data[p] >= 235: + goto st286 + } + default: + goto tr4562 + } + default: + goto tr4562 + } + goto tr1 +tr2965: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4972 + st4972: + if p++; p == pe { + goto _test_eof4972 + } + st_case_4972: +//line segment_words_prod.go:93021 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 166 <= data[p] && data[p] <= 173 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2966: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4973 + st4973: + if p++; p == pe { + goto _test_eof4973 + } + st_case_4973: +//line segment_words_prod.go:93135 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 135 <= data[p] && data[p] <= 147 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2967: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4974 + st4974: + if p++; p == pe { + goto _test_eof4974 + } + st_case_4974: +//line segment_words_prod.go:93249 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto tr4804 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr4808 + case 205: + goto tr4810 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr4813 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr4816 + case 215: + goto tr4817 + case 216: + goto tr4818 + case 217: + goto tr4819 + case 219: + goto tr4820 + case 220: + goto tr4821 + case 221: + goto tr4822 + case 222: + goto tr4823 + case 223: + goto tr4824 + case 224: + goto tr4825 + case 225: + goto tr4826 + case 226: + goto tr4827 + case 227: + goto tr4828 + case 234: + goto tr4829 + case 237: + goto tr4831 + case 239: + goto tr4832 + case 240: + goto tr4833 + case 243: + goto tr4834 + } + switch { + case data[p] < 179: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 128 <= data[p] && data[p] <= 131 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto tr4806 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr1 + } + case data[p] >= 235: + goto tr4830 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr2968: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4975 + st4975: + if p++; p == pe { + goto _test_eof4975 + } + st_case_4975: +//line segment_words_prod.go:93377 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 165: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 91: + switch { + case data[p] < 48: + if data[p] <= 47 { + goto tr1 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 90 { + goto tr2008 + } + case data[p] >= 59: + goto tr1 + } + default: + goto tr2646 + } + case data[p] > 96: + switch { + case data[p] < 123: + if 97 <= data[p] && data[p] <= 122 { + goto tr2008 + } + case data[p] > 128: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr2969: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4976 + st4976: + if p++; p == pe { + goto _test_eof4976 + } + st_case_4976: +//line segment_words_prod.go:93507 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 169 <= data[p] && data[p] <= 182 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2970: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4977 + st4977: + if p++; p == pe { + goto _test_eof4977 + } + st_case_4977: +//line segment_words_prod.go:93621 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 131: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 140: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 141: + switch { + case data[p] < 196: + if 187 <= data[p] && data[p] <= 189 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 +tr2971: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4978 + st4978: + if p++; p == pe { + goto _test_eof4978 + } + st_case_4978: +//line segment_words_prod.go:93741 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 176: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 178: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 180: + switch { + case data[p] < 190: + if 183 <= data[p] && data[p] <= 184 { + goto tr1 + } + case data[p] > 191: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr2972: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4979 + st4979: + if p++; p == pe { + goto _test_eof4979 + } + st_case_4979: +//line segment_words_prod.go:93866 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 129: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 171: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 175: + switch { + case data[p] < 196: + if 181 <= data[p] && data[p] <= 182 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 +tr2973: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4980 + st4980: + if p++; p == pe { + goto _test_eof4980 + } + st_case_4980: +//line segment_words_prod.go:93986 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 163: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 170: + switch { + case data[p] < 196: + if 172 <= data[p] && data[p] <= 173 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 + st3236: + if p++; p == pe { + goto _test_eof3236 + } + st_case_3236: + switch data[p] { + case 172: + goto tr2974 + case 184: + goto tr2975 + case 187: + goto tr2955 + case 190: + goto tr2960 + case 191: + goto tr2976 + } + goto tr148 +tr2974: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4981 + st4981: + if p++; p == pe { + goto _test_eof4981 + } + st_case_4981: +//line segment_words_prod.go:94122 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 158: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2975: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4982 + st4982: + if p++; p == pe { + goto _test_eof4982 + } + st_case_4982: +//line segment_words_prod.go:94234 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 128: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] < 196: + if 160 <= data[p] && data[p] <= 175 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 +tr2976: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4983 + st4983: + if p++; p == pe { + goto _test_eof4983 + } + st_case_4983: +//line segment_words_prod.go:94352 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 185 <= data[p] && data[p] <= 187 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 + st3237: + if p++; p == pe { + goto _test_eof3237 + } + st_case_3237: + switch data[p] { + case 144: + goto tr2977 + case 145: + goto tr2978 + case 150: + goto tr2979 + case 155: + goto tr2980 + case 157: + goto tr2981 + case 158: + goto tr2982 + } + goto tr148 +tr2977: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4984 + st4984: + if p++; p == pe { + goto _test_eof4984 + } + st_case_4984: +//line segment_words_prod.go:94486 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 135: + goto st96 + case 139: + goto st97 + case 141: + goto st98 + case 168: + goto st99 + case 171: + goto st100 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2978: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4985 + st4985: + if p++; p == pe { + goto _test_eof4985 + } + st_case_4985: +//line segment_words_prod.go:94606 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 128: + goto st102 + case 129: + goto st103 + case 130: + goto st104 + case 132: + goto st105 + case 133: + goto st106 + case 134: + goto st107 + case 135: + goto st108 + case 136: + goto st109 + case 139: + goto st110 + case 140: + goto st111 + case 141: + goto st112 + case 146: + goto st113 + case 147: + goto st114 + case 150: + goto st115 + case 151: + goto st116 + case 152: + goto st113 + case 153: + goto st117 + case 154: + goto st118 + case 156: + goto st119 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2979: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4986 + st4986: + if p++; p == pe { + goto _test_eof4986 + } + st_case_4986: +//line segment_words_prod.go:94754 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 171: + goto st121 + case 172: + goto st122 + case 189: + goto st123 + case 190: + goto st124 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2980: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4987 + st4987: + if p++; p == pe { + goto _test_eof4987 + } + st_case_4987: +//line segment_words_prod.go:94872 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 178: + goto st126 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2981: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4988 + st4988: + if p++; p == pe { + goto _test_eof4988 + } + st_case_4988: +//line segment_words_prod.go:94984 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 133: + goto st128 + case 134: + goto st129 + case 137: + goto st130 + case 168: + goto st131 + case 169: + goto st132 + case 170: + goto st133 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2982: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4989 + st4989: + if p++; p == pe { + goto _test_eof4989 + } + st_case_4989: +//line segment_words_prod.go:95106 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 163: + goto st135 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 + st3238: + if p++; p == pe { + goto _test_eof3238 + } + st_case_3238: + if data[p] == 160 { + goto tr2983 + } + goto tr148 +tr2983: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4990 + st4990: + if p++; p == pe { + goto _test_eof4990 + } + st_case_4990: +//line segment_words_prod.go:95227 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 128: + goto st138 + case 129: + goto st139 + case 132: + goto st1 + case 135: + goto st2 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 133 <= data[p] && data[p] <= 134 { + goto st140 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2905: +//line segment_words.rl:72 + + endPos = p + + goto st4991 + st4991: + if p++; p == pe { + goto _test_eof4991 + } + st_case_4991: +//line segment_words_prod.go:95344 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 189: + goto tr4562 + case 194: + goto tr4804 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr4808 + case 205: + goto tr4810 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr4813 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr4816 + case 215: + goto tr4817 + case 216: + goto tr4818 + case 217: + goto tr4819 + case 219: + goto tr4820 + case 220: + goto tr4821 + case 221: + goto tr4822 + case 222: + goto tr4823 + case 223: + goto tr4824 + case 224: + goto tr4825 + case 225: + goto tr4826 + case 226: + goto tr4827 + case 227: + goto tr4828 + case 234: + goto tr4829 + case 237: + goto tr4831 + case 239: + goto tr4832 + case 240: + goto tr4833 + case 243: + goto tr4834 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr2008 + } + case data[p] >= 48: + goto tr2646 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 132 <= data[p] && data[p] <= 185 { + goto tr4562 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto tr4830 + } + default: + goto tr4806 + } + default: + goto tr2008 + } + goto tr1 +tr2906: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4992 + st4992: + if p++; p == pe { + goto _test_eof4992 + } + st_case_4992: +//line segment_words_prod.go:95460 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 144: + goto tr4562 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 164: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr2646 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 152 <= data[p] && data[p] <= 161 { + goto tr4562 + } + case data[p] >= 97: + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto st145 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr4562 + } + case data[p] >= 235: + goto st286 + } + default: + goto tr4562 + } + default: + goto tr4562 + } + goto tr1 +tr2907: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4993 + st4993: + if p++; p == pe { + goto _test_eof4993 + } + st_case_4993: +//line segment_words_prod.go:95590 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 188: + goto tr1 + case 194: + goto tr4804 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr4808 + case 205: + goto tr4810 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr4813 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr4816 + case 215: + goto tr4817 + case 216: + goto tr4818 + case 217: + goto tr4819 + case 219: + goto tr4820 + case 220: + goto tr4821 + case 221: + goto tr4822 + case 222: + goto tr4823 + case 223: + goto tr4824 + case 224: + goto tr4825 + case 225: + goto tr4826 + case 226: + goto tr4827 + case 227: + goto tr4828 + case 234: + goto tr4829 + case 237: + goto tr4831 + case 239: + goto tr4832 + case 240: + goto tr4833 + case 243: + goto tr4834 + } + switch { + case data[p] < 190: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 129 <= data[p] && data[p] <= 131 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto tr4806 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr1 + } + case data[p] >= 235: + goto tr4830 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr2908: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4994 + st4994: + if p++; p == pe { + goto _test_eof4994 + } + st_case_4994: +//line segment_words_prod.go:95720 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 142: + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr2008 + } + case data[p] >= 48: + goto tr2646 + } + case data[p] > 122: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr4562 + } + case data[p] >= 133: + goto tr4562 + } + default: + goto tr2008 + } + case data[p] > 150: + switch { + case data[p] < 196: + switch { + case data[p] > 161: + if 164 <= data[p] && data[p] <= 193 { + goto tr4562 + } + case data[p] >= 152: + goto tr4562 + } + case data[p] > 218: + switch { + case data[p] < 235: + if 228 <= data[p] && data[p] <= 233 { + goto tr4562 + } + case data[p] > 236: + if 238 <= data[p] { + goto tr4562 + } + default: + goto st286 + } + default: + goto st145 + } + default: + goto tr4562 + } + goto tr1 +tr2909: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4995 + st4995: + if p++; p == pe { + goto _test_eof4995 + } + st_case_4995: +//line segment_words_prod.go:95862 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 145: + goto tr1 + case 181: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] < 59: + switch { + case data[p] > 47: + if 48 <= data[p] && data[p] <= 57 { + goto tr2646 + } + default: + goto tr1 + } + case data[p] > 64: + switch { + case data[p] > 90: + if 91 <= data[p] && data[p] <= 96 { + goto tr1 + } + case data[p] >= 65: + goto tr2008 + } + default: + goto tr1 + } + case data[p] > 122: + switch { + case data[p] < 139: + switch { + case data[p] > 130: + if 135 <= data[p] && data[p] <= 136 { + goto tr1 + } + case data[p] >= 123: + goto tr1 + } + case data[p] > 141: + switch { + case data[p] < 196: + if 176 <= data[p] && data[p] <= 177 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + default: + goto tr2008 + } + goto tr4562 +tr2910: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4996 + st4996: + if p++; p == pe { + goto _test_eof4996 + } + st_case_4996: +//line segment_words_prod.go:96008 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 134: + goto tr4562 + case 138: + goto tr4562 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 164: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr2646 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 142 <= data[p] && data[p] <= 161 { + goto tr4562 + } + case data[p] >= 97: + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto st145 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr4562 + } + case data[p] >= 235: + goto st286 + } + default: + goto tr4562 + } + default: + goto tr4562 + } + goto tr1 +tr2911: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4997 + st4997: + if p++; p == pe { + goto _test_eof4997 + } + st_case_4997: +//line segment_words_prod.go:96140 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 188: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 129: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 131: + switch { + case data[p] < 196: + if 190 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 +tr2912: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4998 + st4998: + if p++; p == pe { + goto _test_eof4998 + } + st_case_4998: +//line segment_words_prod.go:96260 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 135: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 128 <= data[p] && data[p] <= 132 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 136: + switch { + case data[p] < 162: + switch { + case data[p] > 141: + if 150 <= data[p] && data[p] <= 151 { + goto tr1 + } + case data[p] >= 139: + goto tr1 + } + case data[p] > 163: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr2913: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st4999 + st4999: + if p++; p == pe { + goto _test_eof4999 + } + st_case_4999: +//line segment_words_prod.go:96393 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 130: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 190 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2914: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st5000 + st5000: + if p++; p == pe { + goto _test_eof5000 + } + st_case_5000: +//line segment_words_prod.go:96509 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 151: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 128: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 130: + switch { + case data[p] < 138: + if 134 <= data[p] && data[p] <= 136 { + goto tr1 + } + case data[p] > 141: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr2915: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st5001 + st5001: + if p++; p == pe { + goto _test_eof5001 + } + st_case_5001: +//line segment_words_prod.go:96634 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto tr4804 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr4808 + case 205: + goto tr4810 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr4813 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr4816 + case 215: + goto tr4817 + case 216: + goto tr4818 + case 217: + goto tr4819 + case 219: + goto tr4820 + case 220: + goto tr4821 + case 221: + goto tr4822 + case 222: + goto tr4823 + case 223: + goto tr4824 + case 224: + goto tr4825 + case 225: + goto tr4826 + case 226: + goto tr4827 + case 227: + goto tr4828 + case 234: + goto tr4829 + case 237: + goto tr4831 + case 239: + goto tr4832 + case 240: + goto tr4833 + case 243: + goto tr4834 + } + switch { + case data[p] < 190: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 128 <= data[p] && data[p] <= 131 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto tr4806 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr1 + } + case data[p] >= 235: + goto tr4830 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr2916: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st5002 + st5002: + if p++; p == pe { + goto _test_eof5002 + } + st_case_5002: +//line segment_words_prod.go:96762 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 133: + goto tr4562 + case 137: + goto tr4562 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 151: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr2646 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 142 <= data[p] && data[p] <= 148 { + goto tr4562 + } + case data[p] >= 97: + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 161: + switch { + case data[p] < 228: + switch { + case data[p] > 193: + if 196 <= data[p] && data[p] <= 218 { + goto st145 + } + case data[p] >= 164: + goto tr4562 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr4562 + } + case data[p] >= 235: + goto st286 + } + default: + goto tr4562 + } + default: + goto tr4562 + } + goto tr1 +tr2917: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st5003 + st5003: + if p++; p == pe { + goto _test_eof5003 + } + st_case_5003: +//line segment_words_prod.go:96899 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 134: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 128 <= data[p] && data[p] <= 132 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 136: + switch { + case data[p] < 162: + switch { + case data[p] > 141: + if 149 <= data[p] && data[p] <= 150 { + goto tr1 + } + case data[p] >= 138: + goto tr1 + } + case data[p] > 163: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr2918: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st5004 + st5004: + if p++; p == pe { + goto _test_eof5004 + } + st_case_5004: +//line segment_words_prod.go:97032 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto tr4804 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr4808 + case 205: + goto tr4810 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr4813 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr4816 + case 215: + goto tr4817 + case 216: + goto tr4818 + case 217: + goto tr4819 + case 219: + goto tr4820 + case 220: + goto tr4821 + case 221: + goto tr4822 + case 222: + goto tr4823 + case 223: + goto tr4824 + case 224: + goto tr4825 + case 225: + goto tr4826 + case 226: + goto tr4827 + case 227: + goto tr4828 + case 234: + goto tr4829 + case 237: + goto tr4831 + case 239: + goto tr4832 + case 240: + goto tr4833 + case 243: + goto tr4834 + } + switch { + case data[p] < 190: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 129 <= data[p] && data[p] <= 131 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto tr4806 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr1 + } + case data[p] >= 235: + goto tr4830 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr2919: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st5005 + st5005: + if p++; p == pe { + goto _test_eof5005 + } + st_case_5005: +//line segment_words_prod.go:97160 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 133: + goto tr4562 + case 137: + goto tr4562 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 152: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr2646 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 142 <= data[p] && data[p] <= 150 { + goto tr4562 + } + case data[p] >= 97: + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 161: + switch { + case data[p] < 228: + switch { + case data[p] > 193: + if 196 <= data[p] && data[p] <= 218 { + goto st145 + } + case data[p] >= 164: + goto tr4562 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr4562 + } + case data[p] >= 235: + goto st286 + } + default: + goto tr4562 + } + default: + goto tr4562 + } + goto tr1 +tr2920: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st5006 + st5006: + if p++; p == pe { + goto _test_eof5006 + } + st_case_5006: +//line segment_words_prod.go:97297 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 130 <= data[p] && data[p] <= 131 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2921: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st5007 + st5007: + if p++; p == pe { + goto _test_eof5007 + } + st_case_5007: +//line segment_words_prod.go:97411 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 138: + goto tr1 + case 150: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 143: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] < 178: + if 152 <= data[p] && data[p] <= 159 { + goto tr1 + } + case data[p] > 179: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr2922: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st5008 + st5008: + if p++; p == pe { + goto _test_eof5008 + } + st_case_5008: +//line segment_words_prod.go:97538 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 177: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 180 <= data[p] && data[p] <= 186 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2923: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st5009 + st5009: + if p++; p == pe { + goto _test_eof5009 + } + st_case_5009: +//line segment_words_prod.go:97654 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 135 <= data[p] && data[p] <= 142 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2924: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st5010 + st5010: + if p++; p == pe { + goto _test_eof5010 + } + st_case_5010: +//line segment_words_prod.go:97768 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 177: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 180: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 185: + switch { + case data[p] < 196: + if 187 <= data[p] && data[p] <= 188 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 +tr2925: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st5011 + st5011: + if p++; p == pe { + goto _test_eof5011 + } + st_case_5011: +//line segment_words_prod.go:97888 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 136 <= data[p] && data[p] <= 141 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2926: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st5012 + st5012: + if p++; p == pe { + goto _test_eof5012 + } + st_case_5012: +//line segment_words_prod.go:98002 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 181: + goto tr1 + case 183: + goto tr1 + case 185: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 152: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 153: + switch { + case data[p] < 196: + if 190 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr4562 +tr2927: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st5013 + st5013: + if p++; p == pe { + goto _test_eof5013 + } + st_case_5013: +//line segment_words_prod.go:98126 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 177 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr2928: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st5014 + st5014: + if p++; p == pe { + goto _test_eof5014 + } + st_case_5014: +//line segment_words_prod.go:98240 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 134: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 128 <= data[p] && data[p] <= 132 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 135: + switch { + case data[p] < 153: + if 141 <= data[p] && data[p] <= 151 { + goto tr1 + } + case data[p] > 188: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr4562 +tr2929: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st5015 + st5015: + if p++; p == pe { + goto _test_eof5015 + } + st_case_5015: +//line segment_words_prod.go:98368 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 134: + goto tr1 + case 194: + goto st1461 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st147 + case 205: + goto st1462 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st1463 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st1464 + case 215: + goto st1465 + case 216: + goto st1466 + case 217: + goto st1467 + case 219: + goto st1468 + case 220: + goto st1469 + case 221: + goto st1470 + case 222: + goto st293 + case 223: + goto st1471 + case 224: + goto st1472 + case 225: + goto st1503 + case 226: + goto st1523 + case 227: + goto st1530 + case 234: + goto st1533 + case 237: + goto st287 + case 239: + goto st1545 + case 240: + goto st1551 + case 243: + goto st1588 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 +tr4469: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5016 + st5016: + if p++; p == pe { + goto _test_eof5016 + } + st_case_5016: +//line segment_words_prod.go:98484 + switch data[p] { + case 173: + goto tr4499 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 146: + if 130 <= data[p] && data[p] <= 133 { + goto tr4499 + } + case data[p] > 159: + switch { + case data[p] > 171: + if 175 <= data[p] { + goto tr4499 + } + case data[p] >= 165: + goto tr4499 + } + default: + goto tr4499 + } + goto tr148 +tr4938: +//line segment_words.rl:72 + + endPos = p + + goto st5017 +tr4470: +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + + goto st5017 + st5017: + if p++; p == pe { + goto _test_eof5017 + } + st_case_5017: +//line segment_words_prod.go:98570 + switch data[p] { + case 194: + goto tr4916 + case 204: + goto tr4917 + case 205: + goto tr4918 + case 210: + goto tr4919 + case 214: + goto tr4920 + case 215: + goto tr4921 + case 216: + goto tr4922 + case 217: + goto tr4923 + case 219: + goto tr4924 + case 220: + goto tr4925 + case 221: + goto tr4926 + case 222: + goto tr4927 + case 223: + goto tr4928 + case 224: + goto tr4929 + case 225: + goto tr4930 + case 226: + goto tr4931 + case 227: + goto tr4932 + case 234: + goto tr4933 + case 239: + goto tr4934 + case 240: + goto tr4935 + case 243: + goto tr4936 + } + if 128 <= data[p] { + goto tr2395 + } + goto tr4499 +tr4916: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5018 + st5018: + if p++; p == pe { + goto _test_eof5018 + } + st_case_5018: +//line segment_words_prod.go:98635 + switch data[p] { + case 173: + goto tr1 + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + goto tr4763 +tr4917: +//line segment_words.rl:72 + + endPos = p + + goto st5019 + st5019: + if p++; p == pe { + goto _test_eof5019 + } + st_case_5019: +//line segment_words_prod.go:98694 + switch data[p] { + case 194: + goto tr4937 + case 204: + goto tr4938 + case 205: + goto tr4939 + case 210: + goto tr4940 + case 214: + goto tr4941 + case 215: + goto tr4942 + case 216: + goto tr4943 + case 217: + goto tr4944 + case 219: + goto tr4945 + case 220: + goto tr4946 + case 221: + goto tr4947 + case 222: + goto tr4948 + case 223: + goto tr4949 + case 224: + goto tr4950 + case 225: + goto tr4951 + case 226: + goto tr4952 + case 227: + goto tr4953 + case 234: + goto tr4954 + case 239: + goto tr4955 + case 240: + goto tr4956 + case 243: + goto tr4957 + } + if 128 <= data[p] { + goto tr1 + } + goto tr4763 +tr4937: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5020 + st5020: + if p++; p == pe { + goto _test_eof5020 + } + st_case_5020: +//line segment_words_prod.go:98759 + switch data[p] { + case 173: + goto tr2395 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr4939: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5021 + st5021: + if p++; p == pe { + goto _test_eof5021 + } + st_case_5021: +//line segment_words_prod.go:98823 + switch data[p] { + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 176 <= data[p] { + goto tr4499 + } + goto tr2395 +tr4940: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5022 + st5022: + if p++; p == pe { + goto _test_eof5022 + } + st_case_5022: +//line segment_words_prod.go:98888 + switch data[p] { + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr2395 + } + goto tr4499 +tr4941: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5023 + st5023: + if p++; p == pe { + goto _test_eof5023 + } + st_case_5023: +//line segment_words_prod.go:98953 + switch data[p] { + case 191: + goto tr2395 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 145 <= data[p] && data[p] <= 189 { + goto tr2395 + } + goto tr4499 +tr4942: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5024 + st5024: + if p++; p == pe { + goto _test_eof5024 + } + st_case_5024: +//line segment_words_prod.go:99020 + switch data[p] { + case 135: + goto tr2395 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto tr2395 + } + case data[p] >= 129: + goto tr2395 + } + goto tr4499 +tr4943: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5025 + st5025: + if p++; p == pe { + goto _test_eof5025 + } + st_case_5025: +//line segment_words_prod.go:99092 + switch data[p] { + case 156: + goto tr2395 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto tr2395 + } + case data[p] >= 128: + goto tr2395 + } + goto tr4499 +tr4944: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5026 + st5026: + if p++; p == pe { + goto _test_eof5026 + } + st_case_5026: +//line segment_words_prod.go:99164 + switch data[p] { + case 176: + goto tr2395 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 139 <= data[p] && data[p] <= 159 { + goto tr2395 + } + goto tr4499 +tr4945: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5027 + st5027: + if p++; p == pe { + goto _test_eof5027 + } + st_case_5027: +//line segment_words_prod.go:99231 + switch data[p] { + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 159: + if 150 <= data[p] && data[p] <= 157 { + goto tr2395 + } + case data[p] > 164: + switch { + case data[p] > 168: + if 170 <= data[p] && data[p] <= 173 { + goto tr2395 + } + case data[p] >= 167: + goto tr2395 + } + default: + goto tr2395 + } + goto tr4499 +tr4946: +//line segment_words.rl:72 + + endPos = p + + goto st5028 + st5028: + if p++; p == pe { + goto _test_eof5028 + } + st_case_5028: +//line segment_words_prod.go:99305 + switch data[p] { + case 143: + goto tr2395 + case 145: + goto tr2395 + case 194: + goto tr4916 + case 204: + goto tr4917 + case 205: + goto tr4918 + case 210: + goto tr4919 + case 214: + goto tr4920 + case 215: + goto tr4921 + case 216: + goto tr4922 + case 217: + goto tr4923 + case 219: + goto tr4924 + case 220: + goto tr4925 + case 221: + goto tr4926 + case 222: + goto tr4927 + case 223: + goto tr4928 + case 224: + goto tr4929 + case 225: + goto tr4930 + case 226: + goto tr4931 + case 227: + goto tr4932 + case 234: + goto tr4933 + case 239: + goto tr4934 + case 240: + goto tr4935 + case 243: + goto tr4936 + } + if 176 <= data[p] { + goto tr2395 + } + goto tr4499 +tr4918: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5029 + st5029: + if p++; p == pe { + goto _test_eof5029 + } + st_case_5029: +//line segment_words_prod.go:99374 + switch data[p] { + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + if 176 <= data[p] { + goto tr4763 + } + goto tr1 +tr4919: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5030 + st5030: + if p++; p == pe { + goto _test_eof5030 + } + st_case_5030: +//line segment_words_prod.go:99439 + switch data[p] { + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr1 + } + goto tr4763 +tr4920: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5031 + st5031: + if p++; p == pe { + goto _test_eof5031 + } + st_case_5031: +//line segment_words_prod.go:99504 + switch data[p] { + case 191: + goto tr1 + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + if 145 <= data[p] && data[p] <= 189 { + goto tr1 + } + goto tr4763 +tr4921: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5032 + st5032: + if p++; p == pe { + goto _test_eof5032 + } + st_case_5032: +//line segment_words_prod.go:99571 + switch data[p] { + case 135: + goto tr1 + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto tr1 + } + case data[p] >= 129: + goto tr1 + } + goto tr4763 +tr4922: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5033 + st5033: + if p++; p == pe { + goto _test_eof5033 + } + st_case_5033: +//line segment_words_prod.go:99643 + switch data[p] { + case 156: + goto tr1 + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr4763 +tr4923: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5034 + st5034: + if p++; p == pe { + goto _test_eof5034 + } + st_case_5034: +//line segment_words_prod.go:99715 + switch data[p] { + case 176: + goto tr1 + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + if 139 <= data[p] && data[p] <= 159 { + goto tr1 + } + goto tr4763 +tr4924: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5035 + st5035: + if p++; p == pe { + goto _test_eof5035 + } + st_case_5035: +//line segment_words_prod.go:99782 + switch data[p] { + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + switch { + case data[p] < 159: + if 150 <= data[p] && data[p] <= 157 { + goto tr1 + } + case data[p] > 164: + switch { + case data[p] > 168: + if 170 <= data[p] && data[p] <= 173 { + goto tr1 + } + case data[p] >= 167: + goto tr1 + } + default: + goto tr1 + } + goto tr4763 +tr4925: +//line segment_words.rl:72 + + endPos = p + + goto st5036 + st5036: + if p++; p == pe { + goto _test_eof5036 + } + st_case_5036: +//line segment_words_prod.go:99856 + switch data[p] { + case 143: + goto tr1 + case 145: + goto tr1 + case 194: + goto tr4937 + case 204: + goto tr4938 + case 205: + goto tr4939 + case 210: + goto tr4940 + case 214: + goto tr4941 + case 215: + goto tr4942 + case 216: + goto tr4943 + case 217: + goto tr4944 + case 219: + goto tr4945 + case 220: + goto tr4946 + case 221: + goto tr4947 + case 222: + goto tr4948 + case 223: + goto tr4949 + case 224: + goto tr4950 + case 225: + goto tr4951 + case 226: + goto tr4952 + case 227: + goto tr4953 + case 234: + goto tr4954 + case 239: + goto tr4955 + case 240: + goto tr4956 + case 243: + goto tr4957 + } + if 176 <= data[p] { + goto tr1 + } + goto tr4763 +tr4947: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5037 + st5037: + if p++; p == pe { + goto _test_eof5037 + } + st_case_5037: +//line segment_words_prod.go:99925 + switch data[p] { + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 139 <= data[p] { + goto tr4499 + } + goto tr2395 +tr4948: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5038 + st5038: + if p++; p == pe { + goto _test_eof5038 + } + st_case_5038: +//line segment_words_prod.go:99990 + switch data[p] { + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 166 <= data[p] && data[p] <= 176 { + goto tr2395 + } + goto tr4499 +tr4949: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5039 + st5039: + if p++; p == pe { + goto _test_eof5039 + } + st_case_5039: +//line segment_words_prod.go:100055 + switch data[p] { + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 171 <= data[p] && data[p] <= 179 { + goto tr2395 + } + goto tr4499 +tr4950: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5040 + st5040: + if p++; p == pe { + goto _test_eof5040 + } + st_case_5040: +//line segment_words_prod.go:100120 + switch data[p] { + case 160: + goto st2650 + case 161: + goto st2651 + case 163: + goto st2652 + case 164: + goto st2653 + case 165: + goto st2654 + case 167: + goto st2656 + case 169: + goto st2657 + case 171: + goto st2658 + case 173: + goto st2660 + case 174: + goto st2661 + case 175: + goto st2662 + case 176: + goto st2663 + case 177: + goto st2664 + case 179: + goto st2665 + case 180: + goto st2666 + case 181: + goto st2667 + case 182: + goto st2668 + case 183: + goto st2669 + case 184: + goto st2670 + case 185: + goto st2671 + case 186: + goto st2672 + case 187: + goto st2673 + case 188: + goto st2674 + case 189: + goto st2675 + case 190: + goto st2676 + case 191: + goto st2677 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto st2659 + } + case data[p] >= 166: + goto st2655 + } + goto tr4499 +tr4951: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5041 + st5041: + if p++; p == pe { + goto _test_eof5041 + } + st_case_5041: +//line segment_words_prod.go:100242 + switch data[p] { + case 128: + goto st2679 + case 129: + goto st2680 + case 130: + goto st2681 + case 141: + goto st2682 + case 156: + goto st2683 + case 157: + goto st2684 + case 158: + goto st2685 + case 159: + goto st2686 + case 160: + goto st2687 + case 162: + goto st2688 + case 164: + goto st2689 + case 168: + goto st2690 + case 169: + goto st2691 + case 170: + goto st2692 + case 172: + goto st2693 + case 173: + goto st2694 + case 174: + goto st2695 + case 175: + goto st2696 + case 176: + goto st2697 + case 179: + goto st2698 + case 183: + goto st2699 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr4952: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5042 + st5042: + if p++; p == pe { + goto _test_eof5042 + } + st_case_5042: +//line segment_words_prod.go:100346 + switch data[p] { + case 128: + goto st2701 + case 129: + goto st2702 + case 131: + goto st2703 + case 179: + goto st2704 + case 181: + goto st2705 + case 183: + goto st2706 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr4953: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5043 + st5043: + if p++; p == pe { + goto _test_eof5043 + } + st_case_5043: +//line segment_words_prod.go:100420 + switch data[p] { + case 128: + goto st2708 + case 130: + goto st2709 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr4954: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5044 + st5044: + if p++; p == pe { + goto _test_eof5044 + } + st_case_5044: +//line segment_words_prod.go:100486 + switch data[p] { + case 153: + goto st2711 + case 154: + goto st2712 + case 155: + goto st2713 + case 160: + goto st2714 + case 162: + goto st2715 + case 163: + goto st2716 + case 164: + goto st2717 + case 165: + goto st2718 + case 166: + goto st2719 + case 167: + goto st2720 + case 168: + goto st2721 + case 169: + goto st2722 + case 170: + goto st2723 + case 171: + goto st2724 + case 175: + goto st2725 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr4955: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5045 + st5045: + if p++; p == pe { + goto _test_eof5045 + } + st_case_5045: +//line segment_words_prod.go:100578 + switch data[p] { + case 172: + goto st2727 + case 184: + goto st2728 + case 187: + goto st2705 + case 190: + goto st2712 + case 191: + goto st2729 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr4956: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5046 + st5046: + if p++; p == pe { + goto _test_eof5046 + } + st_case_5046: +//line segment_words_prod.go:100650 + switch data[p] { + case 144: + goto st2731 + case 145: + goto st2737 + case 150: + goto st2756 + case 155: + goto st2761 + case 157: + goto st2763 + case 158: + goto st2770 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr4957: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5047 +tr4498: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5047 + st5047: + if p++; p == pe { + goto _test_eof5047 + } + st_case_5047: +//line segment_words_prod.go:100739 + switch data[p] { + case 160: + goto st2773 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr4926: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5048 + st5048: + if p++; p == pe { + goto _test_eof5048 + } + st_case_5048: +//line segment_words_prod.go:100803 + switch data[p] { + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + if 139 <= data[p] { + goto tr4763 + } + goto tr1 +tr4927: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5049 + st5049: + if p++; p == pe { + goto _test_eof5049 + } + st_case_5049: +//line segment_words_prod.go:100868 + switch data[p] { + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + if 166 <= data[p] && data[p] <= 176 { + goto tr1 + } + goto tr4763 +tr4928: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5050 + st5050: + if p++; p == pe { + goto _test_eof5050 + } + st_case_5050: +//line segment_words_prod.go:100933 + switch data[p] { + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + if 171 <= data[p] && data[p] <= 179 { + goto tr1 + } + goto tr4763 +tr4929: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5051 + st5051: + if p++; p == pe { + goto _test_eof5051 + } + st_case_5051: +//line segment_words_prod.go:100998 + switch data[p] { + case 160: + goto st14 + case 161: + goto st15 + case 163: + goto st16 + case 164: + goto st17 + case 165: + goto st18 + case 167: + goto st20 + case 169: + goto st21 + case 171: + goto st22 + case 173: + goto st24 + case 174: + goto st25 + case 175: + goto st26 + case 176: + goto st27 + case 177: + goto st28 + case 179: + goto st29 + case 180: + goto st30 + case 181: + goto st31 + case 182: + goto st32 + case 183: + goto st33 + case 184: + goto st34 + case 185: + goto st35 + case 186: + goto st36 + case 187: + goto st37 + case 188: + goto st38 + case 189: + goto st39 + case 190: + goto st40 + case 191: + goto st41 + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto st23 + } + case data[p] >= 166: + goto st19 + } + goto tr4763 +tr4930: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5052 + st5052: + if p++; p == pe { + goto _test_eof5052 + } + st_case_5052: +//line segment_words_prod.go:101120 + switch data[p] { + case 128: + goto st43 + case 129: + goto st44 + case 130: + goto st45 + case 141: + goto st46 + case 156: + goto st47 + case 157: + goto st48 + case 158: + goto st49 + case 159: + goto st50 + case 160: + goto st51 + case 162: + goto st52 + case 164: + goto st53 + case 168: + goto st54 + case 169: + goto st55 + case 170: + goto st56 + case 172: + goto st57 + case 173: + goto st58 + case 174: + goto st59 + case 175: + goto st60 + case 176: + goto st61 + case 179: + goto st62 + case 183: + goto st63 + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + goto tr4763 +tr4931: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5053 + st5053: + if p++; p == pe { + goto _test_eof5053 + } + st_case_5053: +//line segment_words_prod.go:101224 + switch data[p] { + case 128: + goto st65 + case 129: + goto st66 + case 131: + goto st67 + case 179: + goto st68 + case 181: + goto st69 + case 183: + goto st70 + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + goto tr4763 +tr4932: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5054 + st5054: + if p++; p == pe { + goto _test_eof5054 + } + st_case_5054: +//line segment_words_prod.go:101298 + switch data[p] { + case 128: + goto st72 + case 130: + goto st73 + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + goto tr4763 +tr4933: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5055 + st5055: + if p++; p == pe { + goto _test_eof5055 + } + st_case_5055: +//line segment_words_prod.go:101364 + switch data[p] { + case 153: + goto st75 + case 154: + goto st76 + case 155: + goto st77 + case 160: + goto st78 + case 162: + goto st79 + case 163: + goto st80 + case 164: + goto st81 + case 165: + goto st82 + case 166: + goto st83 + case 167: + goto st84 + case 168: + goto st85 + case 169: + goto st86 + case 170: + goto st87 + case 171: + goto st88 + case 175: + goto st89 + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + goto tr4763 +tr4934: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5056 + st5056: + if p++; p == pe { + goto _test_eof5056 + } + st_case_5056: +//line segment_words_prod.go:101456 + switch data[p] { + case 172: + goto st91 + case 184: + goto st92 + case 187: + goto st69 + case 190: + goto st76 + case 191: + goto st93 + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + goto tr4763 +tr4935: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5057 + st5057: + if p++; p == pe { + goto _test_eof5057 + } + st_case_5057: +//line segment_words_prod.go:101528 + switch data[p] { + case 144: + goto st95 + case 145: + goto st101 + case 150: + goto st120 + case 155: + goto st125 + case 157: + goto st127 + case 158: + goto st134 + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + goto tr4763 +tr4936: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 12; + goto st5058 + st5058: + if p++; p == pe { + goto _test_eof5058 + } + st_case_5058: +//line segment_words_prod.go:101602 + switch data[p] { + case 160: + goto st137 + case 194: + goto st2636 + case 204: + goto st2637 + case 205: + goto st2638 + case 210: + goto st2639 + case 214: + goto st2640 + case 215: + goto st2641 + case 216: + goto st2642 + case 217: + goto st2643 + case 219: + goto st2644 + case 220: + goto st2645 + case 221: + goto st2646 + case 222: + goto st2647 + case 223: + goto st2648 + case 224: + goto st2649 + case 225: + goto st2678 + case 226: + goto st2700 + case 227: + goto st2707 + case 234: + goto st2710 + case 239: + goto st2726 + case 240: + goto st2730 + case 243: + goto st2772 + } + goto tr4763 +tr4471: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5059 + st5059: + if p++; p == pe { + goto _test_eof5059 + } + st_case_5059: +//line segment_words_prod.go:101670 + switch data[p] { + case 181: + goto tr4499 + case 190: + goto tr4499 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr4499 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr4499 + } + goto tr2395 +tr4472: +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + + goto st5060 + st5060: + if p++; p == pe { + goto _test_eof5060 + } + st_case_5060: +//line segment_words_prod.go:101752 + switch data[p] { + case 134: + goto tr148 + case 140: + goto tr148 + case 194: + goto tr4783 + case 204: + goto tr4784 + case 205: + goto tr4785 + case 210: + goto tr4786 + case 214: + goto tr4787 + case 215: + goto tr4788 + case 216: + goto tr4789 + case 217: + goto tr4790 + case 219: + goto tr4791 + case 220: + goto tr4792 + case 221: + goto tr4793 + case 222: + goto tr4794 + case 223: + goto tr4795 + case 224: + goto tr4796 + case 225: + goto tr4797 + case 226: + goto tr4798 + case 227: + goto tr4799 + case 234: + goto tr4800 + case 239: + goto tr4801 + case 240: + goto tr4802 + case 243: + goto tr4803 + } + switch { + case data[p] < 142: + if 136 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 161: + if 163 <= data[p] { + goto tr148 + } + default: + goto tr148 + } + goto tr4499 +tr4474: +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + + goto st5061 + st5061: + if p++; p == pe { + goto _test_eof5061 + } + st_case_5061: +//line segment_words_prod.go:101829 + switch data[p] { + case 130: + goto tr4499 + case 194: + goto tr4783 + case 204: + goto tr4784 + case 205: + goto tr4785 + case 210: + goto tr4786 + case 214: + goto tr4787 + case 215: + goto tr4788 + case 216: + goto tr4789 + case 217: + goto tr4790 + case 219: + goto tr4791 + case 220: + goto tr4792 + case 221: + goto tr4793 + case 222: + goto tr4794 + case 223: + goto tr4795 + case 224: + goto tr4796 + case 225: + goto tr4797 + case 226: + goto tr4798 + case 227: + goto tr4799 + case 234: + goto tr4800 + case 239: + goto tr4801 + case 240: + goto tr4802 + case 243: + goto tr4803 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr2395 + } + goto tr148 +tr4477: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5062 + st5062: + if p++; p == pe { + goto _test_eof5062 + } + st_case_5062: +//line segment_words_prod.go:101900 + switch data[p] { + case 190: + goto tr4499 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr4499 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr4499 + } + default: + goto tr2395 + } + goto tr148 +tr4478: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5063 + st5063: + if p++; p == pe { + goto _test_eof5063 + } + st_case_5063: +//line segment_words_prod.go:101980 + switch data[p] { + case 135: + goto tr2395 + case 179: + goto tr148 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr2395 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr2395 + } + goto tr4499 +tr4479: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5064 + st5064: + if p++; p == pe { + goto _test_eof5064 + } + st_case_5064: +//line segment_words_prod.go:102067 + switch data[p] { + case 156: + goto tr2395 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 133 { + goto tr2395 + } + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr2395 + } + goto tr4499 +tr4480: +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + + goto st5065 + st5065: + if p++; p == pe { + goto _test_eof5065 + } + st_case_5065: +//line segment_words_prod.go:102142 + switch data[p] { + case 171: + goto tr126 + case 176: + goto tr2395 + case 194: + goto tr4783 + case 204: + goto tr4784 + case 205: + goto tr4785 + case 210: + goto tr4786 + case 214: + goto tr4787 + case 215: + goto tr4788 + case 216: + goto tr4789 + case 217: + goto tr4790 + case 219: + goto tr4791 + case 220: + goto tr4792 + case 221: + goto tr4793 + case 222: + goto tr4794 + case 223: + goto tr4795 + case 224: + goto tr4796 + case 225: + goto tr4797 + case 226: + goto tr4798 + case 227: + goto tr4799 + case 234: + goto tr4800 + case 239: + goto tr4801 + case 240: + goto tr4802 + case 243: + goto tr4803 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + case data[p] >= 160: + goto tr126 + } + default: + goto tr2395 + } + goto tr4499 +tr4481: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5066 + st5066: + if p++; p == pe { + goto _test_eof5066 + } + st_case_5066: +//line segment_words_prod.go:102229 + switch data[p] { + case 148: + goto tr4499 + case 158: + goto tr4499 + case 169: + goto tr4499 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr2395 + } + case data[p] >= 150: + goto tr2395 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr4499 + } + case data[p] >= 189: + goto tr4499 + } + default: + goto tr126 + } + goto tr148 +tr4482: +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + + goto st5067 + st5067: + if p++; p == pe { + goto _test_eof5067 + } + st_case_5067: +//line segment_words_prod.go:102318 + switch data[p] { + case 144: + goto tr148 + case 194: + goto tr4916 + case 204: + goto tr4917 + case 205: + goto tr4918 + case 210: + goto tr4919 + case 214: + goto tr4920 + case 215: + goto tr4921 + case 216: + goto tr4922 + case 217: + goto tr4923 + case 219: + goto tr4924 + case 220: + goto tr4925 + case 221: + goto tr4926 + case 222: + goto tr4927 + case 223: + goto tr4928 + case 224: + goto tr4929 + case 225: + goto tr4930 + case 226: + goto tr4931 + case 227: + goto tr4932 + case 234: + goto tr4933 + case 239: + goto tr4934 + case 240: + goto tr4935 + case 243: + goto tr4936 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto tr2395 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr2395 + } + default: + goto tr148 + } + goto tr4499 +tr4483: +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + + goto st5068 + st5068: + if p++; p == pe { + goto _test_eof5068 + } + st_case_5068: +//line segment_words_prod.go:102393 + switch data[p] { + case 194: + goto tr4783 + case 204: + goto tr4784 + case 205: + goto tr4785 + case 210: + goto tr4786 + case 214: + goto tr4787 + case 215: + goto tr4788 + case 216: + goto tr4789 + case 217: + goto tr4790 + case 219: + goto tr4791 + case 220: + goto tr4792 + case 221: + goto tr4793 + case 222: + goto tr4794 + case 223: + goto tr4795 + case 224: + goto tr4796 + case 225: + goto tr4797 + case 226: + goto tr4798 + case 227: + goto tr4799 + case 234: + goto tr4800 + case 239: + goto tr4801 + case 240: + goto tr4802 + case 243: + goto tr4803 + } + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr4499 + } + goto tr2395 +tr4484: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5069 + st5069: + if p++; p == pe { + goto _test_eof5069 + } + st_case_5069: +//line segment_words_prod.go:102467 + switch data[p] { + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr4499 + } + case data[p] >= 166: + goto tr2395 + } + goto tr148 +tr4485: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5070 + st5070: + if p++; p == pe { + goto _test_eof5070 + } + st_case_5070: +//line segment_words_prod.go:102541 + switch data[p] { + case 186: + goto tr148 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 170: + switch { + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 171: + goto tr2395 + } + default: + goto tr148 + } + goto tr4499 +tr4486: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5071 + st5071: + if p++; p == pe { + goto _test_eof5071 + } + st_case_5071: +//line segment_words_prod.go:102626 + switch data[p] { + case 160: + goto st3239 + case 161: + goto st3240 + case 162: + goto st168 + case 163: + goto st2652 + case 164: + goto st3241 + case 165: + goto st3242 + case 166: + goto st3243 + case 167: + goto st3244 + case 168: + goto st3245 + case 169: + goto st3246 + case 170: + goto st3247 + case 171: + goto st3248 + case 172: + goto st3249 + case 173: + goto st3250 + case 174: + goto st3251 + case 175: + goto st3252 + case 176: + goto st3253 + case 177: + goto st3254 + case 178: + goto st3255 + case 179: + goto st3256 + case 180: + goto st3257 + case 181: + goto st3258 + case 182: + goto st3259 + case 183: + goto st3260 + case 184: + goto st2670 + case 185: + goto st3261 + case 186: + goto st2672 + case 187: + goto st3262 + case 188: + goto st3263 + case 189: + goto st3264 + case 190: + goto st3265 + case 191: + goto st2677 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 + st3239: + if p++; p == pe { + goto _test_eof3239 + } + st_case_3239: + switch data[p] { + case 154: + goto tr148 + case 164: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] > 149: + if 150 <= data[p] && data[p] <= 173 { + goto tr2395 + } + case data[p] >= 128: + goto tr148 + } + goto tr0 + st3240: + if p++; p == pe { + goto _test_eof3240 + } + st_case_3240: + switch { + case data[p] > 152: + if 153 <= data[p] && data[p] <= 155 { + goto tr2395 + } + case data[p] >= 128: + goto tr148 + } + goto tr0 + st3241: + if p++; p == pe { + goto _test_eof3241 + } + st_case_3241: + if data[p] == 189 { + goto tr148 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr148 + } + goto tr2395 + st3242: + if p++; p == pe { + goto _test_eof3242 + } + st_case_3242: + switch data[p] { + case 144: + goto tr148 + case 176: + goto tr0 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 177 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr0 + } + goto tr2395 + st3243: + if p++; p == pe { + goto _test_eof3243 + } + st_case_3243: + switch data[p] { + case 132: + goto tr0 + case 169: + goto tr0 + case 177: + goto tr0 + case 188: + goto tr2395 + } + switch { + case data[p] < 145: + switch { + case data[p] > 131: + if 141 <= data[p] && data[p] <= 142 { + goto tr0 + } + case data[p] >= 129: + goto tr2395 + } + case data[p] > 146: + switch { + case data[p] < 186: + if 179 <= data[p] && data[p] <= 181 { + goto tr0 + } + case data[p] > 187: + if 190 <= data[p] { + goto tr2395 + } + default: + goto tr0 + } + default: + goto tr0 + } + goto tr148 + st3244: + if p++; p == pe { + goto _test_eof3244 + } + st_case_3244: + switch data[p] { + case 142: + goto tr148 + case 158: + goto tr0 + } + switch { + case data[p] < 156: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr0 + } + case data[p] > 138: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 155 { + goto tr0 + } + case data[p] >= 143: + goto tr0 + } + default: + goto tr0 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr0 + } + case data[p] > 175: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr0 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr126 + } + default: + goto tr148 + } + goto tr2395 + st3245: + if p++; p == pe { + goto _test_eof3245 + } + st_case_3245: + if data[p] == 188 { + goto tr2395 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2395 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto tr2395 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st3246: + if p++; p == pe { + goto _test_eof3246 + } + st_case_3246: + if data[p] == 157 { + goto tr0 + } + switch { + case data[p] < 153: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr0 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 146 <= data[p] && data[p] <= 152 { + goto tr0 + } + case data[p] >= 142: + goto tr0 + } + default: + goto tr0 + } + case data[p] > 158: + switch { + case data[p] < 166: + if 159 <= data[p] && data[p] <= 165 { + goto tr0 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr0 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr126 + } + default: + goto tr148 + } + goto tr2395 + st3247: + if p++; p == pe { + goto _test_eof3247 + } + st_case_3247: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2395 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto tr2395 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st3248: + if p++; p == pe { + goto _test_eof3248 + } + st_case_3248: + switch data[p] { + case 134: + goto tr0 + case 138: + goto tr0 + case 144: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] >= 142: + goto tr0 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr0 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr0 + } + goto tr2395 + st3249: + if p++; p == pe { + goto _test_eof3249 + } + st_case_3249: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2395 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2395 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st3250: + if p++; p == pe { + goto _test_eof3250 + } + st_case_3250: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr2395 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr2395 + } + default: + goto tr2395 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 161: + switch { + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] >= 162: + goto tr2395 + } + default: + goto tr148 + } + default: + goto tr2395 + } + goto tr0 + st3251: + if p++; p == pe { + goto _test_eof3251 + } + st_case_3251: + switch data[p] { + case 130: + goto tr2395 + case 131: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 158: + switch { + case data[p] < 142: + if 133 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 149: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] < 168: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto tr2395 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st3252: + if p++; p == pe { + goto _test_eof3252 + } + st_case_3252: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr2395 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr2395 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] >= 138: + goto tr2395 + } + default: + goto tr2395 + } + goto tr0 + st3253: + if p++; p == pe { + goto _test_eof3253 + } + st_case_3253: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto tr2395 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 190 <= data[p] { + goto tr2395 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st3254: + if p++; p == pe { + goto _test_eof3254 + } + st_case_3254: + switch data[p] { + case 133: + goto tr0 + case 137: + goto tr0 + case 151: + goto tr0 + } + switch { + case data[p] < 160: + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 148 { + goto tr0 + } + case data[p] > 154: + if 155 <= data[p] && data[p] <= 159 { + goto tr0 + } + default: + goto tr148 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr0 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr0 + } + default: + goto tr126 + } + default: + goto tr148 + } + goto tr2395 + st3255: + if p++; p == pe { + goto _test_eof3255 + } + st_case_3255: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2395 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2395 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st3256: + if p++; p == pe { + goto _test_eof3256 + } + st_case_3256: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr2395 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr2395 + } + default: + goto tr2395 + } + case data[p] > 150: + switch { + case data[p] < 162: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 163: + switch { + case data[p] > 175: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr2395 + } + default: + goto tr2395 + } + goto tr0 + st3257: + if p++; p == pe { + goto _test_eof3257 + } + st_case_3257: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto tr2395 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto tr2395 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st3258: + if p++; p == pe { + goto _test_eof3258 + } + st_case_3258: + switch data[p] { + case 133: + goto tr0 + case 137: + goto tr0 + case 142: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 150 { + goto tr0 + } + case data[p] > 158: + if 159 <= data[p] && data[p] <= 161 { + goto tr148 + } + default: + goto tr0 + } + case data[p] > 165: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr126 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr0 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr0 + } + default: + goto tr0 + } + goto tr2395 + st3259: + if p++; p == pe { + goto _test_eof3259 + } + st_case_3259: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr2395 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st3260: + if p++; p == pe { + goto _test_eof3260 + } + st_case_3260: + switch data[p] { + case 138: + goto tr2395 + case 150: + goto tr2395 + } + switch { + case data[p] < 152: + switch { + case data[p] > 134: + if 143 <= data[p] && data[p] <= 148 { + goto tr2395 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto tr2395 + } + case data[p] >= 166: + goto tr126 + } + default: + goto tr2395 + } + goto tr0 + st3261: + if p++; p == pe { + goto _test_eof3261 + } + st_case_3261: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 135: + goto tr2395 + } + goto tr0 + st3262: + if p++; p == pe { + goto _test_eof3262 + } + st_case_3262: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 136: + goto tr2395 + } + goto tr0 + st3263: + if p++; p == pe { + goto _test_eof3263 + } + st_case_3263: + switch data[p] { + case 128: + goto tr148 + case 181: + goto tr2395 + case 183: + goto tr2395 + case 185: + goto tr2395 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto tr2395 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto tr2395 + } + default: + goto tr126 + } + goto tr0 + st3264: + if p++; p == pe { + goto _test_eof3264 + } + st_case_3264: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto tr2395 + } + default: + goto tr148 + } + goto tr0 + st3265: + if p++; p == pe { + goto _test_eof3265 + } + st_case_3265: + switch { + case data[p] < 136: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 135 { + goto tr2395 + } + case data[p] >= 128: + goto tr2395 + } + case data[p] > 140: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr2395 + } + case data[p] >= 141: + goto tr2395 + } + default: + goto tr148 + } + goto tr0 +tr4487: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5072 + st5072: + if p++; p == pe { + goto _test_eof5072 + } + st_case_5072: +//line segment_words_prod.go:103682 + switch data[p] { + case 128: + goto st2679 + case 129: + goto st3266 + case 130: + goto st3267 + case 131: + goto st202 + case 132: + goto st3268 + case 135: + goto st3319 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st3573 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st3574 + case 157: + goto st3575 + case 158: + goto st2685 + case 159: + goto st3576 + case 160: + goto st3577 + case 161: + goto st219 + case 162: + goto st3578 + case 163: + goto st221 + case 164: + goto st3579 + case 165: + goto st1649 + case 167: + goto st1650 + case 168: + goto st3580 + case 169: + goto st2691 + case 170: + goto st3581 + case 172: + goto st3582 + case 173: + goto st3583 + case 174: + goto st3584 + case 175: + goto st3585 + case 176: + goto st3586 + case 177: + goto st1659 + case 179: + goto st3587 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st2699 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 136: + if 133 <= data[p] && data[p] <= 134 { + goto st3318 + } + case data[p] > 152: + switch { + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + case data[p] >= 180: + goto st147 + } + default: + goto st145 + } + goto tr4499 + st3266: + if p++; p == pe { + goto _test_eof3266 + } + st_case_3266: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto tr2395 + } + case data[p] >= 128: + goto tr126 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto tr2395 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr2395 + } + default: + goto tr2395 + } + default: + goto tr2395 + } + goto tr0 + st3267: + if p++; p == pe { + goto _test_eof3267 + } + st_case_3267: + if data[p] == 143 { + goto tr2395 + } + switch { + case data[p] < 144: + if 130 <= data[p] && data[p] <= 141 { + goto tr2395 + } + case data[p] > 153: + switch { + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 154: + goto tr2395 + } + default: + goto tr126 + } + goto tr0 + st3268: + if p++; p == pe { + goto _test_eof3268 + } + st_case_3268: + if 128 <= data[p] { + goto tr2984 + } + goto tr148 +tr2984: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5073 + st5073: + if p++; p == pe { + goto _test_eof5073 + } + st_case_5073: +//line segment_words_prod.go:103918 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 + st3269: + if p++; p == pe { + goto _test_eof3269 + } + st_case_3269: + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr2984 + case 181: + goto tr148 + case 183: + goto st142 + case 186: + goto tr148 + } + goto tr2985 + st3270: + if p++; p == pe { + goto _test_eof3270 + } + st_case_3270: + if 128 <= data[p] { + goto tr2984 + } + goto tr2 + st3271: + if p++; p == pe { + goto _test_eof3271 + } + st_case_3271: + switch data[p] { + case 181: + goto tr2985 + case 190: + goto tr2985 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr2985 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr2985 + } + goto tr2984 + st3272: + if p++; p == pe { + goto _test_eof3272 + } + st_case_3272: + if data[p] == 130 { + goto tr2985 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr2984 + } + goto tr148 + st3273: + if p++; p == pe { + goto _test_eof3273 + } + st_case_3273: + if data[p] == 190 { + goto tr2985 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr2985 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr2985 + } + default: + goto tr2984 + } + goto tr148 + st3274: + if p++; p == pe { + goto _test_eof3274 + } + st_case_3274: + switch data[p] { + case 135: + goto tr2984 + case 179: + goto tr148 + case 180: + goto st142 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr2984 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr2984 + } + goto tr2985 + st3275: + if p++; p == pe { + goto _test_eof3275 + } + st_case_3275: + if data[p] == 156 { + goto tr2984 + } + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 133 { + goto tr2984 + } + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr2984 + } + goto tr2985 + st3276: + if p++; p == pe { + goto _test_eof3276 + } + st_case_3276: + switch data[p] { + case 171: + goto tr421 + case 176: + goto tr2984 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr2984 + } + goto tr2985 + st3277: + if p++; p == pe { + goto _test_eof3277 + } + st_case_3277: + switch data[p] { + case 148: + goto tr2985 + case 158: + goto tr2985 + case 169: + goto tr2985 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr2984 + } + case data[p] >= 150: + goto tr2984 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr2985 + } + case data[p] >= 189: + goto tr2985 + } + default: + goto tr421 + } + goto tr148 + st3278: + if p++; p == pe { + goto _test_eof3278 + } + st_case_3278: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto tr2984 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr2984 + } + default: + goto tr148 + } + goto tr2985 + st3279: + if p++; p == pe { + goto _test_eof3279 + } + st_case_3279: + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr2985 + } + goto tr2984 + st3280: + if p++; p == pe { + goto _test_eof3280 + } + st_case_3280: + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr2985 + } + case data[p] >= 166: + goto tr2984 + } + goto tr148 + st3281: + if p++; p == pe { + goto _test_eof3281 + } + st_case_3281: + if data[p] == 186 { + goto tr148 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 170: + switch { + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 171: + goto tr2984 + } + default: + goto tr148 + } + goto tr2985 + st3282: + if p++; p == pe { + goto _test_eof3282 + } + st_case_3282: + switch data[p] { + case 160: + goto st3283 + case 161: + goto st3284 + case 162: + goto st168 + case 163: + goto st3285 + case 164: + goto st3286 + case 165: + goto st3287 + case 166: + goto st3288 + case 167: + goto st3289 + case 168: + goto st3290 + case 169: + goto st3291 + case 170: + goto st3292 + case 171: + goto st3293 + case 172: + goto st3294 + case 173: + goto st3295 + case 174: + goto st3296 + case 175: + goto st3297 + case 176: + goto st3298 + case 177: + goto st3299 + case 178: + goto st3300 + case 179: + goto st3301 + case 180: + goto st3302 + case 181: + goto st3303 + case 182: + goto st3304 + case 183: + goto st3305 + case 184: + goto st3306 + case 185: + goto st3307 + case 186: + goto st3308 + case 187: + goto st3309 + case 188: + goto st3310 + case 189: + goto st3311 + case 190: + goto st3312 + case 191: + goto st3313 + } + goto tr2985 + st3283: + if p++; p == pe { + goto _test_eof3283 + } + st_case_3283: + switch data[p] { + case 154: + goto tr148 + case 164: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] > 149: + if 150 <= data[p] && data[p] <= 173 { + goto tr2984 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st3284: + if p++; p == pe { + goto _test_eof3284 + } + st_case_3284: + switch { + case data[p] > 152: + if 153 <= data[p] && data[p] <= 155 { + goto tr2984 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st3285: + if p++; p == pe { + goto _test_eof3285 + } + st_case_3285: + if 163 <= data[p] { + goto tr2984 + } + goto tr2 + st3286: + if p++; p == pe { + goto _test_eof3286 + } + st_case_3286: + if data[p] == 189 { + goto tr148 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr148 + } + goto tr2984 + st3287: + if p++; p == pe { + goto _test_eof3287 + } + st_case_3287: + switch data[p] { + case 144: + goto tr148 + case 176: + goto tr2 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 177 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr2 + } + goto tr2984 + st3288: + if p++; p == pe { + goto _test_eof3288 + } + st_case_3288: + switch data[p] { + case 132: + goto tr2 + case 169: + goto tr2 + case 177: + goto tr2 + case 188: + goto tr2984 + } + switch { + case data[p] < 145: + switch { + case data[p] > 131: + if 141 <= data[p] && data[p] <= 142 { + goto tr2 + } + case data[p] >= 129: + goto tr2984 + } + case data[p] > 146: + switch { + case data[p] < 186: + if 179 <= data[p] && data[p] <= 181 { + goto tr2 + } + case data[p] > 187: + if 190 <= data[p] { + goto tr2984 + } + default: + goto tr2 + } + default: + goto tr2 + } + goto tr148 + st3289: + if p++; p == pe { + goto _test_eof3289 + } + st_case_3289: + switch data[p] { + case 142: + goto tr148 + case 158: + goto tr2 + } + switch { + case data[p] < 156: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr2 + } + case data[p] > 138: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 155 { + goto tr2 + } + case data[p] >= 143: + goto tr2 + } + default: + goto tr2 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr2 + } + case data[p] > 175: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr2 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr2984 + st3290: + if p++; p == pe { + goto _test_eof3290 + } + st_case_3290: + if data[p] == 188 { + goto tr2984 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2984 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto tr2984 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st3291: + if p++; p == pe { + goto _test_eof3291 + } + st_case_3291: + if data[p] == 157 { + goto tr2 + } + switch { + case data[p] < 153: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr2 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 146 <= data[p] && data[p] <= 152 { + goto tr2 + } + case data[p] >= 142: + goto tr2 + } + default: + goto tr2 + } + case data[p] > 158: + switch { + case data[p] < 166: + if 159 <= data[p] && data[p] <= 165 { + goto tr2 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr2 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr2984 + st3292: + if p++; p == pe { + goto _test_eof3292 + } + st_case_3292: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2984 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto tr2984 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st3293: + if p++; p == pe { + goto _test_eof3293 + } + st_case_3293: + switch data[p] { + case 134: + goto tr2 + case 138: + goto tr2 + case 144: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] >= 142: + goto tr2 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr2 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr2 + } + goto tr2984 + st3294: + if p++; p == pe { + goto _test_eof3294 + } + st_case_3294: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2984 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2984 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st3295: + if p++; p == pe { + goto _test_eof3295 + } + st_case_3295: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr2984 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr2984 + } + default: + goto tr2984 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 161: + switch { + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 162: + goto tr2984 + } + default: + goto tr148 + } + default: + goto tr2984 + } + goto tr2 + st3296: + if p++; p == pe { + goto _test_eof3296 + } + st_case_3296: + switch data[p] { + case 130: + goto tr2984 + case 131: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 158: + switch { + case data[p] < 142: + if 133 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 149: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] < 168: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto tr2984 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st3297: + if p++; p == pe { + goto _test_eof3297 + } + st_case_3297: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr2984 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr2984 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 138: + goto tr2984 + } + default: + goto tr2984 + } + goto tr2 + st3298: + if p++; p == pe { + goto _test_eof3298 + } + st_case_3298: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto tr2984 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 190 <= data[p] { + goto tr2984 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st3299: + if p++; p == pe { + goto _test_eof3299 + } + st_case_3299: + switch data[p] { + case 133: + goto tr2 + case 137: + goto tr2 + case 151: + goto tr2 + } + switch { + case data[p] < 160: + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 148 { + goto tr2 + } + case data[p] > 154: + if 155 <= data[p] && data[p] <= 159 { + goto tr2 + } + default: + goto tr148 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr2 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr2 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr2984 + st3300: + if p++; p == pe { + goto _test_eof3300 + } + st_case_3300: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2984 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2984 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st3301: + if p++; p == pe { + goto _test_eof3301 + } + st_case_3301: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr2984 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr2984 + } + default: + goto tr2984 + } + case data[p] > 150: + switch { + case data[p] < 162: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 163: + switch { + case data[p] > 175: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr2984 + } + default: + goto tr2984 + } + goto tr2 + st3302: + if p++; p == pe { + goto _test_eof3302 + } + st_case_3302: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto tr2984 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto tr2984 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st3303: + if p++; p == pe { + goto _test_eof3303 + } + st_case_3303: + switch data[p] { + case 133: + goto tr2 + case 137: + goto tr2 + case 142: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 150 { + goto tr2 + } + case data[p] > 158: + if 159 <= data[p] && data[p] <= 161 { + goto tr148 + } + default: + goto tr2 + } + case data[p] > 165: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr2 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr2 + } + default: + goto tr2 + } + goto tr2984 + st3304: + if p++; p == pe { + goto _test_eof3304 + } + st_case_3304: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr2984 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st3305: + if p++; p == pe { + goto _test_eof3305 + } + st_case_3305: + switch data[p] { + case 138: + goto tr2984 + case 150: + goto tr2984 + } + switch { + case data[p] < 152: + switch { + case data[p] > 134: + if 143 <= data[p] && data[p] <= 148 { + goto tr2984 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto tr2984 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr2984 + } + goto tr2 + st3306: + if p++; p == pe { + goto _test_eof3306 + } + st_case_3306: + if data[p] == 177 { + goto tr2984 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr2984 + } + goto tr2 + st3307: + if p++; p == pe { + goto _test_eof3307 + } + st_case_3307: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 135: + goto tr2984 + } + goto tr2 + st3308: + if p++; p == pe { + goto _test_eof3308 + } + st_case_3308: + if data[p] == 177 { + goto tr2984 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr2984 + } + case data[p] >= 180: + goto tr2984 + } + goto tr2 + st3309: + if p++; p == pe { + goto _test_eof3309 + } + st_case_3309: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 136: + goto tr2984 + } + goto tr2 + st3310: + if p++; p == pe { + goto _test_eof3310 + } + st_case_3310: + switch data[p] { + case 128: + goto tr148 + case 181: + goto tr2984 + case 183: + goto tr2984 + case 185: + goto tr2984 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto tr2984 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto tr2984 + } + default: + goto tr421 + } + goto tr2 + st3311: + if p++; p == pe { + goto _test_eof3311 + } + st_case_3311: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto tr2984 + } + default: + goto tr148 + } + goto tr2 + st3312: + if p++; p == pe { + goto _test_eof3312 + } + st_case_3312: + switch { + case data[p] < 136: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 135 { + goto tr2984 + } + case data[p] >= 128: + goto tr2984 + } + case data[p] > 140: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr2984 + } + case data[p] >= 141: + goto tr2984 + } + default: + goto tr148 + } + goto tr2 + st3313: + if p++; p == pe { + goto _test_eof3313 + } + st_case_3313: + if data[p] == 134 { + goto tr2984 + } + goto tr2 + st3314: + if p++; p == pe { + goto _test_eof3314 + } + st_case_3314: + switch data[p] { + case 128: + goto st3315 + case 129: + goto st3316 + case 130: + goto st3317 + case 131: + goto st202 + case 132: + goto st3268 + case 135: + goto st3319 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st3320 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st3321 + case 157: + goto st3322 + case 158: + goto st3323 + case 159: + goto st3324 + case 160: + goto st3325 + case 161: + goto st219 + case 162: + goto st3326 + case 163: + goto st221 + case 164: + goto st3327 + case 165: + goto st468 + case 167: + goto st469 + case 168: + goto st3328 + case 169: + goto st3329 + case 170: + goto st3330 + case 172: + goto st3331 + case 173: + goto st3332 + case 174: + goto st3333 + case 175: + goto st3334 + case 176: + goto st3335 + case 177: + goto st640 + case 179: + goto st3336 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st3337 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + } + switch { + case data[p] < 136: + if 133 <= data[p] && data[p] <= 134 { + goto st3318 + } + case data[p] > 152: + switch { + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + case data[p] >= 180: + goto st147 + } + default: + goto st145 + } + goto tr2985 + st3315: + if p++; p == pe { + goto _test_eof3315 + } + st_case_3315: + if 171 <= data[p] && data[p] <= 190 { + goto tr2984 + } + goto tr2 + st3316: + if p++; p == pe { + goto _test_eof3316 + } + st_case_3316: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto tr2984 + } + case data[p] >= 128: + goto tr421 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto tr2984 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr2984 + } + default: + goto tr2984 + } + default: + goto tr2984 + } + goto tr2 + st3317: + if p++; p == pe { + goto _test_eof3317 + } + st_case_3317: + if data[p] == 143 { + goto tr2984 + } + switch { + case data[p] < 144: + if 130 <= data[p] && data[p] <= 141 { + goto tr2984 + } + case data[p] > 153: + switch { + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 154: + goto tr2984 + } + default: + goto tr421 + } + goto tr2 + st3318: + if p++; p == pe { + goto _test_eof3318 + } + st_case_3318: + goto tr2984 + st3319: + if p++; p == pe { + goto _test_eof3319 + } + st_case_3319: + if 192 <= data[p] { + goto tr148 + } + goto tr2984 + st3320: + if p++; p == pe { + goto _test_eof3320 + } + st_case_3320: + switch { + case data[p] < 157: + if 155 <= data[p] && data[p] <= 156 { + goto tr2 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr2 + } + default: + goto tr2984 + } + goto tr148 + st3321: + if p++; p == pe { + goto _test_eof3321 + } + st_case_3321: + switch { + case data[p] < 146: + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 177: + if 178 <= data[p] && data[p] <= 180 { + goto tr2984 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr2984 + } + goto tr2 + st3322: + if p++; p == pe { + goto _test_eof3322 + } + st_case_3322: + switch { + case data[p] < 160: + switch { + case data[p] > 145: + if 146 <= data[p] && data[p] <= 147 { + goto tr2984 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto tr2984 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st3323: + if p++; p == pe { + goto _test_eof3323 + } + st_case_3323: + if 180 <= data[p] { + goto tr2984 + } + goto tr2 + st3324: + if p++; p == pe { + goto _test_eof3324 + } + st_case_3324: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr2 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 170 <= data[p] { + goto tr2 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr2 + } + goto tr2984 + st3325: + if p++; p == pe { + goto _test_eof3325 + } + st_case_3325: + switch { + case data[p] < 144: + if 139 <= data[p] && data[p] <= 142 { + goto tr2984 + } + case data[p] > 153: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + goto tr2 + st3326: + if p++; p == pe { + goto _test_eof3326 + } + st_case_3326: + if data[p] == 169 { + goto tr2984 + } + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st3327: + if p++; p == pe { + goto _test_eof3327 + } + st_case_3327: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr2984 + } + default: + goto tr2984 + } + goto tr2 + st3328: + if p++; p == pe { + goto _test_eof3328 + } + st_case_3328: + switch { + case data[p] > 150: + if 151 <= data[p] && data[p] <= 155 { + goto tr2984 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st3329: + if p++; p == pe { + goto _test_eof3329 + } + st_case_3329: + if data[p] == 191 { + goto tr2984 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr2984 + } + case data[p] >= 149: + goto tr2984 + } + goto tr2 + st3330: + if p++; p == pe { + goto _test_eof3330 + } + st_case_3330: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto tr2984 + } + default: + goto tr421 + } + goto tr2 + st3331: + if p++; p == pe { + goto _test_eof3331 + } + st_case_3331: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 132 { + goto tr2984 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr2984 + } + default: + goto tr148 + } + goto tr2 + st3332: + if p++; p == pe { + goto _test_eof3332 + } + st_case_3332: + switch { + case data[p] < 144: + switch { + case data[p] > 139: + if 140 <= data[p] && data[p] <= 143 { + goto tr2 + } + case data[p] >= 133: + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr2 + } + case data[p] >= 154: + goto tr2 + } + default: + goto tr421 + } + goto tr2984 + st3333: + if p++; p == pe { + goto _test_eof3333 + } + st_case_3333: + switch { + case data[p] < 161: + switch { + case data[p] > 130: + if 131 <= data[p] && data[p] <= 160 { + goto tr148 + } + case data[p] >= 128: + goto tr2984 + } + case data[p] > 173: + switch { + case data[p] < 176: + if 174 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + default: + goto tr2984 + } + goto tr2 + st3334: + if p++; p == pe { + goto _test_eof3334 + } + st_case_3334: + switch { + case data[p] > 179: + if 180 <= data[p] { + goto tr2 + } + case data[p] >= 166: + goto tr2984 + } + goto tr148 + st3335: + if p++; p == pe { + goto _test_eof3335 + } + st_case_3335: + switch { + case data[p] > 163: + if 164 <= data[p] && data[p] <= 183 { + goto tr2984 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st3336: + if p++; p == pe { + goto _test_eof3336 + } + st_case_3336: + if data[p] == 173 { + goto tr2984 + } + switch { + case data[p] < 169: + switch { + case data[p] > 146: + if 148 <= data[p] && data[p] <= 168 { + goto tr2984 + } + case data[p] >= 144: + goto tr2984 + } + case data[p] > 177: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 180 { + goto tr2984 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto tr2984 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st3337: + if p++; p == pe { + goto _test_eof3337 + } + st_case_3337: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr2984 + } + case data[p] >= 128: + goto tr2984 + } + goto tr2 + st3338: + if p++; p == pe { + goto _test_eof3338 + } + st_case_3338: + switch data[p] { + case 128: + goto st3339 + case 129: + goto st3340 + case 130: + goto st241 + case 131: + goto st3341 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st3342 + case 180: + goto st251 + case 181: + goto st3343 + case 182: + goto st253 + case 183: + goto st3344 + case 184: + goto st255 + } + goto tr2985 + st3339: + if p++; p == pe { + goto _test_eof3339 + } + st_case_3339: + switch data[p] { + case 164: + goto st142 + case 167: + goto st142 + } + switch { + case data[p] < 152: + if 140 <= data[p] && data[p] <= 143 { + goto tr2984 + } + case data[p] > 153: + switch { + case data[p] > 174: + if 191 <= data[p] { + goto tr571 + } + case data[p] >= 170: + goto tr2984 + } + default: + goto st142 + } + goto tr2 + st3340: + if p++; p == pe { + goto _test_eof3340 + } + st_case_3340: + switch data[p] { + case 165: + goto tr2 + case 177: + goto tr148 + case 191: + goto tr148 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr2 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr2 + } + case data[p] >= 160: + goto tr2984 + } + default: + goto tr2 + } + goto tr571 + st3341: + if p++; p == pe { + goto _test_eof3341 + } + st_case_3341: + if 144 <= data[p] && data[p] <= 176 { + goto tr2984 + } + goto tr2 + st3342: + if p++; p == pe { + goto _test_eof3342 + } + st_case_3342: + switch { + case data[p] < 175: + if 165 <= data[p] && data[p] <= 170 { + goto tr2 + } + case data[p] > 177: + if 180 <= data[p] { + goto tr2 + } + default: + goto tr2984 + } + goto tr148 + st3343: + if p++; p == pe { + goto _test_eof3343 + } + st_case_3343: + if data[p] == 191 { + goto tr2984 + } + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr2 + } + case data[p] >= 168: + goto tr2 + } + goto tr148 + st3344: + if p++; p == pe { + goto _test_eof3344 + } + st_case_3344: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto tr2984 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st3345: + if p++; p == pe { + goto _test_eof3345 + } + st_case_3345: + switch data[p] { + case 128: + goto st3346 + case 130: + goto st3347 + case 132: + goto st3348 + case 133: + goto st3318 + case 134: + goto st3349 + case 136: + goto st3350 + case 137: + goto st3429 + } + goto tr2985 + st3346: + if p++; p == pe { + goto _test_eof3346 + } + st_case_3346: + if data[p] == 133 { + goto tr148 + } + switch { + case data[p] > 175: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + case data[p] >= 170: + goto tr2984 + } + goto tr2 + st3347: + if p++; p == pe { + goto _test_eof3347 + } + st_case_3347: + if 153 <= data[p] && data[p] <= 154 { + goto tr2984 + } + goto tr2 + st3348: + if p++; p == pe { + goto _test_eof3348 + } + st_case_3348: + switch { + case data[p] > 173: + if 177 <= data[p] { + goto tr2984 + } + case data[p] >= 133: + goto tr148 + } + goto tr2 + st3349: + if p++; p == pe { + goto _test_eof3349 + } + st_case_3349: + switch { + case data[p] < 160: + if 143 <= data[p] && data[p] <= 159 { + goto tr2 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr2 + } + default: + goto tr148 + } + goto tr2984 + st3350: + if p++; p == pe { + goto _test_eof3350 + } + st_case_3350: + if 128 <= data[p] && data[p] <= 158 { + goto tr3053 + } + goto tr2 +tr3053: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5074 + st5074: + if p++; p == pe { + goto _test_eof5074 + } + st_case_5074: +//line segment_words_prod.go:106179 + switch data[p] { + case 194: + goto st3351 + case 204: + goto st3352 + case 205: + goto st3353 + case 210: + goto st3354 + case 214: + goto st3355 + case 215: + goto st3356 + case 216: + goto st3357 + case 217: + goto st3358 + case 219: + goto st3359 + case 220: + goto st3360 + case 221: + goto st3361 + case 222: + goto st3362 + case 223: + goto st3363 + case 224: + goto st3364 + case 225: + goto st3393 + case 226: + goto st3417 + case 227: + goto st3424 + case 234: + goto st3430 + case 237: + goto st3447 + case 239: + goto st3450 + case 240: + goto st3455 + case 243: + goto st3497 + } + if 235 <= data[p] && data[p] <= 236 { + goto st3446 + } + goto tr5002 + st3351: + if p++; p == pe { + goto _test_eof3351 + } + st_case_3351: + if data[p] == 173 { + goto tr3053 + } + goto tr2985 + st3352: + if p++; p == pe { + goto _test_eof3352 + } + st_case_3352: + if 128 <= data[p] { + goto tr3053 + } + goto tr2985 + st3353: + if p++; p == pe { + goto _test_eof3353 + } + st_case_3353: + if 176 <= data[p] { + goto tr2985 + } + goto tr3053 + st3354: + if p++; p == pe { + goto _test_eof3354 + } + st_case_3354: + if 131 <= data[p] && data[p] <= 137 { + goto tr3053 + } + goto tr2985 + st3355: + if p++; p == pe { + goto _test_eof3355 + } + st_case_3355: + if data[p] == 191 { + goto tr3053 + } + if 145 <= data[p] && data[p] <= 189 { + goto tr3053 + } + goto tr2985 + st3356: + if p++; p == pe { + goto _test_eof3356 + } + st_case_3356: + if data[p] == 135 { + goto tr3053 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto tr3053 + } + case data[p] >= 129: + goto tr3053 + } + goto tr2985 + st3357: + if p++; p == pe { + goto _test_eof3357 + } + st_case_3357: + if data[p] == 156 { + goto tr3053 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto tr3053 + } + case data[p] >= 128: + goto tr3053 + } + goto tr2985 + st3358: + if p++; p == pe { + goto _test_eof3358 + } + st_case_3358: + if data[p] == 176 { + goto tr3053 + } + if 139 <= data[p] && data[p] <= 159 { + goto tr3053 + } + goto tr2985 + st3359: + if p++; p == pe { + goto _test_eof3359 + } + st_case_3359: + switch { + case data[p] < 159: + if 150 <= data[p] && data[p] <= 157 { + goto tr3053 + } + case data[p] > 164: + switch { + case data[p] > 168: + if 170 <= data[p] && data[p] <= 173 { + goto tr3053 + } + case data[p] >= 167: + goto tr3053 + } + default: + goto tr3053 + } + goto tr2985 + st3360: + if p++; p == pe { + goto _test_eof3360 + } + st_case_3360: + switch data[p] { + case 143: + goto tr3053 + case 145: + goto tr3053 + } + if 176 <= data[p] { + goto tr3053 + } + goto tr2985 + st3361: + if p++; p == pe { + goto _test_eof3361 + } + st_case_3361: + if 139 <= data[p] { + goto tr2985 + } + goto tr3053 + st3362: + if p++; p == pe { + goto _test_eof3362 + } + st_case_3362: + if 166 <= data[p] && data[p] <= 176 { + goto tr3053 + } + goto tr2985 + st3363: + if p++; p == pe { + goto _test_eof3363 + } + st_case_3363: + if 171 <= data[p] && data[p] <= 179 { + goto tr3053 + } + goto tr2985 + st3364: + if p++; p == pe { + goto _test_eof3364 + } + st_case_3364: + switch data[p] { + case 160: + goto st3365 + case 161: + goto st3366 + case 163: + goto st3367 + case 164: + goto st3368 + case 165: + goto st3369 + case 167: + goto st3371 + case 169: + goto st3372 + case 171: + goto st3373 + case 173: + goto st3375 + case 174: + goto st3376 + case 175: + goto st3377 + case 176: + goto st3378 + case 177: + goto st3379 + case 179: + goto st3380 + case 180: + goto st3381 + case 181: + goto st3382 + case 182: + goto st3383 + case 183: + goto st3384 + case 184: + goto st3385 + case 185: + goto st3386 + case 186: + goto st3387 + case 187: + goto st3388 + case 188: + goto st3389 + case 189: + goto st3390 + case 190: + goto st3391 + case 191: + goto st3392 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto st3374 + } + case data[p] >= 166: + goto st3370 + } + goto tr2985 + st3365: + if p++; p == pe { + goto _test_eof3365 + } + st_case_3365: + switch { + case data[p] < 155: + if 150 <= data[p] && data[p] <= 153 { + goto tr3053 + } + case data[p] > 163: + switch { + case data[p] > 167: + if 169 <= data[p] && data[p] <= 173 { + goto tr3053 + } + case data[p] >= 165: + goto tr3053 + } + default: + goto tr3053 + } + goto tr2985 + st3366: + if p++; p == pe { + goto _test_eof3366 + } + st_case_3366: + if 153 <= data[p] && data[p] <= 155 { + goto tr3053 + } + goto tr2985 + st3367: + if p++; p == pe { + goto _test_eof3367 + } + st_case_3367: + if 163 <= data[p] { + goto tr3053 + } + goto tr2985 + st3368: + if p++; p == pe { + goto _test_eof3368 + } + st_case_3368: + if data[p] == 189 { + goto tr2985 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr2985 + } + goto tr3053 + st3369: + if p++; p == pe { + goto _test_eof3369 + } + st_case_3369: + if data[p] == 144 { + goto tr2985 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr2985 + } + case data[p] >= 152: + goto tr2985 + } + goto tr3053 + st3370: + if p++; p == pe { + goto _test_eof3370 + } + st_case_3370: + if data[p] == 188 { + goto tr3053 + } + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr3053 + } + case data[p] >= 129: + goto tr3053 + } + goto tr2985 + st3371: + if p++; p == pe { + goto _test_eof3371 + } + st_case_3371: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr2985 + } + case data[p] >= 133: + goto tr2985 + } + case data[p] > 150: + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr2985 + } + case data[p] >= 152: + goto tr2985 + } + default: + goto tr2985 + } + goto tr3053 + st3372: + if p++; p == pe { + goto _test_eof3372 + } + st_case_3372: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr2985 + } + case data[p] >= 131: + goto tr2985 + } + case data[p] > 144: + switch { + case data[p] < 178: + if 146 <= data[p] && data[p] <= 175 { + goto tr2985 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr2985 + } + default: + goto tr2985 + } + default: + goto tr2985 + } + goto tr3053 + st3373: + if p++; p == pe { + goto _test_eof3373 + } + st_case_3373: + switch data[p] { + case 134: + goto tr2985 + case 138: + goto tr2985 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr2985 + } + case data[p] >= 142: + goto tr2985 + } + goto tr3053 + st3374: + if p++; p == pe { + goto _test_eof3374 + } + st_case_3374: + if data[p] == 188 { + goto tr3053 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr3053 + } + case data[p] >= 129: + goto tr3053 + } + goto tr2985 + st3375: + if p++; p == pe { + goto _test_eof3375 + } + st_case_3375: + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr3053 + } + case data[p] >= 128: + goto tr3053 + } + case data[p] > 141: + switch { + case data[p] > 151: + if 162 <= data[p] && data[p] <= 163 { + goto tr3053 + } + case data[p] >= 150: + goto tr3053 + } + default: + goto tr3053 + } + goto tr2985 + st3376: + if p++; p == pe { + goto _test_eof3376 + } + st_case_3376: + if data[p] == 130 { + goto tr3053 + } + if 190 <= data[p] && data[p] <= 191 { + goto tr3053 + } + goto tr2985 + st3377: + if p++; p == pe { + goto _test_eof3377 + } + st_case_3377: + if data[p] == 151 { + goto tr3053 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr3053 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr3053 + } + default: + goto tr3053 + } + goto tr2985 + st3378: + if p++; p == pe { + goto _test_eof3378 + } + st_case_3378: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr3053 + } + case data[p] >= 128: + goto tr3053 + } + goto tr2985 + st3379: + if p++; p == pe { + goto _test_eof3379 + } + st_case_3379: + switch data[p] { + case 133: + goto tr2985 + case 137: + goto tr2985 + } + switch { + case data[p] < 151: + if 142 <= data[p] && data[p] <= 148 { + goto tr2985 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr2985 + } + default: + goto tr2985 + } + goto tr3053 + st3380: + if p++; p == pe { + goto _test_eof3380 + } + st_case_3380: + switch { + case data[p] < 138: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 136 { + goto tr3053 + } + case data[p] >= 128: + goto tr3053 + } + case data[p] > 141: + switch { + case data[p] > 150: + if 162 <= data[p] && data[p] <= 163 { + goto tr3053 + } + case data[p] >= 149: + goto tr3053 + } + default: + goto tr3053 + } + goto tr2985 + st3381: + if p++; p == pe { + goto _test_eof3381 + } + st_case_3381: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr3053 + } + case data[p] >= 129: + goto tr3053 + } + goto tr2985 + st3382: + if p++; p == pe { + goto _test_eof3382 + } + st_case_3382: + switch data[p] { + case 133: + goto tr2985 + case 137: + goto tr2985 + } + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 150 { + goto tr2985 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr2985 + } + default: + goto tr2985 + } + goto tr3053 + st3383: + if p++; p == pe { + goto _test_eof3383 + } + st_case_3383: + if 130 <= data[p] && data[p] <= 131 { + goto tr3053 + } + goto tr2985 + st3384: + if p++; p == pe { + goto _test_eof3384 + } + st_case_3384: + switch data[p] { + case 138: + goto tr3053 + case 150: + goto tr3053 + } + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 148 { + goto tr3053 + } + case data[p] > 159: + if 178 <= data[p] && data[p] <= 179 { + goto tr3053 + } + default: + goto tr3053 + } + goto tr2985 + st3385: + if p++; p == pe { + goto _test_eof3385 + } + st_case_3385: + if data[p] == 177 { + goto tr3053 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr3053 + } + goto tr2985 + st3386: + if p++; p == pe { + goto _test_eof3386 + } + st_case_3386: + if 135 <= data[p] && data[p] <= 142 { + goto tr3053 + } + goto tr2985 + st3387: + if p++; p == pe { + goto _test_eof3387 + } + st_case_3387: + if data[p] == 177 { + goto tr3053 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr3053 + } + case data[p] >= 180: + goto tr3053 + } + goto tr2985 + st3388: + if p++; p == pe { + goto _test_eof3388 + } + st_case_3388: + if 136 <= data[p] && data[p] <= 141 { + goto tr3053 + } + goto tr2985 + st3389: + if p++; p == pe { + goto _test_eof3389 + } + st_case_3389: + switch data[p] { + case 181: + goto tr3053 + case 183: + goto tr3053 + case 185: + goto tr3053 + } + switch { + case data[p] > 153: + if 190 <= data[p] && data[p] <= 191 { + goto tr3053 + } + case data[p] >= 152: + goto tr3053 + } + goto tr2985 + st3390: + if p++; p == pe { + goto _test_eof3390 + } + st_case_3390: + if 177 <= data[p] && data[p] <= 191 { + goto tr3053 + } + goto tr2985 + st3391: + if p++; p == pe { + goto _test_eof3391 + } + st_case_3391: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr3053 + } + case data[p] > 135: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr3053 + } + case data[p] >= 141: + goto tr3053 + } + default: + goto tr3053 + } + goto tr2985 + st3392: + if p++; p == pe { + goto _test_eof3392 + } + st_case_3392: + if data[p] == 134 { + goto tr3053 + } + goto tr2985 + st3393: + if p++; p == pe { + goto _test_eof3393 + } + st_case_3393: + switch data[p] { + case 128: + goto st3394 + case 129: + goto st3395 + case 130: + goto st3396 + case 132: + goto st3352 + case 135: + goto st3398 + case 141: + goto st3399 + case 156: + goto st3400 + case 157: + goto st3401 + case 158: + goto st3402 + case 159: + goto st3403 + case 160: + goto st3404 + case 162: + goto st3405 + case 164: + goto st3406 + case 168: + goto st3407 + case 169: + goto st3408 + case 170: + goto st3409 + case 172: + goto st3410 + case 173: + goto st3411 + case 174: + goto st3412 + case 175: + goto st3413 + case 176: + goto st3414 + case 179: + goto st3415 + case 183: + goto st3416 + } + if 133 <= data[p] && data[p] <= 134 { + goto st3397 + } + goto tr2985 + st3394: + if p++; p == pe { + goto _test_eof3394 + } + st_case_3394: + if 171 <= data[p] && data[p] <= 190 { + goto tr3053 + } + goto tr2985 + st3395: + if p++; p == pe { + goto _test_eof3395 + } + st_case_3395: + switch { + case data[p] < 162: + switch { + case data[p] > 153: + if 158 <= data[p] && data[p] <= 160 { + goto tr3053 + } + case data[p] >= 150: + goto tr3053 + } + case data[p] > 164: + switch { + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr3053 + } + case data[p] >= 167: + goto tr3053 + } + default: + goto tr3053 + } + goto tr2985 + st3396: + if p++; p == pe { + goto _test_eof3396 + } + st_case_3396: + if data[p] == 143 { + goto tr3053 + } + switch { + case data[p] > 141: + if 154 <= data[p] && data[p] <= 157 { + goto tr3053 + } + case data[p] >= 130: + goto tr3053 + } + goto tr2985 + st3397: + if p++; p == pe { + goto _test_eof3397 + } + st_case_3397: + goto tr3053 + st3398: + if p++; p == pe { + goto _test_eof3398 + } + st_case_3398: + if 192 <= data[p] { + goto tr2985 + } + goto tr3053 + st3399: + if p++; p == pe { + goto _test_eof3399 + } + st_case_3399: + if 157 <= data[p] && data[p] <= 159 { + goto tr3053 + } + goto tr2985 + st3400: + if p++; p == pe { + goto _test_eof3400 + } + st_case_3400: + switch { + case data[p] > 148: + if 178 <= data[p] && data[p] <= 180 { + goto tr3053 + } + case data[p] >= 146: + goto tr3053 + } + goto tr2985 + st3401: + if p++; p == pe { + goto _test_eof3401 + } + st_case_3401: + switch { + case data[p] > 147: + if 178 <= data[p] && data[p] <= 179 { + goto tr3053 + } + case data[p] >= 146: + goto tr3053 + } + goto tr2985 + st3402: + if p++; p == pe { + goto _test_eof3402 + } + st_case_3402: + if 180 <= data[p] { + goto tr3053 + } + goto tr2985 + st3403: + if p++; p == pe { + goto _test_eof3403 + } + st_case_3403: + switch { + case data[p] > 156: + if 158 <= data[p] { + goto tr2985 + } + case data[p] >= 148: + goto tr2985 + } + goto tr3053 + st3404: + if p++; p == pe { + goto _test_eof3404 + } + st_case_3404: + if 139 <= data[p] && data[p] <= 142 { + goto tr3053 + } + goto tr2985 + st3405: + if p++; p == pe { + goto _test_eof3405 + } + st_case_3405: + if data[p] == 169 { + goto tr3053 + } + goto tr2985 + st3406: + if p++; p == pe { + goto _test_eof3406 + } + st_case_3406: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr3053 + } + case data[p] >= 160: + goto tr3053 + } + goto tr2985 + st3407: + if p++; p == pe { + goto _test_eof3407 + } + st_case_3407: + if 151 <= data[p] && data[p] <= 155 { + goto tr3053 + } + goto tr2985 + st3408: + if p++; p == pe { + goto _test_eof3408 + } + st_case_3408: + if data[p] == 191 { + goto tr3053 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr3053 + } + case data[p] >= 149: + goto tr3053 + } + goto tr2985 + st3409: + if p++; p == pe { + goto _test_eof3409 + } + st_case_3409: + if 176 <= data[p] && data[p] <= 190 { + goto tr3053 + } + goto tr2985 + st3410: + if p++; p == pe { + goto _test_eof3410 + } + st_case_3410: + switch { + case data[p] > 132: + if 180 <= data[p] { + goto tr3053 + } + case data[p] >= 128: + goto tr3053 + } + goto tr2985 + st3411: + if p++; p == pe { + goto _test_eof3411 + } + st_case_3411: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr2985 + } + case data[p] >= 133: + goto tr2985 + } + goto tr3053 + st3412: + if p++; p == pe { + goto _test_eof3412 + } + st_case_3412: + switch { + case data[p] > 130: + if 161 <= data[p] && data[p] <= 173 { + goto tr3053 + } + case data[p] >= 128: + goto tr3053 + } + goto tr2985 + st3413: + if p++; p == pe { + goto _test_eof3413 + } + st_case_3413: + if 166 <= data[p] && data[p] <= 179 { + goto tr3053 + } + goto tr2985 + st3414: + if p++; p == pe { + goto _test_eof3414 + } + st_case_3414: + if 164 <= data[p] && data[p] <= 183 { + goto tr3053 + } + goto tr2985 + st3415: + if p++; p == pe { + goto _test_eof3415 + } + st_case_3415: + if data[p] == 173 { + goto tr3053 + } + switch { + case data[p] < 148: + if 144 <= data[p] && data[p] <= 146 { + goto tr3053 + } + case data[p] > 168: + switch { + case data[p] > 180: + if 184 <= data[p] && data[p] <= 185 { + goto tr3053 + } + case data[p] >= 178: + goto tr3053 + } + default: + goto tr3053 + } + goto tr2985 + st3416: + if p++; p == pe { + goto _test_eof3416 + } + st_case_3416: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr3053 + } + case data[p] >= 128: + goto tr3053 + } + goto tr2985 + st3417: + if p++; p == pe { + goto _test_eof3417 + } + st_case_3417: + switch data[p] { + case 128: + goto st3418 + case 129: + goto st3419 + case 131: + goto st3420 + case 179: + goto st3421 + case 181: + goto st3422 + case 183: + goto st3423 + } + goto tr2985 + st3418: + if p++; p == pe { + goto _test_eof3418 + } + st_case_3418: + switch { + case data[p] > 143: + if 170 <= data[p] && data[p] <= 174 { + goto tr3053 + } + case data[p] >= 140: + goto tr3053 + } + goto tr2985 + st3419: + if p++; p == pe { + goto _test_eof3419 + } + st_case_3419: + switch { + case data[p] > 164: + if 166 <= data[p] && data[p] <= 175 { + goto tr3053 + } + case data[p] >= 160: + goto tr3053 + } + goto tr2985 + st3420: + if p++; p == pe { + goto _test_eof3420 + } + st_case_3420: + if 144 <= data[p] && data[p] <= 176 { + goto tr3053 + } + goto tr2985 + st3421: + if p++; p == pe { + goto _test_eof3421 + } + st_case_3421: + if 175 <= data[p] && data[p] <= 177 { + goto tr3053 + } + goto tr2985 + st3422: + if p++; p == pe { + goto _test_eof3422 + } + st_case_3422: + if data[p] == 191 { + goto tr3053 + } + goto tr2985 + st3423: + if p++; p == pe { + goto _test_eof3423 + } + st_case_3423: + if 160 <= data[p] && data[p] <= 191 { + goto tr3053 + } + goto tr2985 + st3424: + if p++; p == pe { + goto _test_eof3424 + } + st_case_3424: + switch data[p] { + case 128: + goto st3425 + case 130: + goto st3426 + case 132: + goto st3427 + case 133: + goto st3397 + case 134: + goto st3428 + case 136: + goto st3350 + case 137: + goto st3429 + } + goto tr2985 + st3425: + if p++; p == pe { + goto _test_eof3425 + } + st_case_3425: + if 170 <= data[p] && data[p] <= 175 { + goto tr3053 + } + goto tr2985 + st3426: + if p++; p == pe { + goto _test_eof3426 + } + st_case_3426: + if 153 <= data[p] && data[p] <= 154 { + goto tr3053 + } + goto tr2985 + st3427: + if p++; p == pe { + goto _test_eof3427 + } + st_case_3427: + if 177 <= data[p] { + goto tr3053 + } + goto tr2985 + st3428: + if p++; p == pe { + goto _test_eof3428 + } + st_case_3428: + if 143 <= data[p] { + goto tr2985 + } + goto tr3053 + st3429: + if p++; p == pe { + goto _test_eof3429 + } + st_case_3429: + if 160 <= data[p] && data[p] <= 190 { + goto tr3053 + } + goto tr2 + st3430: + if p++; p == pe { + goto _test_eof3430 + } + st_case_3430: + switch data[p] { + case 153: + goto st3431 + case 154: + goto st3432 + case 155: + goto st3433 + case 160: + goto st3434 + case 162: + goto st3435 + case 163: + goto st3436 + case 164: + goto st3437 + case 165: + goto st3438 + case 166: + goto st3439 + case 167: + goto st3440 + case 168: + goto st3441 + case 169: + goto st3442 + case 170: + goto st3443 + case 171: + goto st3444 + case 175: + goto st3445 + case 176: + goto st3352 + } + if 177 <= data[p] { + goto st3397 + } + goto tr2985 + st3431: + if p++; p == pe { + goto _test_eof3431 + } + st_case_3431: + switch { + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr3053 + } + case data[p] >= 175: + goto tr3053 + } + goto tr2985 + st3432: + if p++; p == pe { + goto _test_eof3432 + } + st_case_3432: + if 158 <= data[p] && data[p] <= 159 { + goto tr3053 + } + goto tr2985 + st3433: + if p++; p == pe { + goto _test_eof3433 + } + st_case_3433: + if 176 <= data[p] && data[p] <= 177 { + goto tr3053 + } + goto tr2985 + st3434: + if p++; p == pe { + goto _test_eof3434 + } + st_case_3434: + switch data[p] { + case 130: + goto tr3053 + case 134: + goto tr3053 + case 139: + goto tr3053 + } + if 163 <= data[p] && data[p] <= 167 { + goto tr3053 + } + goto tr2985 + st3435: + if p++; p == pe { + goto _test_eof3435 + } + st_case_3435: + switch { + case data[p] > 129: + if 180 <= data[p] { + goto tr3053 + } + case data[p] >= 128: + goto tr3053 + } + goto tr2985 + st3436: + if p++; p == pe { + goto _test_eof3436 + } + st_case_3436: + switch { + case data[p] > 159: + if 178 <= data[p] { + goto tr2985 + } + case data[p] >= 133: + goto tr2985 + } + goto tr3053 + st3437: + if p++; p == pe { + goto _test_eof3437 + } + st_case_3437: + if 166 <= data[p] && data[p] <= 173 { + goto tr3053 + } + goto tr2985 + st3438: + if p++; p == pe { + goto _test_eof3438 + } + st_case_3438: + switch { + case data[p] > 147: + if 160 <= data[p] && data[p] <= 188 { + goto tr3053 + } + case data[p] >= 135: + goto tr3053 + } + goto tr2985 + st3439: + if p++; p == pe { + goto _test_eof3439 + } + st_case_3439: + switch { + case data[p] > 131: + if 179 <= data[p] { + goto tr3053 + } + case data[p] >= 128: + goto tr3053 + } + goto tr2985 + st3440: + if p++; p == pe { + goto _test_eof3440 + } + st_case_3440: + switch { + case data[p] > 164: + if 166 <= data[p] { + goto tr2985 + } + case data[p] >= 129: + goto tr2985 + } + goto tr3053 + st3441: + if p++; p == pe { + goto _test_eof3441 + } + st_case_3441: + if 169 <= data[p] && data[p] <= 182 { + goto tr3053 + } + goto tr2985 + st3442: + if p++; p == pe { + goto _test_eof3442 + } + st_case_3442: + if data[p] == 131 { + goto tr3053 + } + switch { + case data[p] > 141: + if 187 <= data[p] && data[p] <= 189 { + goto tr3053 + } + case data[p] >= 140: + goto tr3053 + } + goto tr2985 + st3443: + if p++; p == pe { + goto _test_eof3443 + } + st_case_3443: + if data[p] == 176 { + goto tr3053 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr3053 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr3053 + } + default: + goto tr3053 + } + goto tr2985 + st3444: + if p++; p == pe { + goto _test_eof3444 + } + st_case_3444: + if data[p] == 129 { + goto tr3053 + } + switch { + case data[p] > 175: + if 181 <= data[p] && data[p] <= 182 { + goto tr3053 + } + case data[p] >= 171: + goto tr3053 + } + goto tr2985 + st3445: + if p++; p == pe { + goto _test_eof3445 + } + st_case_3445: + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 173 { + goto tr3053 + } + case data[p] >= 163: + goto tr3053 + } + goto tr2985 + st3446: + if p++; p == pe { + goto _test_eof3446 + } + st_case_3446: + goto st3397 + st3447: + if p++; p == pe { + goto _test_eof3447 + } + st_case_3447: + switch data[p] { + case 158: + goto st3448 + case 159: + goto st3449 + } + if 160 <= data[p] { + goto tr2985 + } + goto st3397 + st3448: + if p++; p == pe { + goto _test_eof3448 + } + st_case_3448: + if 164 <= data[p] && data[p] <= 175 { + goto tr2985 + } + goto tr3053 + st3449: + if p++; p == pe { + goto _test_eof3449 + } + st_case_3449: + switch { + case data[p] > 138: + if 188 <= data[p] { + goto tr2985 + } + case data[p] >= 135: + goto tr2985 + } + goto tr3053 + st3450: + if p++; p == pe { + goto _test_eof3450 + } + st_case_3450: + switch data[p] { + case 172: + goto st3451 + case 184: + goto st3452 + case 187: + goto st3422 + case 190: + goto st3453 + case 191: + goto st3454 + } + goto tr2985 + st3451: + if p++; p == pe { + goto _test_eof3451 + } + st_case_3451: + if data[p] == 158 { + goto tr3053 + } + goto tr2985 + st3452: + if p++; p == pe { + goto _test_eof3452 + } + st_case_3452: + switch { + case data[p] > 143: + if 160 <= data[p] && data[p] <= 175 { + goto tr3053 + } + case data[p] >= 128: + goto tr3053 + } + goto tr2985 + st3453: + if p++; p == pe { + goto _test_eof3453 + } + st_case_3453: + if 158 <= data[p] && data[p] <= 190 { + goto tr3053 + } + goto tr2985 + st3454: + if p++; p == pe { + goto _test_eof3454 + } + st_case_3454: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr3053 + } + case data[p] >= 130: + goto tr3053 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr3053 + } + case data[p] >= 154: + goto tr3053 + } + default: + goto tr3053 + } + goto tr2985 + st3455: + if p++; p == pe { + goto _test_eof3455 + } + st_case_3455: + switch data[p] { + case 144: + goto st3456 + case 145: + goto st3462 + case 150: + goto st3481 + case 155: + goto st3486 + case 157: + goto st3488 + case 158: + goto st3495 + } + goto tr2985 + st3456: + if p++; p == pe { + goto _test_eof3456 + } + st_case_3456: + switch data[p] { + case 135: + goto st3457 + case 139: + goto st3458 + case 141: + goto st3459 + case 168: + goto st3460 + case 171: + goto st3461 + } + goto tr2985 + st3457: + if p++; p == pe { + goto _test_eof3457 + } + st_case_3457: + if data[p] == 189 { + goto tr3053 + } + goto tr2985 + st3458: + if p++; p == pe { + goto _test_eof3458 + } + st_case_3458: + if data[p] == 160 { + goto tr3053 + } + goto tr2985 + st3459: + if p++; p == pe { + goto _test_eof3459 + } + st_case_3459: + if 182 <= data[p] && data[p] <= 186 { + goto tr3053 + } + goto tr2985 + st3460: + if p++; p == pe { + goto _test_eof3460 + } + st_case_3460: + if data[p] == 191 { + goto tr3053 + } + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr3053 + } + case data[p] > 134: + switch { + case data[p] > 143: + if 184 <= data[p] && data[p] <= 186 { + goto tr3053 + } + case data[p] >= 140: + goto tr3053 + } + default: + goto tr3053 + } + goto tr2985 + st3461: + if p++; p == pe { + goto _test_eof3461 + } + st_case_3461: + if 165 <= data[p] && data[p] <= 166 { + goto tr3053 + } + goto tr2985 + st3462: + if p++; p == pe { + goto _test_eof3462 + } + st_case_3462: + switch data[p] { + case 128: + goto st3463 + case 129: + goto st3464 + case 130: + goto st3465 + case 132: + goto st3466 + case 133: + goto st3467 + case 134: + goto st3468 + case 135: + goto st3469 + case 136: + goto st3470 + case 139: + goto st3471 + case 140: + goto st3472 + case 141: + goto st3473 + case 146: + goto st3474 + case 147: + goto st3475 + case 150: + goto st3476 + case 151: + goto st3477 + case 152: + goto st3474 + case 153: + goto st3478 + case 154: + goto st3479 + case 156: + goto st3480 + } + goto tr2985 + st3463: + if p++; p == pe { + goto _test_eof3463 + } + st_case_3463: + switch { + case data[p] > 130: + if 184 <= data[p] { + goto tr3053 + } + case data[p] >= 128: + goto tr3053 + } + goto tr2985 + st3464: + if p++; p == pe { + goto _test_eof3464 + } + st_case_3464: + if 135 <= data[p] && data[p] <= 190 { + goto tr2985 + } + goto tr3053 + st3465: + if p++; p == pe { + goto _test_eof3465 + } + st_case_3465: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr2985 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr2985 + } + default: + goto tr2985 + } + goto tr3053 + st3466: + if p++; p == pe { + goto _test_eof3466 + } + st_case_3466: + switch { + case data[p] > 130: + if 167 <= data[p] && data[p] <= 180 { + goto tr3053 + } + case data[p] >= 128: + goto tr3053 + } + goto tr2985 + st3467: + if p++; p == pe { + goto _test_eof3467 + } + st_case_3467: + if data[p] == 179 { + goto tr3053 + } + goto tr2985 + st3468: + if p++; p == pe { + goto _test_eof3468 + } + st_case_3468: + switch { + case data[p] > 130: + if 179 <= data[p] { + goto tr3053 + } + case data[p] >= 128: + goto tr3053 + } + goto tr2985 + st3469: + if p++; p == pe { + goto _test_eof3469 + } + st_case_3469: + switch { + case data[p] > 137: + if 141 <= data[p] { + goto tr2985 + } + case data[p] >= 129: + goto tr2985 + } + goto tr3053 + st3470: + if p++; p == pe { + goto _test_eof3470 + } + st_case_3470: + if 172 <= data[p] && data[p] <= 183 { + goto tr3053 + } + goto tr2985 + st3471: + if p++; p == pe { + goto _test_eof3471 + } + st_case_3471: + if 159 <= data[p] && data[p] <= 170 { + goto tr3053 + } + goto tr2985 + st3472: + if p++; p == pe { + goto _test_eof3472 + } + st_case_3472: + if data[p] == 188 { + goto tr3053 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr3053 + } + case data[p] >= 128: + goto tr3053 + } + goto tr2985 + st3473: + if p++; p == pe { + goto _test_eof3473 + } + st_case_3473: + if data[p] == 151 { + goto tr3053 + } + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr3053 + } + case data[p] >= 128: + goto tr3053 + } + case data[p] > 141: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr3053 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr3053 + } + default: + goto tr3053 + } + default: + goto tr3053 + } + goto tr2985 + st3474: + if p++; p == pe { + goto _test_eof3474 + } + st_case_3474: + if 176 <= data[p] { + goto tr3053 + } + goto tr2985 + st3475: + if p++; p == pe { + goto _test_eof3475 + } + st_case_3475: + if 132 <= data[p] { + goto tr2985 + } + goto tr3053 + st3476: + if p++; p == pe { + goto _test_eof3476 + } + st_case_3476: + switch { + case data[p] > 181: + if 184 <= data[p] { + goto tr3053 + } + case data[p] >= 175: + goto tr3053 + } + goto tr2985 + st3477: + if p++; p == pe { + goto _test_eof3477 + } + st_case_3477: + switch { + case data[p] > 155: + if 158 <= data[p] { + goto tr2985 + } + case data[p] >= 129: + goto tr2985 + } + goto tr3053 + st3478: + if p++; p == pe { + goto _test_eof3478 + } + st_case_3478: + if 129 <= data[p] { + goto tr2985 + } + goto tr3053 + st3479: + if p++; p == pe { + goto _test_eof3479 + } + st_case_3479: + if 171 <= data[p] && data[p] <= 183 { + goto tr3053 + } + goto tr2985 + st3480: + if p++; p == pe { + goto _test_eof3480 + } + st_case_3480: + if 157 <= data[p] && data[p] <= 171 { + goto tr3053 + } + goto tr2985 + st3481: + if p++; p == pe { + goto _test_eof3481 + } + st_case_3481: + switch data[p] { + case 171: + goto st3482 + case 172: + goto st3483 + case 189: + goto st3484 + case 190: + goto st3485 + } + goto tr2985 + st3482: + if p++; p == pe { + goto _test_eof3482 + } + st_case_3482: + if 176 <= data[p] && data[p] <= 180 { + goto tr3053 + } + goto tr2985 + st3483: + if p++; p == pe { + goto _test_eof3483 + } + st_case_3483: + if 176 <= data[p] && data[p] <= 182 { + goto tr3053 + } + goto tr2985 + st3484: + if p++; p == pe { + goto _test_eof3484 + } + st_case_3484: + if 145 <= data[p] && data[p] <= 190 { + goto tr3053 + } + goto tr2985 + st3485: + if p++; p == pe { + goto _test_eof3485 + } + st_case_3485: + if 143 <= data[p] && data[p] <= 146 { + goto tr3053 + } + goto tr2985 + st3486: + if p++; p == pe { + goto _test_eof3486 + } + st_case_3486: + if data[p] == 178 { + goto st3487 + } + goto tr2985 + st3487: + if p++; p == pe { + goto _test_eof3487 + } + st_case_3487: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr3053 + } + case data[p] >= 157: + goto tr3053 + } + goto tr2985 + st3488: + if p++; p == pe { + goto _test_eof3488 + } + st_case_3488: + switch data[p] { + case 133: + goto st3489 + case 134: + goto st3490 + case 137: + goto st3491 + case 168: + goto st3492 + case 169: + goto st3493 + case 170: + goto st3494 + } + goto tr2985 + st3489: + if p++; p == pe { + goto _test_eof3489 + } + st_case_3489: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr3053 + } + case data[p] >= 165: + goto tr3053 + } + goto tr2985 + st3490: + if p++; p == pe { + goto _test_eof3490 + } + st_case_3490: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr2985 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr2985 + } + default: + goto tr2985 + } + goto tr3053 + st3491: + if p++; p == pe { + goto _test_eof3491 + } + st_case_3491: + if 130 <= data[p] && data[p] <= 132 { + goto tr3053 + } + goto tr2985 + st3492: + if p++; p == pe { + goto _test_eof3492 + } + st_case_3492: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr3053 + } + case data[p] >= 128: + goto tr3053 + } + goto tr2985 + st3493: + if p++; p == pe { + goto _test_eof3493 + } + st_case_3493: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr2985 + } + case data[p] >= 173: + goto tr2985 + } + goto tr3053 + st3494: + if p++; p == pe { + goto _test_eof3494 + } + st_case_3494: + if data[p] == 132 { + goto tr3053 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr3053 + } + case data[p] >= 155: + goto tr3053 + } + goto tr2985 + st3495: + if p++; p == pe { + goto _test_eof3495 + } + st_case_3495: + if data[p] == 163 { + goto st3496 + } + goto tr2985 + st3496: + if p++; p == pe { + goto _test_eof3496 + } + st_case_3496: + if 144 <= data[p] && data[p] <= 150 { + goto tr3053 + } + goto tr2985 + st3497: + if p++; p == pe { + goto _test_eof3497 + } + st_case_3497: + if data[p] == 160 { + goto st3498 + } + goto tr2985 + st3498: + if p++; p == pe { + goto _test_eof3498 + } + st_case_3498: + switch data[p] { + case 128: + goto st3499 + case 129: + goto st3398 + case 132: + goto st3352 + case 135: + goto st3353 + } + if 133 <= data[p] && data[p] <= 134 { + goto st3397 + } + goto tr2985 + st3499: + if p++; p == pe { + goto _test_eof3499 + } + st_case_3499: + if data[p] == 129 { + goto tr3053 + } + if 160 <= data[p] { + goto tr3053 + } + goto tr2985 + st3500: + if p++; p == pe { + goto _test_eof3500 + } + st_case_3500: + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st654 + case 153: + goto st3501 + case 154: + goto st3502 + case 155: + goto st3503 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st3504 + case 161: + goto st272 + case 162: + goto st3505 + case 163: + goto st3506 + case 164: + goto st3507 + case 165: + goto st3508 + case 166: + goto st3509 + case 167: + goto st3510 + case 168: + goto st3511 + case 169: + goto st3512 + case 170: + goto st3513 + case 171: + goto st3514 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st3515 + case 176: + goto st3270 + } + switch { + case data[p] > 157: + if 177 <= data[p] { + goto st3318 + } + case data[p] >= 129: + goto st145 + } + goto tr2985 + st3501: + if p++; p == pe { + goto _test_eof3501 + } + st_case_3501: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr2984 + } + default: + goto tr2984 + } + goto tr2 + st3502: + if p++; p == pe { + goto _test_eof3502 + } + st_case_3502: + switch { + case data[p] < 158: + if 128 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr2984 + } + goto tr2 + st3503: + if p++; p == pe { + goto _test_eof3503 + } + st_case_3503: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr2 + } + case data[p] >= 176: + goto tr2984 + } + goto tr148 + st3504: + if p++; p == pe { + goto _test_eof3504 + } + st_case_3504: + switch data[p] { + case 130: + goto tr2984 + case 134: + goto tr2984 + case 139: + goto tr2984 + } + switch { + case data[p] > 167: + if 168 <= data[p] { + goto tr2 + } + case data[p] >= 163: + goto tr2984 + } + goto tr148 + st3505: + if p++; p == pe { + goto _test_eof3505 + } + st_case_3505: + switch { + case data[p] < 130: + if 128 <= data[p] && data[p] <= 129 { + goto tr2984 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr2984 + } + default: + goto tr148 + } + goto tr2 + st3506: + if p++; p == pe { + goto _test_eof3506 + } + st_case_3506: + switch data[p] { + case 187: + goto tr148 + case 189: + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 143: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 133: + goto tr2 + } + case data[p] > 159: + switch { + case data[p] > 183: + if 184 <= data[p] { + goto tr2 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr2 + } + goto tr2984 + st3507: + if p++; p == pe { + goto _test_eof3507 + } + st_case_3507: + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 165: + switch { + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr2984 + } + default: + goto tr148 + } + goto tr2 + st3508: + if p++; p == pe { + goto _test_eof3508 + } + st_case_3508: + switch { + case data[p] < 148: + if 135 <= data[p] && data[p] <= 147 { + goto tr2984 + } + case data[p] > 159: + switch { + case data[p] > 188: + if 189 <= data[p] { + goto tr2 + } + case data[p] >= 160: + goto tr2984 + } + default: + goto tr2 + } + goto tr148 + st3509: + if p++; p == pe { + goto _test_eof3509 + } + st_case_3509: + switch { + case data[p] < 132: + if 128 <= data[p] && data[p] <= 131 { + goto tr2984 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr2984 + } + default: + goto tr148 + } + goto tr2 + st3510: + if p++; p == pe { + goto _test_eof3510 + } + st_case_3510: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 129: + goto tr2 + } + case data[p] > 164: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr2 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr2 + } + default: + goto tr421 + } + default: + goto tr2 + } + goto tr2984 + st3511: + if p++; p == pe { + goto _test_eof3511 + } + st_case_3511: + switch { + case data[p] > 168: + if 169 <= data[p] && data[p] <= 182 { + goto tr2984 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st3512: + if p++; p == pe { + goto _test_eof3512 + } + st_case_3512: + if data[p] == 131 { + goto tr2984 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 141: + switch { + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto tr2984 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr2984 + } + goto tr2 + st3513: + if p++; p == pe { + goto _test_eof3513 + } + st_case_3513: + if data[p] == 176 { + goto tr2984 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr2984 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr2984 + } + default: + goto tr2984 + } + goto tr2 + st3514: + if p++; p == pe { + goto _test_eof3514 + } + st_case_3514: + if data[p] == 129 { + goto tr2984 + } + switch { + case data[p] < 171: + if 160 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 181 <= data[p] && data[p] <= 182 { + goto tr2984 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr2984 + } + goto tr2 + st3515: + if p++; p == pe { + goto _test_eof3515 + } + st_case_3515: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 162 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 172: + goto tr2984 + } + default: + goto tr2984 + } + goto tr2 + st3516: + if p++; p == pe { + goto _test_eof3516 + } + st_case_3516: + goto st3318 + st3517: + if p++; p == pe { + goto _test_eof3517 + } + st_case_3517: + switch data[p] { + case 158: + goto st3518 + case 159: + goto st3519 + } + if 160 <= data[p] { + goto tr2985 + } + goto st3318 + st3518: + if p++; p == pe { + goto _test_eof3518 + } + st_case_3518: + if 164 <= data[p] && data[p] <= 175 { + goto tr2 + } + goto tr2984 + st3519: + if p++; p == pe { + goto _test_eof3519 + } + st_case_3519: + switch { + case data[p] > 138: + if 188 <= data[p] { + goto tr2 + } + case data[p] >= 135: + goto tr2 + } + goto tr2984 + st3520: + if p++; p == pe { + goto _test_eof3520 + } + st_case_3520: + switch data[p] { + case 172: + goto st3521 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st3522 + case 185: + goto st967 + case 187: + goto st3523 + case 188: + goto st969 + case 189: + goto st303 + case 190: + goto st3524 + case 191: + goto st3525 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr2985 + st3521: + if p++; p == pe { + goto _test_eof3521 + } + st_case_3521: + switch data[p] { + case 158: + goto tr2984 + case 190: + goto tr572 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 170: + goto tr572 + } + default: + goto tr572 + } + goto tr2 + st3522: + if p++; p == pe { + goto _test_eof3522 + } + st_case_3522: + if data[p] == 147 { + goto st142 + } + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr2984 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr571 + } + default: + goto tr2984 + } + goto tr2 + st3523: + if p++; p == pe { + goto _test_eof3523 + } + st_case_3523: + if data[p] == 191 { + goto tr2984 + } + if 189 <= data[p] { + goto tr2 + } + goto tr148 + st3524: + if p++; p == pe { + goto _test_eof3524 + } + st_case_3524: + if 158 <= data[p] && data[p] <= 190 { + goto tr2984 + } + goto tr2 + st3525: + if p++; p == pe { + goto _test_eof3525 + } + st_case_3525: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr2984 + } + case data[p] >= 130: + goto tr2984 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr2984 + } + case data[p] >= 154: + goto tr2984 + } + default: + goto tr2984 + } + goto tr2 + st3526: + if p++; p == pe { + goto _test_eof3526 + } + st_case_3526: + switch data[p] { + case 144: + goto st3527 + case 145: + goto st3533 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st3552 + case 155: + goto st3557 + case 157: + goto st3559 + case 158: + goto st3566 + case 159: + goto st403 + } + goto tr2985 + st3527: + if p++; p == pe { + goto _test_eof3527 + } + st_case_3527: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st3528 + case 138: + goto st313 + case 139: + goto st3529 + case 140: + goto st315 + case 141: + goto st3530 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st684 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st3531 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st3532 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr2 + st3528: + if p++; p == pe { + goto _test_eof3528 + } + st_case_3528: + if data[p] == 189 { + goto tr2984 + } + goto tr2 + st3529: + if p++; p == pe { + goto _test_eof3529 + } + st_case_3529: + if data[p] == 160 { + goto tr2984 + } + if 145 <= data[p] { + goto tr2 + } + goto tr148 + st3530: + if p++; p == pe { + goto _test_eof3530 + } + st_case_3530: + switch { + case data[p] < 182: + if 139 <= data[p] && data[p] <= 143 { + goto tr2 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr2 + } + default: + goto tr2984 + } + goto tr148 + st3531: + if p++; p == pe { + goto _test_eof3531 + } + st_case_3531: + switch data[p] { + case 128: + goto tr148 + case 191: + goto tr2984 + } + switch { + case data[p] < 144: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2984 + } + case data[p] > 134: + if 140 <= data[p] && data[p] <= 143 { + goto tr2984 + } + default: + goto tr2984 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto tr2984 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st3532: + if p++; p == pe { + goto _test_eof3532 + } + st_case_3532: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 164: + if 165 <= data[p] && data[p] <= 166 { + goto tr2984 + } + default: + goto tr148 + } + goto tr2 + st3533: + if p++; p == pe { + goto _test_eof3533 + } + st_case_3533: + switch data[p] { + case 128: + goto st3534 + case 129: + goto st3535 + case 130: + goto st3536 + case 131: + goto st691 + case 132: + goto st3537 + case 133: + goto st3538 + case 134: + goto st3539 + case 135: + goto st3540 + case 136: + goto st3541 + case 138: + goto st348 + case 139: + goto st3542 + case 140: + goto st3543 + case 141: + goto st3544 + case 146: + goto st3545 + case 147: + goto st3546 + case 150: + goto st3547 + case 151: + goto st3548 + case 152: + goto st3545 + case 153: + goto st3549 + case 154: + goto st3550 + case 155: + goto st538 + case 156: + goto st3551 + case 162: + goto st359 + case 163: + goto st707 + case 171: + goto st361 + } + goto tr2 + st3534: + if p++; p == pe { + goto _test_eof3534 + } + st_case_3534: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2984 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr2984 + } + default: + goto tr148 + } + goto tr2 + st3535: + if p++; p == pe { + goto _test_eof3535 + } + st_case_3535: + switch { + case data[p] < 166: + if 135 <= data[p] && data[p] <= 165 { + goto tr2 + } + case data[p] > 175: + if 176 <= data[p] && data[p] <= 190 { + goto tr2 + } + default: + goto tr421 + } + goto tr2984 + st3536: + if p++; p == pe { + goto _test_eof3536 + } + st_case_3536: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr2984 + st3537: + if p++; p == pe { + goto _test_eof3537 + } + st_case_3537: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2984 + } + case data[p] > 166: + switch { + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr421 + } + case data[p] >= 167: + goto tr2984 + } + default: + goto tr148 + } + goto tr2 + st3538: + if p++; p == pe { + goto _test_eof3538 + } + st_case_3538: + switch data[p] { + case 179: + goto tr2984 + case 182: + goto tr148 + } + if 144 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr2 + st3539: + if p++; p == pe { + goto _test_eof3539 + } + st_case_3539: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2984 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr2984 + } + default: + goto tr148 + } + goto tr2 + st3540: + if p++; p == pe { + goto _test_eof3540 + } + st_case_3540: + if data[p] == 155 { + goto tr2 + } + switch { + case data[p] < 141: + switch { + case data[p] > 132: + if 133 <= data[p] && data[p] <= 137 { + goto tr2 + } + case data[p] >= 129: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] < 154: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] > 156: + if 157 <= data[p] { + goto tr2 + } + default: + goto tr148 + } + default: + goto tr2 + } + goto tr2984 + st3541: + if p++; p == pe { + goto _test_eof3541 + } + st_case_3541: + switch { + case data[p] < 147: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] > 171: + if 172 <= data[p] && data[p] <= 183 { + goto tr2984 + } + default: + goto tr148 + } + goto tr2 + st3542: + if p++; p == pe { + goto _test_eof3542 + } + st_case_3542: + switch { + case data[p] < 171: + if 159 <= data[p] && data[p] <= 170 { + goto tr2984 + } + case data[p] > 175: + switch { + case data[p] > 185: + if 186 <= data[p] { + goto tr2 + } + case data[p] >= 176: + goto tr421 + } + default: + goto tr2 + } + goto tr148 + st3543: + if p++; p == pe { + goto _test_eof3543 + } + st_case_3543: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto tr2984 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2984 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2 + st3544: + if p++; p == pe { + goto _test_eof3544 + } + st_case_3544: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr2984 + } + switch { + case data[p] < 157: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr2984 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr2984 + } + default: + goto tr2984 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr2984 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr2984 + } + default: + goto tr2984 + } + default: + goto tr148 + } + goto tr2 + st3545: + if p++; p == pe { + goto _test_eof3545 + } + st_case_3545: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr2984 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st3546: + if p++; p == pe { + goto _test_eof3546 + } + st_case_3546: + if data[p] == 134 { + goto tr2 + } + switch { + case data[p] < 136: + if 132 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] { + goto tr2 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr2 + } + goto tr2984 + st3547: + if p++; p == pe { + goto _test_eof3547 + } + st_case_3547: + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 181: + if 184 <= data[p] { + goto tr2984 + } + default: + goto tr2984 + } + goto tr2 + st3548: + if p++; p == pe { + goto _test_eof3548 + } + st_case_3548: + switch { + case data[p] < 152: + if 129 <= data[p] && data[p] <= 151 { + goto tr2 + } + case data[p] > 155: + if 158 <= data[p] { + goto tr2 + } + default: + goto tr148 + } + goto tr2984 + st3549: + if p++; p == pe { + goto _test_eof3549 + } + st_case_3549: + if data[p] == 132 { + goto tr148 + } + switch { + case data[p] < 144: + if 129 <= data[p] && data[p] <= 143 { + goto tr2 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr2 + } + default: + goto tr421 + } + goto tr2984 + st3550: + if p++; p == pe { + goto _test_eof3550 + } + st_case_3550: + switch { + case data[p] > 170: + if 171 <= data[p] && data[p] <= 183 { + goto tr2984 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st3551: + if p++; p == pe { + goto _test_eof3551 + } + st_case_3551: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 157: + goto tr2984 + } + goto tr2 + st3552: + if p++; p == pe { + goto _test_eof3552 + } + st_case_3552: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st709 + case 171: + goto st3553 + case 172: + goto st3554 + case 173: + goto st712 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st3555 + case 190: + goto st3556 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr2 + st3553: + if p++; p == pe { + goto _test_eof3553 + } + st_case_3553: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto tr2984 + } + case data[p] >= 144: + goto tr148 + } + goto tr2 + st3554: + if p++; p == pe { + goto _test_eof3554 + } + st_case_3554: + switch { + case data[p] > 175: + if 176 <= data[p] && data[p] <= 182 { + goto tr2984 + } + case data[p] >= 128: + goto tr148 + } + goto tr2 + st3555: + if p++; p == pe { + goto _test_eof3555 + } + st_case_3555: + switch { + case data[p] < 145: + if 133 <= data[p] && data[p] <= 143 { + goto tr2 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr2 + } + default: + goto tr2984 + } + goto tr148 + st3556: + if p++; p == pe { + goto _test_eof3556 + } + st_case_3556: + switch { + case data[p] > 146: + if 147 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 143: + goto tr2984 + } + goto tr2 + st3557: + if p++; p == pe { + goto _test_eof3557 + } + st_case_3557: + switch data[p] { + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st3558 + } + goto tr2 + st3558: + if p++; p == pe { + goto _test_eof3558 + } + st_case_3558: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr2984 + } + case data[p] >= 157: + goto tr2984 + } + default: + goto tr148 + } + goto tr2 + st3559: + if p++; p == pe { + goto _test_eof3559 + } + st_case_3559: + switch data[p] { + case 133: + goto st3560 + case 134: + goto st3561 + case 137: + goto st3562 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st721 + case 168: + goto st3563 + case 169: + goto st3564 + case 170: + goto st3565 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr2 + st3560: + if p++; p == pe { + goto _test_eof3560 + } + st_case_3560: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr2984 + } + case data[p] >= 165: + goto tr2984 + } + goto tr2 + st3561: + if p++; p == pe { + goto _test_eof3561 + } + st_case_3561: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr2 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr2984 + st3562: + if p++; p == pe { + goto _test_eof3562 + } + st_case_3562: + if 130 <= data[p] && data[p] <= 132 { + goto tr2984 + } + goto tr2 + st3563: + if p++; p == pe { + goto _test_eof3563 + } + st_case_3563: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr2984 + } + case data[p] >= 128: + goto tr2984 + } + goto tr2 + st3564: + if p++; p == pe { + goto _test_eof3564 + } + st_case_3564: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr2 + } + case data[p] >= 173: + goto tr2 + } + goto tr2984 + st3565: + if p++; p == pe { + goto _test_eof3565 + } + st_case_3565: + if data[p] == 132 { + goto tr2984 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr2984 + } + case data[p] >= 155: + goto tr2984 + } + goto tr2 + st3566: + if p++; p == pe { + goto _test_eof3566 + } + st_case_3566: + switch data[p] { + case 160: + goto st147 + case 163: + goto st3567 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr2 + st3567: + if p++; p == pe { + goto _test_eof3567 + } + st_case_3567: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr2 + } + case data[p] > 150: + if 151 <= data[p] { + goto tr2 + } + default: + goto tr2984 + } + goto tr148 + st3568: + if p++; p == pe { + goto _test_eof3568 + } + st_case_3568: + if data[p] == 160 { + goto st3569 + } + goto tr2985 + st3569: + if p++; p == pe { + goto _test_eof3569 + } + st_case_3569: + switch data[p] { + case 128: + goto st3570 + case 129: + goto st3571 + case 132: + goto st3270 + case 135: + goto st3572 + } + if 133 <= data[p] && data[p] <= 134 { + goto st3318 + } + goto tr2 + st3570: + if p++; p == pe { + goto _test_eof3570 + } + st_case_3570: + if data[p] == 129 { + goto tr2984 + } + if 160 <= data[p] { + goto tr2984 + } + goto tr2 + st3571: + if p++; p == pe { + goto _test_eof3571 + } + st_case_3571: + if 192 <= data[p] { + goto tr2 + } + goto tr2984 + st3572: + if p++; p == pe { + goto _test_eof3572 + } + st_case_3572: + if 176 <= data[p] { + goto tr2 + } + goto tr2984 + st3573: + if p++; p == pe { + goto _test_eof3573 + } + st_case_3573: + switch { + case data[p] < 157: + if 155 <= data[p] && data[p] <= 156 { + goto tr0 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr0 + } + default: + goto tr2395 + } + goto tr148 + st3574: + if p++; p == pe { + goto _test_eof3574 + } + st_case_3574: + switch { + case data[p] < 146: + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 177: + if 178 <= data[p] && data[p] <= 180 { + goto tr2395 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr2395 + } + goto tr0 + st3575: + if p++; p == pe { + goto _test_eof3575 + } + st_case_3575: + switch { + case data[p] < 160: + switch { + case data[p] > 145: + if 146 <= data[p] && data[p] <= 147 { + goto tr2395 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto tr2395 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st3576: + if p++; p == pe { + goto _test_eof3576 + } + st_case_3576: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr0 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 170 <= data[p] { + goto tr0 + } + case data[p] >= 160: + goto tr126 + } + default: + goto tr0 + } + goto tr2395 + st3577: + if p++; p == pe { + goto _test_eof3577 + } + st_case_3577: + switch { + case data[p] < 144: + if 139 <= data[p] && data[p] <= 142 { + goto tr2395 + } + case data[p] > 153: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr126 + } + goto tr0 + st3578: + if p++; p == pe { + goto _test_eof3578 + } + st_case_3578: + if data[p] == 169 { + goto tr2395 + } + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr0 + st3579: + if p++; p == pe { + goto _test_eof3579 + } + st_case_3579: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr2395 + } + default: + goto tr2395 + } + goto tr0 + st3580: + if p++; p == pe { + goto _test_eof3580 + } + st_case_3580: + switch { + case data[p] > 150: + if 151 <= data[p] && data[p] <= 155 { + goto tr2395 + } + case data[p] >= 128: + goto tr148 + } + goto tr0 + st3581: + if p++; p == pe { + goto _test_eof3581 + } + st_case_3581: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto tr2395 + } + default: + goto tr126 + } + goto tr0 + st3582: + if p++; p == pe { + goto _test_eof3582 + } + st_case_3582: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 132 { + goto tr2395 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr2395 + } + default: + goto tr148 + } + goto tr0 + st3583: + if p++; p == pe { + goto _test_eof3583 + } + st_case_3583: + switch { + case data[p] < 144: + switch { + case data[p] > 139: + if 140 <= data[p] && data[p] <= 143 { + goto tr0 + } + case data[p] >= 133: + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr0 + } + case data[p] >= 154: + goto tr0 + } + default: + goto tr126 + } + goto tr2395 + st3584: + if p++; p == pe { + goto _test_eof3584 + } + st_case_3584: + switch { + case data[p] < 161: + switch { + case data[p] > 130: + if 131 <= data[p] && data[p] <= 160 { + goto tr148 + } + case data[p] >= 128: + goto tr2395 + } + case data[p] > 173: + switch { + case data[p] < 176: + if 174 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr148 + } + default: + goto tr126 + } + default: + goto tr2395 + } + goto tr0 + st3585: + if p++; p == pe { + goto _test_eof3585 + } + st_case_3585: + switch { + case data[p] > 179: + if 180 <= data[p] { + goto tr0 + } + case data[p] >= 166: + goto tr2395 + } + goto tr148 + st3586: + if p++; p == pe { + goto _test_eof3586 + } + st_case_3586: + switch { + case data[p] > 163: + if 164 <= data[p] && data[p] <= 183 { + goto tr2395 + } + case data[p] >= 128: + goto tr148 + } + goto tr0 + st3587: + if p++; p == pe { + goto _test_eof3587 + } + st_case_3587: + if data[p] == 173 { + goto tr2395 + } + switch { + case data[p] < 169: + switch { + case data[p] > 146: + if 148 <= data[p] && data[p] <= 168 { + goto tr2395 + } + case data[p] >= 144: + goto tr2395 + } + case data[p] > 177: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 180 { + goto tr2395 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto tr2395 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr0 +tr4488: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5075 + st5075: + if p++; p == pe { + goto _test_eof5075 + } + st_case_5075: +//line segment_words_prod.go:110410 + switch data[p] { + case 128: + goto st3588 + case 129: + goto st3589 + case 130: + goto st241 + case 131: + goto st2703 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st3590 + case 180: + goto st251 + case 181: + goto st3591 + case 182: + goto st253 + case 183: + goto st3592 + case 184: + goto st255 + case 186: + goto st3593 + case 187: + goto st3735 + case 188: + goto st3595 + case 191: + goto st3736 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 189 <= data[p] && data[p] <= 190 { + goto st3734 + } + goto tr4499 + st3588: + if p++; p == pe { + goto _test_eof3588 + } + st_case_3588: + switch { + case data[p] < 168: + if 140 <= data[p] && data[p] <= 143 { + goto tr2395 + } + case data[p] > 169: + switch { + case data[p] > 174: + if 191 <= data[p] { + goto tr2136 + } + case data[p] >= 170: + goto tr2395 + } + default: + goto tr3249 + } + goto tr0 + st3589: + if p++; p == pe { + goto _test_eof3589 + } + st_case_3589: + switch data[p] { + case 165: + goto tr0 + case 177: + goto tr148 + case 191: + goto tr148 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr0 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr0 + } + case data[p] >= 160: + goto tr2395 + } + default: + goto tr0 + } + goto tr2136 + st3590: + if p++; p == pe { + goto _test_eof3590 + } + st_case_3590: + switch { + case data[p] < 175: + if 165 <= data[p] && data[p] <= 170 { + goto tr0 + } + case data[p] > 177: + if 180 <= data[p] { + goto tr0 + } + default: + goto tr2395 + } + goto tr148 + st3591: + if p++; p == pe { + goto _test_eof3591 + } + st_case_3591: + if data[p] == 191 { + goto tr2395 + } + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr0 + } + case data[p] >= 168: + goto tr0 + } + goto tr148 + st3592: + if p++; p == pe { + goto _test_eof3592 + } + st_case_3592: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto tr2395 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st3593: + if p++; p == pe { + goto _test_eof3593 + } + st_case_3593: + switch { + case data[p] > 153: + if 155 <= data[p] { + goto tr3250 + } + case data[p] >= 128: + goto tr3250 + } + goto tr0 +tr3250: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5076 + st5076: + if p++; p == pe { + goto _test_eof5076 + } + st_case_5076: +//line segment_words_prod.go:110650 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 + st3594: + if p++; p == pe { + goto _test_eof3594 + } + st_case_3594: + if data[p] == 173 { + goto tr3250 + } + goto tr3251 + st3595: + if p++; p == pe { + goto _test_eof3595 + } + st_case_3595: + if data[p] <= 127 { + goto tr2 + } + goto tr3250 + st3596: + if p++; p == pe { + goto _test_eof3596 + } + st_case_3596: + if 176 <= data[p] { + goto tr2 + } + goto tr3250 + st3597: + if p++; p == pe { + goto _test_eof3597 + } + st_case_3597: + if 131 <= data[p] && data[p] <= 137 { + goto tr3250 + } + goto tr3251 + st3598: + if p++; p == pe { + goto _test_eof3598 + } + st_case_3598: + if data[p] == 191 { + goto tr3250 + } + if 145 <= data[p] && data[p] <= 189 { + goto tr3250 + } + goto tr3251 + st3599: + if p++; p == pe { + goto _test_eof3599 + } + st_case_3599: + if data[p] == 135 { + goto tr3250 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto tr3250 + } + case data[p] >= 129: + goto tr3250 + } + goto tr3251 + st3600: + if p++; p == pe { + goto _test_eof3600 + } + st_case_3600: + if data[p] == 156 { + goto tr3250 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto tr3250 + } + case data[p] >= 128: + goto tr3250 + } + goto tr3251 + st3601: + if p++; p == pe { + goto _test_eof3601 + } + st_case_3601: + if data[p] == 176 { + goto tr3250 + } + if 139 <= data[p] && data[p] <= 159 { + goto tr3250 + } + goto tr3251 + st3602: + if p++; p == pe { + goto _test_eof3602 + } + st_case_3602: + switch { + case data[p] < 159: + if 150 <= data[p] && data[p] <= 157 { + goto tr3250 + } + case data[p] > 164: + switch { + case data[p] > 168: + if 170 <= data[p] && data[p] <= 173 { + goto tr3250 + } + case data[p] >= 167: + goto tr3250 + } + default: + goto tr3250 + } + goto tr3251 + st3603: + if p++; p == pe { + goto _test_eof3603 + } + st_case_3603: + switch data[p] { + case 143: + goto tr3250 + case 145: + goto tr3250 + } + if 176 <= data[p] { + goto tr3250 + } + goto tr3251 + st3604: + if p++; p == pe { + goto _test_eof3604 + } + st_case_3604: + if 139 <= data[p] { + goto tr3251 + } + goto tr3250 + st3605: + if p++; p == pe { + goto _test_eof3605 + } + st_case_3605: + if 166 <= data[p] && data[p] <= 176 { + goto tr3250 + } + goto tr3251 + st3606: + if p++; p == pe { + goto _test_eof3606 + } + st_case_3606: + if 171 <= data[p] && data[p] <= 179 { + goto tr3250 + } + goto tr3251 + st3607: + if p++; p == pe { + goto _test_eof3607 + } + st_case_3607: + switch data[p] { + case 160: + goto st3608 + case 161: + goto st3609 + case 163: + goto st3610 + case 164: + goto st3611 + case 165: + goto st3612 + case 167: + goto st3614 + case 169: + goto st3615 + case 171: + goto st3616 + case 173: + goto st3618 + case 174: + goto st3619 + case 175: + goto st3620 + case 176: + goto st3621 + case 177: + goto st3622 + case 179: + goto st3623 + case 180: + goto st3624 + case 181: + goto st3625 + case 182: + goto st3626 + case 183: + goto st3627 + case 184: + goto st3628 + case 185: + goto st3629 + case 186: + goto st3630 + case 187: + goto st3631 + case 188: + goto st3632 + case 189: + goto st3633 + case 190: + goto st3634 + case 191: + goto st3635 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto st3617 + } + case data[p] >= 166: + goto st3613 + } + goto tr3251 + st3608: + if p++; p == pe { + goto _test_eof3608 + } + st_case_3608: + switch { + case data[p] < 155: + if 150 <= data[p] && data[p] <= 153 { + goto tr3250 + } + case data[p] > 163: + switch { + case data[p] > 167: + if 169 <= data[p] && data[p] <= 173 { + goto tr3250 + } + case data[p] >= 165: + goto tr3250 + } + default: + goto tr3250 + } + goto tr2 + st3609: + if p++; p == pe { + goto _test_eof3609 + } + st_case_3609: + if 153 <= data[p] && data[p] <= 155 { + goto tr3250 + } + goto tr2 + st3610: + if p++; p == pe { + goto _test_eof3610 + } + st_case_3610: + if 163 <= data[p] { + goto tr3250 + } + goto tr2 + st3611: + if p++; p == pe { + goto _test_eof3611 + } + st_case_3611: + if data[p] == 189 { + goto tr2 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr2 + } + goto tr3250 + st3612: + if p++; p == pe { + goto _test_eof3612 + } + st_case_3612: + if data[p] == 144 { + goto tr2 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr2 + } + case data[p] >= 152: + goto tr2 + } + goto tr3250 + st3613: + if p++; p == pe { + goto _test_eof3613 + } + st_case_3613: + if data[p] == 188 { + goto tr3250 + } + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr3250 + } + case data[p] >= 129: + goto tr3250 + } + goto tr2 + st3614: + if p++; p == pe { + goto _test_eof3614 + } + st_case_3614: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr2 + } + case data[p] >= 133: + goto tr2 + } + case data[p] > 150: + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr2 + } + case data[p] >= 152: + goto tr2 + } + default: + goto tr2 + } + goto tr3250 + st3615: + if p++; p == pe { + goto _test_eof3615 + } + st_case_3615: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr2 + } + case data[p] >= 131: + goto tr2 + } + case data[p] > 144: + switch { + case data[p] < 178: + if 146 <= data[p] && data[p] <= 175 { + goto tr2 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + default: + goto tr2 + } + goto tr3250 + st3616: + if p++; p == pe { + goto _test_eof3616 + } + st_case_3616: + switch data[p] { + case 134: + goto tr2 + case 138: + goto tr2 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr2 + } + case data[p] >= 142: + goto tr2 + } + goto tr3250 + st3617: + if p++; p == pe { + goto _test_eof3617 + } + st_case_3617: + if data[p] == 188 { + goto tr3250 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr3250 + } + case data[p] >= 129: + goto tr3250 + } + goto tr2 + st3618: + if p++; p == pe { + goto _test_eof3618 + } + st_case_3618: + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr3250 + } + case data[p] >= 128: + goto tr3250 + } + case data[p] > 141: + switch { + case data[p] > 151: + if 162 <= data[p] && data[p] <= 163 { + goto tr3250 + } + case data[p] >= 150: + goto tr3250 + } + default: + goto tr3250 + } + goto tr2 + st3619: + if p++; p == pe { + goto _test_eof3619 + } + st_case_3619: + if data[p] == 130 { + goto tr3250 + } + if 190 <= data[p] && data[p] <= 191 { + goto tr3250 + } + goto tr2 + st3620: + if p++; p == pe { + goto _test_eof3620 + } + st_case_3620: + if data[p] == 151 { + goto tr3250 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr3250 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr3250 + } + default: + goto tr3250 + } + goto tr2 + st3621: + if p++; p == pe { + goto _test_eof3621 + } + st_case_3621: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr3250 + } + case data[p] >= 128: + goto tr3250 + } + goto tr2 + st3622: + if p++; p == pe { + goto _test_eof3622 + } + st_case_3622: + switch data[p] { + case 133: + goto tr2 + case 137: + goto tr2 + } + switch { + case data[p] < 151: + if 142 <= data[p] && data[p] <= 148 { + goto tr2 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr3250 + st3623: + if p++; p == pe { + goto _test_eof3623 + } + st_case_3623: + switch { + case data[p] < 138: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 136 { + goto tr3250 + } + case data[p] >= 128: + goto tr3250 + } + case data[p] > 141: + switch { + case data[p] > 150: + if 162 <= data[p] && data[p] <= 163 { + goto tr3250 + } + case data[p] >= 149: + goto tr3250 + } + default: + goto tr3250 + } + goto tr2 + st3624: + if p++; p == pe { + goto _test_eof3624 + } + st_case_3624: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr3250 + } + case data[p] >= 129: + goto tr3250 + } + goto tr2 + st3625: + if p++; p == pe { + goto _test_eof3625 + } + st_case_3625: + switch data[p] { + case 133: + goto tr2 + case 137: + goto tr2 + } + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 150 { + goto tr2 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr3250 + st3626: + if p++; p == pe { + goto _test_eof3626 + } + st_case_3626: + if 130 <= data[p] && data[p] <= 131 { + goto tr3250 + } + goto tr2 + st3627: + if p++; p == pe { + goto _test_eof3627 + } + st_case_3627: + switch data[p] { + case 138: + goto tr3250 + case 150: + goto tr3250 + } + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 148 { + goto tr3250 + } + case data[p] > 159: + if 178 <= data[p] && data[p] <= 179 { + goto tr3250 + } + default: + goto tr3250 + } + goto tr2 + st3628: + if p++; p == pe { + goto _test_eof3628 + } + st_case_3628: + if data[p] == 177 { + goto tr3250 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr3250 + } + goto tr2 + st3629: + if p++; p == pe { + goto _test_eof3629 + } + st_case_3629: + if 135 <= data[p] && data[p] <= 142 { + goto tr3250 + } + goto tr2 + st3630: + if p++; p == pe { + goto _test_eof3630 + } + st_case_3630: + if data[p] == 177 { + goto tr3250 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr3250 + } + case data[p] >= 180: + goto tr3250 + } + goto tr2 + st3631: + if p++; p == pe { + goto _test_eof3631 + } + st_case_3631: + if 136 <= data[p] && data[p] <= 141 { + goto tr3250 + } + goto tr2 + st3632: + if p++; p == pe { + goto _test_eof3632 + } + st_case_3632: + switch data[p] { + case 181: + goto tr3250 + case 183: + goto tr3250 + case 185: + goto tr3250 + } + switch { + case data[p] > 153: + if 190 <= data[p] && data[p] <= 191 { + goto tr3250 + } + case data[p] >= 152: + goto tr3250 + } + goto tr2 + st3633: + if p++; p == pe { + goto _test_eof3633 + } + st_case_3633: + if 177 <= data[p] && data[p] <= 191 { + goto tr3250 + } + goto tr2 + st3634: + if p++; p == pe { + goto _test_eof3634 + } + st_case_3634: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr3250 + } + case data[p] > 135: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr3250 + } + case data[p] >= 141: + goto tr3250 + } + default: + goto tr3250 + } + goto tr2 + st3635: + if p++; p == pe { + goto _test_eof3635 + } + st_case_3635: + if data[p] == 134 { + goto tr3250 + } + goto tr2 + st3636: + if p++; p == pe { + goto _test_eof3636 + } + st_case_3636: + switch data[p] { + case 128: + goto st3637 + case 129: + goto st3638 + case 130: + goto st3639 + case 141: + goto st3640 + case 156: + goto st3641 + case 157: + goto st3642 + case 158: + goto st3643 + case 159: + goto st3644 + case 160: + goto st3645 + case 162: + goto st3646 + case 164: + goto st3647 + case 168: + goto st3648 + case 169: + goto st3649 + case 170: + goto st3650 + case 172: + goto st3651 + case 173: + goto st3652 + case 174: + goto st3653 + case 175: + goto st3654 + case 176: + goto st3655 + case 179: + goto st3656 + case 183: + goto st3657 + } + goto tr3251 + st3637: + if p++; p == pe { + goto _test_eof3637 + } + st_case_3637: + if 171 <= data[p] && data[p] <= 190 { + goto tr3250 + } + goto tr2 + st3638: + if p++; p == pe { + goto _test_eof3638 + } + st_case_3638: + switch { + case data[p] < 162: + switch { + case data[p] > 153: + if 158 <= data[p] && data[p] <= 160 { + goto tr3250 + } + case data[p] >= 150: + goto tr3250 + } + case data[p] > 164: + switch { + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr3250 + } + case data[p] >= 167: + goto tr3250 + } + default: + goto tr3250 + } + goto tr2 + st3639: + if p++; p == pe { + goto _test_eof3639 + } + st_case_3639: + if data[p] == 143 { + goto tr3250 + } + switch { + case data[p] > 141: + if 154 <= data[p] && data[p] <= 157 { + goto tr3250 + } + case data[p] >= 130: + goto tr3250 + } + goto tr2 + st3640: + if p++; p == pe { + goto _test_eof3640 + } + st_case_3640: + if 157 <= data[p] && data[p] <= 159 { + goto tr3250 + } + goto tr2 + st3641: + if p++; p == pe { + goto _test_eof3641 + } + st_case_3641: + switch { + case data[p] > 148: + if 178 <= data[p] && data[p] <= 180 { + goto tr3250 + } + case data[p] >= 146: + goto tr3250 + } + goto tr2 + st3642: + if p++; p == pe { + goto _test_eof3642 + } + st_case_3642: + switch { + case data[p] > 147: + if 178 <= data[p] && data[p] <= 179 { + goto tr3250 + } + case data[p] >= 146: + goto tr3250 + } + goto tr2 + st3643: + if p++; p == pe { + goto _test_eof3643 + } + st_case_3643: + if 180 <= data[p] { + goto tr3250 + } + goto tr2 + st3644: + if p++; p == pe { + goto _test_eof3644 + } + st_case_3644: + switch { + case data[p] > 156: + if 158 <= data[p] { + goto tr2 + } + case data[p] >= 148: + goto tr2 + } + goto tr3250 + st3645: + if p++; p == pe { + goto _test_eof3645 + } + st_case_3645: + if 139 <= data[p] && data[p] <= 142 { + goto tr3250 + } + goto tr2 + st3646: + if p++; p == pe { + goto _test_eof3646 + } + st_case_3646: + if data[p] == 169 { + goto tr3250 + } + goto tr2 + st3647: + if p++; p == pe { + goto _test_eof3647 + } + st_case_3647: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr3250 + } + case data[p] >= 160: + goto tr3250 + } + goto tr2 + st3648: + if p++; p == pe { + goto _test_eof3648 + } + st_case_3648: + if 151 <= data[p] && data[p] <= 155 { + goto tr3250 + } + goto tr2 + st3649: + if p++; p == pe { + goto _test_eof3649 + } + st_case_3649: + if data[p] == 191 { + goto tr3250 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr3250 + } + case data[p] >= 149: + goto tr3250 + } + goto tr2 + st3650: + if p++; p == pe { + goto _test_eof3650 + } + st_case_3650: + if 176 <= data[p] && data[p] <= 190 { + goto tr3250 + } + goto tr2 + st3651: + if p++; p == pe { + goto _test_eof3651 + } + st_case_3651: + switch { + case data[p] > 132: + if 180 <= data[p] { + goto tr3250 + } + case data[p] >= 128: + goto tr3250 + } + goto tr2 + st3652: + if p++; p == pe { + goto _test_eof3652 + } + st_case_3652: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr2 + } + case data[p] >= 133: + goto tr2 + } + goto tr3250 + st3653: + if p++; p == pe { + goto _test_eof3653 + } + st_case_3653: + switch { + case data[p] > 130: + if 161 <= data[p] && data[p] <= 173 { + goto tr3250 + } + case data[p] >= 128: + goto tr3250 + } + goto tr2 + st3654: + if p++; p == pe { + goto _test_eof3654 + } + st_case_3654: + if 166 <= data[p] && data[p] <= 179 { + goto tr3250 + } + goto tr2 + st3655: + if p++; p == pe { + goto _test_eof3655 + } + st_case_3655: + if 164 <= data[p] && data[p] <= 183 { + goto tr3250 + } + goto tr2 + st3656: + if p++; p == pe { + goto _test_eof3656 + } + st_case_3656: + if data[p] == 173 { + goto tr3250 + } + switch { + case data[p] < 148: + if 144 <= data[p] && data[p] <= 146 { + goto tr3250 + } + case data[p] > 168: + switch { + case data[p] > 180: + if 184 <= data[p] && data[p] <= 185 { + goto tr3250 + } + case data[p] >= 178: + goto tr3250 + } + default: + goto tr3250 + } + goto tr2 + st3657: + if p++; p == pe { + goto _test_eof3657 + } + st_case_3657: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr3250 + } + case data[p] >= 128: + goto tr3250 + } + goto tr2 + st3658: + if p++; p == pe { + goto _test_eof3658 + } + st_case_3658: + switch data[p] { + case 128: + goto st3659 + case 129: + goto st3660 + case 131: + goto st3661 + case 179: + goto st3662 + case 181: + goto st3663 + case 183: + goto st3664 + } + goto tr3251 + st3659: + if p++; p == pe { + goto _test_eof3659 + } + st_case_3659: + switch { + case data[p] > 143: + if 170 <= data[p] && data[p] <= 174 { + goto tr3250 + } + case data[p] >= 140: + goto tr3250 + } + goto tr2 + st3660: + if p++; p == pe { + goto _test_eof3660 + } + st_case_3660: + switch { + case data[p] > 164: + if 166 <= data[p] && data[p] <= 175 { + goto tr3250 + } + case data[p] >= 160: + goto tr3250 + } + goto tr2 + st3661: + if p++; p == pe { + goto _test_eof3661 + } + st_case_3661: + if 144 <= data[p] && data[p] <= 176 { + goto tr3250 + } + goto tr2 + st3662: + if p++; p == pe { + goto _test_eof3662 + } + st_case_3662: + if 175 <= data[p] && data[p] <= 177 { + goto tr3250 + } + goto tr2 + st3663: + if p++; p == pe { + goto _test_eof3663 + } + st_case_3663: + if data[p] == 191 { + goto tr3250 + } + goto tr2 + st3664: + if p++; p == pe { + goto _test_eof3664 + } + st_case_3664: + if 160 <= data[p] && data[p] <= 191 { + goto tr3250 + } + goto tr2 + st3665: + if p++; p == pe { + goto _test_eof3665 + } + st_case_3665: + switch data[p] { + case 128: + goto st3666 + case 130: + goto st3667 + } + goto tr3251 + st3666: + if p++; p == pe { + goto _test_eof3666 + } + st_case_3666: + if 170 <= data[p] && data[p] <= 175 { + goto tr3250 + } + goto tr2 + st3667: + if p++; p == pe { + goto _test_eof3667 + } + st_case_3667: + if 153 <= data[p] && data[p] <= 154 { + goto tr3250 + } + goto tr2 + st3668: + if p++; p == pe { + goto _test_eof3668 + } + st_case_3668: + switch data[p] { + case 153: + goto st3669 + case 154: + goto st3670 + case 155: + goto st3671 + case 160: + goto st3672 + case 162: + goto st3673 + case 163: + goto st3674 + case 164: + goto st3675 + case 165: + goto st3676 + case 166: + goto st3677 + case 167: + goto st3678 + case 168: + goto st3679 + case 169: + goto st3680 + case 170: + goto st3681 + case 171: + goto st3682 + case 175: + goto st3683 + } + goto tr3251 + st3669: + if p++; p == pe { + goto _test_eof3669 + } + st_case_3669: + switch { + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr3250 + } + case data[p] >= 175: + goto tr3250 + } + goto tr2 + st3670: + if p++; p == pe { + goto _test_eof3670 + } + st_case_3670: + if 158 <= data[p] && data[p] <= 159 { + goto tr3250 + } + goto tr2 + st3671: + if p++; p == pe { + goto _test_eof3671 + } + st_case_3671: + if 176 <= data[p] && data[p] <= 177 { + goto tr3250 + } + goto tr2 + st3672: + if p++; p == pe { + goto _test_eof3672 + } + st_case_3672: + switch data[p] { + case 130: + goto tr3250 + case 134: + goto tr3250 + case 139: + goto tr3250 + } + if 163 <= data[p] && data[p] <= 167 { + goto tr3250 + } + goto tr2 + st3673: + if p++; p == pe { + goto _test_eof3673 + } + st_case_3673: + switch { + case data[p] > 129: + if 180 <= data[p] { + goto tr3250 + } + case data[p] >= 128: + goto tr3250 + } + goto tr2 + st3674: + if p++; p == pe { + goto _test_eof3674 + } + st_case_3674: + switch { + case data[p] > 159: + if 178 <= data[p] { + goto tr2 + } + case data[p] >= 133: + goto tr2 + } + goto tr3250 + st3675: + if p++; p == pe { + goto _test_eof3675 + } + st_case_3675: + if 166 <= data[p] && data[p] <= 173 { + goto tr3250 + } + goto tr2 + st3676: + if p++; p == pe { + goto _test_eof3676 + } + st_case_3676: + if 135 <= data[p] && data[p] <= 147 { + goto tr3250 + } + goto tr2 + st3677: + if p++; p == pe { + goto _test_eof3677 + } + st_case_3677: + switch { + case data[p] > 131: + if 179 <= data[p] { + goto tr3250 + } + case data[p] >= 128: + goto tr3250 + } + goto tr2 + st3678: + if p++; p == pe { + goto _test_eof3678 + } + st_case_3678: + switch { + case data[p] > 164: + if 166 <= data[p] { + goto tr2 + } + case data[p] >= 129: + goto tr2 + } + goto tr3250 + st3679: + if p++; p == pe { + goto _test_eof3679 + } + st_case_3679: + if 169 <= data[p] && data[p] <= 182 { + goto tr3250 + } + goto tr2 + st3680: + if p++; p == pe { + goto _test_eof3680 + } + st_case_3680: + if data[p] == 131 { + goto tr3250 + } + switch { + case data[p] > 141: + if 187 <= data[p] && data[p] <= 189 { + goto tr3250 + } + case data[p] >= 140: + goto tr3250 + } + goto tr2 + st3681: + if p++; p == pe { + goto _test_eof3681 + } + st_case_3681: + if data[p] == 176 { + goto tr3250 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr3250 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr3250 + } + default: + goto tr3250 + } + goto tr2 + st3682: + if p++; p == pe { + goto _test_eof3682 + } + st_case_3682: + if data[p] == 129 { + goto tr3250 + } + switch { + case data[p] > 175: + if 181 <= data[p] && data[p] <= 182 { + goto tr3250 + } + case data[p] >= 171: + goto tr3250 + } + goto tr2 + st3683: + if p++; p == pe { + goto _test_eof3683 + } + st_case_3683: + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 173 { + goto tr3250 + } + case data[p] >= 163: + goto tr3250 + } + goto tr2 + st3684: + if p++; p == pe { + goto _test_eof3684 + } + st_case_3684: + switch data[p] { + case 172: + goto st3685 + case 184: + goto st3686 + case 187: + goto st3663 + case 190: + goto st3670 + case 191: + goto st3687 + } + goto tr3251 + st3685: + if p++; p == pe { + goto _test_eof3685 + } + st_case_3685: + if data[p] == 158 { + goto tr3250 + } + goto tr2 + st3686: + if p++; p == pe { + goto _test_eof3686 + } + st_case_3686: + switch { + case data[p] > 143: + if 160 <= data[p] && data[p] <= 175 { + goto tr3250 + } + case data[p] >= 128: + goto tr3250 + } + goto tr2 + st3687: + if p++; p == pe { + goto _test_eof3687 + } + st_case_3687: + if 185 <= data[p] && data[p] <= 187 { + goto tr3250 + } + goto tr2 + st3688: + if p++; p == pe { + goto _test_eof3688 + } + st_case_3688: + switch data[p] { + case 144: + goto st3689 + case 145: + goto st3695 + case 150: + goto st3714 + case 155: + goto st3719 + case 157: + goto st3721 + case 158: + goto st3728 + } + goto tr3251 + st3689: + if p++; p == pe { + goto _test_eof3689 + } + st_case_3689: + switch data[p] { + case 135: + goto st3690 + case 139: + goto st3691 + case 141: + goto st3692 + case 168: + goto st3693 + case 171: + goto st3694 + } + goto tr2 + st3690: + if p++; p == pe { + goto _test_eof3690 + } + st_case_3690: + if data[p] == 189 { + goto tr3250 + } + goto tr2 + st3691: + if p++; p == pe { + goto _test_eof3691 + } + st_case_3691: + if data[p] == 160 { + goto tr3250 + } + goto tr2 + st3692: + if p++; p == pe { + goto _test_eof3692 + } + st_case_3692: + if 182 <= data[p] && data[p] <= 186 { + goto tr3250 + } + goto tr2 + st3693: + if p++; p == pe { + goto _test_eof3693 + } + st_case_3693: + if data[p] == 191 { + goto tr3250 + } + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr3250 + } + case data[p] > 134: + switch { + case data[p] > 143: + if 184 <= data[p] && data[p] <= 186 { + goto tr3250 + } + case data[p] >= 140: + goto tr3250 + } + default: + goto tr3250 + } + goto tr2 + st3694: + if p++; p == pe { + goto _test_eof3694 + } + st_case_3694: + if 165 <= data[p] && data[p] <= 166 { + goto tr3250 + } + goto tr2 + st3695: + if p++; p == pe { + goto _test_eof3695 + } + st_case_3695: + switch data[p] { + case 128: + goto st3696 + case 129: + goto st3697 + case 130: + goto st3698 + case 132: + goto st3699 + case 133: + goto st3700 + case 134: + goto st3701 + case 135: + goto st3702 + case 136: + goto st3703 + case 139: + goto st3704 + case 140: + goto st3705 + case 141: + goto st3706 + case 146: + goto st3707 + case 147: + goto st3708 + case 150: + goto st3709 + case 151: + goto st3710 + case 152: + goto st3707 + case 153: + goto st3711 + case 154: + goto st3712 + case 156: + goto st3713 + } + goto tr2 + st3696: + if p++; p == pe { + goto _test_eof3696 + } + st_case_3696: + switch { + case data[p] > 130: + if 184 <= data[p] { + goto tr3250 + } + case data[p] >= 128: + goto tr3250 + } + goto tr2 + st3697: + if p++; p == pe { + goto _test_eof3697 + } + st_case_3697: + if 135 <= data[p] && data[p] <= 190 { + goto tr2 + } + goto tr3250 + st3698: + if p++; p == pe { + goto _test_eof3698 + } + st_case_3698: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr2 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr3250 + st3699: + if p++; p == pe { + goto _test_eof3699 + } + st_case_3699: + switch { + case data[p] > 130: + if 167 <= data[p] && data[p] <= 180 { + goto tr3250 + } + case data[p] >= 128: + goto tr3250 + } + goto tr2 + st3700: + if p++; p == pe { + goto _test_eof3700 + } + st_case_3700: + if data[p] == 179 { + goto tr3250 + } + goto tr2 + st3701: + if p++; p == pe { + goto _test_eof3701 + } + st_case_3701: + switch { + case data[p] > 130: + if 179 <= data[p] { + goto tr3250 + } + case data[p] >= 128: + goto tr3250 + } + goto tr2 + st3702: + if p++; p == pe { + goto _test_eof3702 + } + st_case_3702: + switch { + case data[p] > 137: + if 141 <= data[p] { + goto tr2 + } + case data[p] >= 129: + goto tr2 + } + goto tr3250 + st3703: + if p++; p == pe { + goto _test_eof3703 + } + st_case_3703: + if 172 <= data[p] && data[p] <= 183 { + goto tr3250 + } + goto tr2 + st3704: + if p++; p == pe { + goto _test_eof3704 + } + st_case_3704: + if 159 <= data[p] && data[p] <= 170 { + goto tr3250 + } + goto tr2 + st3705: + if p++; p == pe { + goto _test_eof3705 + } + st_case_3705: + if data[p] == 188 { + goto tr3250 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr3250 + } + case data[p] >= 128: + goto tr3250 + } + goto tr2 + st3706: + if p++; p == pe { + goto _test_eof3706 + } + st_case_3706: + if data[p] == 151 { + goto tr3250 + } + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr3250 + } + case data[p] >= 128: + goto tr3250 + } + case data[p] > 141: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr3250 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr3250 + } + default: + goto tr3250 + } + default: + goto tr3250 + } + goto tr2 + st3707: + if p++; p == pe { + goto _test_eof3707 + } + st_case_3707: + if 176 <= data[p] { + goto tr3250 + } + goto tr2 + st3708: + if p++; p == pe { + goto _test_eof3708 + } + st_case_3708: + if 132 <= data[p] { + goto tr2 + } + goto tr3250 + st3709: + if p++; p == pe { + goto _test_eof3709 + } + st_case_3709: + switch { + case data[p] > 181: + if 184 <= data[p] { + goto tr3250 + } + case data[p] >= 175: + goto tr3250 + } + goto tr2 + st3710: + if p++; p == pe { + goto _test_eof3710 + } + st_case_3710: + switch { + case data[p] > 155: + if 158 <= data[p] { + goto tr2 + } + case data[p] >= 129: + goto tr2 + } + goto tr3250 + st3711: + if p++; p == pe { + goto _test_eof3711 + } + st_case_3711: + if 129 <= data[p] { + goto tr2 + } + goto tr3250 + st3712: + if p++; p == pe { + goto _test_eof3712 + } + st_case_3712: + if 171 <= data[p] && data[p] <= 183 { + goto tr3250 + } + goto tr2 + st3713: + if p++; p == pe { + goto _test_eof3713 + } + st_case_3713: + if 157 <= data[p] && data[p] <= 171 { + goto tr3250 + } + goto tr2 + st3714: + if p++; p == pe { + goto _test_eof3714 + } + st_case_3714: + switch data[p] { + case 171: + goto st3715 + case 172: + goto st3716 + case 189: + goto st3717 + case 190: + goto st3718 + } + goto tr2 + st3715: + if p++; p == pe { + goto _test_eof3715 + } + st_case_3715: + if 176 <= data[p] && data[p] <= 180 { + goto tr3250 + } + goto tr2 + st3716: + if p++; p == pe { + goto _test_eof3716 + } + st_case_3716: + if 176 <= data[p] && data[p] <= 182 { + goto tr3250 + } + goto tr2 + st3717: + if p++; p == pe { + goto _test_eof3717 + } + st_case_3717: + if 145 <= data[p] && data[p] <= 190 { + goto tr3250 + } + goto tr2 + st3718: + if p++; p == pe { + goto _test_eof3718 + } + st_case_3718: + if 143 <= data[p] && data[p] <= 146 { + goto tr3250 + } + goto tr2 + st3719: + if p++; p == pe { + goto _test_eof3719 + } + st_case_3719: + if data[p] == 178 { + goto st3720 + } + goto tr2 + st3720: + if p++; p == pe { + goto _test_eof3720 + } + st_case_3720: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr3250 + } + case data[p] >= 157: + goto tr3250 + } + goto tr2 + st3721: + if p++; p == pe { + goto _test_eof3721 + } + st_case_3721: + switch data[p] { + case 133: + goto st3722 + case 134: + goto st3723 + case 137: + goto st3724 + case 168: + goto st3725 + case 169: + goto st3726 + case 170: + goto st3727 + } + goto tr2 + st3722: + if p++; p == pe { + goto _test_eof3722 + } + st_case_3722: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr3250 + } + case data[p] >= 165: + goto tr3250 + } + goto tr2 + st3723: + if p++; p == pe { + goto _test_eof3723 + } + st_case_3723: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr2 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr2 + } + default: + goto tr2 + } + goto tr3250 + st3724: + if p++; p == pe { + goto _test_eof3724 + } + st_case_3724: + if 130 <= data[p] && data[p] <= 132 { + goto tr3250 + } + goto tr2 + st3725: + if p++; p == pe { + goto _test_eof3725 + } + st_case_3725: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr3250 + } + case data[p] >= 128: + goto tr3250 + } + goto tr2 + st3726: + if p++; p == pe { + goto _test_eof3726 + } + st_case_3726: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr2 + } + case data[p] >= 173: + goto tr2 + } + goto tr3250 + st3727: + if p++; p == pe { + goto _test_eof3727 + } + st_case_3727: + if data[p] == 132 { + goto tr3250 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr3250 + } + case data[p] >= 155: + goto tr3250 + } + goto tr2 + st3728: + if p++; p == pe { + goto _test_eof3728 + } + st_case_3728: + if data[p] == 163 { + goto st3729 + } + goto tr2 + st3729: + if p++; p == pe { + goto _test_eof3729 + } + st_case_3729: + if 144 <= data[p] && data[p] <= 150 { + goto tr3250 + } + goto tr2 + st3730: + if p++; p == pe { + goto _test_eof3730 + } + st_case_3730: + if data[p] == 160 { + goto st3731 + } + goto tr3251 + st3731: + if p++; p == pe { + goto _test_eof3731 + } + st_case_3731: + switch data[p] { + case 128: + goto st3732 + case 129: + goto st3733 + case 132: + goto st3595 + case 135: + goto st3596 + } + if 133 <= data[p] && data[p] <= 134 { + goto st3734 + } + goto tr2 + st3732: + if p++; p == pe { + goto _test_eof3732 + } + st_case_3732: + if data[p] == 129 { + goto tr3250 + } + if 160 <= data[p] { + goto tr3250 + } + goto tr2 + st3733: + if p++; p == pe { + goto _test_eof3733 + } + st_case_3733: + if 192 <= data[p] { + goto tr2 + } + goto tr3250 + st3734: + if p++; p == pe { + goto _test_eof3734 + } + st_case_3734: + goto tr3250 + st3735: + if p++; p == pe { + goto _test_eof3735 + } + st_case_3735: + if 180 <= data[p] { + goto tr0 + } + goto tr3250 + st3736: + if p++; p == pe { + goto _test_eof3736 + } + st_case_3736: + if 150 <= data[p] { + goto tr0 + } + goto tr3250 +tr4489: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5077 + st5077: + if p++; p == pe { + goto _test_eof5077 + } + st_case_5077: +//line segment_words_prod.go:112822 + switch data[p] { + case 128: + goto st3737 + case 129: + goto st4175 + case 130: + goto st4317 + case 131: + goto st4101 + case 132: + goto st3348 + case 133: + goto st3318 + case 134: + goto st3349 + case 135: + goto st4102 + case 136: + goto st3350 + case 137: + goto st3429 + case 139: + goto st4103 + case 140: + goto st4028 + case 141: + goto st4104 + case 144: + goto st3595 + case 194: + goto st4318 + case 204: + goto st4460 + case 205: + goto st4461 + case 210: + goto st4462 + case 214: + goto st4463 + case 215: + goto st4464 + case 216: + goto st4465 + case 217: + goto st4466 + case 219: + goto st4467 + case 220: + goto st4468 + case 221: + goto st4469 + case 222: + goto st4470 + case 223: + goto st4471 + case 224: + goto st4472 + case 225: + goto st4473 + case 226: + goto st4474 + case 227: + goto st4475 + case 234: + goto st4476 + case 239: + goto st4477 + case 240: + goto st4478 + case 243: + goto st4479 + } + if 145 <= data[p] { + goto st3734 + } + goto tr4499 + st3737: + if p++; p == pe { + goto _test_eof3737 + } + st_case_3737: + switch data[p] { + case 133: + goto tr3374 + case 135: + goto tr3250 + case 187: + goto tr3374 + case 188: + goto tr148 + } + switch { + case data[p] < 174: + switch { + case data[p] > 169: + if 170 <= data[p] && data[p] <= 173 { + goto tr2395 + } + case data[p] >= 161: + goto tr3250 + } + case data[p] > 175: + switch { + case data[p] > 181: + if 184 <= data[p] && data[p] <= 186 { + goto tr3250 + } + case data[p] >= 177: + goto tr3376 + } + default: + goto tr3375 + } + goto tr0 +tr3374: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:119 +act = 4; + goto st5078 + st5078: + if p++; p == pe { + goto _test_eof5078 + } + st_case_5078: +//line segment_words_prod.go:112953 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3738 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3739 + case 205: + goto st3740 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3741 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3742 + case 215: + goto st3743 + case 216: + goto st3744 + case 217: + goto st3745 + case 219: + goto st3746 + case 220: + goto st3747 + case 221: + goto st3748 + case 222: + goto st3749 + case 223: + goto st3750 + case 224: + goto st3751 + case 225: + goto st3783 + case 226: + goto st3805 + case 227: + goto st3812 + case 234: + goto st3815 + case 237: + goto st287 + case 239: + goto st3831 + case 240: + goto st3837 + case 243: + goto st3879 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st286 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr4562 + st3738: + if p++; p == pe { + goto _test_eof3738 + } + st_case_3738: + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr3374 + case 181: + goto tr148 + case 183: + goto st142 + case 186: + goto tr148 + } + goto tr420 + st3739: + if p++; p == pe { + goto _test_eof3739 + } + st_case_3739: + if 128 <= data[p] { + goto tr3374 + } + goto tr420 + st3740: + if p++; p == pe { + goto _test_eof3740 + } + st_case_3740: + switch data[p] { + case 181: + goto tr420 + case 190: + goto tr420 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + goto tr3374 + st3741: + if p++; p == pe { + goto _test_eof3741 + } + st_case_3741: + if data[p] == 130 { + goto tr420 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr3374 + } + goto tr148 + st3742: + if p++; p == pe { + goto _test_eof3742 + } + st_case_3742: + if data[p] == 190 { + goto tr420 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr420 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + default: + goto tr3374 + } + goto tr148 + st3743: + if p++; p == pe { + goto _test_eof3743 + } + st_case_3743: + switch data[p] { + case 135: + goto tr3374 + case 179: + goto tr148 + case 180: + goto st142 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr3374 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr3374 + } + goto tr420 + st3744: + if p++; p == pe { + goto _test_eof3744 + } + st_case_3744: + if data[p] == 156 { + goto tr3374 + } + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 133 { + goto tr3374 + } + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr3374 + } + goto tr420 + st3745: + if p++; p == pe { + goto _test_eof3745 + } + st_case_3745: + switch data[p] { + case 171: + goto tr421 + case 176: + goto tr3374 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr3374 + } + goto tr420 + st3746: + if p++; p == pe { + goto _test_eof3746 + } + st_case_3746: + switch data[p] { + case 148: + goto tr420 + case 158: + goto tr420 + case 169: + goto tr420 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr3374 + } + case data[p] >= 150: + goto tr3374 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 189: + goto tr420 + } + default: + goto tr421 + } + goto tr148 + st3747: + if p++; p == pe { + goto _test_eof3747 + } + st_case_3747: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto tr3374 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr3374 + } + default: + goto tr148 + } + goto tr420 + st3748: + if p++; p == pe { + goto _test_eof3748 + } + st_case_3748: + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr420 + } + goto tr3374 + st3749: + if p++; p == pe { + goto _test_eof3749 + } + st_case_3749: + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr3374 + } + goto tr148 + st3750: + if p++; p == pe { + goto _test_eof3750 + } + st_case_3750: + if data[p] == 186 { + goto tr148 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 170: + switch { + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 171: + goto tr3374 + } + default: + goto tr148 + } + goto tr420 + st3751: + if p++; p == pe { + goto _test_eof3751 + } + st_case_3751: + switch data[p] { + case 160: + goto st3752 + case 161: + goto st3753 + case 162: + goto st168 + case 163: + goto st3754 + case 164: + goto st3755 + case 165: + goto st3756 + case 166: + goto st3757 + case 167: + goto st3758 + case 168: + goto st3759 + case 169: + goto st3760 + case 170: + goto st3761 + case 171: + goto st3762 + case 172: + goto st3763 + case 173: + goto st3764 + case 174: + goto st3765 + case 175: + goto st3766 + case 176: + goto st3767 + case 177: + goto st3768 + case 178: + goto st3769 + case 179: + goto st3770 + case 180: + goto st3771 + case 181: + goto st3772 + case 182: + goto st3773 + case 183: + goto st3774 + case 184: + goto st3775 + case 185: + goto st3776 + case 186: + goto st3777 + case 187: + goto st3778 + case 188: + goto st3779 + case 189: + goto st3780 + case 190: + goto st3781 + case 191: + goto st3782 + } + goto tr420 + st3752: + if p++; p == pe { + goto _test_eof3752 + } + st_case_3752: + switch data[p] { + case 154: + goto tr148 + case 164: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] > 149: + if 150 <= data[p] && data[p] <= 173 { + goto tr3374 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3753: + if p++; p == pe { + goto _test_eof3753 + } + st_case_3753: + switch { + case data[p] > 152: + if 153 <= data[p] && data[p] <= 155 { + goto tr3374 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3754: + if p++; p == pe { + goto _test_eof3754 + } + st_case_3754: + if 163 <= data[p] { + goto tr3374 + } + goto tr420 + st3755: + if p++; p == pe { + goto _test_eof3755 + } + st_case_3755: + if data[p] == 189 { + goto tr148 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr148 + } + goto tr3374 + st3756: + if p++; p == pe { + goto _test_eof3756 + } + st_case_3756: + switch data[p] { + case 144: + goto tr148 + case 176: + goto tr420 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 177 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr420 + } + goto tr3374 + st3757: + if p++; p == pe { + goto _test_eof3757 + } + st_case_3757: + switch data[p] { + case 132: + goto tr420 + case 169: + goto tr420 + case 177: + goto tr420 + case 188: + goto tr3374 + } + switch { + case data[p] < 145: + switch { + case data[p] > 131: + if 141 <= data[p] && data[p] <= 142 { + goto tr420 + } + case data[p] >= 129: + goto tr3374 + } + case data[p] > 146: + switch { + case data[p] < 186: + if 179 <= data[p] && data[p] <= 181 { + goto tr420 + } + case data[p] > 187: + if 190 <= data[p] { + goto tr3374 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st3758: + if p++; p == pe { + goto _test_eof3758 + } + st_case_3758: + switch data[p] { + case 142: + goto tr148 + case 158: + goto tr420 + } + switch { + case data[p] < 156: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 155 { + goto tr420 + } + case data[p] >= 143: + goto tr420 + } + default: + goto tr420 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr3374 + st3759: + if p++; p == pe { + goto _test_eof3759 + } + st_case_3759: + if data[p] == 188 { + goto tr3374 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr3374 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto tr3374 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3760: + if p++; p == pe { + goto _test_eof3760 + } + st_case_3760: + if data[p] == 157 { + goto tr420 + } + switch { + case data[p] < 153: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr420 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 146 <= data[p] && data[p] <= 152 { + goto tr420 + } + case data[p] >= 142: + goto tr420 + } + default: + goto tr420 + } + case data[p] > 158: + switch { + case data[p] < 166: + if 159 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr3374 + st3761: + if p++; p == pe { + goto _test_eof3761 + } + st_case_3761: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr3374 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto tr3374 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3762: + if p++; p == pe { + goto _test_eof3762 + } + st_case_3762: + switch data[p] { + case 134: + goto tr420 + case 138: + goto tr420 + case 144: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] >= 142: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr420 + } + goto tr3374 + st3763: + if p++; p == pe { + goto _test_eof3763 + } + st_case_3763: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr3374 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr3374 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3764: + if p++; p == pe { + goto _test_eof3764 + } + st_case_3764: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr3374 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr3374 + } + default: + goto tr3374 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 161: + switch { + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 162: + goto tr3374 + } + default: + goto tr148 + } + default: + goto tr3374 + } + goto tr420 + st3765: + if p++; p == pe { + goto _test_eof3765 + } + st_case_3765: + switch data[p] { + case 130: + goto tr3374 + case 131: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 158: + switch { + case data[p] < 142: + if 133 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 149: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] < 168: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto tr3374 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3766: + if p++; p == pe { + goto _test_eof3766 + } + st_case_3766: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr3374 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr3374 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 138: + goto tr3374 + } + default: + goto tr3374 + } + goto tr420 + st3767: + if p++; p == pe { + goto _test_eof3767 + } + st_case_3767: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto tr3374 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 190 <= data[p] { + goto tr3374 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3768: + if p++; p == pe { + goto _test_eof3768 + } + st_case_3768: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 151: + goto tr420 + } + switch { + case data[p] < 160: + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 148 { + goto tr420 + } + case data[p] > 154: + if 155 <= data[p] && data[p] <= 159 { + goto tr420 + } + default: + goto tr148 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr3374 + st3769: + if p++; p == pe { + goto _test_eof3769 + } + st_case_3769: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr3374 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr3374 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3770: + if p++; p == pe { + goto _test_eof3770 + } + st_case_3770: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr3374 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr3374 + } + default: + goto tr3374 + } + case data[p] > 150: + switch { + case data[p] < 162: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 163: + switch { + case data[p] > 175: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr3374 + } + default: + goto tr3374 + } + goto tr420 + st3771: + if p++; p == pe { + goto _test_eof3771 + } + st_case_3771: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto tr3374 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto tr3374 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3772: + if p++; p == pe { + goto _test_eof3772 + } + st_case_3772: + switch data[p] { + case 133: + goto tr420 + case 137: + goto tr420 + case 142: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 150 { + goto tr420 + } + case data[p] > 158: + if 159 <= data[p] && data[p] <= 161 { + goto tr148 + } + default: + goto tr420 + } + case data[p] > 165: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr420 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr420 + } + default: + goto tr420 + } + goto tr3374 + st3773: + if p++; p == pe { + goto _test_eof3773 + } + st_case_3773: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr3374 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3774: + if p++; p == pe { + goto _test_eof3774 + } + st_case_3774: + switch data[p] { + case 138: + goto tr3374 + case 150: + goto tr3374 + } + switch { + case data[p] < 152: + switch { + case data[p] > 134: + if 143 <= data[p] && data[p] <= 148 { + goto tr3374 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto tr3374 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr3374 + } + goto tr420 + st3775: + if p++; p == pe { + goto _test_eof3775 + } + st_case_3775: + if data[p] == 177 { + goto tr3374 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr3374 + } + goto tr420 + st3776: + if p++; p == pe { + goto _test_eof3776 + } + st_case_3776: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 135: + goto tr3374 + } + goto tr420 + st3777: + if p++; p == pe { + goto _test_eof3777 + } + st_case_3777: + if data[p] == 177 { + goto tr3374 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr3374 + } + case data[p] >= 180: + goto tr3374 + } + goto tr420 + st3778: + if p++; p == pe { + goto _test_eof3778 + } + st_case_3778: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 136: + goto tr3374 + } + goto tr420 + st3779: + if p++; p == pe { + goto _test_eof3779 + } + st_case_3779: + switch data[p] { + case 128: + goto tr148 + case 181: + goto tr3374 + case 183: + goto tr3374 + case 185: + goto tr3374 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto tr3374 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto tr3374 + } + default: + goto tr421 + } + goto tr420 + st3780: + if p++; p == pe { + goto _test_eof3780 + } + st_case_3780: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto tr3374 + } + default: + goto tr148 + } + goto tr420 + st3781: + if p++; p == pe { + goto _test_eof3781 + } + st_case_3781: + switch { + case data[p] < 136: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 135 { + goto tr3374 + } + case data[p] >= 128: + goto tr3374 + } + case data[p] > 140: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr3374 + } + case data[p] >= 141: + goto tr3374 + } + default: + goto tr148 + } + goto tr420 + st3782: + if p++; p == pe { + goto _test_eof3782 + } + st_case_3782: + if data[p] == 134 { + goto tr3374 + } + goto tr420 + st3783: + if p++; p == pe { + goto _test_eof3783 + } + st_case_3783: + switch data[p] { + case 128: + goto st3784 + case 129: + goto st3785 + case 130: + goto st3786 + case 131: + goto st202 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st3787 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st3788 + case 157: + goto st3789 + case 158: + goto st3790 + case 159: + goto st3791 + case 160: + goto st3792 + case 161: + goto st219 + case 162: + goto st3793 + case 163: + goto st221 + case 164: + goto st3794 + case 165: + goto st468 + case 167: + goto st469 + case 168: + goto st3795 + case 169: + goto st3796 + case 170: + goto st3797 + case 172: + goto st3798 + case 173: + goto st3799 + case 174: + goto st3800 + case 175: + goto st3801 + case 176: + goto st3802 + case 177: + goto st640 + case 179: + goto st3803 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st3804 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + } + switch { + case data[p] < 180: + if 132 <= data[p] && data[p] <= 152 { + goto st145 + } + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + default: + goto st147 + } + goto tr420 + st3784: + if p++; p == pe { + goto _test_eof3784 + } + st_case_3784: + if 171 <= data[p] && data[p] <= 190 { + goto tr3374 + } + goto tr420 + st3785: + if p++; p == pe { + goto _test_eof3785 + } + st_case_3785: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto tr3374 + } + case data[p] >= 128: + goto tr421 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto tr3374 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr3374 + } + default: + goto tr3374 + } + default: + goto tr3374 + } + goto tr420 + st3786: + if p++; p == pe { + goto _test_eof3786 + } + st_case_3786: + if data[p] == 143 { + goto tr3374 + } + switch { + case data[p] < 144: + if 130 <= data[p] && data[p] <= 141 { + goto tr3374 + } + case data[p] > 153: + switch { + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 154: + goto tr3374 + } + default: + goto tr421 + } + goto tr420 + st3787: + if p++; p == pe { + goto _test_eof3787 + } + st_case_3787: + switch { + case data[p] < 157: + if 155 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr420 + } + default: + goto tr3374 + } + goto tr148 + st3788: + if p++; p == pe { + goto _test_eof3788 + } + st_case_3788: + switch { + case data[p] < 146: + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 177: + if 178 <= data[p] && data[p] <= 180 { + goto tr3374 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr3374 + } + goto tr420 + st3789: + if p++; p == pe { + goto _test_eof3789 + } + st_case_3789: + switch { + case data[p] < 160: + switch { + case data[p] > 145: + if 146 <= data[p] && data[p] <= 147 { + goto tr3374 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto tr3374 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3790: + if p++; p == pe { + goto _test_eof3790 + } + st_case_3790: + if 180 <= data[p] { + goto tr3374 + } + goto tr420 + st3791: + if p++; p == pe { + goto _test_eof3791 + } + st_case_3791: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 170 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr420 + } + goto tr3374 + st3792: + if p++; p == pe { + goto _test_eof3792 + } + st_case_3792: + switch { + case data[p] < 144: + if 139 <= data[p] && data[p] <= 142 { + goto tr3374 + } + case data[p] > 153: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + goto tr420 + st3793: + if p++; p == pe { + goto _test_eof3793 + } + st_case_3793: + if data[p] == 169 { + goto tr3374 + } + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3794: + if p++; p == pe { + goto _test_eof3794 + } + st_case_3794: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr3374 + } + default: + goto tr3374 + } + goto tr420 + st3795: + if p++; p == pe { + goto _test_eof3795 + } + st_case_3795: + switch { + case data[p] > 150: + if 151 <= data[p] && data[p] <= 155 { + goto tr3374 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3796: + if p++; p == pe { + goto _test_eof3796 + } + st_case_3796: + if data[p] == 191 { + goto tr3374 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr3374 + } + case data[p] >= 149: + goto tr3374 + } + goto tr420 + st3797: + if p++; p == pe { + goto _test_eof3797 + } + st_case_3797: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto tr3374 + } + default: + goto tr421 + } + goto tr420 + st3798: + if p++; p == pe { + goto _test_eof3798 + } + st_case_3798: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 132 { + goto tr3374 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr3374 + } + default: + goto tr148 + } + goto tr420 + st3799: + if p++; p == pe { + goto _test_eof3799 + } + st_case_3799: + switch { + case data[p] < 144: + switch { + case data[p] > 139: + if 140 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] >= 133: + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 154: + goto tr420 + } + default: + goto tr421 + } + goto tr3374 + st3800: + if p++; p == pe { + goto _test_eof3800 + } + st_case_3800: + switch { + case data[p] < 161: + switch { + case data[p] > 130: + if 131 <= data[p] && data[p] <= 160 { + goto tr148 + } + case data[p] >= 128: + goto tr3374 + } + case data[p] > 173: + switch { + case data[p] < 176: + if 174 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + default: + goto tr3374 + } + goto tr420 + st3801: + if p++; p == pe { + goto _test_eof3801 + } + st_case_3801: + switch { + case data[p] > 179: + if 180 <= data[p] { + goto tr420 + } + case data[p] >= 166: + goto tr3374 + } + goto tr148 + st3802: + if p++; p == pe { + goto _test_eof3802 + } + st_case_3802: + switch { + case data[p] > 163: + if 164 <= data[p] && data[p] <= 183 { + goto tr3374 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3803: + if p++; p == pe { + goto _test_eof3803 + } + st_case_3803: + if data[p] == 173 { + goto tr3374 + } + switch { + case data[p] < 169: + switch { + case data[p] > 146: + if 148 <= data[p] && data[p] <= 168 { + goto tr3374 + } + case data[p] >= 144: + goto tr3374 + } + case data[p] > 177: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 180 { + goto tr3374 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto tr3374 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3804: + if p++; p == pe { + goto _test_eof3804 + } + st_case_3804: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr3374 + } + case data[p] >= 128: + goto tr3374 + } + goto tr420 + st3805: + if p++; p == pe { + goto _test_eof3805 + } + st_case_3805: + switch data[p] { + case 128: + goto st3806 + case 129: + goto st3807 + case 130: + goto st241 + case 131: + goto st3808 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st3809 + case 180: + goto st251 + case 181: + goto st3810 + case 182: + goto st253 + case 183: + goto st3811 + case 184: + goto st255 + } + goto tr420 + st3806: + if p++; p == pe { + goto _test_eof3806 + } + st_case_3806: + switch data[p] { + case 164: + goto st142 + case 167: + goto st142 + } + switch { + case data[p] < 152: + if 140 <= data[p] && data[p] <= 143 { + goto tr3374 + } + case data[p] > 153: + switch { + case data[p] > 174: + if 191 <= data[p] { + goto tr571 + } + case data[p] >= 170: + goto tr3374 + } + default: + goto st142 + } + goto tr420 + st3807: + if p++; p == pe { + goto _test_eof3807 + } + st_case_3807: + switch data[p] { + case 165: + goto tr420 + case 177: + goto tr148 + case 191: + goto tr148 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 160: + goto tr3374 + } + default: + goto tr420 + } + goto tr571 + st3808: + if p++; p == pe { + goto _test_eof3808 + } + st_case_3808: + if 144 <= data[p] && data[p] <= 176 { + goto tr3374 + } + goto tr420 + st3809: + if p++; p == pe { + goto _test_eof3809 + } + st_case_3809: + switch { + case data[p] < 175: + if 165 <= data[p] && data[p] <= 170 { + goto tr420 + } + case data[p] > 177: + if 180 <= data[p] { + goto tr420 + } + default: + goto tr3374 + } + goto tr148 + st3810: + if p++; p == pe { + goto _test_eof3810 + } + st_case_3810: + if data[p] == 191 { + goto tr3374 + } + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr420 + } + case data[p] >= 168: + goto tr420 + } + goto tr148 + st3811: + if p++; p == pe { + goto _test_eof3811 + } + st_case_3811: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto tr3374 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3812: + if p++; p == pe { + goto _test_eof3812 + } + st_case_3812: + switch data[p] { + case 128: + goto st3813 + case 130: + goto st3814 + case 132: + goto st259 + case 133: + goto st145 + case 134: + goto st260 + } + goto tr420 + st3813: + if p++; p == pe { + goto _test_eof3813 + } + st_case_3813: + if data[p] == 133 { + goto tr148 + } + switch { + case data[p] > 175: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + case data[p] >= 170: + goto tr3374 + } + goto tr420 + st3814: + if p++; p == pe { + goto _test_eof3814 + } + st_case_3814: + if 153 <= data[p] && data[p] <= 154 { + goto tr3374 + } + goto tr420 + st3815: + if p++; p == pe { + goto _test_eof3815 + } + st_case_3815: + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st654 + case 153: + goto st3816 + case 154: + goto st3817 + case 155: + goto st3818 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st3819 + case 161: + goto st272 + case 162: + goto st3820 + case 163: + goto st3821 + case 164: + goto st3822 + case 165: + goto st3823 + case 166: + goto st3824 + case 167: + goto st3825 + case 168: + goto st3826 + case 169: + goto st3827 + case 170: + goto st3828 + case 171: + goto st3829 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st3830 + case 176: + goto st147 + } + if 129 <= data[p] { + goto st145 + } + goto tr420 + st3816: + if p++; p == pe { + goto _test_eof3816 + } + st_case_3816: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr3374 + } + default: + goto tr3374 + } + goto tr420 + st3817: + if p++; p == pe { + goto _test_eof3817 + } + st_case_3817: + switch { + case data[p] < 158: + if 128 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr3374 + } + goto tr420 + st3818: + if p++; p == pe { + goto _test_eof3818 + } + st_case_3818: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr3374 + } + goto tr148 + st3819: + if p++; p == pe { + goto _test_eof3819 + } + st_case_3819: + switch data[p] { + case 130: + goto tr3374 + case 134: + goto tr3374 + case 139: + goto tr3374 + } + switch { + case data[p] > 167: + if 168 <= data[p] { + goto tr420 + } + case data[p] >= 163: + goto tr3374 + } + goto tr148 + st3820: + if p++; p == pe { + goto _test_eof3820 + } + st_case_3820: + switch { + case data[p] < 130: + if 128 <= data[p] && data[p] <= 129 { + goto tr3374 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr3374 + } + default: + goto tr148 + } + goto tr420 + st3821: + if p++; p == pe { + goto _test_eof3821 + } + st_case_3821: + switch data[p] { + case 187: + goto tr148 + case 189: + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 143: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 133: + goto tr420 + } + case data[p] > 159: + switch { + case data[p] > 183: + if 184 <= data[p] { + goto tr420 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr420 + } + goto tr3374 + st3822: + if p++; p == pe { + goto _test_eof3822 + } + st_case_3822: + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 165: + switch { + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr3374 + } + default: + goto tr148 + } + goto tr420 + st3823: + if p++; p == pe { + goto _test_eof3823 + } + st_case_3823: + switch { + case data[p] < 148: + if 135 <= data[p] && data[p] <= 147 { + goto tr3374 + } + case data[p] > 159: + if 189 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr148 + st3824: + if p++; p == pe { + goto _test_eof3824 + } + st_case_3824: + switch { + case data[p] < 132: + if 128 <= data[p] && data[p] <= 131 { + goto tr3374 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr3374 + } + default: + goto tr148 + } + goto tr420 + st3825: + if p++; p == pe { + goto _test_eof3825 + } + st_case_3825: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 129: + goto tr420 + } + case data[p] > 164: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr420 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + default: + goto tr420 + } + goto tr3374 + st3826: + if p++; p == pe { + goto _test_eof3826 + } + st_case_3826: + switch { + case data[p] > 168: + if 169 <= data[p] && data[p] <= 182 { + goto tr3374 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3827: + if p++; p == pe { + goto _test_eof3827 + } + st_case_3827: + if data[p] == 131 { + goto tr3374 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 141: + switch { + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto tr3374 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr3374 + } + goto tr420 + st3828: + if p++; p == pe { + goto _test_eof3828 + } + st_case_3828: + if data[p] == 176 { + goto tr3374 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr3374 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr3374 + } + default: + goto tr3374 + } + goto tr420 + st3829: + if p++; p == pe { + goto _test_eof3829 + } + st_case_3829: + if data[p] == 129 { + goto tr3374 + } + switch { + case data[p] < 171: + if 160 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 181 <= data[p] && data[p] <= 182 { + goto tr3374 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr3374 + } + goto tr420 + st3830: + if p++; p == pe { + goto _test_eof3830 + } + st_case_3830: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 162 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 172: + goto tr3374 + } + default: + goto tr3374 + } + goto tr420 + st3831: + if p++; p == pe { + goto _test_eof3831 + } + st_case_3831: + switch data[p] { + case 172: + goto st3832 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st3833 + case 185: + goto st967 + case 187: + goto st3834 + case 188: + goto st969 + case 189: + goto st303 + case 190: + goto st3835 + case 191: + goto st3836 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr420 + st3832: + if p++; p == pe { + goto _test_eof3832 + } + st_case_3832: + switch data[p] { + case 158: + goto tr3374 + case 190: + goto tr572 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 170: + goto tr572 + } + default: + goto tr572 + } + goto tr420 + st3833: + if p++; p == pe { + goto _test_eof3833 + } + st_case_3833: + if data[p] == 147 { + goto st142 + } + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr3374 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr571 + } + default: + goto tr3374 + } + goto tr420 + st3834: + if p++; p == pe { + goto _test_eof3834 + } + st_case_3834: + if data[p] == 191 { + goto tr3374 + } + if 189 <= data[p] { + goto tr420 + } + goto tr148 + st3835: + if p++; p == pe { + goto _test_eof3835 + } + st_case_3835: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 190 { + goto tr148 + } + case data[p] >= 158: + goto tr3374 + } + goto tr420 + st3836: + if p++; p == pe { + goto _test_eof3836 + } + st_case_3836: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr148 + } + case data[p] >= 130: + goto tr148 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr3374 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3837: + if p++; p == pe { + goto _test_eof3837 + } + st_case_3837: + switch data[p] { + case 144: + goto st3838 + case 145: + goto st3844 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st3863 + case 155: + goto st3868 + case 157: + goto st3870 + case 158: + goto st3877 + case 159: + goto st403 + } + goto tr420 + st3838: + if p++; p == pe { + goto _test_eof3838 + } + st_case_3838: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st3839 + case 138: + goto st313 + case 139: + goto st3840 + case 140: + goto st315 + case 141: + goto st3841 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st684 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st3842 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st3843 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr420 + st3839: + if p++; p == pe { + goto _test_eof3839 + } + st_case_3839: + if data[p] == 189 { + goto tr3374 + } + goto tr420 + st3840: + if p++; p == pe { + goto _test_eof3840 + } + st_case_3840: + if data[p] == 160 { + goto tr3374 + } + if 145 <= data[p] { + goto tr420 + } + goto tr148 + st3841: + if p++; p == pe { + goto _test_eof3841 + } + st_case_3841: + switch { + case data[p] < 182: + if 139 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr420 + } + default: + goto tr3374 + } + goto tr148 + st3842: + if p++; p == pe { + goto _test_eof3842 + } + st_case_3842: + switch data[p] { + case 128: + goto tr148 + case 191: + goto tr3374 + } + switch { + case data[p] < 144: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr3374 + } + case data[p] > 134: + if 140 <= data[p] && data[p] <= 143 { + goto tr3374 + } + default: + goto tr3374 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto tr3374 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3843: + if p++; p == pe { + goto _test_eof3843 + } + st_case_3843: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 164: + if 165 <= data[p] && data[p] <= 166 { + goto tr3374 + } + default: + goto tr148 + } + goto tr420 + st3844: + if p++; p == pe { + goto _test_eof3844 + } + st_case_3844: + switch data[p] { + case 128: + goto st3845 + case 129: + goto st3846 + case 130: + goto st3847 + case 131: + goto st691 + case 132: + goto st3848 + case 133: + goto st3849 + case 134: + goto st3850 + case 135: + goto st3851 + case 136: + goto st3852 + case 138: + goto st348 + case 139: + goto st3853 + case 140: + goto st3854 + case 141: + goto st3855 + case 146: + goto st3856 + case 147: + goto st3857 + case 150: + goto st3858 + case 151: + goto st3859 + case 152: + goto st3856 + case 153: + goto st3860 + case 154: + goto st3861 + case 155: + goto st538 + case 156: + goto st3862 + case 162: + goto st359 + case 163: + goto st707 + case 171: + goto st361 + } + goto tr420 + st3845: + if p++; p == pe { + goto _test_eof3845 + } + st_case_3845: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr3374 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr3374 + } + default: + goto tr148 + } + goto tr420 + st3846: + if p++; p == pe { + goto _test_eof3846 + } + st_case_3846: + switch { + case data[p] < 166: + if 135 <= data[p] && data[p] <= 165 { + goto tr420 + } + case data[p] > 175: + if 176 <= data[p] && data[p] <= 190 { + goto tr420 + } + default: + goto tr421 + } + goto tr3374 + st3847: + if p++; p == pe { + goto _test_eof3847 + } + st_case_3847: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr3374 + st3848: + if p++; p == pe { + goto _test_eof3848 + } + st_case_3848: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr3374 + } + case data[p] > 166: + switch { + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr421 + } + case data[p] >= 167: + goto tr3374 + } + default: + goto tr148 + } + goto tr420 + st3849: + if p++; p == pe { + goto _test_eof3849 + } + st_case_3849: + switch data[p] { + case 179: + goto tr3374 + case 182: + goto tr148 + } + if 144 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr420 + st3850: + if p++; p == pe { + goto _test_eof3850 + } + st_case_3850: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr3374 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr3374 + } + default: + goto tr148 + } + goto tr420 + st3851: + if p++; p == pe { + goto _test_eof3851 + } + st_case_3851: + if data[p] == 155 { + goto tr420 + } + switch { + case data[p] < 141: + switch { + case data[p] > 132: + if 133 <= data[p] && data[p] <= 137 { + goto tr420 + } + case data[p] >= 129: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] < 154: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] > 156: + if 157 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + default: + goto tr420 + } + goto tr3374 + st3852: + if p++; p == pe { + goto _test_eof3852 + } + st_case_3852: + switch { + case data[p] < 147: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] > 171: + if 172 <= data[p] && data[p] <= 183 { + goto tr3374 + } + default: + goto tr148 + } + goto tr420 + st3853: + if p++; p == pe { + goto _test_eof3853 + } + st_case_3853: + switch { + case data[p] < 171: + if 159 <= data[p] && data[p] <= 170 { + goto tr3374 + } + case data[p] > 175: + switch { + case data[p] > 185: + if 186 <= data[p] { + goto tr420 + } + case data[p] >= 176: + goto tr421 + } + default: + goto tr420 + } + goto tr148 + st3854: + if p++; p == pe { + goto _test_eof3854 + } + st_case_3854: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto tr3374 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr3374 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr420 + st3855: + if p++; p == pe { + goto _test_eof3855 + } + st_case_3855: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr3374 + } + switch { + case data[p] < 157: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr3374 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr3374 + } + default: + goto tr3374 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr3374 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr3374 + } + default: + goto tr3374 + } + default: + goto tr148 + } + goto tr420 + st3856: + if p++; p == pe { + goto _test_eof3856 + } + st_case_3856: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr3374 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3857: + if p++; p == pe { + goto _test_eof3857 + } + st_case_3857: + if data[p] == 134 { + goto tr420 + } + switch { + case data[p] < 136: + if 132 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr420 + } + goto tr3374 + st3858: + if p++; p == pe { + goto _test_eof3858 + } + st_case_3858: + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 181: + if 184 <= data[p] { + goto tr3374 + } + default: + goto tr3374 + } + goto tr420 + st3859: + if p++; p == pe { + goto _test_eof3859 + } + st_case_3859: + switch { + case data[p] < 152: + if 129 <= data[p] && data[p] <= 151 { + goto tr420 + } + case data[p] > 155: + if 158 <= data[p] { + goto tr420 + } + default: + goto tr148 + } + goto tr3374 + st3860: + if p++; p == pe { + goto _test_eof3860 + } + st_case_3860: + if data[p] == 132 { + goto tr148 + } + switch { + case data[p] < 144: + if 129 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr420 + } + default: + goto tr421 + } + goto tr3374 + st3861: + if p++; p == pe { + goto _test_eof3861 + } + st_case_3861: + switch { + case data[p] > 170: + if 171 <= data[p] && data[p] <= 183 { + goto tr3374 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3862: + if p++; p == pe { + goto _test_eof3862 + } + st_case_3862: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 157: + goto tr3374 + } + goto tr420 + st3863: + if p++; p == pe { + goto _test_eof3863 + } + st_case_3863: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st709 + case 171: + goto st3864 + case 172: + goto st3865 + case 173: + goto st712 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st3866 + case 190: + goto st3867 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr420 + st3864: + if p++; p == pe { + goto _test_eof3864 + } + st_case_3864: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto tr3374 + } + case data[p] >= 144: + goto tr148 + } + goto tr420 + st3865: + if p++; p == pe { + goto _test_eof3865 + } + st_case_3865: + switch { + case data[p] > 175: + if 176 <= data[p] && data[p] <= 182 { + goto tr3374 + } + case data[p] >= 128: + goto tr148 + } + goto tr420 + st3866: + if p++; p == pe { + goto _test_eof3866 + } + st_case_3866: + switch { + case data[p] < 145: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr420 + } + default: + goto tr3374 + } + goto tr148 + st3867: + if p++; p == pe { + goto _test_eof3867 + } + st_case_3867: + switch { + case data[p] > 146: + if 147 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 143: + goto tr3374 + } + goto tr420 + st3868: + if p++; p == pe { + goto _test_eof3868 + } + st_case_3868: + switch data[p] { + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st3869 + } + goto tr420 + st3869: + if p++; p == pe { + goto _test_eof3869 + } + st_case_3869: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr3374 + } + case data[p] >= 157: + goto tr3374 + } + default: + goto tr148 + } + goto tr420 + st3870: + if p++; p == pe { + goto _test_eof3870 + } + st_case_3870: + switch data[p] { + case 133: + goto st3871 + case 134: + goto st3872 + case 137: + goto st3873 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st721 + case 168: + goto st3874 + case 169: + goto st3875 + case 170: + goto st3876 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr420 + st3871: + if p++; p == pe { + goto _test_eof3871 + } + st_case_3871: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr3374 + } + case data[p] >= 165: + goto tr3374 + } + goto tr420 + st3872: + if p++; p == pe { + goto _test_eof3872 + } + st_case_3872: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr420 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr420 + } + default: + goto tr420 + } + goto tr3374 + st3873: + if p++; p == pe { + goto _test_eof3873 + } + st_case_3873: + if 130 <= data[p] && data[p] <= 132 { + goto tr3374 + } + goto tr420 + st3874: + if p++; p == pe { + goto _test_eof3874 + } + st_case_3874: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr3374 + } + case data[p] >= 128: + goto tr3374 + } + goto tr420 + st3875: + if p++; p == pe { + goto _test_eof3875 + } + st_case_3875: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr420 + } + case data[p] >= 173: + goto tr420 + } + goto tr3374 + st3876: + if p++; p == pe { + goto _test_eof3876 + } + st_case_3876: + if data[p] == 132 { + goto tr3374 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr3374 + } + case data[p] >= 155: + goto tr3374 + } + goto tr420 + st3877: + if p++; p == pe { + goto _test_eof3877 + } + st_case_3877: + switch data[p] { + case 160: + goto st147 + case 163: + goto st3878 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr420 + st3878: + if p++; p == pe { + goto _test_eof3878 + } + st_case_3878: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr420 + } + case data[p] > 150: + if 151 <= data[p] { + goto tr420 + } + default: + goto tr3374 + } + goto tr148 + st3879: + if p++; p == pe { + goto _test_eof3879 + } + st_case_3879: + if data[p] == 160 { + goto st3880 + } + goto tr420 + st3880: + if p++; p == pe { + goto _test_eof3880 + } + st_case_3880: + switch data[p] { + case 128: + goto st3881 + case 129: + goto st3882 + case 132: + goto st3739 + case 135: + goto st3884 + } + if 133 <= data[p] && data[p] <= 134 { + goto st3883 + } + goto tr420 + st3881: + if p++; p == pe { + goto _test_eof3881 + } + st_case_3881: + if data[p] == 129 { + goto tr3374 + } + if 160 <= data[p] { + goto tr3374 + } + goto tr420 + st3882: + if p++; p == pe { + goto _test_eof3882 + } + st_case_3882: + if 192 <= data[p] { + goto tr420 + } + goto tr3374 + st3883: + if p++; p == pe { + goto _test_eof3883 + } + st_case_3883: + goto tr3374 + st3884: + if p++; p == pe { + goto _test_eof3884 + } + st_case_3884: + if 176 <= data[p] { + goto tr420 + } + goto tr3374 +tr3375: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5079 + st5079: + if p++; p == pe { + goto _test_eof5079 + } + st_case_5079: +//line segment_words_prod.go:116725 + switch data[p] { + case 194: + goto st3885 + case 204: + goto st3886 + case 205: + goto st3887 + case 210: + goto st3888 + case 214: + goto st3889 + case 215: + goto st3890 + case 216: + goto st3891 + case 217: + goto st3892 + case 219: + goto st3893 + case 220: + goto st3894 + case 221: + goto st3895 + case 222: + goto st3896 + case 223: + goto st3897 + case 224: + goto st3898 + case 225: + goto st3927 + case 226: + goto st3949 + case 227: + goto st3956 + case 234: + goto st3959 + case 237: + goto st3447 + case 239: + goto st3975 + case 240: + goto st3980 + case 243: + goto st4022 + } + if 235 <= data[p] && data[p] <= 236 { + goto st3446 + } + goto tr5002 + st3885: + if p++; p == pe { + goto _test_eof3885 + } + st_case_3885: + if data[p] == 173 { + goto tr3375 + } + goto tr2985 + st3886: + if p++; p == pe { + goto _test_eof3886 + } + st_case_3886: + if 128 <= data[p] { + goto tr3375 + } + goto tr2985 + st3887: + if p++; p == pe { + goto _test_eof3887 + } + st_case_3887: + if 176 <= data[p] { + goto tr2985 + } + goto tr3375 + st3888: + if p++; p == pe { + goto _test_eof3888 + } + st_case_3888: + if 131 <= data[p] && data[p] <= 137 { + goto tr3375 + } + goto tr2985 + st3889: + if p++; p == pe { + goto _test_eof3889 + } + st_case_3889: + if data[p] == 191 { + goto tr3375 + } + if 145 <= data[p] && data[p] <= 189 { + goto tr3375 + } + goto tr2985 + st3890: + if p++; p == pe { + goto _test_eof3890 + } + st_case_3890: + if data[p] == 135 { + goto tr3375 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto tr3375 + } + case data[p] >= 129: + goto tr3375 + } + goto tr2985 + st3891: + if p++; p == pe { + goto _test_eof3891 + } + st_case_3891: + if data[p] == 156 { + goto tr3375 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto tr3375 + } + case data[p] >= 128: + goto tr3375 + } + goto tr2985 + st3892: + if p++; p == pe { + goto _test_eof3892 + } + st_case_3892: + if data[p] == 176 { + goto tr3375 + } + if 139 <= data[p] && data[p] <= 159 { + goto tr3375 + } + goto tr2985 + st3893: + if p++; p == pe { + goto _test_eof3893 + } + st_case_3893: + switch { + case data[p] < 159: + if 150 <= data[p] && data[p] <= 157 { + goto tr3375 + } + case data[p] > 164: + switch { + case data[p] > 168: + if 170 <= data[p] && data[p] <= 173 { + goto tr3375 + } + case data[p] >= 167: + goto tr3375 + } + default: + goto tr3375 + } + goto tr2985 + st3894: + if p++; p == pe { + goto _test_eof3894 + } + st_case_3894: + switch data[p] { + case 143: + goto tr3375 + case 145: + goto tr3375 + } + if 176 <= data[p] { + goto tr3375 + } + goto tr2985 + st3895: + if p++; p == pe { + goto _test_eof3895 + } + st_case_3895: + if 139 <= data[p] { + goto tr2985 + } + goto tr3375 + st3896: + if p++; p == pe { + goto _test_eof3896 + } + st_case_3896: + if 166 <= data[p] && data[p] <= 176 { + goto tr3375 + } + goto tr2985 + st3897: + if p++; p == pe { + goto _test_eof3897 + } + st_case_3897: + if 171 <= data[p] && data[p] <= 179 { + goto tr3375 + } + goto tr2985 + st3898: + if p++; p == pe { + goto _test_eof3898 + } + st_case_3898: + switch data[p] { + case 160: + goto st3899 + case 161: + goto st3900 + case 163: + goto st3901 + case 164: + goto st3902 + case 165: + goto st3903 + case 167: + goto st3905 + case 169: + goto st3906 + case 171: + goto st3907 + case 173: + goto st3909 + case 174: + goto st3910 + case 175: + goto st3911 + case 176: + goto st3912 + case 177: + goto st3913 + case 179: + goto st3914 + case 180: + goto st3915 + case 181: + goto st3916 + case 182: + goto st3917 + case 183: + goto st3918 + case 184: + goto st3919 + case 185: + goto st3920 + case 186: + goto st3921 + case 187: + goto st3922 + case 188: + goto st3923 + case 189: + goto st3924 + case 190: + goto st3925 + case 191: + goto st3926 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto st3908 + } + case data[p] >= 166: + goto st3904 + } + goto tr2985 + st3899: + if p++; p == pe { + goto _test_eof3899 + } + st_case_3899: + switch { + case data[p] < 155: + if 150 <= data[p] && data[p] <= 153 { + goto tr3375 + } + case data[p] > 163: + switch { + case data[p] > 167: + if 169 <= data[p] && data[p] <= 173 { + goto tr3375 + } + case data[p] >= 165: + goto tr3375 + } + default: + goto tr3375 + } + goto tr2985 + st3900: + if p++; p == pe { + goto _test_eof3900 + } + st_case_3900: + if 153 <= data[p] && data[p] <= 155 { + goto tr3375 + } + goto tr2985 + st3901: + if p++; p == pe { + goto _test_eof3901 + } + st_case_3901: + if 163 <= data[p] { + goto tr3375 + } + goto tr2985 + st3902: + if p++; p == pe { + goto _test_eof3902 + } + st_case_3902: + if data[p] == 189 { + goto tr2985 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr2985 + } + goto tr3375 + st3903: + if p++; p == pe { + goto _test_eof3903 + } + st_case_3903: + if data[p] == 144 { + goto tr2985 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr2985 + } + case data[p] >= 152: + goto tr2985 + } + goto tr3375 + st3904: + if p++; p == pe { + goto _test_eof3904 + } + st_case_3904: + if data[p] == 188 { + goto tr3375 + } + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr3375 + } + case data[p] >= 129: + goto tr3375 + } + goto tr2985 + st3905: + if p++; p == pe { + goto _test_eof3905 + } + st_case_3905: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr2985 + } + case data[p] >= 133: + goto tr2985 + } + case data[p] > 150: + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr2985 + } + case data[p] >= 152: + goto tr2985 + } + default: + goto tr2985 + } + goto tr3375 + st3906: + if p++; p == pe { + goto _test_eof3906 + } + st_case_3906: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr2985 + } + case data[p] >= 131: + goto tr2985 + } + case data[p] > 144: + switch { + case data[p] < 178: + if 146 <= data[p] && data[p] <= 175 { + goto tr2985 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr2985 + } + default: + goto tr2985 + } + default: + goto tr2985 + } + goto tr3375 + st3907: + if p++; p == pe { + goto _test_eof3907 + } + st_case_3907: + switch data[p] { + case 134: + goto tr2985 + case 138: + goto tr2985 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr2985 + } + case data[p] >= 142: + goto tr2985 + } + goto tr3375 + st3908: + if p++; p == pe { + goto _test_eof3908 + } + st_case_3908: + if data[p] == 188 { + goto tr3375 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr3375 + } + case data[p] >= 129: + goto tr3375 + } + goto tr2985 + st3909: + if p++; p == pe { + goto _test_eof3909 + } + st_case_3909: + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr3375 + } + case data[p] >= 128: + goto tr3375 + } + case data[p] > 141: + switch { + case data[p] > 151: + if 162 <= data[p] && data[p] <= 163 { + goto tr3375 + } + case data[p] >= 150: + goto tr3375 + } + default: + goto tr3375 + } + goto tr2985 + st3910: + if p++; p == pe { + goto _test_eof3910 + } + st_case_3910: + if data[p] == 130 { + goto tr3375 + } + if 190 <= data[p] && data[p] <= 191 { + goto tr3375 + } + goto tr2985 + st3911: + if p++; p == pe { + goto _test_eof3911 + } + st_case_3911: + if data[p] == 151 { + goto tr3375 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr3375 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr3375 + } + default: + goto tr3375 + } + goto tr2985 + st3912: + if p++; p == pe { + goto _test_eof3912 + } + st_case_3912: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr3375 + } + case data[p] >= 128: + goto tr3375 + } + goto tr2985 + st3913: + if p++; p == pe { + goto _test_eof3913 + } + st_case_3913: + switch data[p] { + case 133: + goto tr2985 + case 137: + goto tr2985 + } + switch { + case data[p] < 151: + if 142 <= data[p] && data[p] <= 148 { + goto tr2985 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr2985 + } + default: + goto tr2985 + } + goto tr3375 + st3914: + if p++; p == pe { + goto _test_eof3914 + } + st_case_3914: + switch { + case data[p] < 138: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 136 { + goto tr3375 + } + case data[p] >= 128: + goto tr3375 + } + case data[p] > 141: + switch { + case data[p] > 150: + if 162 <= data[p] && data[p] <= 163 { + goto tr3375 + } + case data[p] >= 149: + goto tr3375 + } + default: + goto tr3375 + } + goto tr2985 + st3915: + if p++; p == pe { + goto _test_eof3915 + } + st_case_3915: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr3375 + } + case data[p] >= 129: + goto tr3375 + } + goto tr2985 + st3916: + if p++; p == pe { + goto _test_eof3916 + } + st_case_3916: + switch data[p] { + case 133: + goto tr2985 + case 137: + goto tr2985 + } + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 150 { + goto tr2985 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr2985 + } + default: + goto tr2985 + } + goto tr3375 + st3917: + if p++; p == pe { + goto _test_eof3917 + } + st_case_3917: + if 130 <= data[p] && data[p] <= 131 { + goto tr3375 + } + goto tr2985 + st3918: + if p++; p == pe { + goto _test_eof3918 + } + st_case_3918: + switch data[p] { + case 138: + goto tr3375 + case 150: + goto tr3375 + } + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 148 { + goto tr3375 + } + case data[p] > 159: + if 178 <= data[p] && data[p] <= 179 { + goto tr3375 + } + default: + goto tr3375 + } + goto tr2985 + st3919: + if p++; p == pe { + goto _test_eof3919 + } + st_case_3919: + if data[p] == 177 { + goto tr3375 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr3375 + } + goto tr2985 + st3920: + if p++; p == pe { + goto _test_eof3920 + } + st_case_3920: + if 135 <= data[p] && data[p] <= 142 { + goto tr3375 + } + goto tr2985 + st3921: + if p++; p == pe { + goto _test_eof3921 + } + st_case_3921: + if data[p] == 177 { + goto tr3375 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr3375 + } + case data[p] >= 180: + goto tr3375 + } + goto tr2985 + st3922: + if p++; p == pe { + goto _test_eof3922 + } + st_case_3922: + if 136 <= data[p] && data[p] <= 141 { + goto tr3375 + } + goto tr2985 + st3923: + if p++; p == pe { + goto _test_eof3923 + } + st_case_3923: + switch data[p] { + case 181: + goto tr3375 + case 183: + goto tr3375 + case 185: + goto tr3375 + } + switch { + case data[p] > 153: + if 190 <= data[p] && data[p] <= 191 { + goto tr3375 + } + case data[p] >= 152: + goto tr3375 + } + goto tr2985 + st3924: + if p++; p == pe { + goto _test_eof3924 + } + st_case_3924: + if 177 <= data[p] && data[p] <= 191 { + goto tr3375 + } + goto tr2985 + st3925: + if p++; p == pe { + goto _test_eof3925 + } + st_case_3925: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr3375 + } + case data[p] > 135: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr3375 + } + case data[p] >= 141: + goto tr3375 + } + default: + goto tr3375 + } + goto tr2985 + st3926: + if p++; p == pe { + goto _test_eof3926 + } + st_case_3926: + if data[p] == 134 { + goto tr3375 + } + goto tr2985 + st3927: + if p++; p == pe { + goto _test_eof3927 + } + st_case_3927: + switch data[p] { + case 128: + goto st3928 + case 129: + goto st3929 + case 130: + goto st3930 + case 132: + goto st3352 + case 135: + goto st3398 + case 141: + goto st3931 + case 156: + goto st3932 + case 157: + goto st3933 + case 158: + goto st3934 + case 159: + goto st3935 + case 160: + goto st3936 + case 162: + goto st3937 + case 164: + goto st3938 + case 168: + goto st3939 + case 169: + goto st3940 + case 170: + goto st3941 + case 172: + goto st3942 + case 173: + goto st3943 + case 174: + goto st3944 + case 175: + goto st3945 + case 176: + goto st3946 + case 179: + goto st3947 + case 183: + goto st3948 + } + if 133 <= data[p] && data[p] <= 134 { + goto st3397 + } + goto tr2985 + st3928: + if p++; p == pe { + goto _test_eof3928 + } + st_case_3928: + if 171 <= data[p] && data[p] <= 190 { + goto tr3375 + } + goto tr2985 + st3929: + if p++; p == pe { + goto _test_eof3929 + } + st_case_3929: + switch { + case data[p] < 162: + switch { + case data[p] > 153: + if 158 <= data[p] && data[p] <= 160 { + goto tr3375 + } + case data[p] >= 150: + goto tr3375 + } + case data[p] > 164: + switch { + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr3375 + } + case data[p] >= 167: + goto tr3375 + } + default: + goto tr3375 + } + goto tr2985 + st3930: + if p++; p == pe { + goto _test_eof3930 + } + st_case_3930: + if data[p] == 143 { + goto tr3375 + } + switch { + case data[p] > 141: + if 154 <= data[p] && data[p] <= 157 { + goto tr3375 + } + case data[p] >= 130: + goto tr3375 + } + goto tr2985 + st3931: + if p++; p == pe { + goto _test_eof3931 + } + st_case_3931: + if 157 <= data[p] && data[p] <= 159 { + goto tr3375 + } + goto tr2985 + st3932: + if p++; p == pe { + goto _test_eof3932 + } + st_case_3932: + switch { + case data[p] > 148: + if 178 <= data[p] && data[p] <= 180 { + goto tr3375 + } + case data[p] >= 146: + goto tr3375 + } + goto tr2985 + st3933: + if p++; p == pe { + goto _test_eof3933 + } + st_case_3933: + switch { + case data[p] > 147: + if 178 <= data[p] && data[p] <= 179 { + goto tr3375 + } + case data[p] >= 146: + goto tr3375 + } + goto tr2985 + st3934: + if p++; p == pe { + goto _test_eof3934 + } + st_case_3934: + if 180 <= data[p] { + goto tr3375 + } + goto tr2985 + st3935: + if p++; p == pe { + goto _test_eof3935 + } + st_case_3935: + switch { + case data[p] > 156: + if 158 <= data[p] { + goto tr2985 + } + case data[p] >= 148: + goto tr2985 + } + goto tr3375 + st3936: + if p++; p == pe { + goto _test_eof3936 + } + st_case_3936: + if 139 <= data[p] && data[p] <= 142 { + goto tr3375 + } + goto tr2985 + st3937: + if p++; p == pe { + goto _test_eof3937 + } + st_case_3937: + if data[p] == 169 { + goto tr3375 + } + goto tr2985 + st3938: + if p++; p == pe { + goto _test_eof3938 + } + st_case_3938: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr3375 + } + case data[p] >= 160: + goto tr3375 + } + goto tr2985 + st3939: + if p++; p == pe { + goto _test_eof3939 + } + st_case_3939: + if 151 <= data[p] && data[p] <= 155 { + goto tr3375 + } + goto tr2985 + st3940: + if p++; p == pe { + goto _test_eof3940 + } + st_case_3940: + if data[p] == 191 { + goto tr3375 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr3375 + } + case data[p] >= 149: + goto tr3375 + } + goto tr2985 + st3941: + if p++; p == pe { + goto _test_eof3941 + } + st_case_3941: + if 176 <= data[p] && data[p] <= 190 { + goto tr3375 + } + goto tr2985 + st3942: + if p++; p == pe { + goto _test_eof3942 + } + st_case_3942: + switch { + case data[p] > 132: + if 180 <= data[p] { + goto tr3375 + } + case data[p] >= 128: + goto tr3375 + } + goto tr2985 + st3943: + if p++; p == pe { + goto _test_eof3943 + } + st_case_3943: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr2985 + } + case data[p] >= 133: + goto tr2985 + } + goto tr3375 + st3944: + if p++; p == pe { + goto _test_eof3944 + } + st_case_3944: + switch { + case data[p] > 130: + if 161 <= data[p] && data[p] <= 173 { + goto tr3375 + } + case data[p] >= 128: + goto tr3375 + } + goto tr2985 + st3945: + if p++; p == pe { + goto _test_eof3945 + } + st_case_3945: + if 166 <= data[p] && data[p] <= 179 { + goto tr3375 + } + goto tr2985 + st3946: + if p++; p == pe { + goto _test_eof3946 + } + st_case_3946: + if 164 <= data[p] && data[p] <= 183 { + goto tr3375 + } + goto tr2985 + st3947: + if p++; p == pe { + goto _test_eof3947 + } + st_case_3947: + if data[p] == 173 { + goto tr3375 + } + switch { + case data[p] < 148: + if 144 <= data[p] && data[p] <= 146 { + goto tr3375 + } + case data[p] > 168: + switch { + case data[p] > 180: + if 184 <= data[p] && data[p] <= 185 { + goto tr3375 + } + case data[p] >= 178: + goto tr3375 + } + default: + goto tr3375 + } + goto tr2985 + st3948: + if p++; p == pe { + goto _test_eof3948 + } + st_case_3948: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr3375 + } + case data[p] >= 128: + goto tr3375 + } + goto tr2985 + st3949: + if p++; p == pe { + goto _test_eof3949 + } + st_case_3949: + switch data[p] { + case 128: + goto st3950 + case 129: + goto st3951 + case 131: + goto st3952 + case 179: + goto st3953 + case 181: + goto st3954 + case 183: + goto st3955 + } + goto tr2985 + st3950: + if p++; p == pe { + goto _test_eof3950 + } + st_case_3950: + switch { + case data[p] > 143: + if 170 <= data[p] && data[p] <= 174 { + goto tr3375 + } + case data[p] >= 140: + goto tr3375 + } + goto tr2985 + st3951: + if p++; p == pe { + goto _test_eof3951 + } + st_case_3951: + switch { + case data[p] > 164: + if 166 <= data[p] && data[p] <= 175 { + goto tr3375 + } + case data[p] >= 160: + goto tr3375 + } + goto tr2985 + st3952: + if p++; p == pe { + goto _test_eof3952 + } + st_case_3952: + if 144 <= data[p] && data[p] <= 176 { + goto tr3375 + } + goto tr2985 + st3953: + if p++; p == pe { + goto _test_eof3953 + } + st_case_3953: + if 175 <= data[p] && data[p] <= 177 { + goto tr3375 + } + goto tr2985 + st3954: + if p++; p == pe { + goto _test_eof3954 + } + st_case_3954: + if data[p] == 191 { + goto tr3375 + } + goto tr2985 + st3955: + if p++; p == pe { + goto _test_eof3955 + } + st_case_3955: + if 160 <= data[p] && data[p] <= 191 { + goto tr3375 + } + goto tr2985 + st3956: + if p++; p == pe { + goto _test_eof3956 + } + st_case_3956: + switch data[p] { + case 128: + goto st3957 + case 130: + goto st3958 + case 132: + goto st3427 + case 133: + goto st3397 + case 134: + goto st3428 + case 136: + goto st3350 + case 137: + goto st3429 + } + goto tr2985 + st3957: + if p++; p == pe { + goto _test_eof3957 + } + st_case_3957: + if 170 <= data[p] && data[p] <= 175 { + goto tr3375 + } + goto tr2985 + st3958: + if p++; p == pe { + goto _test_eof3958 + } + st_case_3958: + if 153 <= data[p] && data[p] <= 154 { + goto tr3375 + } + goto tr2985 + st3959: + if p++; p == pe { + goto _test_eof3959 + } + st_case_3959: + switch data[p] { + case 153: + goto st3960 + case 154: + goto st3961 + case 155: + goto st3962 + case 160: + goto st3963 + case 162: + goto st3964 + case 163: + goto st3965 + case 164: + goto st3966 + case 165: + goto st3967 + case 166: + goto st3968 + case 167: + goto st3969 + case 168: + goto st3970 + case 169: + goto st3971 + case 170: + goto st3972 + case 171: + goto st3973 + case 175: + goto st3974 + case 176: + goto st3352 + } + if 177 <= data[p] { + goto st3397 + } + goto tr2985 + st3960: + if p++; p == pe { + goto _test_eof3960 + } + st_case_3960: + switch { + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr3375 + } + case data[p] >= 175: + goto tr3375 + } + goto tr2985 + st3961: + if p++; p == pe { + goto _test_eof3961 + } + st_case_3961: + if 158 <= data[p] && data[p] <= 159 { + goto tr3375 + } + goto tr2985 + st3962: + if p++; p == pe { + goto _test_eof3962 + } + st_case_3962: + if 176 <= data[p] && data[p] <= 177 { + goto tr3375 + } + goto tr2985 + st3963: + if p++; p == pe { + goto _test_eof3963 + } + st_case_3963: + switch data[p] { + case 130: + goto tr3375 + case 134: + goto tr3375 + case 139: + goto tr3375 + } + if 163 <= data[p] && data[p] <= 167 { + goto tr3375 + } + goto tr2985 + st3964: + if p++; p == pe { + goto _test_eof3964 + } + st_case_3964: + switch { + case data[p] > 129: + if 180 <= data[p] { + goto tr3375 + } + case data[p] >= 128: + goto tr3375 + } + goto tr2985 + st3965: + if p++; p == pe { + goto _test_eof3965 + } + st_case_3965: + switch { + case data[p] > 159: + if 178 <= data[p] { + goto tr2985 + } + case data[p] >= 133: + goto tr2985 + } + goto tr3375 + st3966: + if p++; p == pe { + goto _test_eof3966 + } + st_case_3966: + if 166 <= data[p] && data[p] <= 173 { + goto tr3375 + } + goto tr2985 + st3967: + if p++; p == pe { + goto _test_eof3967 + } + st_case_3967: + switch { + case data[p] > 147: + if 160 <= data[p] && data[p] <= 188 { + goto tr3053 + } + case data[p] >= 135: + goto tr3375 + } + goto tr2985 + st3968: + if p++; p == pe { + goto _test_eof3968 + } + st_case_3968: + switch { + case data[p] > 131: + if 179 <= data[p] { + goto tr3375 + } + case data[p] >= 128: + goto tr3375 + } + goto tr2985 + st3969: + if p++; p == pe { + goto _test_eof3969 + } + st_case_3969: + switch { + case data[p] > 164: + if 166 <= data[p] { + goto tr2985 + } + case data[p] >= 129: + goto tr2985 + } + goto tr3375 + st3970: + if p++; p == pe { + goto _test_eof3970 + } + st_case_3970: + if 169 <= data[p] && data[p] <= 182 { + goto tr3375 + } + goto tr2985 + st3971: + if p++; p == pe { + goto _test_eof3971 + } + st_case_3971: + if data[p] == 131 { + goto tr3375 + } + switch { + case data[p] > 141: + if 187 <= data[p] && data[p] <= 189 { + goto tr3375 + } + case data[p] >= 140: + goto tr3375 + } + goto tr2985 + st3972: + if p++; p == pe { + goto _test_eof3972 + } + st_case_3972: + if data[p] == 176 { + goto tr3375 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr3375 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr3375 + } + default: + goto tr3375 + } + goto tr2985 + st3973: + if p++; p == pe { + goto _test_eof3973 + } + st_case_3973: + if data[p] == 129 { + goto tr3375 + } + switch { + case data[p] > 175: + if 181 <= data[p] && data[p] <= 182 { + goto tr3375 + } + case data[p] >= 171: + goto tr3375 + } + goto tr2985 + st3974: + if p++; p == pe { + goto _test_eof3974 + } + st_case_3974: + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 173 { + goto tr3375 + } + case data[p] >= 163: + goto tr3375 + } + goto tr2985 + st3975: + if p++; p == pe { + goto _test_eof3975 + } + st_case_3975: + switch data[p] { + case 172: + goto st3976 + case 184: + goto st3977 + case 187: + goto st3954 + case 190: + goto st3978 + case 191: + goto st3979 + } + goto tr2985 + st3976: + if p++; p == pe { + goto _test_eof3976 + } + st_case_3976: + if data[p] == 158 { + goto tr3375 + } + goto tr2985 + st3977: + if p++; p == pe { + goto _test_eof3977 + } + st_case_3977: + switch { + case data[p] > 143: + if 160 <= data[p] && data[p] <= 175 { + goto tr3375 + } + case data[p] >= 128: + goto tr3375 + } + goto tr2985 + st3978: + if p++; p == pe { + goto _test_eof3978 + } + st_case_3978: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 190 { + goto tr3053 + } + case data[p] >= 158: + goto tr3375 + } + goto tr2985 + st3979: + if p++; p == pe { + goto _test_eof3979 + } + st_case_3979: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr3053 + } + case data[p] >= 130: + goto tr3053 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr3375 + } + case data[p] >= 154: + goto tr3053 + } + default: + goto tr3053 + } + goto tr2985 + st3980: + if p++; p == pe { + goto _test_eof3980 + } + st_case_3980: + switch data[p] { + case 144: + goto st3981 + case 145: + goto st3987 + case 150: + goto st4006 + case 155: + goto st4011 + case 157: + goto st4013 + case 158: + goto st4020 + } + goto tr2985 + st3981: + if p++; p == pe { + goto _test_eof3981 + } + st_case_3981: + switch data[p] { + case 135: + goto st3982 + case 139: + goto st3983 + case 141: + goto st3984 + case 168: + goto st3985 + case 171: + goto st3986 + } + goto tr2985 + st3982: + if p++; p == pe { + goto _test_eof3982 + } + st_case_3982: + if data[p] == 189 { + goto tr3375 + } + goto tr2985 + st3983: + if p++; p == pe { + goto _test_eof3983 + } + st_case_3983: + if data[p] == 160 { + goto tr3375 + } + goto tr2985 + st3984: + if p++; p == pe { + goto _test_eof3984 + } + st_case_3984: + if 182 <= data[p] && data[p] <= 186 { + goto tr3375 + } + goto tr2985 + st3985: + if p++; p == pe { + goto _test_eof3985 + } + st_case_3985: + if data[p] == 191 { + goto tr3375 + } + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr3375 + } + case data[p] > 134: + switch { + case data[p] > 143: + if 184 <= data[p] && data[p] <= 186 { + goto tr3375 + } + case data[p] >= 140: + goto tr3375 + } + default: + goto tr3375 + } + goto tr2985 + st3986: + if p++; p == pe { + goto _test_eof3986 + } + st_case_3986: + if 165 <= data[p] && data[p] <= 166 { + goto tr3375 + } + goto tr2985 + st3987: + if p++; p == pe { + goto _test_eof3987 + } + st_case_3987: + switch data[p] { + case 128: + goto st3988 + case 129: + goto st3989 + case 130: + goto st3990 + case 132: + goto st3991 + case 133: + goto st3992 + case 134: + goto st3993 + case 135: + goto st3994 + case 136: + goto st3995 + case 139: + goto st3996 + case 140: + goto st3997 + case 141: + goto st3998 + case 146: + goto st3999 + case 147: + goto st4000 + case 150: + goto st4001 + case 151: + goto st4002 + case 152: + goto st3999 + case 153: + goto st4003 + case 154: + goto st4004 + case 156: + goto st4005 + } + goto tr2985 + st3988: + if p++; p == pe { + goto _test_eof3988 + } + st_case_3988: + switch { + case data[p] > 130: + if 184 <= data[p] { + goto tr3375 + } + case data[p] >= 128: + goto tr3375 + } + goto tr2985 + st3989: + if p++; p == pe { + goto _test_eof3989 + } + st_case_3989: + if 135 <= data[p] && data[p] <= 190 { + goto tr2985 + } + goto tr3375 + st3990: + if p++; p == pe { + goto _test_eof3990 + } + st_case_3990: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr2985 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr2985 + } + default: + goto tr2985 + } + goto tr3375 + st3991: + if p++; p == pe { + goto _test_eof3991 + } + st_case_3991: + switch { + case data[p] > 130: + if 167 <= data[p] && data[p] <= 180 { + goto tr3375 + } + case data[p] >= 128: + goto tr3375 + } + goto tr2985 + st3992: + if p++; p == pe { + goto _test_eof3992 + } + st_case_3992: + if data[p] == 179 { + goto tr3375 + } + goto tr2985 + st3993: + if p++; p == pe { + goto _test_eof3993 + } + st_case_3993: + switch { + case data[p] > 130: + if 179 <= data[p] { + goto tr3375 + } + case data[p] >= 128: + goto tr3375 + } + goto tr2985 + st3994: + if p++; p == pe { + goto _test_eof3994 + } + st_case_3994: + switch { + case data[p] > 137: + if 141 <= data[p] { + goto tr2985 + } + case data[p] >= 129: + goto tr2985 + } + goto tr3375 + st3995: + if p++; p == pe { + goto _test_eof3995 + } + st_case_3995: + if 172 <= data[p] && data[p] <= 183 { + goto tr3375 + } + goto tr2985 + st3996: + if p++; p == pe { + goto _test_eof3996 + } + st_case_3996: + if 159 <= data[p] && data[p] <= 170 { + goto tr3375 + } + goto tr2985 + st3997: + if p++; p == pe { + goto _test_eof3997 + } + st_case_3997: + if data[p] == 188 { + goto tr3375 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr3375 + } + case data[p] >= 128: + goto tr3375 + } + goto tr2985 + st3998: + if p++; p == pe { + goto _test_eof3998 + } + st_case_3998: + if data[p] == 151 { + goto tr3375 + } + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr3375 + } + case data[p] >= 128: + goto tr3375 + } + case data[p] > 141: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr3375 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr3375 + } + default: + goto tr3375 + } + default: + goto tr3375 + } + goto tr2985 + st3999: + if p++; p == pe { + goto _test_eof3999 + } + st_case_3999: + if 176 <= data[p] { + goto tr3375 + } + goto tr2985 + st4000: + if p++; p == pe { + goto _test_eof4000 + } + st_case_4000: + if 132 <= data[p] { + goto tr2985 + } + goto tr3375 + st4001: + if p++; p == pe { + goto _test_eof4001 + } + st_case_4001: + switch { + case data[p] > 181: + if 184 <= data[p] { + goto tr3375 + } + case data[p] >= 175: + goto tr3375 + } + goto tr2985 + st4002: + if p++; p == pe { + goto _test_eof4002 + } + st_case_4002: + switch { + case data[p] > 155: + if 158 <= data[p] { + goto tr2985 + } + case data[p] >= 129: + goto tr2985 + } + goto tr3375 + st4003: + if p++; p == pe { + goto _test_eof4003 + } + st_case_4003: + if 129 <= data[p] { + goto tr2985 + } + goto tr3375 + st4004: + if p++; p == pe { + goto _test_eof4004 + } + st_case_4004: + if 171 <= data[p] && data[p] <= 183 { + goto tr3375 + } + goto tr2985 + st4005: + if p++; p == pe { + goto _test_eof4005 + } + st_case_4005: + if 157 <= data[p] && data[p] <= 171 { + goto tr3375 + } + goto tr2985 + st4006: + if p++; p == pe { + goto _test_eof4006 + } + st_case_4006: + switch data[p] { + case 171: + goto st4007 + case 172: + goto st4008 + case 189: + goto st4009 + case 190: + goto st4010 + } + goto tr2985 + st4007: + if p++; p == pe { + goto _test_eof4007 + } + st_case_4007: + if 176 <= data[p] && data[p] <= 180 { + goto tr3375 + } + goto tr2985 + st4008: + if p++; p == pe { + goto _test_eof4008 + } + st_case_4008: + if 176 <= data[p] && data[p] <= 182 { + goto tr3375 + } + goto tr2985 + st4009: + if p++; p == pe { + goto _test_eof4009 + } + st_case_4009: + if 145 <= data[p] && data[p] <= 190 { + goto tr3375 + } + goto tr2985 + st4010: + if p++; p == pe { + goto _test_eof4010 + } + st_case_4010: + if 143 <= data[p] && data[p] <= 146 { + goto tr3375 + } + goto tr2985 + st4011: + if p++; p == pe { + goto _test_eof4011 + } + st_case_4011: + if data[p] == 178 { + goto st4012 + } + goto tr2985 + st4012: + if p++; p == pe { + goto _test_eof4012 + } + st_case_4012: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr3375 + } + case data[p] >= 157: + goto tr3375 + } + goto tr2985 + st4013: + if p++; p == pe { + goto _test_eof4013 + } + st_case_4013: + switch data[p] { + case 133: + goto st4014 + case 134: + goto st4015 + case 137: + goto st4016 + case 168: + goto st4017 + case 169: + goto st4018 + case 170: + goto st4019 + } + goto tr2985 + st4014: + if p++; p == pe { + goto _test_eof4014 + } + st_case_4014: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr3375 + } + case data[p] >= 165: + goto tr3375 + } + goto tr2985 + st4015: + if p++; p == pe { + goto _test_eof4015 + } + st_case_4015: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr2985 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr2985 + } + default: + goto tr2985 + } + goto tr3375 + st4016: + if p++; p == pe { + goto _test_eof4016 + } + st_case_4016: + if 130 <= data[p] && data[p] <= 132 { + goto tr3375 + } + goto tr2985 + st4017: + if p++; p == pe { + goto _test_eof4017 + } + st_case_4017: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr3375 + } + case data[p] >= 128: + goto tr3375 + } + goto tr2985 + st4018: + if p++; p == pe { + goto _test_eof4018 + } + st_case_4018: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr2985 + } + case data[p] >= 173: + goto tr2985 + } + goto tr3375 + st4019: + if p++; p == pe { + goto _test_eof4019 + } + st_case_4019: + if data[p] == 132 { + goto tr3375 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr3375 + } + case data[p] >= 155: + goto tr3375 + } + goto tr2985 + st4020: + if p++; p == pe { + goto _test_eof4020 + } + st_case_4020: + if data[p] == 163 { + goto st4021 + } + goto tr2985 + st4021: + if p++; p == pe { + goto _test_eof4021 + } + st_case_4021: + if 144 <= data[p] && data[p] <= 150 { + goto tr3375 + } + goto tr2985 + st4022: + if p++; p == pe { + goto _test_eof4022 + } + st_case_4022: + if data[p] == 160 { + goto st4023 + } + goto tr2985 + st4023: + if p++; p == pe { + goto _test_eof4023 + } + st_case_4023: + switch data[p] { + case 128: + goto st4024 + case 129: + goto st4025 + case 132: + goto st3886 + case 135: + goto st3887 + } + if 133 <= data[p] && data[p] <= 134 { + goto st4026 + } + goto tr2985 + st4024: + if p++; p == pe { + goto _test_eof4024 + } + st_case_4024: + if data[p] == 129 { + goto tr3375 + } + if 160 <= data[p] { + goto tr3375 + } + goto tr2985 + st4025: + if p++; p == pe { + goto _test_eof4025 + } + st_case_4025: + if 192 <= data[p] { + goto tr2985 + } + goto tr3375 + st4026: + if p++; p == pe { + goto _test_eof4026 + } + st_case_4026: + goto tr3375 +tr3376: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:104 +act = 3; + goto st5080 + st5080: + if p++; p == pe { + goto _test_eof5080 + } + st_case_5080: +//line segment_words_prod.go:118940 + switch data[p] { + case 95: + goto tr571 + case 194: + goto st4027 + case 204: + goto st4028 + case 205: + goto st4029 + case 210: + goto st4030 + case 214: + goto st4031 + case 215: + goto st4032 + case 216: + goto st4033 + case 217: + goto st4034 + case 219: + goto st4035 + case 220: + goto st4036 + case 221: + goto st4037 + case 222: + goto st4038 + case 223: + goto st4039 + case 224: + goto st4040 + case 225: + goto st4069 + case 226: + goto st4091 + case 227: + goto st4098 + case 234: + goto st4105 + case 239: + goto st4121 + case 240: + goto st4127 + case 243: + goto st4170 + } + goto tr5137 + st4027: + if p++; p == pe { + goto _test_eof4027 + } + st_case_4027: + if data[p] == 173 { + goto tr3376 + } + goto tr3627 + st4028: + if p++; p == pe { + goto _test_eof4028 + } + st_case_4028: + if 128 <= data[p] { + goto tr3376 + } + goto tr2 + st4029: + if p++; p == pe { + goto _test_eof4029 + } + st_case_4029: + if 176 <= data[p] { + goto tr3627 + } + goto tr3376 + st4030: + if p++; p == pe { + goto _test_eof4030 + } + st_case_4030: + if 131 <= data[p] && data[p] <= 137 { + goto tr3376 + } + goto tr3627 + st4031: + if p++; p == pe { + goto _test_eof4031 + } + st_case_4031: + if data[p] == 191 { + goto tr3376 + } + if 145 <= data[p] && data[p] <= 189 { + goto tr3376 + } + goto tr3627 + st4032: + if p++; p == pe { + goto _test_eof4032 + } + st_case_4032: + if data[p] == 135 { + goto tr3376 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto tr3376 + } + case data[p] >= 129: + goto tr3376 + } + goto tr3627 + st4033: + if p++; p == pe { + goto _test_eof4033 + } + st_case_4033: + if data[p] == 156 { + goto tr3376 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto tr3376 + } + case data[p] >= 128: + goto tr3376 + } + goto tr3627 + st4034: + if p++; p == pe { + goto _test_eof4034 + } + st_case_4034: + if data[p] == 176 { + goto tr3376 + } + if 139 <= data[p] && data[p] <= 159 { + goto tr3376 + } + goto tr3627 + st4035: + if p++; p == pe { + goto _test_eof4035 + } + st_case_4035: + switch { + case data[p] < 159: + if 150 <= data[p] && data[p] <= 157 { + goto tr3376 + } + case data[p] > 164: + switch { + case data[p] > 168: + if 170 <= data[p] && data[p] <= 173 { + goto tr3376 + } + case data[p] >= 167: + goto tr3376 + } + default: + goto tr3376 + } + goto tr3627 + st4036: + if p++; p == pe { + goto _test_eof4036 + } + st_case_4036: + switch data[p] { + case 143: + goto tr3376 + case 145: + goto tr3376 + } + if 176 <= data[p] { + goto tr3376 + } + goto tr3627 + st4037: + if p++; p == pe { + goto _test_eof4037 + } + st_case_4037: + if 139 <= data[p] { + goto tr3627 + } + goto tr3376 + st4038: + if p++; p == pe { + goto _test_eof4038 + } + st_case_4038: + if 166 <= data[p] && data[p] <= 176 { + goto tr3376 + } + goto tr3627 + st4039: + if p++; p == pe { + goto _test_eof4039 + } + st_case_4039: + if 171 <= data[p] && data[p] <= 179 { + goto tr3376 + } + goto tr3627 + st4040: + if p++; p == pe { + goto _test_eof4040 + } + st_case_4040: + switch data[p] { + case 160: + goto st4041 + case 161: + goto st4042 + case 163: + goto st4043 + case 164: + goto st4044 + case 165: + goto st4045 + case 167: + goto st4047 + case 169: + goto st4048 + case 171: + goto st4049 + case 173: + goto st4051 + case 174: + goto st4052 + case 175: + goto st4053 + case 176: + goto st4054 + case 177: + goto st4055 + case 179: + goto st4056 + case 180: + goto st4057 + case 181: + goto st4058 + case 182: + goto st4059 + case 183: + goto st4060 + case 184: + goto st4061 + case 185: + goto st4062 + case 186: + goto st4063 + case 187: + goto st4064 + case 188: + goto st4065 + case 189: + goto st4066 + case 190: + goto st4067 + case 191: + goto st4068 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto st4050 + } + case data[p] >= 166: + goto st4046 + } + goto tr3627 + st4041: + if p++; p == pe { + goto _test_eof4041 + } + st_case_4041: + switch { + case data[p] < 155: + if 150 <= data[p] && data[p] <= 153 { + goto tr3376 + } + case data[p] > 163: + switch { + case data[p] > 167: + if 169 <= data[p] && data[p] <= 173 { + goto tr3376 + } + case data[p] >= 165: + goto tr3376 + } + default: + goto tr3376 + } + goto tr3627 + st4042: + if p++; p == pe { + goto _test_eof4042 + } + st_case_4042: + if 153 <= data[p] && data[p] <= 155 { + goto tr3376 + } + goto tr3627 + st4043: + if p++; p == pe { + goto _test_eof4043 + } + st_case_4043: + if 163 <= data[p] { + goto tr3376 + } + goto tr3627 + st4044: + if p++; p == pe { + goto _test_eof4044 + } + st_case_4044: + if data[p] == 189 { + goto tr3627 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr3627 + } + goto tr3376 + st4045: + if p++; p == pe { + goto _test_eof4045 + } + st_case_4045: + if data[p] == 144 { + goto tr3627 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr3627 + } + case data[p] >= 152: + goto tr3627 + } + goto tr3376 + st4046: + if p++; p == pe { + goto _test_eof4046 + } + st_case_4046: + if data[p] == 188 { + goto tr3376 + } + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr3376 + } + case data[p] >= 129: + goto tr3376 + } + goto tr3627 + st4047: + if p++; p == pe { + goto _test_eof4047 + } + st_case_4047: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr3627 + } + case data[p] >= 133: + goto tr3627 + } + case data[p] > 150: + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr3627 + } + case data[p] >= 152: + goto tr3627 + } + default: + goto tr3627 + } + goto tr3376 + st4048: + if p++; p == pe { + goto _test_eof4048 + } + st_case_4048: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr3627 + } + case data[p] >= 131: + goto tr3627 + } + case data[p] > 144: + switch { + case data[p] < 178: + if 146 <= data[p] && data[p] <= 175 { + goto tr3627 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr3627 + } + default: + goto tr3627 + } + default: + goto tr3627 + } + goto tr3376 + st4049: + if p++; p == pe { + goto _test_eof4049 + } + st_case_4049: + switch data[p] { + case 134: + goto tr3627 + case 138: + goto tr3627 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr3627 + } + case data[p] >= 142: + goto tr3627 + } + goto tr3376 + st4050: + if p++; p == pe { + goto _test_eof4050 + } + st_case_4050: + if data[p] == 188 { + goto tr3376 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr3376 + } + case data[p] >= 129: + goto tr3376 + } + goto tr3627 + st4051: + if p++; p == pe { + goto _test_eof4051 + } + st_case_4051: + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr3376 + } + case data[p] >= 128: + goto tr3376 + } + case data[p] > 141: + switch { + case data[p] > 151: + if 162 <= data[p] && data[p] <= 163 { + goto tr3376 + } + case data[p] >= 150: + goto tr3376 + } + default: + goto tr3376 + } + goto tr3627 + st4052: + if p++; p == pe { + goto _test_eof4052 + } + st_case_4052: + if data[p] == 130 { + goto tr3376 + } + if 190 <= data[p] && data[p] <= 191 { + goto tr3376 + } + goto tr3627 + st4053: + if p++; p == pe { + goto _test_eof4053 + } + st_case_4053: + if data[p] == 151 { + goto tr3376 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr3376 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr3376 + } + default: + goto tr3376 + } + goto tr3627 + st4054: + if p++; p == pe { + goto _test_eof4054 + } + st_case_4054: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr3376 + } + case data[p] >= 128: + goto tr3376 + } + goto tr3627 + st4055: + if p++; p == pe { + goto _test_eof4055 + } + st_case_4055: + switch data[p] { + case 133: + goto tr3627 + case 137: + goto tr3627 + } + switch { + case data[p] < 151: + if 142 <= data[p] && data[p] <= 148 { + goto tr3627 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr3627 + } + default: + goto tr3627 + } + goto tr3376 + st4056: + if p++; p == pe { + goto _test_eof4056 + } + st_case_4056: + switch { + case data[p] < 138: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 136 { + goto tr3376 + } + case data[p] >= 128: + goto tr3376 + } + case data[p] > 141: + switch { + case data[p] > 150: + if 162 <= data[p] && data[p] <= 163 { + goto tr3376 + } + case data[p] >= 149: + goto tr3376 + } + default: + goto tr3376 + } + goto tr3627 + st4057: + if p++; p == pe { + goto _test_eof4057 + } + st_case_4057: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr3376 + } + case data[p] >= 129: + goto tr3376 + } + goto tr3627 + st4058: + if p++; p == pe { + goto _test_eof4058 + } + st_case_4058: + switch data[p] { + case 133: + goto tr3627 + case 137: + goto tr3627 + } + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 150 { + goto tr3627 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr3627 + } + default: + goto tr3627 + } + goto tr3376 + st4059: + if p++; p == pe { + goto _test_eof4059 + } + st_case_4059: + if 130 <= data[p] && data[p] <= 131 { + goto tr3376 + } + goto tr3627 + st4060: + if p++; p == pe { + goto _test_eof4060 + } + st_case_4060: + switch data[p] { + case 138: + goto tr3376 + case 150: + goto tr3376 + } + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 148 { + goto tr3376 + } + case data[p] > 159: + if 178 <= data[p] && data[p] <= 179 { + goto tr3376 + } + default: + goto tr3376 + } + goto tr3627 + st4061: + if p++; p == pe { + goto _test_eof4061 + } + st_case_4061: + if data[p] == 177 { + goto tr3376 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr3376 + } + goto tr3627 + st4062: + if p++; p == pe { + goto _test_eof4062 + } + st_case_4062: + if 135 <= data[p] && data[p] <= 142 { + goto tr3376 + } + goto tr3627 + st4063: + if p++; p == pe { + goto _test_eof4063 + } + st_case_4063: + if data[p] == 177 { + goto tr3376 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr3376 + } + case data[p] >= 180: + goto tr3376 + } + goto tr3627 + st4064: + if p++; p == pe { + goto _test_eof4064 + } + st_case_4064: + if 136 <= data[p] && data[p] <= 141 { + goto tr3376 + } + goto tr3627 + st4065: + if p++; p == pe { + goto _test_eof4065 + } + st_case_4065: + switch data[p] { + case 181: + goto tr3376 + case 183: + goto tr3376 + case 185: + goto tr3376 + } + switch { + case data[p] > 153: + if 190 <= data[p] && data[p] <= 191 { + goto tr3376 + } + case data[p] >= 152: + goto tr3376 + } + goto tr3627 + st4066: + if p++; p == pe { + goto _test_eof4066 + } + st_case_4066: + if 177 <= data[p] && data[p] <= 191 { + goto tr3376 + } + goto tr3627 + st4067: + if p++; p == pe { + goto _test_eof4067 + } + st_case_4067: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr3376 + } + case data[p] > 135: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr3376 + } + case data[p] >= 141: + goto tr3376 + } + default: + goto tr3376 + } + goto tr3627 + st4068: + if p++; p == pe { + goto _test_eof4068 + } + st_case_4068: + if data[p] == 134 { + goto tr3376 + } + goto tr3627 + st4069: + if p++; p == pe { + goto _test_eof4069 + } + st_case_4069: + switch data[p] { + case 128: + goto st4070 + case 129: + goto st4071 + case 130: + goto st4072 + case 141: + goto st4073 + case 156: + goto st4074 + case 157: + goto st4075 + case 158: + goto st4076 + case 159: + goto st4077 + case 160: + goto st4078 + case 162: + goto st4079 + case 164: + goto st4080 + case 168: + goto st4081 + case 169: + goto st4082 + case 170: + goto st4083 + case 172: + goto st4084 + case 173: + goto st4085 + case 174: + goto st4086 + case 175: + goto st4087 + case 176: + goto st4088 + case 179: + goto st4089 + case 183: + goto st4090 + } + goto tr3627 + st4070: + if p++; p == pe { + goto _test_eof4070 + } + st_case_4070: + if 171 <= data[p] && data[p] <= 190 { + goto tr3376 + } + goto tr3627 + st4071: + if p++; p == pe { + goto _test_eof4071 + } + st_case_4071: + switch { + case data[p] < 162: + switch { + case data[p] > 153: + if 158 <= data[p] && data[p] <= 160 { + goto tr3376 + } + case data[p] >= 150: + goto tr3376 + } + case data[p] > 164: + switch { + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr3376 + } + case data[p] >= 167: + goto tr3376 + } + default: + goto tr3376 + } + goto tr3627 + st4072: + if p++; p == pe { + goto _test_eof4072 + } + st_case_4072: + if data[p] == 143 { + goto tr3376 + } + switch { + case data[p] > 141: + if 154 <= data[p] && data[p] <= 157 { + goto tr3376 + } + case data[p] >= 130: + goto tr3376 + } + goto tr3627 + st4073: + if p++; p == pe { + goto _test_eof4073 + } + st_case_4073: + if 157 <= data[p] && data[p] <= 159 { + goto tr3376 + } + goto tr3627 + st4074: + if p++; p == pe { + goto _test_eof4074 + } + st_case_4074: + switch { + case data[p] > 148: + if 178 <= data[p] && data[p] <= 180 { + goto tr3376 + } + case data[p] >= 146: + goto tr3376 + } + goto tr3627 + st4075: + if p++; p == pe { + goto _test_eof4075 + } + st_case_4075: + switch { + case data[p] > 147: + if 178 <= data[p] && data[p] <= 179 { + goto tr3376 + } + case data[p] >= 146: + goto tr3376 + } + goto tr3627 + st4076: + if p++; p == pe { + goto _test_eof4076 + } + st_case_4076: + if 180 <= data[p] { + goto tr3376 + } + goto tr3627 + st4077: + if p++; p == pe { + goto _test_eof4077 + } + st_case_4077: + switch { + case data[p] > 156: + if 158 <= data[p] { + goto tr3627 + } + case data[p] >= 148: + goto tr3627 + } + goto tr3376 + st4078: + if p++; p == pe { + goto _test_eof4078 + } + st_case_4078: + if 139 <= data[p] && data[p] <= 142 { + goto tr3376 + } + goto tr3627 + st4079: + if p++; p == pe { + goto _test_eof4079 + } + st_case_4079: + if data[p] == 169 { + goto tr3376 + } + goto tr3627 + st4080: + if p++; p == pe { + goto _test_eof4080 + } + st_case_4080: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr3376 + } + case data[p] >= 160: + goto tr3376 + } + goto tr3627 + st4081: + if p++; p == pe { + goto _test_eof4081 + } + st_case_4081: + if 151 <= data[p] && data[p] <= 155 { + goto tr3376 + } + goto tr3627 + st4082: + if p++; p == pe { + goto _test_eof4082 + } + st_case_4082: + if data[p] == 191 { + goto tr3376 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr3376 + } + case data[p] >= 149: + goto tr3376 + } + goto tr3627 + st4083: + if p++; p == pe { + goto _test_eof4083 + } + st_case_4083: + if 176 <= data[p] && data[p] <= 190 { + goto tr3376 + } + goto tr3627 + st4084: + if p++; p == pe { + goto _test_eof4084 + } + st_case_4084: + switch { + case data[p] > 132: + if 180 <= data[p] { + goto tr3376 + } + case data[p] >= 128: + goto tr3376 + } + goto tr3627 + st4085: + if p++; p == pe { + goto _test_eof4085 + } + st_case_4085: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr3627 + } + case data[p] >= 133: + goto tr3627 + } + goto tr3376 + st4086: + if p++; p == pe { + goto _test_eof4086 + } + st_case_4086: + switch { + case data[p] > 130: + if 161 <= data[p] && data[p] <= 173 { + goto tr3376 + } + case data[p] >= 128: + goto tr3376 + } + goto tr3627 + st4087: + if p++; p == pe { + goto _test_eof4087 + } + st_case_4087: + if 166 <= data[p] && data[p] <= 179 { + goto tr3376 + } + goto tr3627 + st4088: + if p++; p == pe { + goto _test_eof4088 + } + st_case_4088: + if 164 <= data[p] && data[p] <= 183 { + goto tr3376 + } + goto tr3627 + st4089: + if p++; p == pe { + goto _test_eof4089 + } + st_case_4089: + if data[p] == 173 { + goto tr3376 + } + switch { + case data[p] < 148: + if 144 <= data[p] && data[p] <= 146 { + goto tr3376 + } + case data[p] > 168: + switch { + case data[p] > 180: + if 184 <= data[p] && data[p] <= 185 { + goto tr3376 + } + case data[p] >= 178: + goto tr3376 + } + default: + goto tr3376 + } + goto tr3627 + st4090: + if p++; p == pe { + goto _test_eof4090 + } + st_case_4090: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr3376 + } + case data[p] >= 128: + goto tr3376 + } + goto tr3627 + st4091: + if p++; p == pe { + goto _test_eof4091 + } + st_case_4091: + switch data[p] { + case 128: + goto st4092 + case 129: + goto st4093 + case 131: + goto st4094 + case 179: + goto st4095 + case 181: + goto st4096 + case 183: + goto st4097 + } + goto tr3627 + st4092: + if p++; p == pe { + goto _test_eof4092 + } + st_case_4092: + switch { + case data[p] < 170: + if 140 <= data[p] && data[p] <= 143 { + goto tr3376 + } + case data[p] > 174: + if 191 <= data[p] { + goto tr571 + } + default: + goto tr3376 + } + goto tr3627 + st4093: + if p++; p == pe { + goto _test_eof4093 + } + st_case_4093: + if data[p] == 165 { + goto tr3627 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr3627 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr3627 + } + case data[p] >= 160: + goto tr3376 + } + default: + goto tr3627 + } + goto tr571 + st4094: + if p++; p == pe { + goto _test_eof4094 + } + st_case_4094: + if 144 <= data[p] && data[p] <= 176 { + goto tr3376 + } + goto tr3627 + st4095: + if p++; p == pe { + goto _test_eof4095 + } + st_case_4095: + if 175 <= data[p] && data[p] <= 177 { + goto tr3376 + } + goto tr3627 + st4096: + if p++; p == pe { + goto _test_eof4096 + } + st_case_4096: + if data[p] == 191 { + goto tr3376 + } + goto tr3627 + st4097: + if p++; p == pe { + goto _test_eof4097 + } + st_case_4097: + if 160 <= data[p] && data[p] <= 191 { + goto tr3376 + } + goto tr3627 + st4098: + if p++; p == pe { + goto _test_eof4098 + } + st_case_4098: + switch data[p] { + case 128: + goto st4099 + case 130: + goto st4100 + case 131: + goto st4101 + case 135: + goto st4102 + case 139: + goto st4103 + case 140: + goto st4028 + case 141: + goto st4104 + } + goto tr3627 + st4099: + if p++; p == pe { + goto _test_eof4099 + } + st_case_4099: + switch { + case data[p] > 175: + if 177 <= data[p] && data[p] <= 181 { + goto tr3376 + } + case data[p] >= 170: + goto tr3376 + } + goto tr3627 + st4100: + if p++; p == pe { + goto _test_eof4100 + } + st_case_4100: + switch { + case data[p] > 156: + if 160 <= data[p] { + goto tr3376 + } + case data[p] >= 153: + goto tr3376 + } + goto tr3627 + st4101: + if p++; p == pe { + goto _test_eof4101 + } + st_case_4101: + if data[p] == 187 { + goto tr2 + } + if 192 <= data[p] { + goto tr2 + } + goto tr3376 + st4102: + if p++; p == pe { + goto _test_eof4102 + } + st_case_4102: + if 176 <= data[p] && data[p] <= 191 { + goto tr3376 + } + goto tr2 + st4103: + if p++; p == pe { + goto _test_eof4103 + } + st_case_4103: + if 144 <= data[p] && data[p] <= 190 { + goto tr3376 + } + goto tr2 + st4104: + if p++; p == pe { + goto _test_eof4104 + } + st_case_4104: + if 152 <= data[p] { + goto tr2 + } + goto tr3376 + st4105: + if p++; p == pe { + goto _test_eof4105 + } + st_case_4105: + switch data[p] { + case 153: + goto st4106 + case 154: + goto st4107 + case 155: + goto st4108 + case 160: + goto st4109 + case 162: + goto st4110 + case 163: + goto st4111 + case 164: + goto st4112 + case 165: + goto st4113 + case 166: + goto st4114 + case 167: + goto st4115 + case 168: + goto st4116 + case 169: + goto st4117 + case 170: + goto st4118 + case 171: + goto st4119 + case 175: + goto st4120 + } + goto tr3627 + st4106: + if p++; p == pe { + goto _test_eof4106 + } + st_case_4106: + switch { + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr3376 + } + case data[p] >= 175: + goto tr3376 + } + goto tr3627 + st4107: + if p++; p == pe { + goto _test_eof4107 + } + st_case_4107: + if 158 <= data[p] && data[p] <= 159 { + goto tr3376 + } + goto tr3627 + st4108: + if p++; p == pe { + goto _test_eof4108 + } + st_case_4108: + if 176 <= data[p] && data[p] <= 177 { + goto tr3376 + } + goto tr3627 + st4109: + if p++; p == pe { + goto _test_eof4109 + } + st_case_4109: + switch data[p] { + case 130: + goto tr3376 + case 134: + goto tr3376 + case 139: + goto tr3376 + } + if 163 <= data[p] && data[p] <= 167 { + goto tr3376 + } + goto tr3627 + st4110: + if p++; p == pe { + goto _test_eof4110 + } + st_case_4110: + switch { + case data[p] > 129: + if 180 <= data[p] { + goto tr3376 + } + case data[p] >= 128: + goto tr3376 + } + goto tr3627 + st4111: + if p++; p == pe { + goto _test_eof4111 + } + st_case_4111: + switch { + case data[p] > 159: + if 178 <= data[p] { + goto tr3627 + } + case data[p] >= 133: + goto tr3627 + } + goto tr3376 + st4112: + if p++; p == pe { + goto _test_eof4112 + } + st_case_4112: + if 166 <= data[p] && data[p] <= 173 { + goto tr3376 + } + goto tr3627 + st4113: + if p++; p == pe { + goto _test_eof4113 + } + st_case_4113: + if 135 <= data[p] && data[p] <= 147 { + goto tr3376 + } + goto tr3627 + st4114: + if p++; p == pe { + goto _test_eof4114 + } + st_case_4114: + switch { + case data[p] > 131: + if 179 <= data[p] { + goto tr3376 + } + case data[p] >= 128: + goto tr3376 + } + goto tr3627 + st4115: + if p++; p == pe { + goto _test_eof4115 + } + st_case_4115: + switch { + case data[p] > 164: + if 166 <= data[p] { + goto tr3627 + } + case data[p] >= 129: + goto tr3627 + } + goto tr3376 + st4116: + if p++; p == pe { + goto _test_eof4116 + } + st_case_4116: + if 169 <= data[p] && data[p] <= 182 { + goto tr3376 + } + goto tr3627 + st4117: + if p++; p == pe { + goto _test_eof4117 + } + st_case_4117: + if data[p] == 131 { + goto tr3376 + } + switch { + case data[p] > 141: + if 187 <= data[p] && data[p] <= 189 { + goto tr3376 + } + case data[p] >= 140: + goto tr3376 + } + goto tr3627 + st4118: + if p++; p == pe { + goto _test_eof4118 + } + st_case_4118: + if data[p] == 176 { + goto tr3376 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr3376 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr3376 + } + default: + goto tr3376 + } + goto tr3627 + st4119: + if p++; p == pe { + goto _test_eof4119 + } + st_case_4119: + if data[p] == 129 { + goto tr3376 + } + switch { + case data[p] > 175: + if 181 <= data[p] && data[p] <= 182 { + goto tr3376 + } + case data[p] >= 171: + goto tr3376 + } + goto tr3627 + st4120: + if p++; p == pe { + goto _test_eof4120 + } + st_case_4120: + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 173 { + goto tr3376 + } + case data[p] >= 163: + goto tr3376 + } + goto tr3627 + st4121: + if p++; p == pe { + goto _test_eof4121 + } + st_case_4121: + switch data[p] { + case 172: + goto st4122 + case 184: + goto st4123 + case 185: + goto st1187 + case 187: + goto st4096 + case 188: + goto st1188 + case 189: + goto st4124 + case 190: + goto st4125 + case 191: + goto st4126 + } + goto tr3627 + st4122: + if p++; p == pe { + goto _test_eof4122 + } + st_case_4122: + if data[p] == 158 { + goto tr3376 + } + goto tr3627 + st4123: + if p++; p == pe { + goto _test_eof4123 + } + st_case_4123: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr3376 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr571 + } + default: + goto tr3376 + } + goto tr3627 + st4124: + if p++; p == pe { + goto _test_eof4124 + } + st_case_4124: + if 166 <= data[p] { + goto tr3376 + } + goto tr3627 + st4125: + if p++; p == pe { + goto _test_eof4125 + } + st_case_4125: + if 160 <= data[p] { + goto tr3627 + } + goto tr3376 + st4126: + if p++; p == pe { + goto _test_eof4126 + } + st_case_4126: + if 185 <= data[p] && data[p] <= 187 { + goto tr3376 + } + goto tr3627 + st4127: + if p++; p == pe { + goto _test_eof4127 + } + st_case_4127: + switch data[p] { + case 144: + goto st4128 + case 145: + goto st4134 + case 150: + goto st4153 + case 155: + goto st4158 + case 157: + goto st4161 + case 158: + goto st4168 + } + goto tr3627 + st4128: + if p++; p == pe { + goto _test_eof4128 + } + st_case_4128: + switch data[p] { + case 135: + goto st4129 + case 139: + goto st4130 + case 141: + goto st4131 + case 168: + goto st4132 + case 171: + goto st4133 + } + goto tr3627 + st4129: + if p++; p == pe { + goto _test_eof4129 + } + st_case_4129: + if data[p] == 189 { + goto tr3376 + } + goto tr3627 + st4130: + if p++; p == pe { + goto _test_eof4130 + } + st_case_4130: + if data[p] == 160 { + goto tr3376 + } + goto tr3627 + st4131: + if p++; p == pe { + goto _test_eof4131 + } + st_case_4131: + if 182 <= data[p] && data[p] <= 186 { + goto tr3376 + } + goto tr3627 + st4132: + if p++; p == pe { + goto _test_eof4132 + } + st_case_4132: + if data[p] == 191 { + goto tr3376 + } + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr3376 + } + case data[p] > 134: + switch { + case data[p] > 143: + if 184 <= data[p] && data[p] <= 186 { + goto tr3376 + } + case data[p] >= 140: + goto tr3376 + } + default: + goto tr3376 + } + goto tr3627 + st4133: + if p++; p == pe { + goto _test_eof4133 + } + st_case_4133: + if 165 <= data[p] && data[p] <= 166 { + goto tr3376 + } + goto tr3627 + st4134: + if p++; p == pe { + goto _test_eof4134 + } + st_case_4134: + switch data[p] { + case 128: + goto st4135 + case 129: + goto st4136 + case 130: + goto st4137 + case 132: + goto st4138 + case 133: + goto st4139 + case 134: + goto st4140 + case 135: + goto st4141 + case 136: + goto st4142 + case 139: + goto st4143 + case 140: + goto st4144 + case 141: + goto st4145 + case 146: + goto st4146 + case 147: + goto st4147 + case 150: + goto st4148 + case 151: + goto st4149 + case 152: + goto st4146 + case 153: + goto st4150 + case 154: + goto st4151 + case 156: + goto st4152 + } + goto tr3627 + st4135: + if p++; p == pe { + goto _test_eof4135 + } + st_case_4135: + switch { + case data[p] > 130: + if 184 <= data[p] { + goto tr3376 + } + case data[p] >= 128: + goto tr3376 + } + goto tr3627 + st4136: + if p++; p == pe { + goto _test_eof4136 + } + st_case_4136: + if 135 <= data[p] && data[p] <= 190 { + goto tr3627 + } + goto tr3376 + st4137: + if p++; p == pe { + goto _test_eof4137 + } + st_case_4137: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr3627 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr3627 + } + default: + goto tr3627 + } + goto tr3376 + st4138: + if p++; p == pe { + goto _test_eof4138 + } + st_case_4138: + switch { + case data[p] > 130: + if 167 <= data[p] && data[p] <= 180 { + goto tr3376 + } + case data[p] >= 128: + goto tr3376 + } + goto tr3627 + st4139: + if p++; p == pe { + goto _test_eof4139 + } + st_case_4139: + if data[p] == 179 { + goto tr3376 + } + goto tr3627 + st4140: + if p++; p == pe { + goto _test_eof4140 + } + st_case_4140: + switch { + case data[p] > 130: + if 179 <= data[p] { + goto tr3376 + } + case data[p] >= 128: + goto tr3376 + } + goto tr3627 + st4141: + if p++; p == pe { + goto _test_eof4141 + } + st_case_4141: + switch { + case data[p] > 137: + if 141 <= data[p] { + goto tr3627 + } + case data[p] >= 129: + goto tr3627 + } + goto tr3376 + st4142: + if p++; p == pe { + goto _test_eof4142 + } + st_case_4142: + if 172 <= data[p] && data[p] <= 183 { + goto tr3376 + } + goto tr3627 + st4143: + if p++; p == pe { + goto _test_eof4143 + } + st_case_4143: + if 159 <= data[p] && data[p] <= 170 { + goto tr3376 + } + goto tr3627 + st4144: + if p++; p == pe { + goto _test_eof4144 + } + st_case_4144: + if data[p] == 188 { + goto tr3376 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr3376 + } + case data[p] >= 128: + goto tr3376 + } + goto tr3627 + st4145: + if p++; p == pe { + goto _test_eof4145 + } + st_case_4145: + if data[p] == 151 { + goto tr3376 + } + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr3376 + } + case data[p] >= 128: + goto tr3376 + } + case data[p] > 141: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr3376 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr3376 + } + default: + goto tr3376 + } + default: + goto tr3376 + } + goto tr3627 + st4146: + if p++; p == pe { + goto _test_eof4146 + } + st_case_4146: + if 176 <= data[p] { + goto tr3376 + } + goto tr3627 + st4147: + if p++; p == pe { + goto _test_eof4147 + } + st_case_4147: + if 132 <= data[p] { + goto tr3627 + } + goto tr3376 + st4148: + if p++; p == pe { + goto _test_eof4148 + } + st_case_4148: + switch { + case data[p] > 181: + if 184 <= data[p] { + goto tr3376 + } + case data[p] >= 175: + goto tr3376 + } + goto tr3627 + st4149: + if p++; p == pe { + goto _test_eof4149 + } + st_case_4149: + switch { + case data[p] > 155: + if 158 <= data[p] { + goto tr3627 + } + case data[p] >= 129: + goto tr3627 + } + goto tr3376 + st4150: + if p++; p == pe { + goto _test_eof4150 + } + st_case_4150: + if 129 <= data[p] { + goto tr3627 + } + goto tr3376 + st4151: + if p++; p == pe { + goto _test_eof4151 + } + st_case_4151: + if 171 <= data[p] && data[p] <= 183 { + goto tr3376 + } + goto tr3627 + st4152: + if p++; p == pe { + goto _test_eof4152 + } + st_case_4152: + if 157 <= data[p] && data[p] <= 171 { + goto tr3376 + } + goto tr3627 + st4153: + if p++; p == pe { + goto _test_eof4153 + } + st_case_4153: + switch data[p] { + case 171: + goto st4154 + case 172: + goto st4155 + case 189: + goto st4156 + case 190: + goto st4157 + } + goto tr3627 + st4154: + if p++; p == pe { + goto _test_eof4154 + } + st_case_4154: + if 176 <= data[p] && data[p] <= 180 { + goto tr3376 + } + goto tr3627 + st4155: + if p++; p == pe { + goto _test_eof4155 + } + st_case_4155: + if 176 <= data[p] && data[p] <= 182 { + goto tr3376 + } + goto tr3627 + st4156: + if p++; p == pe { + goto _test_eof4156 + } + st_case_4156: + if 145 <= data[p] && data[p] <= 190 { + goto tr3376 + } + goto tr3627 + st4157: + if p++; p == pe { + goto _test_eof4157 + } + st_case_4157: + if 143 <= data[p] && data[p] <= 146 { + goto tr3376 + } + goto tr3627 + st4158: + if p++; p == pe { + goto _test_eof4158 + } + st_case_4158: + switch data[p] { + case 128: + goto st4159 + case 178: + goto st4160 + } + goto tr3627 + st4159: + if p++; p == pe { + goto _test_eof4159 + } + st_case_4159: + if data[p] == 128 { + goto tr3376 + } + goto tr3627 + st4160: + if p++; p == pe { + goto _test_eof4160 + } + st_case_4160: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr3376 + } + case data[p] >= 157: + goto tr3376 + } + goto tr3627 + st4161: + if p++; p == pe { + goto _test_eof4161 + } + st_case_4161: + switch data[p] { + case 133: + goto st4162 + case 134: + goto st4163 + case 137: + goto st4164 + case 168: + goto st4165 + case 169: + goto st4166 + case 170: + goto st4167 + } + goto tr3627 + st4162: + if p++; p == pe { + goto _test_eof4162 + } + st_case_4162: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr3376 + } + case data[p] >= 165: + goto tr3376 + } + goto tr3627 + st4163: + if p++; p == pe { + goto _test_eof4163 + } + st_case_4163: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr3627 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr3627 + } + default: + goto tr3627 + } + goto tr3376 + st4164: + if p++; p == pe { + goto _test_eof4164 + } + st_case_4164: + if 130 <= data[p] && data[p] <= 132 { + goto tr3376 + } + goto tr3627 + st4165: + if p++; p == pe { + goto _test_eof4165 + } + st_case_4165: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr3376 + } + case data[p] >= 128: + goto tr3376 + } + goto tr3627 + st4166: + if p++; p == pe { + goto _test_eof4166 + } + st_case_4166: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr3627 + } + case data[p] >= 173: + goto tr3627 + } + goto tr3376 + st4167: + if p++; p == pe { + goto _test_eof4167 + } + st_case_4167: + if data[p] == 132 { + goto tr3376 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr3376 + } + case data[p] >= 155: + goto tr3376 + } + goto tr3627 + st4168: + if p++; p == pe { + goto _test_eof4168 + } + st_case_4168: + if data[p] == 163 { + goto st4169 + } + goto tr3627 + st4169: + if p++; p == pe { + goto _test_eof4169 + } + st_case_4169: + if 144 <= data[p] && data[p] <= 150 { + goto tr3376 + } + goto tr3627 + st4170: + if p++; p == pe { + goto _test_eof4170 + } + st_case_4170: + if data[p] == 160 { + goto st4171 + } + goto tr3627 + st4171: + if p++; p == pe { + goto _test_eof4171 + } + st_case_4171: + switch data[p] { + case 128: + goto st4172 + case 129: + goto st4173 + case 132: + goto st4028 + case 135: + goto st4029 + } + if 133 <= data[p] && data[p] <= 134 { + goto st4174 + } + goto tr3627 + st4172: + if p++; p == pe { + goto _test_eof4172 + } + st_case_4172: + if data[p] == 129 { + goto tr3376 + } + if 160 <= data[p] { + goto tr3376 + } + goto tr3627 + st4173: + if p++; p == pe { + goto _test_eof4173 + } + st_case_4173: + if 192 <= data[p] { + goto tr3627 + } + goto tr3376 + st4174: + if p++; p == pe { + goto _test_eof4174 + } + st_case_4174: + goto tr3376 + st4175: + if p++; p == pe { + goto _test_eof4175 + } + st_case_4175: + if 129 <= data[p] { + goto tr3757 + } + goto tr0 +tr3757: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + + goto st5081 + st5081: + if p++; p == pe { + goto _test_eof5081 + } + st_case_5081: +//line segment_words_prod.go:121214 + switch data[p] { + case 194: + goto st4176 + case 204: + goto st4177 + case 205: + goto st4178 + case 210: + goto st4179 + case 214: + goto st4180 + case 215: + goto st4181 + case 216: + goto st4182 + case 217: + goto st4183 + case 219: + goto st4184 + case 220: + goto st4185 + case 221: + goto st4186 + case 222: + goto st4187 + case 223: + goto st4188 + case 224: + goto st4189 + case 225: + goto st4218 + case 226: + goto st4240 + case 227: + goto st4247 + case 234: + goto st4250 + case 239: + goto st4266 + case 240: + goto st4270 + case 243: + goto st4312 + } + goto tr5157 + st4176: + if p++; p == pe { + goto _test_eof4176 + } + st_case_4176: + if data[p] == 173 { + goto tr3757 + } + goto tr3758 + st4177: + if p++; p == pe { + goto _test_eof4177 + } + st_case_4177: + if 128 <= data[p] { + goto tr3757 + } + goto tr3758 + st4178: + if p++; p == pe { + goto _test_eof4178 + } + st_case_4178: + if 176 <= data[p] { + goto tr3758 + } + goto tr3757 + st4179: + if p++; p == pe { + goto _test_eof4179 + } + st_case_4179: + if 131 <= data[p] && data[p] <= 137 { + goto tr3757 + } + goto tr3758 + st4180: + if p++; p == pe { + goto _test_eof4180 + } + st_case_4180: + if data[p] == 191 { + goto tr3757 + } + if 145 <= data[p] && data[p] <= 189 { + goto tr3757 + } + goto tr3758 + st4181: + if p++; p == pe { + goto _test_eof4181 + } + st_case_4181: + if data[p] == 135 { + goto tr3757 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto tr3757 + } + case data[p] >= 129: + goto tr3757 + } + goto tr3758 + st4182: + if p++; p == pe { + goto _test_eof4182 + } + st_case_4182: + if data[p] == 156 { + goto tr3757 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto tr3757 + } + case data[p] >= 128: + goto tr3757 + } + goto tr3758 + st4183: + if p++; p == pe { + goto _test_eof4183 + } + st_case_4183: + if data[p] == 176 { + goto tr3757 + } + if 139 <= data[p] && data[p] <= 159 { + goto tr3757 + } + goto tr3758 + st4184: + if p++; p == pe { + goto _test_eof4184 + } + st_case_4184: + switch { + case data[p] < 159: + if 150 <= data[p] && data[p] <= 157 { + goto tr3757 + } + case data[p] > 164: + switch { + case data[p] > 168: + if 170 <= data[p] && data[p] <= 173 { + goto tr3757 + } + case data[p] >= 167: + goto tr3757 + } + default: + goto tr3757 + } + goto tr3758 + st4185: + if p++; p == pe { + goto _test_eof4185 + } + st_case_4185: + switch data[p] { + case 143: + goto tr3757 + case 145: + goto tr3757 + } + if 176 <= data[p] { + goto tr3757 + } + goto tr3758 + st4186: + if p++; p == pe { + goto _test_eof4186 + } + st_case_4186: + if 139 <= data[p] { + goto tr3758 + } + goto tr3757 + st4187: + if p++; p == pe { + goto _test_eof4187 + } + st_case_4187: + if 166 <= data[p] && data[p] <= 176 { + goto tr3757 + } + goto tr3758 + st4188: + if p++; p == pe { + goto _test_eof4188 + } + st_case_4188: + if 171 <= data[p] && data[p] <= 179 { + goto tr3757 + } + goto tr3758 + st4189: + if p++; p == pe { + goto _test_eof4189 + } + st_case_4189: + switch data[p] { + case 160: + goto st4190 + case 161: + goto st4191 + case 163: + goto st4192 + case 164: + goto st4193 + case 165: + goto st4194 + case 167: + goto st4196 + case 169: + goto st4197 + case 171: + goto st4198 + case 173: + goto st4200 + case 174: + goto st4201 + case 175: + goto st4202 + case 176: + goto st4203 + case 177: + goto st4204 + case 179: + goto st4205 + case 180: + goto st4206 + case 181: + goto st4207 + case 182: + goto st4208 + case 183: + goto st4209 + case 184: + goto st4210 + case 185: + goto st4211 + case 186: + goto st4212 + case 187: + goto st4213 + case 188: + goto st4214 + case 189: + goto st4215 + case 190: + goto st4216 + case 191: + goto st4217 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto st4199 + } + case data[p] >= 166: + goto st4195 + } + goto tr3758 + st4190: + if p++; p == pe { + goto _test_eof4190 + } + st_case_4190: + switch { + case data[p] < 155: + if 150 <= data[p] && data[p] <= 153 { + goto tr3757 + } + case data[p] > 163: + switch { + case data[p] > 167: + if 169 <= data[p] && data[p] <= 173 { + goto tr3757 + } + case data[p] >= 165: + goto tr3757 + } + default: + goto tr3757 + } + goto tr3758 + st4191: + if p++; p == pe { + goto _test_eof4191 + } + st_case_4191: + if 153 <= data[p] && data[p] <= 155 { + goto tr3757 + } + goto tr3758 + st4192: + if p++; p == pe { + goto _test_eof4192 + } + st_case_4192: + if 163 <= data[p] { + goto tr3757 + } + goto tr3758 + st4193: + if p++; p == pe { + goto _test_eof4193 + } + st_case_4193: + if data[p] == 189 { + goto tr3758 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr3758 + } + goto tr3757 + st4194: + if p++; p == pe { + goto _test_eof4194 + } + st_case_4194: + if data[p] == 144 { + goto tr3758 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr3758 + } + case data[p] >= 152: + goto tr3758 + } + goto tr3757 + st4195: + if p++; p == pe { + goto _test_eof4195 + } + st_case_4195: + if data[p] == 188 { + goto tr3757 + } + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr3757 + } + case data[p] >= 129: + goto tr3757 + } + goto tr3758 + st4196: + if p++; p == pe { + goto _test_eof4196 + } + st_case_4196: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr3758 + } + case data[p] >= 133: + goto tr3758 + } + case data[p] > 150: + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr3758 + } + case data[p] >= 152: + goto tr3758 + } + default: + goto tr3758 + } + goto tr3757 + st4197: + if p++; p == pe { + goto _test_eof4197 + } + st_case_4197: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr3758 + } + case data[p] >= 131: + goto tr3758 + } + case data[p] > 144: + switch { + case data[p] < 178: + if 146 <= data[p] && data[p] <= 175 { + goto tr3758 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr3758 + } + default: + goto tr3758 + } + default: + goto tr3758 + } + goto tr3757 + st4198: + if p++; p == pe { + goto _test_eof4198 + } + st_case_4198: + switch data[p] { + case 134: + goto tr3758 + case 138: + goto tr3758 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr3758 + } + case data[p] >= 142: + goto tr3758 + } + goto tr3757 + st4199: + if p++; p == pe { + goto _test_eof4199 + } + st_case_4199: + if data[p] == 188 { + goto tr3757 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr3757 + } + case data[p] >= 129: + goto tr3757 + } + goto tr3758 + st4200: + if p++; p == pe { + goto _test_eof4200 + } + st_case_4200: + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr3757 + } + case data[p] >= 128: + goto tr3757 + } + case data[p] > 141: + switch { + case data[p] > 151: + if 162 <= data[p] && data[p] <= 163 { + goto tr3757 + } + case data[p] >= 150: + goto tr3757 + } + default: + goto tr3757 + } + goto tr3758 + st4201: + if p++; p == pe { + goto _test_eof4201 + } + st_case_4201: + if data[p] == 130 { + goto tr3757 + } + if 190 <= data[p] && data[p] <= 191 { + goto tr3757 + } + goto tr3758 + st4202: + if p++; p == pe { + goto _test_eof4202 + } + st_case_4202: + if data[p] == 151 { + goto tr3757 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr3757 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr3757 + } + default: + goto tr3757 + } + goto tr3758 + st4203: + if p++; p == pe { + goto _test_eof4203 + } + st_case_4203: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr3757 + } + case data[p] >= 128: + goto tr3757 + } + goto tr3758 + st4204: + if p++; p == pe { + goto _test_eof4204 + } + st_case_4204: + switch data[p] { + case 133: + goto tr3758 + case 137: + goto tr3758 + } + switch { + case data[p] < 151: + if 142 <= data[p] && data[p] <= 148 { + goto tr3758 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr3758 + } + default: + goto tr3758 + } + goto tr3757 + st4205: + if p++; p == pe { + goto _test_eof4205 + } + st_case_4205: + switch { + case data[p] < 138: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 136 { + goto tr3757 + } + case data[p] >= 128: + goto tr3757 + } + case data[p] > 141: + switch { + case data[p] > 150: + if 162 <= data[p] && data[p] <= 163 { + goto tr3757 + } + case data[p] >= 149: + goto tr3757 + } + default: + goto tr3757 + } + goto tr3758 + st4206: + if p++; p == pe { + goto _test_eof4206 + } + st_case_4206: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr3757 + } + case data[p] >= 129: + goto tr3757 + } + goto tr3758 + st4207: + if p++; p == pe { + goto _test_eof4207 + } + st_case_4207: + switch data[p] { + case 133: + goto tr3758 + case 137: + goto tr3758 + } + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 150 { + goto tr3758 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr3758 + } + default: + goto tr3758 + } + goto tr3757 + st4208: + if p++; p == pe { + goto _test_eof4208 + } + st_case_4208: + if 130 <= data[p] && data[p] <= 131 { + goto tr3757 + } + goto tr3758 + st4209: + if p++; p == pe { + goto _test_eof4209 + } + st_case_4209: + switch data[p] { + case 138: + goto tr3757 + case 150: + goto tr3757 + } + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 148 { + goto tr3757 + } + case data[p] > 159: + if 178 <= data[p] && data[p] <= 179 { + goto tr3757 + } + default: + goto tr3757 + } + goto tr3758 + st4210: + if p++; p == pe { + goto _test_eof4210 + } + st_case_4210: + if data[p] == 177 { + goto tr3757 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr3757 + } + goto tr3758 + st4211: + if p++; p == pe { + goto _test_eof4211 + } + st_case_4211: + if 135 <= data[p] && data[p] <= 142 { + goto tr3757 + } + goto tr3758 + st4212: + if p++; p == pe { + goto _test_eof4212 + } + st_case_4212: + if data[p] == 177 { + goto tr3757 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr3757 + } + case data[p] >= 180: + goto tr3757 + } + goto tr3758 + st4213: + if p++; p == pe { + goto _test_eof4213 + } + st_case_4213: + if 136 <= data[p] && data[p] <= 141 { + goto tr3757 + } + goto tr3758 + st4214: + if p++; p == pe { + goto _test_eof4214 + } + st_case_4214: + switch data[p] { + case 181: + goto tr3757 + case 183: + goto tr3757 + case 185: + goto tr3757 + } + switch { + case data[p] > 153: + if 190 <= data[p] && data[p] <= 191 { + goto tr3757 + } + case data[p] >= 152: + goto tr3757 + } + goto tr3758 + st4215: + if p++; p == pe { + goto _test_eof4215 + } + st_case_4215: + if 177 <= data[p] && data[p] <= 191 { + goto tr3757 + } + goto tr3758 + st4216: + if p++; p == pe { + goto _test_eof4216 + } + st_case_4216: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr3757 + } + case data[p] > 135: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr3757 + } + case data[p] >= 141: + goto tr3757 + } + default: + goto tr3757 + } + goto tr3758 + st4217: + if p++; p == pe { + goto _test_eof4217 + } + st_case_4217: + if data[p] == 134 { + goto tr3757 + } + goto tr3758 + st4218: + if p++; p == pe { + goto _test_eof4218 + } + st_case_4218: + switch data[p] { + case 128: + goto st4219 + case 129: + goto st4220 + case 130: + goto st4221 + case 141: + goto st4222 + case 156: + goto st4223 + case 157: + goto st4224 + case 158: + goto st4225 + case 159: + goto st4226 + case 160: + goto st4227 + case 162: + goto st4228 + case 164: + goto st4229 + case 168: + goto st4230 + case 169: + goto st4231 + case 170: + goto st4232 + case 172: + goto st4233 + case 173: + goto st4234 + case 174: + goto st4235 + case 175: + goto st4236 + case 176: + goto st4237 + case 179: + goto st4238 + case 183: + goto st4239 + } + goto tr3758 + st4219: + if p++; p == pe { + goto _test_eof4219 + } + st_case_4219: + if 171 <= data[p] && data[p] <= 190 { + goto tr3757 + } + goto tr3758 + st4220: + if p++; p == pe { + goto _test_eof4220 + } + st_case_4220: + switch { + case data[p] < 162: + switch { + case data[p] > 153: + if 158 <= data[p] && data[p] <= 160 { + goto tr3757 + } + case data[p] >= 150: + goto tr3757 + } + case data[p] > 164: + switch { + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr3757 + } + case data[p] >= 167: + goto tr3757 + } + default: + goto tr3757 + } + goto tr3758 + st4221: + if p++; p == pe { + goto _test_eof4221 + } + st_case_4221: + if data[p] == 143 { + goto tr3757 + } + switch { + case data[p] > 141: + if 154 <= data[p] && data[p] <= 157 { + goto tr3757 + } + case data[p] >= 130: + goto tr3757 + } + goto tr3758 + st4222: + if p++; p == pe { + goto _test_eof4222 + } + st_case_4222: + if 157 <= data[p] && data[p] <= 159 { + goto tr3757 + } + goto tr3758 + st4223: + if p++; p == pe { + goto _test_eof4223 + } + st_case_4223: + switch { + case data[p] > 148: + if 178 <= data[p] && data[p] <= 180 { + goto tr3757 + } + case data[p] >= 146: + goto tr3757 + } + goto tr3758 + st4224: + if p++; p == pe { + goto _test_eof4224 + } + st_case_4224: + switch { + case data[p] > 147: + if 178 <= data[p] && data[p] <= 179 { + goto tr3757 + } + case data[p] >= 146: + goto tr3757 + } + goto tr3758 + st4225: + if p++; p == pe { + goto _test_eof4225 + } + st_case_4225: + if 180 <= data[p] { + goto tr3757 + } + goto tr3758 + st4226: + if p++; p == pe { + goto _test_eof4226 + } + st_case_4226: + switch { + case data[p] > 156: + if 158 <= data[p] { + goto tr3758 + } + case data[p] >= 148: + goto tr3758 + } + goto tr3757 + st4227: + if p++; p == pe { + goto _test_eof4227 + } + st_case_4227: + if 139 <= data[p] && data[p] <= 142 { + goto tr3757 + } + goto tr3758 + st4228: + if p++; p == pe { + goto _test_eof4228 + } + st_case_4228: + if data[p] == 169 { + goto tr3757 + } + goto tr3758 + st4229: + if p++; p == pe { + goto _test_eof4229 + } + st_case_4229: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr3757 + } + case data[p] >= 160: + goto tr3757 + } + goto tr3758 + st4230: + if p++; p == pe { + goto _test_eof4230 + } + st_case_4230: + if 151 <= data[p] && data[p] <= 155 { + goto tr3757 + } + goto tr3758 + st4231: + if p++; p == pe { + goto _test_eof4231 + } + st_case_4231: + if data[p] == 191 { + goto tr3757 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr3757 + } + case data[p] >= 149: + goto tr3757 + } + goto tr3758 + st4232: + if p++; p == pe { + goto _test_eof4232 + } + st_case_4232: + if 176 <= data[p] && data[p] <= 190 { + goto tr3757 + } + goto tr3758 + st4233: + if p++; p == pe { + goto _test_eof4233 + } + st_case_4233: + switch { + case data[p] > 132: + if 180 <= data[p] { + goto tr3757 + } + case data[p] >= 128: + goto tr3757 + } + goto tr3758 + st4234: + if p++; p == pe { + goto _test_eof4234 + } + st_case_4234: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr3758 + } + case data[p] >= 133: + goto tr3758 + } + goto tr3757 + st4235: + if p++; p == pe { + goto _test_eof4235 + } + st_case_4235: + switch { + case data[p] > 130: + if 161 <= data[p] && data[p] <= 173 { + goto tr3757 + } + case data[p] >= 128: + goto tr3757 + } + goto tr3758 + st4236: + if p++; p == pe { + goto _test_eof4236 + } + st_case_4236: + if 166 <= data[p] && data[p] <= 179 { + goto tr3757 + } + goto tr3758 + st4237: + if p++; p == pe { + goto _test_eof4237 + } + st_case_4237: + if 164 <= data[p] && data[p] <= 183 { + goto tr3757 + } + goto tr3758 + st4238: + if p++; p == pe { + goto _test_eof4238 + } + st_case_4238: + if data[p] == 173 { + goto tr3757 + } + switch { + case data[p] < 148: + if 144 <= data[p] && data[p] <= 146 { + goto tr3757 + } + case data[p] > 168: + switch { + case data[p] > 180: + if 184 <= data[p] && data[p] <= 185 { + goto tr3757 + } + case data[p] >= 178: + goto tr3757 + } + default: + goto tr3757 + } + goto tr3758 + st4239: + if p++; p == pe { + goto _test_eof4239 + } + st_case_4239: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr3757 + } + case data[p] >= 128: + goto tr3757 + } + goto tr3758 + st4240: + if p++; p == pe { + goto _test_eof4240 + } + st_case_4240: + switch data[p] { + case 128: + goto st4241 + case 129: + goto st4242 + case 131: + goto st4243 + case 179: + goto st4244 + case 181: + goto st4245 + case 183: + goto st4246 + } + goto tr3758 + st4241: + if p++; p == pe { + goto _test_eof4241 + } + st_case_4241: + switch { + case data[p] > 143: + if 170 <= data[p] && data[p] <= 174 { + goto tr3757 + } + case data[p] >= 140: + goto tr3757 + } + goto tr3758 + st4242: + if p++; p == pe { + goto _test_eof4242 + } + st_case_4242: + switch { + case data[p] > 164: + if 166 <= data[p] && data[p] <= 175 { + goto tr3757 + } + case data[p] >= 160: + goto tr3757 + } + goto tr3758 + st4243: + if p++; p == pe { + goto _test_eof4243 + } + st_case_4243: + if 144 <= data[p] && data[p] <= 176 { + goto tr3757 + } + goto tr3758 + st4244: + if p++; p == pe { + goto _test_eof4244 + } + st_case_4244: + if 175 <= data[p] && data[p] <= 177 { + goto tr3757 + } + goto tr3758 + st4245: + if p++; p == pe { + goto _test_eof4245 + } + st_case_4245: + if data[p] == 191 { + goto tr3757 + } + goto tr3758 + st4246: + if p++; p == pe { + goto _test_eof4246 + } + st_case_4246: + if 160 <= data[p] && data[p] <= 191 { + goto tr3757 + } + goto tr3758 + st4247: + if p++; p == pe { + goto _test_eof4247 + } + st_case_4247: + switch data[p] { + case 128: + goto st4248 + case 130: + goto st4249 + } + goto tr3758 + st4248: + if p++; p == pe { + goto _test_eof4248 + } + st_case_4248: + if 170 <= data[p] && data[p] <= 175 { + goto tr3757 + } + goto tr3758 + st4249: + if p++; p == pe { + goto _test_eof4249 + } + st_case_4249: + if 153 <= data[p] && data[p] <= 154 { + goto tr3757 + } + goto tr3758 + st4250: + if p++; p == pe { + goto _test_eof4250 + } + st_case_4250: + switch data[p] { + case 153: + goto st4251 + case 154: + goto st4252 + case 155: + goto st4253 + case 160: + goto st4254 + case 162: + goto st4255 + case 163: + goto st4256 + case 164: + goto st4257 + case 165: + goto st4258 + case 166: + goto st4259 + case 167: + goto st4260 + case 168: + goto st4261 + case 169: + goto st4262 + case 170: + goto st4263 + case 171: + goto st4264 + case 175: + goto st4265 + } + goto tr3758 + st4251: + if p++; p == pe { + goto _test_eof4251 + } + st_case_4251: + switch { + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr3757 + } + case data[p] >= 175: + goto tr3757 + } + goto tr3758 + st4252: + if p++; p == pe { + goto _test_eof4252 + } + st_case_4252: + if 158 <= data[p] && data[p] <= 159 { + goto tr3757 + } + goto tr3758 + st4253: + if p++; p == pe { + goto _test_eof4253 + } + st_case_4253: + if 176 <= data[p] && data[p] <= 177 { + goto tr3757 + } + goto tr3758 + st4254: + if p++; p == pe { + goto _test_eof4254 + } + st_case_4254: + switch data[p] { + case 130: + goto tr3757 + case 134: + goto tr3757 + case 139: + goto tr3757 + } + if 163 <= data[p] && data[p] <= 167 { + goto tr3757 + } + goto tr3758 + st4255: + if p++; p == pe { + goto _test_eof4255 + } + st_case_4255: + switch { + case data[p] > 129: + if 180 <= data[p] { + goto tr3757 + } + case data[p] >= 128: + goto tr3757 + } + goto tr3758 + st4256: + if p++; p == pe { + goto _test_eof4256 + } + st_case_4256: + switch { + case data[p] > 159: + if 178 <= data[p] { + goto tr3758 + } + case data[p] >= 133: + goto tr3758 + } + goto tr3757 + st4257: + if p++; p == pe { + goto _test_eof4257 + } + st_case_4257: + if 166 <= data[p] && data[p] <= 173 { + goto tr3757 + } + goto tr3758 + st4258: + if p++; p == pe { + goto _test_eof4258 + } + st_case_4258: + if 135 <= data[p] && data[p] <= 147 { + goto tr3757 + } + goto tr3758 + st4259: + if p++; p == pe { + goto _test_eof4259 + } + st_case_4259: + switch { + case data[p] > 131: + if 179 <= data[p] { + goto tr3757 + } + case data[p] >= 128: + goto tr3757 + } + goto tr3758 + st4260: + if p++; p == pe { + goto _test_eof4260 + } + st_case_4260: + switch { + case data[p] > 164: + if 166 <= data[p] { + goto tr3758 + } + case data[p] >= 129: + goto tr3758 + } + goto tr3757 + st4261: + if p++; p == pe { + goto _test_eof4261 + } + st_case_4261: + if 169 <= data[p] && data[p] <= 182 { + goto tr3757 + } + goto tr3758 + st4262: + if p++; p == pe { + goto _test_eof4262 + } + st_case_4262: + if data[p] == 131 { + goto tr3757 + } + switch { + case data[p] > 141: + if 187 <= data[p] && data[p] <= 189 { + goto tr3757 + } + case data[p] >= 140: + goto tr3757 + } + goto tr3758 + st4263: + if p++; p == pe { + goto _test_eof4263 + } + st_case_4263: + if data[p] == 176 { + goto tr3757 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr3757 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr3757 + } + default: + goto tr3757 + } + goto tr3758 + st4264: + if p++; p == pe { + goto _test_eof4264 + } + st_case_4264: + if data[p] == 129 { + goto tr3757 + } + switch { + case data[p] > 175: + if 181 <= data[p] && data[p] <= 182 { + goto tr3757 + } + case data[p] >= 171: + goto tr3757 + } + goto tr3758 + st4265: + if p++; p == pe { + goto _test_eof4265 + } + st_case_4265: + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 173 { + goto tr3757 + } + case data[p] >= 163: + goto tr3757 + } + goto tr3758 + st4266: + if p++; p == pe { + goto _test_eof4266 + } + st_case_4266: + switch data[p] { + case 172: + goto st4267 + case 184: + goto st4268 + case 187: + goto st4245 + case 190: + goto st4252 + case 191: + goto st4269 + } + goto tr3758 + st4267: + if p++; p == pe { + goto _test_eof4267 + } + st_case_4267: + if data[p] == 158 { + goto tr3757 + } + goto tr3758 + st4268: + if p++; p == pe { + goto _test_eof4268 + } + st_case_4268: + switch { + case data[p] > 143: + if 160 <= data[p] && data[p] <= 175 { + goto tr3757 + } + case data[p] >= 128: + goto tr3757 + } + goto tr3758 + st4269: + if p++; p == pe { + goto _test_eof4269 + } + st_case_4269: + if 185 <= data[p] && data[p] <= 187 { + goto tr3757 + } + goto tr3758 + st4270: + if p++; p == pe { + goto _test_eof4270 + } + st_case_4270: + switch data[p] { + case 144: + goto st4271 + case 145: + goto st4277 + case 150: + goto st4296 + case 155: + goto st4301 + case 157: + goto st4303 + case 158: + goto st4310 + } + goto tr3758 + st4271: + if p++; p == pe { + goto _test_eof4271 + } + st_case_4271: + switch data[p] { + case 135: + goto st4272 + case 139: + goto st4273 + case 141: + goto st4274 + case 168: + goto st4275 + case 171: + goto st4276 + } + goto tr3758 + st4272: + if p++; p == pe { + goto _test_eof4272 + } + st_case_4272: + if data[p] == 189 { + goto tr3757 + } + goto tr3758 + st4273: + if p++; p == pe { + goto _test_eof4273 + } + st_case_4273: + if data[p] == 160 { + goto tr3757 + } + goto tr3758 + st4274: + if p++; p == pe { + goto _test_eof4274 + } + st_case_4274: + if 182 <= data[p] && data[p] <= 186 { + goto tr3757 + } + goto tr3758 + st4275: + if p++; p == pe { + goto _test_eof4275 + } + st_case_4275: + if data[p] == 191 { + goto tr3757 + } + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr3757 + } + case data[p] > 134: + switch { + case data[p] > 143: + if 184 <= data[p] && data[p] <= 186 { + goto tr3757 + } + case data[p] >= 140: + goto tr3757 + } + default: + goto tr3757 + } + goto tr3758 + st4276: + if p++; p == pe { + goto _test_eof4276 + } + st_case_4276: + if 165 <= data[p] && data[p] <= 166 { + goto tr3757 + } + goto tr3758 + st4277: + if p++; p == pe { + goto _test_eof4277 + } + st_case_4277: + switch data[p] { + case 128: + goto st4278 + case 129: + goto st4279 + case 130: + goto st4280 + case 132: + goto st4281 + case 133: + goto st4282 + case 134: + goto st4283 + case 135: + goto st4284 + case 136: + goto st4285 + case 139: + goto st4286 + case 140: + goto st4287 + case 141: + goto st4288 + case 146: + goto st4289 + case 147: + goto st4290 + case 150: + goto st4291 + case 151: + goto st4292 + case 152: + goto st4289 + case 153: + goto st4293 + case 154: + goto st4294 + case 156: + goto st4295 + } + goto tr3758 + st4278: + if p++; p == pe { + goto _test_eof4278 + } + st_case_4278: + switch { + case data[p] > 130: + if 184 <= data[p] { + goto tr3757 + } + case data[p] >= 128: + goto tr3757 + } + goto tr3758 + st4279: + if p++; p == pe { + goto _test_eof4279 + } + st_case_4279: + if 135 <= data[p] && data[p] <= 190 { + goto tr3758 + } + goto tr3757 + st4280: + if p++; p == pe { + goto _test_eof4280 + } + st_case_4280: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr3758 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr3758 + } + default: + goto tr3758 + } + goto tr3757 + st4281: + if p++; p == pe { + goto _test_eof4281 + } + st_case_4281: + switch { + case data[p] > 130: + if 167 <= data[p] && data[p] <= 180 { + goto tr3757 + } + case data[p] >= 128: + goto tr3757 + } + goto tr3758 + st4282: + if p++; p == pe { + goto _test_eof4282 + } + st_case_4282: + if data[p] == 179 { + goto tr3757 + } + goto tr3758 + st4283: + if p++; p == pe { + goto _test_eof4283 + } + st_case_4283: + switch { + case data[p] > 130: + if 179 <= data[p] { + goto tr3757 + } + case data[p] >= 128: + goto tr3757 + } + goto tr3758 + st4284: + if p++; p == pe { + goto _test_eof4284 + } + st_case_4284: + switch { + case data[p] > 137: + if 141 <= data[p] { + goto tr3758 + } + case data[p] >= 129: + goto tr3758 + } + goto tr3757 + st4285: + if p++; p == pe { + goto _test_eof4285 + } + st_case_4285: + if 172 <= data[p] && data[p] <= 183 { + goto tr3757 + } + goto tr3758 + st4286: + if p++; p == pe { + goto _test_eof4286 + } + st_case_4286: + if 159 <= data[p] && data[p] <= 170 { + goto tr3757 + } + goto tr3758 + st4287: + if p++; p == pe { + goto _test_eof4287 + } + st_case_4287: + if data[p] == 188 { + goto tr3757 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr3757 + } + case data[p] >= 128: + goto tr3757 + } + goto tr3758 + st4288: + if p++; p == pe { + goto _test_eof4288 + } + st_case_4288: + if data[p] == 151 { + goto tr3757 + } + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr3757 + } + case data[p] >= 128: + goto tr3757 + } + case data[p] > 141: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr3757 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr3757 + } + default: + goto tr3757 + } + default: + goto tr3757 + } + goto tr3758 + st4289: + if p++; p == pe { + goto _test_eof4289 + } + st_case_4289: + if 176 <= data[p] { + goto tr3757 + } + goto tr3758 + st4290: + if p++; p == pe { + goto _test_eof4290 + } + st_case_4290: + if 132 <= data[p] { + goto tr3758 + } + goto tr3757 + st4291: + if p++; p == pe { + goto _test_eof4291 + } + st_case_4291: + switch { + case data[p] > 181: + if 184 <= data[p] { + goto tr3757 + } + case data[p] >= 175: + goto tr3757 + } + goto tr3758 + st4292: + if p++; p == pe { + goto _test_eof4292 + } + st_case_4292: + switch { + case data[p] > 155: + if 158 <= data[p] { + goto tr3758 + } + case data[p] >= 129: + goto tr3758 + } + goto tr3757 + st4293: + if p++; p == pe { + goto _test_eof4293 + } + st_case_4293: + if 129 <= data[p] { + goto tr3758 + } + goto tr3757 + st4294: + if p++; p == pe { + goto _test_eof4294 + } + st_case_4294: + if 171 <= data[p] && data[p] <= 183 { + goto tr3757 + } + goto tr3758 + st4295: + if p++; p == pe { + goto _test_eof4295 + } + st_case_4295: + if 157 <= data[p] && data[p] <= 171 { + goto tr3757 + } + goto tr3758 + st4296: + if p++; p == pe { + goto _test_eof4296 + } + st_case_4296: + switch data[p] { + case 171: + goto st4297 + case 172: + goto st4298 + case 189: + goto st4299 + case 190: + goto st4300 + } + goto tr3758 + st4297: + if p++; p == pe { + goto _test_eof4297 + } + st_case_4297: + if 176 <= data[p] && data[p] <= 180 { + goto tr3757 + } + goto tr3758 + st4298: + if p++; p == pe { + goto _test_eof4298 + } + st_case_4298: + if 176 <= data[p] && data[p] <= 182 { + goto tr3757 + } + goto tr3758 + st4299: + if p++; p == pe { + goto _test_eof4299 + } + st_case_4299: + if 145 <= data[p] && data[p] <= 190 { + goto tr3757 + } + goto tr3758 + st4300: + if p++; p == pe { + goto _test_eof4300 + } + st_case_4300: + if 143 <= data[p] && data[p] <= 146 { + goto tr3757 + } + goto tr3758 + st4301: + if p++; p == pe { + goto _test_eof4301 + } + st_case_4301: + if data[p] == 178 { + goto st4302 + } + goto tr3758 + st4302: + if p++; p == pe { + goto _test_eof4302 + } + st_case_4302: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr3757 + } + case data[p] >= 157: + goto tr3757 + } + goto tr3758 + st4303: + if p++; p == pe { + goto _test_eof4303 + } + st_case_4303: + switch data[p] { + case 133: + goto st4304 + case 134: + goto st4305 + case 137: + goto st4306 + case 168: + goto st4307 + case 169: + goto st4308 + case 170: + goto st4309 + } + goto tr3758 + st4304: + if p++; p == pe { + goto _test_eof4304 + } + st_case_4304: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr3757 + } + case data[p] >= 165: + goto tr3757 + } + goto tr3758 + st4305: + if p++; p == pe { + goto _test_eof4305 + } + st_case_4305: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr3758 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr3758 + } + default: + goto tr3758 + } + goto tr3757 + st4306: + if p++; p == pe { + goto _test_eof4306 + } + st_case_4306: + if 130 <= data[p] && data[p] <= 132 { + goto tr3757 + } + goto tr3758 + st4307: + if p++; p == pe { + goto _test_eof4307 + } + st_case_4307: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr3757 + } + case data[p] >= 128: + goto tr3757 + } + goto tr3758 + st4308: + if p++; p == pe { + goto _test_eof4308 + } + st_case_4308: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr3758 + } + case data[p] >= 173: + goto tr3758 + } + goto tr3757 + st4309: + if p++; p == pe { + goto _test_eof4309 + } + st_case_4309: + if data[p] == 132 { + goto tr3757 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr3757 + } + case data[p] >= 155: + goto tr3757 + } + goto tr3758 + st4310: + if p++; p == pe { + goto _test_eof4310 + } + st_case_4310: + if data[p] == 163 { + goto st4311 + } + goto tr3758 + st4311: + if p++; p == pe { + goto _test_eof4311 + } + st_case_4311: + if 144 <= data[p] && data[p] <= 150 { + goto tr3757 + } + goto tr3758 + st4312: + if p++; p == pe { + goto _test_eof4312 + } + st_case_4312: + if data[p] == 160 { + goto st4313 + } + goto tr3758 + st4313: + if p++; p == pe { + goto _test_eof4313 + } + st_case_4313: + switch data[p] { + case 128: + goto st4314 + case 129: + goto st4315 + case 132: + goto st4177 + case 135: + goto st4178 + } + if 133 <= data[p] && data[p] <= 134 { + goto st4316 + } + goto tr3758 + st4314: + if p++; p == pe { + goto _test_eof4314 + } + st_case_4314: + if data[p] == 129 { + goto tr3757 + } + if 160 <= data[p] { + goto tr3757 + } + goto tr3758 + st4315: + if p++; p == pe { + goto _test_eof4315 + } + st_case_4315: + if 192 <= data[p] { + goto tr3758 + } + goto tr3757 + st4316: + if p++; p == pe { + goto _test_eof4316 + } + st_case_4316: + goto tr3757 + st4317: + if p++; p == pe { + goto _test_eof4317 + } + st_case_4317: + switch { + case data[p] < 153: + if 151 <= data[p] && data[p] <= 152 { + goto tr0 + } + case data[p] > 154: + switch { + case data[p] > 156: + if 160 <= data[p] { + goto tr3376 + } + case data[p] >= 155: + goto tr3376 + } + default: + goto tr2395 + } + goto tr3757 + st4318: + if p++; p == pe { + goto _test_eof4318 + } + st_case_4318: + if data[p] == 173 { + goto tr3881 + } + goto tr3250 +tr3881: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + + goto st5082 + st5082: + if p++; p == pe { + goto _test_eof5082 + } + st_case_5082: +//line segment_words_prod.go:123394 + switch data[p] { + case 194: + goto st4319 + case 204: + goto st4320 + case 205: + goto st4321 + case 210: + goto st4322 + case 214: + goto st4323 + case 215: + goto st4324 + case 216: + goto st4325 + case 217: + goto st4326 + case 219: + goto st4327 + case 220: + goto st4328 + case 221: + goto st4329 + case 222: + goto st4330 + case 223: + goto st4331 + case 224: + goto st4332 + case 225: + goto st4361 + case 226: + goto st4383 + case 227: + goto st4390 + case 234: + goto st4393 + case 239: + goto st4409 + case 240: + goto st4413 + case 243: + goto st4455 + } + goto tr5054 + st4319: + if p++; p == pe { + goto _test_eof4319 + } + st_case_4319: + if data[p] == 173 { + goto tr3881 + } + goto tr3251 + st4320: + if p++; p == pe { + goto _test_eof4320 + } + st_case_4320: + if 128 <= data[p] { + goto tr3881 + } + goto tr3251 + st4321: + if p++; p == pe { + goto _test_eof4321 + } + st_case_4321: + if 176 <= data[p] { + goto tr3251 + } + goto tr3881 + st4322: + if p++; p == pe { + goto _test_eof4322 + } + st_case_4322: + if 131 <= data[p] && data[p] <= 137 { + goto tr3881 + } + goto tr3251 + st4323: + if p++; p == pe { + goto _test_eof4323 + } + st_case_4323: + if data[p] == 191 { + goto tr3881 + } + if 145 <= data[p] && data[p] <= 189 { + goto tr3881 + } + goto tr3251 + st4324: + if p++; p == pe { + goto _test_eof4324 + } + st_case_4324: + if data[p] == 135 { + goto tr3881 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto tr3881 + } + case data[p] >= 129: + goto tr3881 + } + goto tr3251 + st4325: + if p++; p == pe { + goto _test_eof4325 + } + st_case_4325: + if data[p] == 156 { + goto tr3881 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto tr3881 + } + case data[p] >= 128: + goto tr3881 + } + goto tr3251 + st4326: + if p++; p == pe { + goto _test_eof4326 + } + st_case_4326: + if data[p] == 176 { + goto tr3881 + } + if 139 <= data[p] && data[p] <= 159 { + goto tr3881 + } + goto tr3251 + st4327: + if p++; p == pe { + goto _test_eof4327 + } + st_case_4327: + switch { + case data[p] < 159: + if 150 <= data[p] && data[p] <= 157 { + goto tr3881 + } + case data[p] > 164: + switch { + case data[p] > 168: + if 170 <= data[p] && data[p] <= 173 { + goto tr3881 + } + case data[p] >= 167: + goto tr3881 + } + default: + goto tr3881 + } + goto tr3251 + st4328: + if p++; p == pe { + goto _test_eof4328 + } + st_case_4328: + switch data[p] { + case 143: + goto tr3881 + case 145: + goto tr3881 + } + if 176 <= data[p] { + goto tr3881 + } + goto tr3251 + st4329: + if p++; p == pe { + goto _test_eof4329 + } + st_case_4329: + if 139 <= data[p] { + goto tr3251 + } + goto tr3881 + st4330: + if p++; p == pe { + goto _test_eof4330 + } + st_case_4330: + if 166 <= data[p] && data[p] <= 176 { + goto tr3881 + } + goto tr3251 + st4331: + if p++; p == pe { + goto _test_eof4331 + } + st_case_4331: + if 171 <= data[p] && data[p] <= 179 { + goto tr3881 + } + goto tr3251 + st4332: + if p++; p == pe { + goto _test_eof4332 + } + st_case_4332: + switch data[p] { + case 160: + goto st4333 + case 161: + goto st4334 + case 163: + goto st4335 + case 164: + goto st4336 + case 165: + goto st4337 + case 167: + goto st4339 + case 169: + goto st4340 + case 171: + goto st4341 + case 173: + goto st4343 + case 174: + goto st4344 + case 175: + goto st4345 + case 176: + goto st4346 + case 177: + goto st4347 + case 179: + goto st4348 + case 180: + goto st4349 + case 181: + goto st4350 + case 182: + goto st4351 + case 183: + goto st4352 + case 184: + goto st4353 + case 185: + goto st4354 + case 186: + goto st4355 + case 187: + goto st4356 + case 188: + goto st4357 + case 189: + goto st4358 + case 190: + goto st4359 + case 191: + goto st4360 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto st4342 + } + case data[p] >= 166: + goto st4338 + } + goto tr3251 + st4333: + if p++; p == pe { + goto _test_eof4333 + } + st_case_4333: + switch { + case data[p] < 155: + if 150 <= data[p] && data[p] <= 153 { + goto tr3881 + } + case data[p] > 163: + switch { + case data[p] > 167: + if 169 <= data[p] && data[p] <= 173 { + goto tr3881 + } + case data[p] >= 165: + goto tr3881 + } + default: + goto tr3881 + } + goto tr3251 + st4334: + if p++; p == pe { + goto _test_eof4334 + } + st_case_4334: + if 153 <= data[p] && data[p] <= 155 { + goto tr3881 + } + goto tr3251 + st4335: + if p++; p == pe { + goto _test_eof4335 + } + st_case_4335: + if 163 <= data[p] { + goto tr3881 + } + goto tr3251 + st4336: + if p++; p == pe { + goto _test_eof4336 + } + st_case_4336: + if data[p] == 189 { + goto tr3251 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr3251 + } + goto tr3881 + st4337: + if p++; p == pe { + goto _test_eof4337 + } + st_case_4337: + if data[p] == 144 { + goto tr3251 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr3251 + } + case data[p] >= 152: + goto tr3251 + } + goto tr3881 + st4338: + if p++; p == pe { + goto _test_eof4338 + } + st_case_4338: + if data[p] == 188 { + goto tr3881 + } + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr3881 + } + case data[p] >= 129: + goto tr3881 + } + goto tr3251 + st4339: + if p++; p == pe { + goto _test_eof4339 + } + st_case_4339: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr3251 + } + case data[p] >= 133: + goto tr3251 + } + case data[p] > 150: + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr3251 + } + case data[p] >= 152: + goto tr3251 + } + default: + goto tr3251 + } + goto tr3881 + st4340: + if p++; p == pe { + goto _test_eof4340 + } + st_case_4340: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr3251 + } + case data[p] >= 131: + goto tr3251 + } + case data[p] > 144: + switch { + case data[p] < 178: + if 146 <= data[p] && data[p] <= 175 { + goto tr3251 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr3251 + } + default: + goto tr3251 + } + default: + goto tr3251 + } + goto tr3881 + st4341: + if p++; p == pe { + goto _test_eof4341 + } + st_case_4341: + switch data[p] { + case 134: + goto tr3251 + case 138: + goto tr3251 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr3251 + } + case data[p] >= 142: + goto tr3251 + } + goto tr3881 + st4342: + if p++; p == pe { + goto _test_eof4342 + } + st_case_4342: + if data[p] == 188 { + goto tr3881 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr3881 + } + case data[p] >= 129: + goto tr3881 + } + goto tr3251 + st4343: + if p++; p == pe { + goto _test_eof4343 + } + st_case_4343: + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr3881 + } + case data[p] >= 128: + goto tr3881 + } + case data[p] > 141: + switch { + case data[p] > 151: + if 162 <= data[p] && data[p] <= 163 { + goto tr3881 + } + case data[p] >= 150: + goto tr3881 + } + default: + goto tr3881 + } + goto tr3251 + st4344: + if p++; p == pe { + goto _test_eof4344 + } + st_case_4344: + if data[p] == 130 { + goto tr3881 + } + if 190 <= data[p] && data[p] <= 191 { + goto tr3881 + } + goto tr3251 + st4345: + if p++; p == pe { + goto _test_eof4345 + } + st_case_4345: + if data[p] == 151 { + goto tr3881 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr3881 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr3881 + } + default: + goto tr3881 + } + goto tr3251 + st4346: + if p++; p == pe { + goto _test_eof4346 + } + st_case_4346: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr3881 + } + case data[p] >= 128: + goto tr3881 + } + goto tr3251 + st4347: + if p++; p == pe { + goto _test_eof4347 + } + st_case_4347: + switch data[p] { + case 133: + goto tr3251 + case 137: + goto tr3251 + } + switch { + case data[p] < 151: + if 142 <= data[p] && data[p] <= 148 { + goto tr3251 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr3251 + } + default: + goto tr3251 + } + goto tr3881 + st4348: + if p++; p == pe { + goto _test_eof4348 + } + st_case_4348: + switch { + case data[p] < 138: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 136 { + goto tr3881 + } + case data[p] >= 128: + goto tr3881 + } + case data[p] > 141: + switch { + case data[p] > 150: + if 162 <= data[p] && data[p] <= 163 { + goto tr3881 + } + case data[p] >= 149: + goto tr3881 + } + default: + goto tr3881 + } + goto tr3251 + st4349: + if p++; p == pe { + goto _test_eof4349 + } + st_case_4349: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr3881 + } + case data[p] >= 129: + goto tr3881 + } + goto tr3251 + st4350: + if p++; p == pe { + goto _test_eof4350 + } + st_case_4350: + switch data[p] { + case 133: + goto tr3251 + case 137: + goto tr3251 + } + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 150 { + goto tr3251 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr3251 + } + default: + goto tr3251 + } + goto tr3881 + st4351: + if p++; p == pe { + goto _test_eof4351 + } + st_case_4351: + if 130 <= data[p] && data[p] <= 131 { + goto tr3881 + } + goto tr3251 + st4352: + if p++; p == pe { + goto _test_eof4352 + } + st_case_4352: + switch data[p] { + case 138: + goto tr3881 + case 150: + goto tr3881 + } + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 148 { + goto tr3881 + } + case data[p] > 159: + if 178 <= data[p] && data[p] <= 179 { + goto tr3881 + } + default: + goto tr3881 + } + goto tr3251 + st4353: + if p++; p == pe { + goto _test_eof4353 + } + st_case_4353: + if data[p] == 177 { + goto tr3881 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr3881 + } + goto tr3251 + st4354: + if p++; p == pe { + goto _test_eof4354 + } + st_case_4354: + if 135 <= data[p] && data[p] <= 142 { + goto tr3881 + } + goto tr3251 + st4355: + if p++; p == pe { + goto _test_eof4355 + } + st_case_4355: + if data[p] == 177 { + goto tr3881 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr3881 + } + case data[p] >= 180: + goto tr3881 + } + goto tr3251 + st4356: + if p++; p == pe { + goto _test_eof4356 + } + st_case_4356: + if 136 <= data[p] && data[p] <= 141 { + goto tr3881 + } + goto tr3251 + st4357: + if p++; p == pe { + goto _test_eof4357 + } + st_case_4357: + switch data[p] { + case 181: + goto tr3881 + case 183: + goto tr3881 + case 185: + goto tr3881 + } + switch { + case data[p] > 153: + if 190 <= data[p] && data[p] <= 191 { + goto tr3881 + } + case data[p] >= 152: + goto tr3881 + } + goto tr3251 + st4358: + if p++; p == pe { + goto _test_eof4358 + } + st_case_4358: + if 177 <= data[p] && data[p] <= 191 { + goto tr3881 + } + goto tr3251 + st4359: + if p++; p == pe { + goto _test_eof4359 + } + st_case_4359: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr3881 + } + case data[p] > 135: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr3881 + } + case data[p] >= 141: + goto tr3881 + } + default: + goto tr3881 + } + goto tr3251 + st4360: + if p++; p == pe { + goto _test_eof4360 + } + st_case_4360: + if data[p] == 134 { + goto tr3881 + } + goto tr3251 + st4361: + if p++; p == pe { + goto _test_eof4361 + } + st_case_4361: + switch data[p] { + case 128: + goto st4362 + case 129: + goto st4363 + case 130: + goto st4364 + case 141: + goto st4365 + case 156: + goto st4366 + case 157: + goto st4367 + case 158: + goto st4368 + case 159: + goto st4369 + case 160: + goto st4370 + case 162: + goto st4371 + case 164: + goto st4372 + case 168: + goto st4373 + case 169: + goto st4374 + case 170: + goto st4375 + case 172: + goto st4376 + case 173: + goto st4377 + case 174: + goto st4378 + case 175: + goto st4379 + case 176: + goto st4380 + case 179: + goto st4381 + case 183: + goto st4382 + } + goto tr3251 + st4362: + if p++; p == pe { + goto _test_eof4362 + } + st_case_4362: + if 171 <= data[p] && data[p] <= 190 { + goto tr3881 + } + goto tr3251 + st4363: + if p++; p == pe { + goto _test_eof4363 + } + st_case_4363: + switch { + case data[p] < 162: + switch { + case data[p] > 153: + if 158 <= data[p] && data[p] <= 160 { + goto tr3881 + } + case data[p] >= 150: + goto tr3881 + } + case data[p] > 164: + switch { + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr3881 + } + case data[p] >= 167: + goto tr3881 + } + default: + goto tr3881 + } + goto tr3251 + st4364: + if p++; p == pe { + goto _test_eof4364 + } + st_case_4364: + if data[p] == 143 { + goto tr3881 + } + switch { + case data[p] > 141: + if 154 <= data[p] && data[p] <= 157 { + goto tr3881 + } + case data[p] >= 130: + goto tr3881 + } + goto tr3251 + st4365: + if p++; p == pe { + goto _test_eof4365 + } + st_case_4365: + if 157 <= data[p] && data[p] <= 159 { + goto tr3881 + } + goto tr3251 + st4366: + if p++; p == pe { + goto _test_eof4366 + } + st_case_4366: + switch { + case data[p] > 148: + if 178 <= data[p] && data[p] <= 180 { + goto tr3881 + } + case data[p] >= 146: + goto tr3881 + } + goto tr3251 + st4367: + if p++; p == pe { + goto _test_eof4367 + } + st_case_4367: + switch { + case data[p] > 147: + if 178 <= data[p] && data[p] <= 179 { + goto tr3881 + } + case data[p] >= 146: + goto tr3881 + } + goto tr3251 + st4368: + if p++; p == pe { + goto _test_eof4368 + } + st_case_4368: + if 180 <= data[p] { + goto tr3881 + } + goto tr3251 + st4369: + if p++; p == pe { + goto _test_eof4369 + } + st_case_4369: + switch { + case data[p] > 156: + if 158 <= data[p] { + goto tr3251 + } + case data[p] >= 148: + goto tr3251 + } + goto tr3881 + st4370: + if p++; p == pe { + goto _test_eof4370 + } + st_case_4370: + if 139 <= data[p] && data[p] <= 142 { + goto tr3881 + } + goto tr3251 + st4371: + if p++; p == pe { + goto _test_eof4371 + } + st_case_4371: + if data[p] == 169 { + goto tr3881 + } + goto tr3251 + st4372: + if p++; p == pe { + goto _test_eof4372 + } + st_case_4372: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr3881 + } + case data[p] >= 160: + goto tr3881 + } + goto tr3251 + st4373: + if p++; p == pe { + goto _test_eof4373 + } + st_case_4373: + if 151 <= data[p] && data[p] <= 155 { + goto tr3881 + } + goto tr3251 + st4374: + if p++; p == pe { + goto _test_eof4374 + } + st_case_4374: + if data[p] == 191 { + goto tr3881 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr3881 + } + case data[p] >= 149: + goto tr3881 + } + goto tr3251 + st4375: + if p++; p == pe { + goto _test_eof4375 + } + st_case_4375: + if 176 <= data[p] && data[p] <= 190 { + goto tr3881 + } + goto tr3251 + st4376: + if p++; p == pe { + goto _test_eof4376 + } + st_case_4376: + switch { + case data[p] > 132: + if 180 <= data[p] { + goto tr3881 + } + case data[p] >= 128: + goto tr3881 + } + goto tr3251 + st4377: + if p++; p == pe { + goto _test_eof4377 + } + st_case_4377: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr3251 + } + case data[p] >= 133: + goto tr3251 + } + goto tr3881 + st4378: + if p++; p == pe { + goto _test_eof4378 + } + st_case_4378: + switch { + case data[p] > 130: + if 161 <= data[p] && data[p] <= 173 { + goto tr3881 + } + case data[p] >= 128: + goto tr3881 + } + goto tr3251 + st4379: + if p++; p == pe { + goto _test_eof4379 + } + st_case_4379: + if 166 <= data[p] && data[p] <= 179 { + goto tr3881 + } + goto tr3251 + st4380: + if p++; p == pe { + goto _test_eof4380 + } + st_case_4380: + if 164 <= data[p] && data[p] <= 183 { + goto tr3881 + } + goto tr3251 + st4381: + if p++; p == pe { + goto _test_eof4381 + } + st_case_4381: + if data[p] == 173 { + goto tr3881 + } + switch { + case data[p] < 148: + if 144 <= data[p] && data[p] <= 146 { + goto tr3881 + } + case data[p] > 168: + switch { + case data[p] > 180: + if 184 <= data[p] && data[p] <= 185 { + goto tr3881 + } + case data[p] >= 178: + goto tr3881 + } + default: + goto tr3881 + } + goto tr3251 + st4382: + if p++; p == pe { + goto _test_eof4382 + } + st_case_4382: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr3881 + } + case data[p] >= 128: + goto tr3881 + } + goto tr3251 + st4383: + if p++; p == pe { + goto _test_eof4383 + } + st_case_4383: + switch data[p] { + case 128: + goto st4384 + case 129: + goto st4385 + case 131: + goto st4386 + case 179: + goto st4387 + case 181: + goto st4388 + case 183: + goto st4389 + } + goto tr3251 + st4384: + if p++; p == pe { + goto _test_eof4384 + } + st_case_4384: + switch { + case data[p] > 143: + if 170 <= data[p] && data[p] <= 174 { + goto tr3881 + } + case data[p] >= 140: + goto tr3881 + } + goto tr3251 + st4385: + if p++; p == pe { + goto _test_eof4385 + } + st_case_4385: + switch { + case data[p] > 164: + if 166 <= data[p] && data[p] <= 175 { + goto tr3881 + } + case data[p] >= 160: + goto tr3881 + } + goto tr3251 + st4386: + if p++; p == pe { + goto _test_eof4386 + } + st_case_4386: + if 144 <= data[p] && data[p] <= 176 { + goto tr3881 + } + goto tr3251 + st4387: + if p++; p == pe { + goto _test_eof4387 + } + st_case_4387: + if 175 <= data[p] && data[p] <= 177 { + goto tr3881 + } + goto tr3251 + st4388: + if p++; p == pe { + goto _test_eof4388 + } + st_case_4388: + if data[p] == 191 { + goto tr3881 + } + goto tr3251 + st4389: + if p++; p == pe { + goto _test_eof4389 + } + st_case_4389: + if 160 <= data[p] && data[p] <= 191 { + goto tr3881 + } + goto tr3251 + st4390: + if p++; p == pe { + goto _test_eof4390 + } + st_case_4390: + switch data[p] { + case 128: + goto st4391 + case 130: + goto st4392 + } + goto tr3251 + st4391: + if p++; p == pe { + goto _test_eof4391 + } + st_case_4391: + if 170 <= data[p] && data[p] <= 175 { + goto tr3881 + } + goto tr3251 + st4392: + if p++; p == pe { + goto _test_eof4392 + } + st_case_4392: + if 153 <= data[p] && data[p] <= 154 { + goto tr3881 + } + goto tr3251 + st4393: + if p++; p == pe { + goto _test_eof4393 + } + st_case_4393: + switch data[p] { + case 153: + goto st4394 + case 154: + goto st4395 + case 155: + goto st4396 + case 160: + goto st4397 + case 162: + goto st4398 + case 163: + goto st4399 + case 164: + goto st4400 + case 165: + goto st4401 + case 166: + goto st4402 + case 167: + goto st4403 + case 168: + goto st4404 + case 169: + goto st4405 + case 170: + goto st4406 + case 171: + goto st4407 + case 175: + goto st4408 + } + goto tr3251 + st4394: + if p++; p == pe { + goto _test_eof4394 + } + st_case_4394: + switch { + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr3881 + } + case data[p] >= 175: + goto tr3881 + } + goto tr3251 + st4395: + if p++; p == pe { + goto _test_eof4395 + } + st_case_4395: + if 158 <= data[p] && data[p] <= 159 { + goto tr3881 + } + goto tr3251 + st4396: + if p++; p == pe { + goto _test_eof4396 + } + st_case_4396: + if 176 <= data[p] && data[p] <= 177 { + goto tr3881 + } + goto tr3251 + st4397: + if p++; p == pe { + goto _test_eof4397 + } + st_case_4397: + switch data[p] { + case 130: + goto tr3881 + case 134: + goto tr3881 + case 139: + goto tr3881 + } + if 163 <= data[p] && data[p] <= 167 { + goto tr3881 + } + goto tr3251 + st4398: + if p++; p == pe { + goto _test_eof4398 + } + st_case_4398: + switch { + case data[p] > 129: + if 180 <= data[p] { + goto tr3881 + } + case data[p] >= 128: + goto tr3881 + } + goto tr3251 + st4399: + if p++; p == pe { + goto _test_eof4399 + } + st_case_4399: + switch { + case data[p] > 159: + if 178 <= data[p] { + goto tr3251 + } + case data[p] >= 133: + goto tr3251 + } + goto tr3881 + st4400: + if p++; p == pe { + goto _test_eof4400 + } + st_case_4400: + if 166 <= data[p] && data[p] <= 173 { + goto tr3881 + } + goto tr3251 + st4401: + if p++; p == pe { + goto _test_eof4401 + } + st_case_4401: + if 135 <= data[p] && data[p] <= 147 { + goto tr3881 + } + goto tr3251 + st4402: + if p++; p == pe { + goto _test_eof4402 + } + st_case_4402: + switch { + case data[p] > 131: + if 179 <= data[p] { + goto tr3881 + } + case data[p] >= 128: + goto tr3881 + } + goto tr3251 + st4403: + if p++; p == pe { + goto _test_eof4403 + } + st_case_4403: + switch { + case data[p] > 164: + if 166 <= data[p] { + goto tr3251 + } + case data[p] >= 129: + goto tr3251 + } + goto tr3881 + st4404: + if p++; p == pe { + goto _test_eof4404 + } + st_case_4404: + if 169 <= data[p] && data[p] <= 182 { + goto tr3881 + } + goto tr3251 + st4405: + if p++; p == pe { + goto _test_eof4405 + } + st_case_4405: + if data[p] == 131 { + goto tr3881 + } + switch { + case data[p] > 141: + if 187 <= data[p] && data[p] <= 189 { + goto tr3881 + } + case data[p] >= 140: + goto tr3881 + } + goto tr3251 + st4406: + if p++; p == pe { + goto _test_eof4406 + } + st_case_4406: + if data[p] == 176 { + goto tr3881 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr3881 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr3881 + } + default: + goto tr3881 + } + goto tr3251 + st4407: + if p++; p == pe { + goto _test_eof4407 + } + st_case_4407: + if data[p] == 129 { + goto tr3881 + } + switch { + case data[p] > 175: + if 181 <= data[p] && data[p] <= 182 { + goto tr3881 + } + case data[p] >= 171: + goto tr3881 + } + goto tr3251 + st4408: + if p++; p == pe { + goto _test_eof4408 + } + st_case_4408: + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 173 { + goto tr3881 + } + case data[p] >= 163: + goto tr3881 + } + goto tr3251 + st4409: + if p++; p == pe { + goto _test_eof4409 + } + st_case_4409: + switch data[p] { + case 172: + goto st4410 + case 184: + goto st4411 + case 187: + goto st4388 + case 190: + goto st4395 + case 191: + goto st4412 + } + goto tr3251 + st4410: + if p++; p == pe { + goto _test_eof4410 + } + st_case_4410: + if data[p] == 158 { + goto tr3881 + } + goto tr3251 + st4411: + if p++; p == pe { + goto _test_eof4411 + } + st_case_4411: + switch { + case data[p] > 143: + if 160 <= data[p] && data[p] <= 175 { + goto tr3881 + } + case data[p] >= 128: + goto tr3881 + } + goto tr3251 + st4412: + if p++; p == pe { + goto _test_eof4412 + } + st_case_4412: + if 185 <= data[p] && data[p] <= 187 { + goto tr3881 + } + goto tr3251 + st4413: + if p++; p == pe { + goto _test_eof4413 + } + st_case_4413: + switch data[p] { + case 144: + goto st4414 + case 145: + goto st4420 + case 150: + goto st4439 + case 155: + goto st4444 + case 157: + goto st4446 + case 158: + goto st4453 + } + goto tr3251 + st4414: + if p++; p == pe { + goto _test_eof4414 + } + st_case_4414: + switch data[p] { + case 135: + goto st4415 + case 139: + goto st4416 + case 141: + goto st4417 + case 168: + goto st4418 + case 171: + goto st4419 + } + goto tr3251 + st4415: + if p++; p == pe { + goto _test_eof4415 + } + st_case_4415: + if data[p] == 189 { + goto tr3881 + } + goto tr3251 + st4416: + if p++; p == pe { + goto _test_eof4416 + } + st_case_4416: + if data[p] == 160 { + goto tr3881 + } + goto tr3251 + st4417: + if p++; p == pe { + goto _test_eof4417 + } + st_case_4417: + if 182 <= data[p] && data[p] <= 186 { + goto tr3881 + } + goto tr3251 + st4418: + if p++; p == pe { + goto _test_eof4418 + } + st_case_4418: + if data[p] == 191 { + goto tr3881 + } + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr3881 + } + case data[p] > 134: + switch { + case data[p] > 143: + if 184 <= data[p] && data[p] <= 186 { + goto tr3881 + } + case data[p] >= 140: + goto tr3881 + } + default: + goto tr3881 + } + goto tr3251 + st4419: + if p++; p == pe { + goto _test_eof4419 + } + st_case_4419: + if 165 <= data[p] && data[p] <= 166 { + goto tr3881 + } + goto tr3251 + st4420: + if p++; p == pe { + goto _test_eof4420 + } + st_case_4420: + switch data[p] { + case 128: + goto st4421 + case 129: + goto st4422 + case 130: + goto st4423 + case 132: + goto st4424 + case 133: + goto st4425 + case 134: + goto st4426 + case 135: + goto st4427 + case 136: + goto st4428 + case 139: + goto st4429 + case 140: + goto st4430 + case 141: + goto st4431 + case 146: + goto st4432 + case 147: + goto st4433 + case 150: + goto st4434 + case 151: + goto st4435 + case 152: + goto st4432 + case 153: + goto st4436 + case 154: + goto st4437 + case 156: + goto st4438 + } + goto tr3251 + st4421: + if p++; p == pe { + goto _test_eof4421 + } + st_case_4421: + switch { + case data[p] > 130: + if 184 <= data[p] { + goto tr3881 + } + case data[p] >= 128: + goto tr3881 + } + goto tr3251 + st4422: + if p++; p == pe { + goto _test_eof4422 + } + st_case_4422: + if 135 <= data[p] && data[p] <= 190 { + goto tr3251 + } + goto tr3881 + st4423: + if p++; p == pe { + goto _test_eof4423 + } + st_case_4423: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr3251 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr3251 + } + default: + goto tr3251 + } + goto tr3881 + st4424: + if p++; p == pe { + goto _test_eof4424 + } + st_case_4424: + switch { + case data[p] > 130: + if 167 <= data[p] && data[p] <= 180 { + goto tr3881 + } + case data[p] >= 128: + goto tr3881 + } + goto tr3251 + st4425: + if p++; p == pe { + goto _test_eof4425 + } + st_case_4425: + if data[p] == 179 { + goto tr3881 + } + goto tr3251 + st4426: + if p++; p == pe { + goto _test_eof4426 + } + st_case_4426: + switch { + case data[p] > 130: + if 179 <= data[p] { + goto tr3881 + } + case data[p] >= 128: + goto tr3881 + } + goto tr3251 + st4427: + if p++; p == pe { + goto _test_eof4427 + } + st_case_4427: + switch { + case data[p] > 137: + if 141 <= data[p] { + goto tr3251 + } + case data[p] >= 129: + goto tr3251 + } + goto tr3881 + st4428: + if p++; p == pe { + goto _test_eof4428 + } + st_case_4428: + if 172 <= data[p] && data[p] <= 183 { + goto tr3881 + } + goto tr3251 + st4429: + if p++; p == pe { + goto _test_eof4429 + } + st_case_4429: + if 159 <= data[p] && data[p] <= 170 { + goto tr3881 + } + goto tr3251 + st4430: + if p++; p == pe { + goto _test_eof4430 + } + st_case_4430: + if data[p] == 188 { + goto tr3881 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr3881 + } + case data[p] >= 128: + goto tr3881 + } + goto tr3251 + st4431: + if p++; p == pe { + goto _test_eof4431 + } + st_case_4431: + if data[p] == 151 { + goto tr3881 + } + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr3881 + } + case data[p] >= 128: + goto tr3881 + } + case data[p] > 141: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr3881 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr3881 + } + default: + goto tr3881 + } + default: + goto tr3881 + } + goto tr3251 + st4432: + if p++; p == pe { + goto _test_eof4432 + } + st_case_4432: + if 176 <= data[p] { + goto tr3881 + } + goto tr3251 + st4433: + if p++; p == pe { + goto _test_eof4433 + } + st_case_4433: + if 132 <= data[p] { + goto tr3251 + } + goto tr3881 + st4434: + if p++; p == pe { + goto _test_eof4434 + } + st_case_4434: + switch { + case data[p] > 181: + if 184 <= data[p] { + goto tr3881 + } + case data[p] >= 175: + goto tr3881 + } + goto tr3251 + st4435: + if p++; p == pe { + goto _test_eof4435 + } + st_case_4435: + switch { + case data[p] > 155: + if 158 <= data[p] { + goto tr3251 + } + case data[p] >= 129: + goto tr3251 + } + goto tr3881 + st4436: + if p++; p == pe { + goto _test_eof4436 + } + st_case_4436: + if 129 <= data[p] { + goto tr3251 + } + goto tr3881 + st4437: + if p++; p == pe { + goto _test_eof4437 + } + st_case_4437: + if 171 <= data[p] && data[p] <= 183 { + goto tr3881 + } + goto tr3251 + st4438: + if p++; p == pe { + goto _test_eof4438 + } + st_case_4438: + if 157 <= data[p] && data[p] <= 171 { + goto tr3881 + } + goto tr3251 + st4439: + if p++; p == pe { + goto _test_eof4439 + } + st_case_4439: + switch data[p] { + case 171: + goto st4440 + case 172: + goto st4441 + case 189: + goto st4442 + case 190: + goto st4443 + } + goto tr3251 + st4440: + if p++; p == pe { + goto _test_eof4440 + } + st_case_4440: + if 176 <= data[p] && data[p] <= 180 { + goto tr3881 + } + goto tr3251 + st4441: + if p++; p == pe { + goto _test_eof4441 + } + st_case_4441: + if 176 <= data[p] && data[p] <= 182 { + goto tr3881 + } + goto tr3251 + st4442: + if p++; p == pe { + goto _test_eof4442 + } + st_case_4442: + if 145 <= data[p] && data[p] <= 190 { + goto tr3881 + } + goto tr3251 + st4443: + if p++; p == pe { + goto _test_eof4443 + } + st_case_4443: + if 143 <= data[p] && data[p] <= 146 { + goto tr3881 + } + goto tr3251 + st4444: + if p++; p == pe { + goto _test_eof4444 + } + st_case_4444: + if data[p] == 178 { + goto st4445 + } + goto tr3251 + st4445: + if p++; p == pe { + goto _test_eof4445 + } + st_case_4445: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr3881 + } + case data[p] >= 157: + goto tr3881 + } + goto tr3251 + st4446: + if p++; p == pe { + goto _test_eof4446 + } + st_case_4446: + switch data[p] { + case 133: + goto st4447 + case 134: + goto st4448 + case 137: + goto st4449 + case 168: + goto st4450 + case 169: + goto st4451 + case 170: + goto st4452 + } + goto tr3251 + st4447: + if p++; p == pe { + goto _test_eof4447 + } + st_case_4447: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr3881 + } + case data[p] >= 165: + goto tr3881 + } + goto tr3251 + st4448: + if p++; p == pe { + goto _test_eof4448 + } + st_case_4448: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr3251 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr3251 + } + default: + goto tr3251 + } + goto tr3881 + st4449: + if p++; p == pe { + goto _test_eof4449 + } + st_case_4449: + if 130 <= data[p] && data[p] <= 132 { + goto tr3881 + } + goto tr3251 + st4450: + if p++; p == pe { + goto _test_eof4450 + } + st_case_4450: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr3881 + } + case data[p] >= 128: + goto tr3881 + } + goto tr3251 + st4451: + if p++; p == pe { + goto _test_eof4451 + } + st_case_4451: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr3251 + } + case data[p] >= 173: + goto tr3251 + } + goto tr3881 + st4452: + if p++; p == pe { + goto _test_eof4452 + } + st_case_4452: + if data[p] == 132 { + goto tr3881 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr3881 + } + case data[p] >= 155: + goto tr3881 + } + goto tr3251 + st4453: + if p++; p == pe { + goto _test_eof4453 + } + st_case_4453: + if data[p] == 163 { + goto st4454 + } + goto tr3251 + st4454: + if p++; p == pe { + goto _test_eof4454 + } + st_case_4454: + if 144 <= data[p] && data[p] <= 150 { + goto tr3881 + } + goto tr3251 + st4455: + if p++; p == pe { + goto _test_eof4455 + } + st_case_4455: + if data[p] == 160 { + goto st4456 + } + goto tr3251 + st4456: + if p++; p == pe { + goto _test_eof4456 + } + st_case_4456: + switch data[p] { + case 128: + goto st4457 + case 129: + goto st4458 + case 132: + goto st4320 + case 135: + goto st4321 + } + if 133 <= data[p] && data[p] <= 134 { + goto st4459 + } + goto tr3251 + st4457: + if p++; p == pe { + goto _test_eof4457 + } + st_case_4457: + if data[p] == 129 { + goto tr3881 + } + if 160 <= data[p] { + goto tr3881 + } + goto tr3251 + st4458: + if p++; p == pe { + goto _test_eof4458 + } + st_case_4458: + if 192 <= data[p] { + goto tr3251 + } + goto tr3881 + st4459: + if p++; p == pe { + goto _test_eof4459 + } + st_case_4459: + goto tr3881 + st4460: + if p++; p == pe { + goto _test_eof4460 + } + st_case_4460: + if 128 <= data[p] { + goto tr3881 + } + goto tr3250 + st4461: + if p++; p == pe { + goto _test_eof4461 + } + st_case_4461: + if 176 <= data[p] { + goto tr3250 + } + goto tr3881 + st4462: + if p++; p == pe { + goto _test_eof4462 + } + st_case_4462: + if 131 <= data[p] && data[p] <= 137 { + goto tr3881 + } + goto tr3250 + st4463: + if p++; p == pe { + goto _test_eof4463 + } + st_case_4463: + if data[p] == 191 { + goto tr3881 + } + if 145 <= data[p] && data[p] <= 189 { + goto tr3881 + } + goto tr3250 + st4464: + if p++; p == pe { + goto _test_eof4464 + } + st_case_4464: + if data[p] == 135 { + goto tr3881 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto tr3881 + } + case data[p] >= 129: + goto tr3881 + } + goto tr3250 + st4465: + if p++; p == pe { + goto _test_eof4465 + } + st_case_4465: + if data[p] == 156 { + goto tr3881 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto tr3881 + } + case data[p] >= 128: + goto tr3881 + } + goto tr3250 + st4466: + if p++; p == pe { + goto _test_eof4466 + } + st_case_4466: + if data[p] == 176 { + goto tr3881 + } + if 139 <= data[p] && data[p] <= 159 { + goto tr3881 + } + goto tr3250 + st4467: + if p++; p == pe { + goto _test_eof4467 + } + st_case_4467: + switch { + case data[p] < 159: + if 150 <= data[p] && data[p] <= 157 { + goto tr3881 + } + case data[p] > 164: + switch { + case data[p] > 168: + if 170 <= data[p] && data[p] <= 173 { + goto tr3881 + } + case data[p] >= 167: + goto tr3881 + } + default: + goto tr3881 + } + goto tr3250 + st4468: + if p++; p == pe { + goto _test_eof4468 + } + st_case_4468: + switch data[p] { + case 143: + goto tr3881 + case 145: + goto tr3881 + } + if 176 <= data[p] { + goto tr3881 + } + goto tr3250 + st4469: + if p++; p == pe { + goto _test_eof4469 + } + st_case_4469: + if 139 <= data[p] { + goto tr3250 + } + goto tr3881 + st4470: + if p++; p == pe { + goto _test_eof4470 + } + st_case_4470: + if 166 <= data[p] && data[p] <= 176 { + goto tr3881 + } + goto tr3250 + st4471: + if p++; p == pe { + goto _test_eof4471 + } + st_case_4471: + if 171 <= data[p] && data[p] <= 179 { + goto tr3881 + } + goto tr3250 + st4472: + if p++; p == pe { + goto _test_eof4472 + } + st_case_4472: + switch data[p] { + case 160: + goto tr4004 + case 161: + goto tr4005 + case 163: + goto tr4006 + case 164: + goto tr4007 + case 165: + goto tr4008 + case 167: + goto tr4010 + case 169: + goto tr4011 + case 171: + goto tr4012 + case 173: + goto tr4014 + case 174: + goto tr4015 + case 175: + goto tr4016 + case 176: + goto tr4017 + case 177: + goto tr4018 + case 179: + goto tr4019 + case 180: + goto tr4020 + case 181: + goto tr4021 + case 182: + goto tr4022 + case 183: + goto tr4023 + case 184: + goto tr4024 + case 185: + goto tr4025 + case 186: + goto tr4026 + case 187: + goto tr4027 + case 188: + goto tr4028 + case 189: + goto tr4029 + case 190: + goto tr4030 + case 191: + goto tr4031 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto tr4013 + } + case data[p] >= 166: + goto tr4009 + } + goto tr3250 +tr4004: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5083 + st5083: + if p++; p == pe { + goto _test_eof5083 + } + st_case_5083: +//line segment_words_prod.go:125762 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] < 155: + if 150 <= data[p] && data[p] <= 153 { + goto tr1 + } + case data[p] > 163: + switch { + case data[p] > 167: + if 169 <= data[p] && data[p] <= 173 { + goto tr1 + } + case data[p] >= 165: + goto tr1 + } + default: + goto tr1 + } + goto tr5054 +tr4005: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5084 + st5084: + if p++; p == pe { + goto _test_eof5084 + } + st_case_5084: +//line segment_words_prod.go:125841 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 153 <= data[p] && data[p] <= 155 { + goto tr1 + } + goto tr5054 +tr4006: +//line segment_words.rl:72 + + endPos = p + + goto st5085 + st5085: + if p++; p == pe { + goto _test_eof5085 + } + st_case_5085: +//line segment_words_prod.go:125901 + switch data[p] { + case 194: + goto tr5196 + case 204: + goto tr5197 + case 205: + goto tr5198 + case 210: + goto tr5199 + case 214: + goto tr5200 + case 215: + goto tr5201 + case 216: + goto tr5202 + case 217: + goto tr5203 + case 219: + goto tr5204 + case 220: + goto tr5205 + case 221: + goto tr5206 + case 222: + goto tr5207 + case 223: + goto tr5208 + case 224: + goto tr5209 + case 225: + goto tr5210 + case 226: + goto tr5211 + case 227: + goto tr5212 + case 234: + goto tr5213 + case 239: + goto tr5214 + case 240: + goto tr5215 + case 243: + goto tr5216 + } + if 163 <= data[p] { + goto tr1 + } + goto tr5054 +tr5196: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5086 + st5086: + if p++; p == pe { + goto _test_eof5086 + } + st_case_5086: +//line segment_words_prod.go:125966 + switch data[p] { + case 173: + goto tr3250 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr5197: +//line segment_words.rl:72 + + endPos = p + + goto st5087 + st5087: + if p++; p == pe { + goto _test_eof5087 + } + st_case_5087: +//line segment_words_prod.go:126025 + switch data[p] { + case 194: + goto tr5217 + case 204: + goto tr5218 + case 205: + goto tr5219 + case 210: + goto tr5220 + case 214: + goto tr5221 + case 215: + goto tr5222 + case 216: + goto tr5223 + case 217: + goto tr5224 + case 219: + goto tr5225 + case 220: + goto tr5226 + case 221: + goto tr5227 + case 222: + goto tr5228 + case 223: + goto tr5229 + case 224: + goto tr5230 + case 225: + goto tr5231 + case 226: + goto tr5232 + case 227: + goto tr5233 + case 234: + goto tr5234 + case 239: + goto tr5235 + case 240: + goto tr5236 + case 243: + goto tr5237 + } + if 128 <= data[p] { + goto tr3250 + } + goto tr4499 +tr5217: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5088 + st5088: + if p++; p == pe { + goto _test_eof5088 + } + st_case_5088: +//line segment_words_prod.go:126090 + switch data[p] { + case 173: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 +tr5218: +//line segment_words.rl:72 + + endPos = p + + goto st5089 + st5089: + if p++; p == pe { + goto _test_eof5089 + } + st_case_5089: +//line segment_words_prod.go:126149 + switch data[p] { + case 194: + goto tr5196 + case 204: + goto tr5197 + case 205: + goto tr5198 + case 210: + goto tr5199 + case 214: + goto tr5200 + case 215: + goto tr5201 + case 216: + goto tr5202 + case 217: + goto tr5203 + case 219: + goto tr5204 + case 220: + goto tr5205 + case 221: + goto tr5206 + case 222: + goto tr5207 + case 223: + goto tr5208 + case 224: + goto tr5209 + case 225: + goto tr5210 + case 226: + goto tr5211 + case 227: + goto tr5212 + case 234: + goto tr5213 + case 239: + goto tr5214 + case 240: + goto tr5215 + case 243: + goto tr5216 + } + if 128 <= data[p] { + goto tr1 + } + goto tr5054 +tr5198: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5090 + st5090: + if p++; p == pe { + goto _test_eof5090 + } + st_case_5090: +//line segment_words_prod.go:126214 + switch data[p] { + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 176 <= data[p] { + goto tr4499 + } + goto tr3250 +tr5199: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5091 + st5091: + if p++; p == pe { + goto _test_eof5091 + } + st_case_5091: +//line segment_words_prod.go:126279 + switch data[p] { + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr3250 + } + goto tr4499 +tr5200: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5092 + st5092: + if p++; p == pe { + goto _test_eof5092 + } + st_case_5092: +//line segment_words_prod.go:126344 + switch data[p] { + case 191: + goto tr3250 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 145 <= data[p] && data[p] <= 189 { + goto tr3250 + } + goto tr4499 +tr5201: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5093 + st5093: + if p++; p == pe { + goto _test_eof5093 + } + st_case_5093: +//line segment_words_prod.go:126411 + switch data[p] { + case 135: + goto tr3250 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto tr3250 + } + case data[p] >= 129: + goto tr3250 + } + goto tr4499 +tr5202: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5094 + st5094: + if p++; p == pe { + goto _test_eof5094 + } + st_case_5094: +//line segment_words_prod.go:126483 + switch data[p] { + case 156: + goto tr3250 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto tr3250 + } + case data[p] >= 128: + goto tr3250 + } + goto tr4499 +tr5203: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5095 + st5095: + if p++; p == pe { + goto _test_eof5095 + } + st_case_5095: +//line segment_words_prod.go:126555 + switch data[p] { + case 176: + goto tr3250 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 139 <= data[p] && data[p] <= 159 { + goto tr3250 + } + goto tr4499 +tr5204: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5096 + st5096: + if p++; p == pe { + goto _test_eof5096 + } + st_case_5096: +//line segment_words_prod.go:126622 + switch data[p] { + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 159: + if 150 <= data[p] && data[p] <= 157 { + goto tr3250 + } + case data[p] > 164: + switch { + case data[p] > 168: + if 170 <= data[p] && data[p] <= 173 { + goto tr3250 + } + case data[p] >= 167: + goto tr3250 + } + default: + goto tr3250 + } + goto tr4499 +tr5205: +//line segment_words.rl:72 + + endPos = p + + goto st5097 + st5097: + if p++; p == pe { + goto _test_eof5097 + } + st_case_5097: +//line segment_words_prod.go:126696 + switch data[p] { + case 143: + goto tr3250 + case 145: + goto tr3250 + case 194: + goto tr5217 + case 204: + goto tr5218 + case 205: + goto tr5219 + case 210: + goto tr5220 + case 214: + goto tr5221 + case 215: + goto tr5222 + case 216: + goto tr5223 + case 217: + goto tr5224 + case 219: + goto tr5225 + case 220: + goto tr5226 + case 221: + goto tr5227 + case 222: + goto tr5228 + case 223: + goto tr5229 + case 224: + goto tr5230 + case 225: + goto tr5231 + case 226: + goto tr5232 + case 227: + goto tr5233 + case 234: + goto tr5234 + case 239: + goto tr5235 + case 240: + goto tr5236 + case 243: + goto tr5237 + } + if 176 <= data[p] { + goto tr3250 + } + goto tr4499 +tr5219: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5098 + st5098: + if p++; p == pe { + goto _test_eof5098 + } + st_case_5098: +//line segment_words_prod.go:126765 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 176 <= data[p] { + goto tr5054 + } + goto tr1 +tr5220: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5099 + st5099: + if p++; p == pe { + goto _test_eof5099 + } + st_case_5099: +//line segment_words_prod.go:126830 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr1 + } + goto tr5054 +tr5221: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5100 + st5100: + if p++; p == pe { + goto _test_eof5100 + } + st_case_5100: +//line segment_words_prod.go:126895 + switch data[p] { + case 191: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 145 <= data[p] && data[p] <= 189 { + goto tr1 + } + goto tr5054 +tr5222: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5101 + st5101: + if p++; p == pe { + goto _test_eof5101 + } + st_case_5101: +//line segment_words_prod.go:126962 + switch data[p] { + case 135: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto tr1 + } + case data[p] >= 129: + goto tr1 + } + goto tr5054 +tr5223: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5102 + st5102: + if p++; p == pe { + goto _test_eof5102 + } + st_case_5102: +//line segment_words_prod.go:127034 + switch data[p] { + case 156: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr5054 +tr5224: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5103 + st5103: + if p++; p == pe { + goto _test_eof5103 + } + st_case_5103: +//line segment_words_prod.go:127106 + switch data[p] { + case 176: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 139 <= data[p] && data[p] <= 159 { + goto tr1 + } + goto tr5054 +tr5225: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5104 + st5104: + if p++; p == pe { + goto _test_eof5104 + } + st_case_5104: +//line segment_words_prod.go:127173 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] < 159: + if 150 <= data[p] && data[p] <= 157 { + goto tr1 + } + case data[p] > 164: + switch { + case data[p] > 168: + if 170 <= data[p] && data[p] <= 173 { + goto tr1 + } + case data[p] >= 167: + goto tr1 + } + default: + goto tr1 + } + goto tr5054 +tr5226: +//line segment_words.rl:72 + + endPos = p + + goto st5105 + st5105: + if p++; p == pe { + goto _test_eof5105 + } + st_case_5105: +//line segment_words_prod.go:127247 + switch data[p] { + case 143: + goto tr1 + case 145: + goto tr1 + case 194: + goto tr5196 + case 204: + goto tr5197 + case 205: + goto tr5198 + case 210: + goto tr5199 + case 214: + goto tr5200 + case 215: + goto tr5201 + case 216: + goto tr5202 + case 217: + goto tr5203 + case 219: + goto tr5204 + case 220: + goto tr5205 + case 221: + goto tr5206 + case 222: + goto tr5207 + case 223: + goto tr5208 + case 224: + goto tr5209 + case 225: + goto tr5210 + case 226: + goto tr5211 + case 227: + goto tr5212 + case 234: + goto tr5213 + case 239: + goto tr5214 + case 240: + goto tr5215 + case 243: + goto tr5216 + } + if 176 <= data[p] { + goto tr1 + } + goto tr5054 +tr5206: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5106 + st5106: + if p++; p == pe { + goto _test_eof5106 + } + st_case_5106: +//line segment_words_prod.go:127316 + switch data[p] { + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 139 <= data[p] { + goto tr4499 + } + goto tr3250 +tr5207: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5107 + st5107: + if p++; p == pe { + goto _test_eof5107 + } + st_case_5107: +//line segment_words_prod.go:127381 + switch data[p] { + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 166 <= data[p] && data[p] <= 176 { + goto tr3250 + } + goto tr4499 +tr5208: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5108 + st5108: + if p++; p == pe { + goto _test_eof5108 + } + st_case_5108: +//line segment_words_prod.go:127446 + switch data[p] { + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 171 <= data[p] && data[p] <= 179 { + goto tr3250 + } + goto tr4499 +tr5209: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5109 + st5109: + if p++; p == pe { + goto _test_eof5109 + } + st_case_5109: +//line segment_words_prod.go:127511 + switch data[p] { + case 160: + goto st3608 + case 161: + goto st3609 + case 163: + goto st3610 + case 164: + goto st3611 + case 165: + goto st3612 + case 167: + goto st3614 + case 169: + goto st3615 + case 171: + goto st3616 + case 173: + goto st3618 + case 174: + goto st3619 + case 175: + goto st3620 + case 176: + goto st3621 + case 177: + goto st3622 + case 179: + goto st3623 + case 180: + goto st3624 + case 181: + goto st3625 + case 182: + goto st3626 + case 183: + goto st3627 + case 184: + goto st3628 + case 185: + goto st3629 + case 186: + goto st3630 + case 187: + goto st3631 + case 188: + goto st3632 + case 189: + goto st3633 + case 190: + goto st3634 + case 191: + goto st3635 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto st3617 + } + case data[p] >= 166: + goto st3613 + } + goto tr4499 +tr5210: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5110 + st5110: + if p++; p == pe { + goto _test_eof5110 + } + st_case_5110: +//line segment_words_prod.go:127633 + switch data[p] { + case 128: + goto st3637 + case 129: + goto st3638 + case 130: + goto st3639 + case 141: + goto st3640 + case 156: + goto st3641 + case 157: + goto st3642 + case 158: + goto st3643 + case 159: + goto st3644 + case 160: + goto st3645 + case 162: + goto st3646 + case 164: + goto st3647 + case 168: + goto st3648 + case 169: + goto st3649 + case 170: + goto st3650 + case 172: + goto st3651 + case 173: + goto st3652 + case 174: + goto st3653 + case 175: + goto st3654 + case 176: + goto st3655 + case 179: + goto st3656 + case 183: + goto st3657 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr5211: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5111 + st5111: + if p++; p == pe { + goto _test_eof5111 + } + st_case_5111: +//line segment_words_prod.go:127737 + switch data[p] { + case 128: + goto st3659 + case 129: + goto st3660 + case 131: + goto st3661 + case 179: + goto st3662 + case 181: + goto st3663 + case 183: + goto st3664 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr5212: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5112 + st5112: + if p++; p == pe { + goto _test_eof5112 + } + st_case_5112: +//line segment_words_prod.go:127811 + switch data[p] { + case 128: + goto st3666 + case 130: + goto st3667 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr5213: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5113 + st5113: + if p++; p == pe { + goto _test_eof5113 + } + st_case_5113: +//line segment_words_prod.go:127877 + switch data[p] { + case 153: + goto st3669 + case 154: + goto st3670 + case 155: + goto st3671 + case 160: + goto st3672 + case 162: + goto st3673 + case 163: + goto st3674 + case 164: + goto st3675 + case 165: + goto st3676 + case 166: + goto st3677 + case 167: + goto st3678 + case 168: + goto st3679 + case 169: + goto st3680 + case 170: + goto st3681 + case 171: + goto st3682 + case 175: + goto st3683 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr5214: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5114 + st5114: + if p++; p == pe { + goto _test_eof5114 + } + st_case_5114: +//line segment_words_prod.go:127969 + switch data[p] { + case 172: + goto st3685 + case 184: + goto st3686 + case 187: + goto st3663 + case 190: + goto st3670 + case 191: + goto st3687 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr5215: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5115 + st5115: + if p++; p == pe { + goto _test_eof5115 + } + st_case_5115: +//line segment_words_prod.go:128041 + switch data[p] { + case 144: + goto st3689 + case 145: + goto st3695 + case 150: + goto st3714 + case 155: + goto st3719 + case 157: + goto st3721 + case 158: + goto st3728 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr5216: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5116 + st5116: + if p++; p == pe { + goto _test_eof5116 + } + st_case_5116: +//line segment_words_prod.go:128115 + switch data[p] { + case 160: + goto st3731 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr5227: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5117 + st5117: + if p++; p == pe { + goto _test_eof5117 + } + st_case_5117: +//line segment_words_prod.go:128179 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 139 <= data[p] { + goto tr5054 + } + goto tr1 +tr5228: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5118 + st5118: + if p++; p == pe { + goto _test_eof5118 + } + st_case_5118: +//line segment_words_prod.go:128244 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 166 <= data[p] && data[p] <= 176 { + goto tr1 + } + goto tr5054 +tr5229: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5119 + st5119: + if p++; p == pe { + goto _test_eof5119 + } + st_case_5119: +//line segment_words_prod.go:128309 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 171 <= data[p] && data[p] <= 179 { + goto tr1 + } + goto tr5054 +tr5230: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5120 + st5120: + if p++; p == pe { + goto _test_eof5120 + } + st_case_5120: +//line segment_words_prod.go:128374 + switch data[p] { + case 160: + goto st14 + case 161: + goto st15 + case 163: + goto st16 + case 164: + goto st17 + case 165: + goto st18 + case 167: + goto st20 + case 169: + goto st21 + case 171: + goto st22 + case 173: + goto st24 + case 174: + goto st25 + case 175: + goto st26 + case 176: + goto st27 + case 177: + goto st28 + case 179: + goto st29 + case 180: + goto st30 + case 181: + goto st31 + case 182: + goto st32 + case 183: + goto st33 + case 184: + goto st34 + case 185: + goto st35 + case 186: + goto st36 + case 187: + goto st37 + case 188: + goto st38 + case 189: + goto st39 + case 190: + goto st40 + case 191: + goto st41 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto st23 + } + case data[p] >= 166: + goto st19 + } + goto tr5054 +tr5231: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5121 + st5121: + if p++; p == pe { + goto _test_eof5121 + } + st_case_5121: +//line segment_words_prod.go:128496 + switch data[p] { + case 128: + goto st43 + case 129: + goto st44 + case 130: + goto st45 + case 141: + goto st46 + case 156: + goto st47 + case 157: + goto st48 + case 158: + goto st49 + case 159: + goto st50 + case 160: + goto st51 + case 162: + goto st52 + case 164: + goto st53 + case 168: + goto st54 + case 169: + goto st55 + case 170: + goto st56 + case 172: + goto st57 + case 173: + goto st58 + case 174: + goto st59 + case 175: + goto st60 + case 176: + goto st61 + case 179: + goto st62 + case 183: + goto st63 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 +tr5232: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5122 + st5122: + if p++; p == pe { + goto _test_eof5122 + } + st_case_5122: +//line segment_words_prod.go:128600 + switch data[p] { + case 128: + goto st65 + case 129: + goto st66 + case 131: + goto st67 + case 179: + goto st68 + case 181: + goto st69 + case 183: + goto st70 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 +tr5233: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5123 + st5123: + if p++; p == pe { + goto _test_eof5123 + } + st_case_5123: +//line segment_words_prod.go:128674 + switch data[p] { + case 128: + goto st72 + case 130: + goto st73 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 +tr5234: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5124 + st5124: + if p++; p == pe { + goto _test_eof5124 + } + st_case_5124: +//line segment_words_prod.go:128740 + switch data[p] { + case 153: + goto st75 + case 154: + goto st76 + case 155: + goto st77 + case 160: + goto st78 + case 162: + goto st79 + case 163: + goto st80 + case 164: + goto st81 + case 165: + goto st82 + case 166: + goto st83 + case 167: + goto st84 + case 168: + goto st85 + case 169: + goto st86 + case 170: + goto st87 + case 171: + goto st88 + case 175: + goto st89 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 +tr5235: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5125 + st5125: + if p++; p == pe { + goto _test_eof5125 + } + st_case_5125: +//line segment_words_prod.go:128832 + switch data[p] { + case 172: + goto st91 + case 184: + goto st92 + case 187: + goto st69 + case 190: + goto st76 + case 191: + goto st93 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 +tr5236: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5126 + st5126: + if p++; p == pe { + goto _test_eof5126 + } + st_case_5126: +//line segment_words_prod.go:128904 + switch data[p] { + case 144: + goto st95 + case 145: + goto st101 + case 150: + goto st120 + case 155: + goto st125 + case 157: + goto st127 + case 158: + goto st134 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 +tr5237: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5127 + st5127: + if p++; p == pe { + goto _test_eof5127 + } + st_case_5127: +//line segment_words_prod.go:128978 + switch data[p] { + case 160: + goto st137 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 +tr4007: +//line segment_words.rl:72 + + endPos = p + + goto st5128 + st5128: + if p++; p == pe { + goto _test_eof5128 + } + st_case_5128: +//line segment_words_prod.go:129037 + switch data[p] { + case 189: + goto tr5054 + case 194: + goto tr5196 + case 204: + goto tr5197 + case 205: + goto tr5198 + case 210: + goto tr5199 + case 214: + goto tr5200 + case 215: + goto tr5201 + case 216: + goto tr5202 + case 217: + goto tr5203 + case 219: + goto tr5204 + case 220: + goto tr5205 + case 221: + goto tr5206 + case 222: + goto tr5207 + case 223: + goto tr5208 + case 224: + goto tr5209 + case 225: + goto tr5210 + case 226: + goto tr5211 + case 227: + goto tr5212 + case 234: + goto tr5213 + case 239: + goto tr5214 + case 240: + goto tr5215 + case 243: + goto tr5216 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr5054 + } + goto tr1 +tr4008: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5129 + st5129: + if p++; p == pe { + goto _test_eof5129 + } + st_case_5129: +//line segment_words_prod.go:129104 + switch data[p] { + case 144: + goto tr5054 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr5054 + } + case data[p] >= 152: + goto tr5054 + } + goto tr1 +tr4009: +//line segment_words.rl:72 + + endPos = p + + goto st5130 + st5130: + if p++; p == pe { + goto _test_eof5130 + } + st_case_5130: +//line segment_words_prod.go:129171 + switch data[p] { + case 188: + goto tr1 + case 194: + goto tr5196 + case 204: + goto tr5197 + case 205: + goto tr5198 + case 210: + goto tr5199 + case 214: + goto tr5200 + case 215: + goto tr5201 + case 216: + goto tr5202 + case 217: + goto tr5203 + case 219: + goto tr5204 + case 220: + goto tr5205 + case 221: + goto tr5206 + case 222: + goto tr5207 + case 223: + goto tr5208 + case 224: + goto tr5209 + case 225: + goto tr5210 + case 226: + goto tr5211 + case 227: + goto tr5212 + case 234: + goto tr5213 + case 239: + goto tr5214 + case 240: + goto tr5215 + case 243: + goto tr5216 + } + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr1 + } + case data[p] >= 129: + goto tr1 + } + goto tr5054 +tr4010: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5131 + st5131: + if p++; p == pe { + goto _test_eof5131 + } + st_case_5131: +//line segment_words_prod.go:129243 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr5054 + } + case data[p] >= 133: + goto tr5054 + } + case data[p] > 150: + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr5054 + } + case data[p] >= 152: + goto tr5054 + } + default: + goto tr5054 + } + goto tr1 +tr4011: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5132 + st5132: + if p++; p == pe { + goto _test_eof5132 + } + st_case_5132: +//line segment_words_prod.go:129327 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr5054 + } + case data[p] >= 131: + goto tr5054 + } + case data[p] > 144: + switch { + case data[p] < 178: + if 146 <= data[p] && data[p] <= 175 { + goto tr5054 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr5054 + } + default: + goto tr5054 + } + default: + goto tr5054 + } + goto tr1 +tr4012: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5133 + st5133: + if p++; p == pe { + goto _test_eof5133 + } + st_case_5133: +//line segment_words_prod.go:129415 + switch data[p] { + case 134: + goto tr5054 + case 138: + goto tr5054 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr5054 + } + case data[p] >= 142: + goto tr5054 + } + goto tr1 +tr4013: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5134 + st5134: + if p++; p == pe { + goto _test_eof5134 + } + st_case_5134: +//line segment_words_prod.go:129489 + switch data[p] { + case 188: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] >= 129: + goto tr1 + } + goto tr5054 +tr4014: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5135 + st5135: + if p++; p == pe { + goto _test_eof5135 + } + st_case_5135: +//line segment_words_prod.go:129561 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + case data[p] > 141: + switch { + case data[p] > 151: + if 162 <= data[p] && data[p] <= 163 { + goto tr1 + } + case data[p] >= 150: + goto tr1 + } + default: + goto tr1 + } + goto tr5054 +tr4015: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5136 + st5136: + if p++; p == pe { + goto _test_eof5136 + } + st_case_5136: +//line segment_words_prod.go:129645 + switch data[p] { + case 130: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 190 <= data[p] && data[p] <= 191 { + goto tr1 + } + goto tr5054 +tr4016: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5137 + st5137: + if p++; p == pe { + goto _test_eof5137 + } + st_case_5137: +//line segment_words_prod.go:129712 + switch data[p] { + case 151: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr1 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr1 + } + default: + goto tr1 + } + goto tr5054 +tr4017: +//line segment_words.rl:72 + + endPos = p + + goto st5138 + st5138: + if p++; p == pe { + goto _test_eof5138 + } + st_case_5138: +//line segment_words_prod.go:129783 + switch data[p] { + case 194: + goto tr5196 + case 204: + goto tr5197 + case 205: + goto tr5198 + case 210: + goto tr5199 + case 214: + goto tr5200 + case 215: + goto tr5201 + case 216: + goto tr5202 + case 217: + goto tr5203 + case 219: + goto tr5204 + case 220: + goto tr5205 + case 221: + goto tr5206 + case 222: + goto tr5207 + case 223: + goto tr5208 + case 224: + goto tr5209 + case 225: + goto tr5210 + case 226: + goto tr5211 + case 227: + goto tr5212 + case 234: + goto tr5213 + case 239: + goto tr5214 + case 240: + goto tr5215 + case 243: + goto tr5216 + } + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr5054 +tr4018: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5139 + st5139: + if p++; p == pe { + goto _test_eof5139 + } + st_case_5139: +//line segment_words_prod.go:129853 + switch data[p] { + case 133: + goto tr5054 + case 137: + goto tr5054 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] < 151: + if 142 <= data[p] && data[p] <= 148 { + goto tr5054 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr5054 + } + default: + goto tr5054 + } + goto tr1 +tr4019: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5140 + st5140: + if p++; p == pe { + goto _test_eof5140 + } + st_case_5140: +//line segment_words_prod.go:129931 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] < 138: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 136 { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + case data[p] > 141: + switch { + case data[p] > 150: + if 162 <= data[p] && data[p] <= 163 { + goto tr1 + } + case data[p] >= 149: + goto tr1 + } + default: + goto tr1 + } + goto tr5054 +tr4020: +//line segment_words.rl:72 + + endPos = p + + goto st5141 + st5141: + if p++; p == pe { + goto _test_eof5141 + } + st_case_5141: +//line segment_words_prod.go:130010 + switch data[p] { + case 194: + goto tr5196 + case 204: + goto tr5197 + case 205: + goto tr5198 + case 210: + goto tr5199 + case 214: + goto tr5200 + case 215: + goto tr5201 + case 216: + goto tr5202 + case 217: + goto tr5203 + case 219: + goto tr5204 + case 220: + goto tr5205 + case 221: + goto tr5206 + case 222: + goto tr5207 + case 223: + goto tr5208 + case 224: + goto tr5209 + case 225: + goto tr5210 + case 226: + goto tr5211 + case 227: + goto tr5212 + case 234: + goto tr5213 + case 239: + goto tr5214 + case 240: + goto tr5215 + case 243: + goto tr5216 + } + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr1 + } + case data[p] >= 129: + goto tr1 + } + goto tr5054 +tr4021: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5142 + st5142: + if p++; p == pe { + goto _test_eof5142 + } + st_case_5142: +//line segment_words_prod.go:130080 + switch data[p] { + case 133: + goto tr5054 + case 137: + goto tr5054 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 150 { + goto tr5054 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr5054 + } + default: + goto tr5054 + } + goto tr1 +tr4022: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5143 + st5143: + if p++; p == pe { + goto _test_eof5143 + } + st_case_5143: +//line segment_words_prod.go:130158 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 130 <= data[p] && data[p] <= 131 { + goto tr1 + } + goto tr5054 +tr4023: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5144 + st5144: + if p++; p == pe { + goto _test_eof5144 + } + st_case_5144: +//line segment_words_prod.go:130223 + switch data[p] { + case 138: + goto tr1 + case 150: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 148 { + goto tr1 + } + case data[p] > 159: + if 178 <= data[p] && data[p] <= 179 { + goto tr1 + } + default: + goto tr1 + } + goto tr5054 +tr4024: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5145 + st5145: + if p++; p == pe { + goto _test_eof5145 + } + st_case_5145: +//line segment_words_prod.go:130301 + switch data[p] { + case 177: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr1 + } + goto tr5054 +tr4025: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5146 + st5146: + if p++; p == pe { + goto _test_eof5146 + } + st_case_5146: +//line segment_words_prod.go:130368 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 135 <= data[p] && data[p] <= 142 { + goto tr1 + } + goto tr5054 +tr4026: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5147 + st5147: + if p++; p == pe { + goto _test_eof5147 + } + st_case_5147: +//line segment_words_prod.go:130433 + switch data[p] { + case 177: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr1 + } + case data[p] >= 180: + goto tr1 + } + goto tr5054 +tr4027: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5148 + st5148: + if p++; p == pe { + goto _test_eof5148 + } + st_case_5148: +//line segment_words_prod.go:130505 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 136 <= data[p] && data[p] <= 141 { + goto tr1 + } + goto tr5054 +tr4028: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5149 + st5149: + if p++; p == pe { + goto _test_eof5149 + } + st_case_5149: +//line segment_words_prod.go:130570 + switch data[p] { + case 181: + goto tr1 + case 183: + goto tr1 + case 185: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 153: + if 190 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] >= 152: + goto tr1 + } + goto tr5054 +tr4029: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5150 + st5150: + if p++; p == pe { + goto _test_eof5150 + } + st_case_5150: +//line segment_words_prod.go:130646 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 177 <= data[p] && data[p] <= 191 { + goto tr1 + } + goto tr5054 +tr4030: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5151 + st5151: + if p++; p == pe { + goto _test_eof5151 + } + st_case_5151: +//line segment_words_prod.go:130711 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr1 + } + case data[p] > 135: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr1 + } + case data[p] >= 141: + goto tr1 + } + default: + goto tr1 + } + goto tr5054 +tr4031: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5152 + st5152: + if p++; p == pe { + goto _test_eof5152 + } + st_case_5152: +//line segment_words_prod.go:130790 + switch data[p] { + case 134: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 + st4473: + if p++; p == pe { + goto _test_eof4473 + } + st_case_4473: + switch data[p] { + case 128: + goto tr4032 + case 129: + goto tr4033 + case 130: + goto tr4034 + case 141: + goto tr4035 + case 156: + goto tr4036 + case 157: + goto tr4037 + case 158: + goto tr4038 + case 159: + goto tr4039 + case 160: + goto tr4040 + case 162: + goto tr4041 + case 164: + goto tr4042 + case 168: + goto tr4043 + case 169: + goto tr4044 + case 170: + goto tr4045 + case 172: + goto tr4046 + case 173: + goto tr4047 + case 174: + goto tr4048 + case 175: + goto tr4049 + case 176: + goto tr4050 + case 179: + goto tr4051 + case 183: + goto tr4052 + } + goto tr3250 +tr4032: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5153 + st5153: + if p++; p == pe { + goto _test_eof5153 + } + st_case_5153: +//line segment_words_prod.go:130904 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 171 <= data[p] && data[p] <= 190 { + goto tr1 + } + goto tr5054 +tr4033: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5154 + st5154: + if p++; p == pe { + goto _test_eof5154 + } + st_case_5154: +//line segment_words_prod.go:130969 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] < 162: + switch { + case data[p] > 153: + if 158 <= data[p] && data[p] <= 160 { + goto tr1 + } + case data[p] >= 150: + goto tr1 + } + case data[p] > 164: + switch { + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr1 + } + case data[p] >= 167: + goto tr1 + } + default: + goto tr1 + } + goto tr5054 +tr4034: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5155 + st5155: + if p++; p == pe { + goto _test_eof5155 + } + st_case_5155: +//line segment_words_prod.go:131053 + switch data[p] { + case 143: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 141: + if 154 <= data[p] && data[p] <= 157 { + goto tr1 + } + case data[p] >= 130: + goto tr1 + } + goto tr5054 +tr4035: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5156 + st5156: + if p++; p == pe { + goto _test_eof5156 + } + st_case_5156: +//line segment_words_prod.go:131125 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 157 <= data[p] && data[p] <= 159 { + goto tr1 + } + goto tr5054 +tr4036: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5157 + st5157: + if p++; p == pe { + goto _test_eof5157 + } + st_case_5157: +//line segment_words_prod.go:131190 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 148: + if 178 <= data[p] && data[p] <= 180 { + goto tr1 + } + case data[p] >= 146: + goto tr1 + } + goto tr5054 +tr4037: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5158 + st5158: + if p++; p == pe { + goto _test_eof5158 + } + st_case_5158: +//line segment_words_prod.go:131260 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 147: + if 178 <= data[p] && data[p] <= 179 { + goto tr1 + } + case data[p] >= 146: + goto tr1 + } + goto tr5054 +tr4038: +//line segment_words.rl:72 + + endPos = p + + goto st5159 + st5159: + if p++; p == pe { + goto _test_eof5159 + } + st_case_5159: +//line segment_words_prod.go:131325 + switch data[p] { + case 194: + goto tr5196 + case 204: + goto tr5197 + case 205: + goto tr5198 + case 210: + goto tr5199 + case 214: + goto tr5200 + case 215: + goto tr5201 + case 216: + goto tr5202 + case 217: + goto tr5203 + case 219: + goto tr5204 + case 220: + goto tr5205 + case 221: + goto tr5206 + case 222: + goto tr5207 + case 223: + goto tr5208 + case 224: + goto tr5209 + case 225: + goto tr5210 + case 226: + goto tr5211 + case 227: + goto tr5212 + case 234: + goto tr5213 + case 239: + goto tr5214 + case 240: + goto tr5215 + case 243: + goto tr5216 + } + if 180 <= data[p] { + goto tr1 + } + goto tr5054 +tr4039: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5160 + st5160: + if p++; p == pe { + goto _test_eof5160 + } + st_case_5160: +//line segment_words_prod.go:131390 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 156: + if 158 <= data[p] { + goto tr5054 + } + case data[p] >= 148: + goto tr5054 + } + goto tr1 +tr4040: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5161 + st5161: + if p++; p == pe { + goto _test_eof5161 + } + st_case_5161: +//line segment_words_prod.go:131460 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 139 <= data[p] && data[p] <= 142 { + goto tr1 + } + goto tr5054 +tr4041: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5162 + st5162: + if p++; p == pe { + goto _test_eof5162 + } + st_case_5162: +//line segment_words_prod.go:131525 + switch data[p] { + case 169: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 +tr4042: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5163 + st5163: + if p++; p == pe { + goto _test_eof5163 + } + st_case_5163: +//line segment_words_prod.go:131589 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr1 + } + case data[p] >= 160: + goto tr1 + } + goto tr5054 +tr4043: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5164 + st5164: + if p++; p == pe { + goto _test_eof5164 + } + st_case_5164: +//line segment_words_prod.go:131659 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 151 <= data[p] && data[p] <= 155 { + goto tr1 + } + goto tr5054 +tr4044: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5165 + st5165: + if p++; p == pe { + goto _test_eof5165 + } + st_case_5165: +//line segment_words_prod.go:131724 + switch data[p] { + case 191: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr1 + } + case data[p] >= 149: + goto tr1 + } + goto tr5054 +tr4045: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5166 + st5166: + if p++; p == pe { + goto _test_eof5166 + } + st_case_5166: +//line segment_words_prod.go:131796 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 176 <= data[p] && data[p] <= 190 { + goto tr1 + } + goto tr5054 +tr4046: +//line segment_words.rl:72 + + endPos = p + + goto st5167 + st5167: + if p++; p == pe { + goto _test_eof5167 + } + st_case_5167: +//line segment_words_prod.go:131856 + switch data[p] { + case 194: + goto tr5196 + case 204: + goto tr5197 + case 205: + goto tr5198 + case 210: + goto tr5199 + case 214: + goto tr5200 + case 215: + goto tr5201 + case 216: + goto tr5202 + case 217: + goto tr5203 + case 219: + goto tr5204 + case 220: + goto tr5205 + case 221: + goto tr5206 + case 222: + goto tr5207 + case 223: + goto tr5208 + case 224: + goto tr5209 + case 225: + goto tr5210 + case 226: + goto tr5211 + case 227: + goto tr5212 + case 234: + goto tr5213 + case 239: + goto tr5214 + case 240: + goto tr5215 + case 243: + goto tr5216 + } + switch { + case data[p] > 132: + if 180 <= data[p] { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr5054 +tr4047: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5168 + st5168: + if p++; p == pe { + goto _test_eof5168 + } + st_case_5168: +//line segment_words_prod.go:131926 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr5054 + } + case data[p] >= 133: + goto tr5054 + } + goto tr1 +tr4048: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5169 + st5169: + if p++; p == pe { + goto _test_eof5169 + } + st_case_5169: +//line segment_words_prod.go:131996 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 130: + if 161 <= data[p] && data[p] <= 173 { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr5054 +tr4049: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5170 + st5170: + if p++; p == pe { + goto _test_eof5170 + } + st_case_5170: +//line segment_words_prod.go:132066 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 166 <= data[p] && data[p] <= 179 { + goto tr1 + } + goto tr5054 +tr4050: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5171 + st5171: + if p++; p == pe { + goto _test_eof5171 + } + st_case_5171: +//line segment_words_prod.go:132131 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 164 <= data[p] && data[p] <= 183 { + goto tr1 + } + goto tr5054 +tr4051: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5172 + st5172: + if p++; p == pe { + goto _test_eof5172 + } + st_case_5172: +//line segment_words_prod.go:132196 + switch data[p] { + case 173: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] < 148: + if 144 <= data[p] && data[p] <= 146 { + goto tr1 + } + case data[p] > 168: + switch { + case data[p] > 180: + if 184 <= data[p] && data[p] <= 185 { + goto tr1 + } + case data[p] >= 178: + goto tr1 + } + default: + goto tr1 + } + goto tr5054 +tr4052: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5173 + st5173: + if p++; p == pe { + goto _test_eof5173 + } + st_case_5173: +//line segment_words_prod.go:132277 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr5054 + st4474: + if p++; p == pe { + goto _test_eof4474 + } + st_case_4474: + switch data[p] { + case 128: + goto tr4053 + case 129: + goto tr4054 + case 131: + goto tr4055 + case 179: + goto tr4056 + case 181: + goto tr4057 + case 183: + goto tr4058 + } + goto tr3250 +tr4053: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5174 + st5174: + if p++; p == pe { + goto _test_eof5174 + } + st_case_5174: +//line segment_words_prod.go:132367 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 143: + if 170 <= data[p] && data[p] <= 174 { + goto tr1 + } + case data[p] >= 140: + goto tr1 + } + goto tr5054 +tr4054: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5175 + st5175: + if p++; p == pe { + goto _test_eof5175 + } + st_case_5175: +//line segment_words_prod.go:132437 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 164: + if 166 <= data[p] && data[p] <= 175 { + goto tr1 + } + case data[p] >= 160: + goto tr1 + } + goto tr5054 +tr4055: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5176 + st5176: + if p++; p == pe { + goto _test_eof5176 + } + st_case_5176: +//line segment_words_prod.go:132507 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 144 <= data[p] && data[p] <= 176 { + goto tr1 + } + goto tr5054 +tr4056: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5177 + st5177: + if p++; p == pe { + goto _test_eof5177 + } + st_case_5177: +//line segment_words_prod.go:132572 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 175 <= data[p] && data[p] <= 177 { + goto tr1 + } + goto tr5054 +tr4057: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5178 + st5178: + if p++; p == pe { + goto _test_eof5178 + } + st_case_5178: +//line segment_words_prod.go:132637 + switch data[p] { + case 191: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 +tr4058: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5179 + st5179: + if p++; p == pe { + goto _test_eof5179 + } + st_case_5179: +//line segment_words_prod.go:132701 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 160 <= data[p] && data[p] <= 191 { + goto tr1 + } + goto tr5054 + st4475: + if p++; p == pe { + goto _test_eof4475 + } + st_case_4475: + switch data[p] { + case 128: + goto tr4059 + case 130: + goto tr4060 + } + goto tr3250 +tr4059: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5180 + st5180: + if p++; p == pe { + goto _test_eof5180 + } + st_case_5180: +//line segment_words_prod.go:132778 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 170 <= data[p] && data[p] <= 175 { + goto tr1 + } + goto tr5054 +tr4060: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5181 + st5181: + if p++; p == pe { + goto _test_eof5181 + } + st_case_5181: +//line segment_words_prod.go:132843 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 153 <= data[p] && data[p] <= 154 { + goto tr1 + } + goto tr5054 + st4476: + if p++; p == pe { + goto _test_eof4476 + } + st_case_4476: + switch data[p] { + case 153: + goto tr4061 + case 154: + goto tr4062 + case 155: + goto tr4063 + case 160: + goto tr4064 + case 162: + goto tr4065 + case 163: + goto tr4066 + case 164: + goto tr4067 + case 165: + goto tr4068 + case 166: + goto tr4069 + case 167: + goto tr4070 + case 168: + goto tr4071 + case 169: + goto tr4072 + case 170: + goto tr4073 + case 171: + goto tr4074 + case 175: + goto tr4075 + } + goto tr3250 +tr4061: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5182 + st5182: + if p++; p == pe { + goto _test_eof5182 + } + st_case_5182: +//line segment_words_prod.go:132946 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr1 + } + case data[p] >= 175: + goto tr1 + } + goto tr5054 +tr4062: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5183 + st5183: + if p++; p == pe { + goto _test_eof5183 + } + st_case_5183: +//line segment_words_prod.go:133016 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 158 <= data[p] && data[p] <= 159 { + goto tr1 + } + goto tr5054 +tr4063: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5184 + st5184: + if p++; p == pe { + goto _test_eof5184 + } + st_case_5184: +//line segment_words_prod.go:133081 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 176 <= data[p] && data[p] <= 177 { + goto tr1 + } + goto tr5054 +tr4064: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5185 + st5185: + if p++; p == pe { + goto _test_eof5185 + } + st_case_5185: +//line segment_words_prod.go:133146 + switch data[p] { + case 130: + goto tr1 + case 134: + goto tr1 + case 139: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 163 <= data[p] && data[p] <= 167 { + goto tr1 + } + goto tr5054 +tr4065: +//line segment_words.rl:72 + + endPos = p + + goto st5186 + st5186: + if p++; p == pe { + goto _test_eof5186 + } + st_case_5186: +//line segment_words_prod.go:133212 + switch data[p] { + case 194: + goto tr5196 + case 204: + goto tr5197 + case 205: + goto tr5198 + case 210: + goto tr5199 + case 214: + goto tr5200 + case 215: + goto tr5201 + case 216: + goto tr5202 + case 217: + goto tr5203 + case 219: + goto tr5204 + case 220: + goto tr5205 + case 221: + goto tr5206 + case 222: + goto tr5207 + case 223: + goto tr5208 + case 224: + goto tr5209 + case 225: + goto tr5210 + case 226: + goto tr5211 + case 227: + goto tr5212 + case 234: + goto tr5213 + case 239: + goto tr5214 + case 240: + goto tr5215 + case 243: + goto tr5216 + } + switch { + case data[p] > 129: + if 180 <= data[p] { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr5054 +tr4066: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5187 + st5187: + if p++; p == pe { + goto _test_eof5187 + } + st_case_5187: +//line segment_words_prod.go:133282 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 159: + if 178 <= data[p] { + goto tr5054 + } + case data[p] >= 133: + goto tr5054 + } + goto tr1 +tr4067: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5188 + st5188: + if p++; p == pe { + goto _test_eof5188 + } + st_case_5188: +//line segment_words_prod.go:133352 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 166 <= data[p] && data[p] <= 173 { + goto tr1 + } + goto tr5054 +tr4068: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5189 + st5189: + if p++; p == pe { + goto _test_eof5189 + } + st_case_5189: +//line segment_words_prod.go:133417 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 135 <= data[p] && data[p] <= 147 { + goto tr1 + } + goto tr5054 +tr4069: +//line segment_words.rl:72 + + endPos = p + + goto st5190 + st5190: + if p++; p == pe { + goto _test_eof5190 + } + st_case_5190: +//line segment_words_prod.go:133477 + switch data[p] { + case 194: + goto tr5196 + case 204: + goto tr5197 + case 205: + goto tr5198 + case 210: + goto tr5199 + case 214: + goto tr5200 + case 215: + goto tr5201 + case 216: + goto tr5202 + case 217: + goto tr5203 + case 219: + goto tr5204 + case 220: + goto tr5205 + case 221: + goto tr5206 + case 222: + goto tr5207 + case 223: + goto tr5208 + case 224: + goto tr5209 + case 225: + goto tr5210 + case 226: + goto tr5211 + case 227: + goto tr5212 + case 234: + goto tr5213 + case 239: + goto tr5214 + case 240: + goto tr5215 + case 243: + goto tr5216 + } + switch { + case data[p] > 131: + if 179 <= data[p] { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr5054 +tr4070: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5191 + st5191: + if p++; p == pe { + goto _test_eof5191 + } + st_case_5191: +//line segment_words_prod.go:133547 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 164: + if 166 <= data[p] { + goto tr5054 + } + case data[p] >= 129: + goto tr5054 + } + goto tr1 +tr4071: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5192 + st5192: + if p++; p == pe { + goto _test_eof5192 + } + st_case_5192: +//line segment_words_prod.go:133617 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 169 <= data[p] && data[p] <= 182 { + goto tr1 + } + goto tr5054 +tr4072: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5193 + st5193: + if p++; p == pe { + goto _test_eof5193 + } + st_case_5193: +//line segment_words_prod.go:133682 + switch data[p] { + case 131: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 141: + if 187 <= data[p] && data[p] <= 189 { + goto tr1 + } + case data[p] >= 140: + goto tr1 + } + goto tr5054 +tr4073: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5194 + st5194: + if p++; p == pe { + goto _test_eof5194 + } + st_case_5194: +//line segment_words_prod.go:133754 + switch data[p] { + case 176: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr1 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr1 + } + default: + goto tr1 + } + goto tr5054 +tr4074: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5195 + st5195: + if p++; p == pe { + goto _test_eof5195 + } + st_case_5195: +//line segment_words_prod.go:133830 + switch data[p] { + case 129: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 175: + if 181 <= data[p] && data[p] <= 182 { + goto tr1 + } + case data[p] >= 171: + goto tr1 + } + goto tr5054 +tr4075: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5196 + st5196: + if p++; p == pe { + goto _test_eof5196 + } + st_case_5196: +//line segment_words_prod.go:133902 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 173 { + goto tr1 + } + case data[p] >= 163: + goto tr1 + } + goto tr5054 + st4477: + if p++; p == pe { + goto _test_eof4477 + } + st_case_4477: + switch data[p] { + case 172: + goto tr4076 + case 184: + goto tr4077 + case 187: + goto tr4057 + case 190: + goto tr4062 + case 191: + goto tr4078 + } + goto tr3250 +tr4076: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5197 + st5197: + if p++; p == pe { + goto _test_eof5197 + } + st_case_5197: +//line segment_words_prod.go:133990 + switch data[p] { + case 158: + goto tr1 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 +tr4077: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5198 + st5198: + if p++; p == pe { + goto _test_eof5198 + } + st_case_5198: +//line segment_words_prod.go:134054 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + switch { + case data[p] > 143: + if 160 <= data[p] && data[p] <= 175 { + goto tr1 + } + case data[p] >= 128: + goto tr1 + } + goto tr5054 +tr4078: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5199 + st5199: + if p++; p == pe { + goto _test_eof5199 + } + st_case_5199: +//line segment_words_prod.go:134124 + switch data[p] { + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 185 <= data[p] && data[p] <= 187 { + goto tr1 + } + goto tr5054 + st4478: + if p++; p == pe { + goto _test_eof4478 + } + st_case_4478: + switch data[p] { + case 144: + goto tr4079 + case 145: + goto tr4080 + case 150: + goto tr4081 + case 155: + goto tr4082 + case 157: + goto tr4083 + case 158: + goto tr4084 + } + goto tr3250 +tr4079: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5200 + st5200: + if p++; p == pe { + goto _test_eof5200 + } + st_case_5200: +//line segment_words_prod.go:134209 + switch data[p] { + case 135: + goto st96 + case 139: + goto st97 + case 141: + goto st98 + case 168: + goto st99 + case 171: + goto st100 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 +tr4080: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5201 + st5201: + if p++; p == pe { + goto _test_eof5201 + } + st_case_5201: +//line segment_words_prod.go:134281 + switch data[p] { + case 128: + goto st102 + case 129: + goto st103 + case 130: + goto st104 + case 132: + goto st105 + case 133: + goto st106 + case 134: + goto st107 + case 135: + goto st108 + case 136: + goto st109 + case 139: + goto st110 + case 140: + goto st111 + case 141: + goto st112 + case 146: + goto st113 + case 147: + goto st114 + case 150: + goto st115 + case 151: + goto st116 + case 152: + goto st113 + case 153: + goto st117 + case 154: + goto st118 + case 156: + goto st119 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 +tr4081: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5202 + st5202: + if p++; p == pe { + goto _test_eof5202 + } + st_case_5202: +//line segment_words_prod.go:134381 + switch data[p] { + case 171: + goto st121 + case 172: + goto st122 + case 189: + goto st123 + case 190: + goto st124 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 +tr4082: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5203 + st5203: + if p++; p == pe { + goto _test_eof5203 + } + st_case_5203: +//line segment_words_prod.go:134451 + switch data[p] { + case 178: + goto st126 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 +tr4083: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5204 + st5204: + if p++; p == pe { + goto _test_eof5204 + } + st_case_5204: +//line segment_words_prod.go:134515 + switch data[p] { + case 133: + goto st128 + case 134: + goto st129 + case 137: + goto st130 + case 168: + goto st131 + case 169: + goto st132 + case 170: + goto st133 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 +tr4084: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5205 + st5205: + if p++; p == pe { + goto _test_eof5205 + } + st_case_5205: +//line segment_words_prod.go:134589 + switch data[p] { + case 163: + goto st135 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + goto tr5054 + st4479: + if p++; p == pe { + goto _test_eof4479 + } + st_case_4479: + if data[p] == 160 { + goto tr4085 + } + goto tr3250 +tr4085: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:131 +act = 5; + goto st5206 + st5206: + if p++; p == pe { + goto _test_eof5206 + } + st_case_5206: +//line segment_words_prod.go:134662 + switch data[p] { + case 128: + goto st138 + case 129: + goto st139 + case 132: + goto st1 + case 135: + goto st2 + case 194: + goto st3594 + case 204: + goto st3595 + case 205: + goto st3596 + case 210: + goto st3597 + case 214: + goto st3598 + case 215: + goto st3599 + case 216: + goto st3600 + case 217: + goto st3601 + case 219: + goto st3602 + case 220: + goto st3603 + case 221: + goto st3604 + case 222: + goto st3605 + case 223: + goto st3606 + case 224: + goto st3607 + case 225: + goto st3636 + case 226: + goto st3658 + case 227: + goto st3665 + case 234: + goto st3668 + case 239: + goto st3684 + case 240: + goto st3688 + case 243: + goto st3730 + } + if 133 <= data[p] && data[p] <= 134 { + goto st140 + } + goto tr5054 +tr4490: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5207 + st5207: + if p++; p == pe { + goto _test_eof5207 + } + st_case_5207: +//line segment_words_prod.go:134739 + switch data[p] { + case 182: + goto st4480 + case 183: + goto tr4499 + case 184: + goto st3595 + case 194: + goto st4318 + case 204: + goto st4460 + case 205: + goto st4461 + case 210: + goto st4462 + case 214: + goto st4463 + case 215: + goto st4464 + case 216: + goto st4465 + case 217: + goto st4466 + case 219: + goto st4467 + case 220: + goto st4468 + case 221: + goto st4469 + case 222: + goto st4470 + case 223: + goto st4471 + case 224: + goto st4472 + case 225: + goto st4473 + case 226: + goto st4474 + case 227: + goto st4475 + case 234: + goto st4476 + case 239: + goto st4477 + case 240: + goto st4478 + case 243: + goto st4479 + } + goto st3734 + st4480: + if p++; p == pe { + goto _test_eof4480 + } + st_case_4480: + if 182 <= data[p] { + goto tr0 + } + goto tr3250 +tr4491: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5208 + st5208: + if p++; p == pe { + goto _test_eof5208 + } + st_case_5208: +//line segment_words_prod.go:134820 + switch data[p] { + case 194: + goto st4318 + case 204: + goto st4460 + case 205: + goto st4461 + case 210: + goto st4462 + case 214: + goto st4463 + case 215: + goto st4464 + case 216: + goto st4465 + case 217: + goto st4466 + case 219: + goto st4467 + case 220: + goto st4468 + case 221: + goto st4469 + case 222: + goto st4470 + case 223: + goto st4471 + case 224: + goto st4472 + case 225: + goto st4473 + case 226: + goto st4474 + case 227: + goto st4475 + case 234: + goto st4476 + case 239: + goto st4477 + case 240: + goto st4478 + case 243: + goto st4479 + } + goto st3734 +tr4492: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5209 + st5209: + if p++; p == pe { + goto _test_eof5209 + } + st_case_5209: +//line segment_words_prod.go:134886 + switch data[p] { + case 191: + goto st3736 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 192 <= data[p] { + goto tr4499 + } + goto st3734 +tr4493: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5210 + st5210: + if p++; p == pe { + goto _test_eof5210 + } + st_case_5210: +//line segment_words_prod.go:134957 + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st1673 + case 153: + goto st4481 + case 154: + goto st4482 + case 155: + goto st4483 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st4484 + case 161: + goto st272 + case 162: + goto st4485 + case 163: + goto st4486 + case 164: + goto st4487 + case 165: + goto st4488 + case 166: + goto st4489 + case 167: + goto st4490 + case 168: + goto st4491 + case 169: + goto st4492 + case 170: + goto st2723 + case 171: + goto st4493 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st4494 + case 176: + goto st3270 + case 194: + goto st4495 + case 204: + goto st4643 + case 205: + goto st4644 + case 210: + goto st4645 + case 214: + goto st4646 + case 215: + goto st4647 + case 216: + goto st4648 + case 217: + goto st4649 + case 219: + goto st4650 + case 220: + goto st4651 + case 221: + goto st4652 + case 222: + goto st4653 + case 223: + goto st4654 + case 224: + goto st4655 + case 225: + goto st4656 + case 226: + goto st4657 + case 227: + goto st4658 + case 234: + goto st4659 + case 239: + goto st4660 + case 240: + goto st4661 + case 243: + goto st4662 + } + switch { + case data[p] > 157: + if 177 <= data[p] { + goto st3318 + } + case data[p] >= 129: + goto st145 + } + goto tr4499 + st4481: + if p++; p == pe { + goto _test_eof4481 + } + st_case_4481: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr2395 + } + default: + goto tr2395 + } + goto tr0 + st4482: + if p++; p == pe { + goto _test_eof4482 + } + st_case_4482: + switch { + case data[p] < 158: + if 128 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr2395 + } + goto tr0 + st4483: + if p++; p == pe { + goto _test_eof4483 + } + st_case_4483: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr0 + } + case data[p] >= 176: + goto tr2395 + } + goto tr148 + st4484: + if p++; p == pe { + goto _test_eof4484 + } + st_case_4484: + switch data[p] { + case 130: + goto tr2395 + case 134: + goto tr2395 + case 139: + goto tr2395 + } + switch { + case data[p] > 167: + if 168 <= data[p] { + goto tr0 + } + case data[p] >= 163: + goto tr2395 + } + goto tr148 + st4485: + if p++; p == pe { + goto _test_eof4485 + } + st_case_4485: + switch { + case data[p] < 130: + if 128 <= data[p] && data[p] <= 129 { + goto tr2395 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr2395 + } + default: + goto tr148 + } + goto tr0 + st4486: + if p++; p == pe { + goto _test_eof4486 + } + st_case_4486: + switch data[p] { + case 187: + goto tr148 + case 189: + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 143: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 133: + goto tr0 + } + case data[p] > 159: + switch { + case data[p] > 183: + if 184 <= data[p] { + goto tr0 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr0 + } + goto tr2395 + st4487: + if p++; p == pe { + goto _test_eof4487 + } + st_case_4487: + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr126 + } + case data[p] > 165: + switch { + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr2395 + } + default: + goto tr148 + } + goto tr0 + st4488: + if p++; p == pe { + goto _test_eof4488 + } + st_case_4488: + switch { + case data[p] < 148: + if 135 <= data[p] && data[p] <= 147 { + goto tr2395 + } + case data[p] > 159: + switch { + case data[p] > 188: + if 189 <= data[p] { + goto tr0 + } + case data[p] >= 160: + goto tr2984 + } + default: + goto tr0 + } + goto tr148 + st4489: + if p++; p == pe { + goto _test_eof4489 + } + st_case_4489: + switch { + case data[p] < 132: + if 128 <= data[p] && data[p] <= 131 { + goto tr2395 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr2395 + } + default: + goto tr148 + } + goto tr0 + st4490: + if p++; p == pe { + goto _test_eof4490 + } + st_case_4490: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] >= 129: + goto tr0 + } + case data[p] > 164: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr0 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr0 + } + default: + goto tr126 + } + default: + goto tr0 + } + goto tr2395 + st4491: + if p++; p == pe { + goto _test_eof4491 + } + st_case_4491: + switch { + case data[p] > 168: + if 169 <= data[p] && data[p] <= 182 { + goto tr2395 + } + case data[p] >= 128: + goto tr148 + } + goto tr0 + st4492: + if p++; p == pe { + goto _test_eof4492 + } + st_case_4492: + if data[p] == 131 { + goto tr2395 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 141: + switch { + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto tr2395 + } + case data[p] >= 144: + goto tr126 + } + default: + goto tr2395 + } + goto tr0 + st4493: + if p++; p == pe { + goto _test_eof4493 + } + st_case_4493: + if data[p] == 129 { + goto tr2395 + } + switch { + case data[p] < 171: + if 160 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 181 <= data[p] && data[p] <= 182 { + goto tr2395 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr2395 + } + goto tr0 + st4494: + if p++; p == pe { + goto _test_eof4494 + } + st_case_4494: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 162 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + case data[p] >= 172: + goto tr2395 + } + default: + goto tr2395 + } + goto tr0 + st4495: + if p++; p == pe { + goto _test_eof4495 + } + st_case_4495: + if data[p] == 173 { + goto tr4086 + } + goto tr2984 +tr4086: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5211 + st5211: + if p++; p == pe { + goto _test_eof5211 + } + st_case_5211: +//line segment_words_prod.go:135407 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st4496 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st4497 + case 205: + goto st4498 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st4499 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st4500 + case 215: + goto st4501 + case 216: + goto st4502 + case 217: + goto st4503 + case 219: + goto st4504 + case 220: + goto st4505 + case 221: + goto st4506 + case 222: + goto st4507 + case 223: + goto st4508 + case 224: + goto st4509 + case 225: + goto st4541 + case 226: + goto st4563 + case 227: + goto st4570 + case 234: + goto st4573 + case 237: + goto st3517 + case 239: + goto st4589 + case 240: + goto st4595 + case 243: + goto st4637 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 + st4496: + if p++; p == pe { + goto _test_eof4496 + } + st_case_4496: + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr4086 + case 181: + goto tr148 + case 183: + goto st142 + case 186: + goto tr148 + } + goto tr2985 + st4497: + if p++; p == pe { + goto _test_eof4497 + } + st_case_4497: + if data[p] <= 127 { + goto tr2985 + } + goto tr4086 + st4498: + if p++; p == pe { + goto _test_eof4498 + } + st_case_4498: + switch data[p] { + case 181: + goto tr2985 + case 190: + goto tr2985 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr2985 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr2985 + } + goto tr4086 + st4499: + if p++; p == pe { + goto _test_eof4499 + } + st_case_4499: + if data[p] == 130 { + goto tr2985 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr4086 + } + goto tr148 + st4500: + if p++; p == pe { + goto _test_eof4500 + } + st_case_4500: + if data[p] == 190 { + goto tr2985 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr2985 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr2985 + } + default: + goto tr4086 + } + goto tr148 + st4501: + if p++; p == pe { + goto _test_eof4501 + } + st_case_4501: + switch data[p] { + case 135: + goto tr4086 + case 179: + goto tr148 + case 180: + goto st142 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr4086 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr4086 + } + goto tr2985 + st4502: + if p++; p == pe { + goto _test_eof4502 + } + st_case_4502: + if data[p] == 156 { + goto tr4086 + } + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 133 { + goto tr4086 + } + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr4086 + } + goto tr2985 + st4503: + if p++; p == pe { + goto _test_eof4503 + } + st_case_4503: + switch data[p] { + case 171: + goto tr421 + case 176: + goto tr4086 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr4086 + } + goto tr2985 + st4504: + if p++; p == pe { + goto _test_eof4504 + } + st_case_4504: + switch data[p] { + case 148: + goto tr2985 + case 158: + goto tr2985 + case 169: + goto tr2985 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr4086 + } + case data[p] >= 150: + goto tr4086 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr2985 + } + case data[p] >= 189: + goto tr2985 + } + default: + goto tr421 + } + goto tr148 + st4505: + if p++; p == pe { + goto _test_eof4505 + } + st_case_4505: + if data[p] == 144 { + goto tr148 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto tr4086 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr4086 + } + default: + goto tr148 + } + goto tr2985 + st4506: + if p++; p == pe { + goto _test_eof4506 + } + st_case_4506: + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr2985 + } + goto tr4086 + st4507: + if p++; p == pe { + goto _test_eof4507 + } + st_case_4507: + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr2985 + } + case data[p] >= 166: + goto tr4086 + } + goto tr148 + st4508: + if p++; p == pe { + goto _test_eof4508 + } + st_case_4508: + if data[p] == 186 { + goto tr148 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 170: + switch { + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 171: + goto tr4086 + } + default: + goto tr148 + } + goto tr2985 + st4509: + if p++; p == pe { + goto _test_eof4509 + } + st_case_4509: + switch data[p] { + case 160: + goto st4510 + case 161: + goto st4511 + case 162: + goto st168 + case 163: + goto st4512 + case 164: + goto st4513 + case 165: + goto st4514 + case 166: + goto st4515 + case 167: + goto st4516 + case 168: + goto st4517 + case 169: + goto st4518 + case 170: + goto st4519 + case 171: + goto st4520 + case 172: + goto st4521 + case 173: + goto st4522 + case 174: + goto st4523 + case 175: + goto st4524 + case 176: + goto st4525 + case 177: + goto st4526 + case 178: + goto st4527 + case 179: + goto st4528 + case 180: + goto st4529 + case 181: + goto st4530 + case 182: + goto st4531 + case 183: + goto st4532 + case 184: + goto st4533 + case 185: + goto st4534 + case 186: + goto st4535 + case 187: + goto st4536 + case 188: + goto st4537 + case 189: + goto st4538 + case 190: + goto st4539 + case 191: + goto st4540 + } + goto tr2985 + st4510: + if p++; p == pe { + goto _test_eof4510 + } + st_case_4510: + switch data[p] { + case 154: + goto tr148 + case 164: + goto tr148 + case 168: + goto tr148 + } + switch { + case data[p] > 149: + if 150 <= data[p] && data[p] <= 173 { + goto tr4086 + } + case data[p] >= 128: + goto tr148 + } + goto tr2985 + st4511: + if p++; p == pe { + goto _test_eof4511 + } + st_case_4511: + switch { + case data[p] > 152: + if 153 <= data[p] && data[p] <= 155 { + goto tr4086 + } + case data[p] >= 128: + goto tr148 + } + goto tr2985 + st4512: + if p++; p == pe { + goto _test_eof4512 + } + st_case_4512: + if 163 <= data[p] { + goto tr4086 + } + goto tr2985 + st4513: + if p++; p == pe { + goto _test_eof4513 + } + st_case_4513: + if data[p] == 189 { + goto tr148 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr148 + } + goto tr4086 + st4514: + if p++; p == pe { + goto _test_eof4514 + } + st_case_4514: + switch data[p] { + case 144: + goto tr148 + case 176: + goto tr2985 + } + switch { + case data[p] < 164: + if 152 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 177 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr2985 + } + goto tr4086 + st4515: + if p++; p == pe { + goto _test_eof4515 + } + st_case_4515: + switch data[p] { + case 132: + goto tr2985 + case 169: + goto tr2985 + case 177: + goto tr2985 + case 188: + goto tr4086 + } + switch { + case data[p] < 145: + switch { + case data[p] > 131: + if 141 <= data[p] && data[p] <= 142 { + goto tr2985 + } + case data[p] >= 129: + goto tr4086 + } + case data[p] > 146: + switch { + case data[p] < 186: + if 179 <= data[p] && data[p] <= 181 { + goto tr2985 + } + case data[p] > 187: + if 190 <= data[p] { + goto tr4086 + } + default: + goto tr2985 + } + default: + goto tr2985 + } + goto tr148 + st4516: + if p++; p == pe { + goto _test_eof4516 + } + st_case_4516: + switch data[p] { + case 142: + goto tr148 + case 158: + goto tr2985 + } + switch { + case data[p] < 156: + switch { + case data[p] < 137: + if 133 <= data[p] && data[p] <= 134 { + goto tr2985 + } + case data[p] > 138: + switch { + case data[p] > 150: + if 152 <= data[p] && data[p] <= 155 { + goto tr2985 + } + case data[p] >= 143: + goto tr2985 + } + default: + goto tr2985 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr2985 + } + case data[p] > 175: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr2985 + } + case data[p] >= 176: + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr4086 + st4517: + if p++; p == pe { + goto _test_eof4517 + } + st_case_4517: + if data[p] == 188 { + goto tr4086 + } + switch { + case data[p] < 170: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr4086 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 147 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] >= 143: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 176: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 182: + switch { + case data[p] > 185: + if 190 <= data[p] { + goto tr4086 + } + case data[p] >= 184: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2985 + st4518: + if p++; p == pe { + goto _test_eof4518 + } + st_case_4518: + if data[p] == 157 { + goto tr2985 + } + switch { + case data[p] < 153: + switch { + case data[p] < 137: + if 131 <= data[p] && data[p] <= 134 { + goto tr2985 + } + case data[p] > 138: + switch { + case data[p] > 144: + if 146 <= data[p] && data[p] <= 152 { + goto tr2985 + } + case data[p] >= 142: + goto tr2985 + } + default: + goto tr2985 + } + case data[p] > 158: + switch { + case data[p] < 166: + if 159 <= data[p] && data[p] <= 165 { + goto tr2985 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr2985 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr4086 + st4519: + if p++; p == pe { + goto _test_eof4519 + } + st_case_4519: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr4086 + } + case data[p] > 141: + if 143 <= data[p] && data[p] <= 145 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] { + goto tr4086 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2985 + st4520: + if p++; p == pe { + goto _test_eof4520 + } + st_case_4520: + switch data[p] { + case 134: + goto tr2985 + case 138: + goto tr2985 + case 144: + goto tr148 + case 185: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] >= 142: + goto tr2985 + } + case data[p] > 165: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr2985 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr2985 + } + goto tr4086 + st4521: + if p++; p == pe { + goto _test_eof4521 + } + st_case_4521: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr4086 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr4086 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2985 + st4522: + if p++; p == pe { + goto _test_eof4522 + } + st_case_4522: + if data[p] == 177 { + goto tr148 + } + switch { + case data[p] < 150: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr4086 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr4086 + } + default: + goto tr4086 + } + case data[p] > 151: + switch { + case data[p] < 159: + if 156 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 161: + switch { + case data[p] > 163: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 162: + goto tr4086 + } + default: + goto tr148 + } + default: + goto tr4086 + } + goto tr2985 + st4523: + if p++; p == pe { + goto _test_eof4523 + } + st_case_4523: + switch data[p] { + case 130: + goto tr4086 + case 131: + goto tr148 + case 156: + goto tr148 + } + switch { + case data[p] < 158: + switch { + case data[p] < 142: + if 133 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 144: + switch { + case data[p] > 149: + if 153 <= data[p] && data[p] <= 154 { + goto tr148 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] < 168: + if 163 <= data[p] && data[p] <= 164 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 185: + if 190 <= data[p] && data[p] <= 191 { + goto tr4086 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2985 + st4524: + if p++; p == pe { + goto _test_eof4524 + } + st_case_4524: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr4086 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr4086 + } + case data[p] > 136: + switch { + case data[p] > 141: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] >= 138: + goto tr4086 + } + default: + goto tr4086 + } + goto tr2985 + st4525: + if p++; p == pe { + goto _test_eof4525 + } + st_case_4525: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 128: + goto tr4086 + } + case data[p] > 144: + switch { + case data[p] < 170: + if 146 <= data[p] && data[p] <= 168 { + goto tr148 + } + case data[p] > 185: + if 190 <= data[p] { + goto tr4086 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2985 + st4526: + if p++; p == pe { + goto _test_eof4526 + } + st_case_4526: + switch data[p] { + case 133: + goto tr2985 + case 137: + goto tr2985 + case 151: + goto tr2985 + } + switch { + case data[p] < 160: + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 148 { + goto tr2985 + } + case data[p] > 154: + if 155 <= data[p] && data[p] <= 159 { + goto tr2985 + } + default: + goto tr148 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 164 <= data[p] && data[p] <= 165 { + goto tr2985 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr2985 + } + default: + goto tr421 + } + default: + goto tr148 + } + goto tr4086 + st4527: + if p++; p == pe { + goto _test_eof4527 + } + st_case_4527: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 146: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr4086 + } + case data[p] > 140: + if 142 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 181: + if 170 <= data[p] && data[p] <= 179 { + goto tr148 + } + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr4086 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2985 + st4528: + if p++; p == pe { + goto _test_eof4528 + } + st_case_4528: + if data[p] == 158 { + goto tr148 + } + switch { + case data[p] < 149: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr4086 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr4086 + } + default: + goto tr4086 + } + case data[p] > 150: + switch { + case data[p] < 162: + if 160 <= data[p] && data[p] <= 161 { + goto tr148 + } + case data[p] > 163: + switch { + case data[p] > 175: + if 177 <= data[p] && data[p] <= 178 { + goto tr148 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr4086 + } + default: + goto tr4086 + } + goto tr2985 + st4529: + if p++; p == pe { + goto _test_eof4529 + } + st_case_4529: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 142: + switch { + case data[p] > 131: + if 133 <= data[p] && data[p] <= 140 { + goto tr148 + } + case data[p] >= 129: + goto tr4086 + } + case data[p] > 144: + switch { + case data[p] > 186: + if 190 <= data[p] { + goto tr4086 + } + case data[p] >= 146: + goto tr148 + } + default: + goto tr148 + } + goto tr2985 + st4530: + if p++; p == pe { + goto _test_eof4530 + } + st_case_4530: + switch data[p] { + case 133: + goto tr2985 + case 137: + goto tr2985 + case 142: + goto tr148 + } + switch { + case data[p] < 164: + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 150 { + goto tr2985 + } + case data[p] > 158: + if 159 <= data[p] && data[p] <= 161 { + goto tr148 + } + default: + goto tr2985 + } + case data[p] > 165: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr421 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr2985 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr2985 + } + default: + goto tr2985 + } + goto tr4086 + st4531: + if p++; p == pe { + goto _test_eof4531 + } + st_case_4531: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 133: + if 130 <= data[p] && data[p] <= 131 { + goto tr4086 + } + case data[p] > 150: + switch { + case data[p] > 177: + if 179 <= data[p] && data[p] <= 187 { + goto tr148 + } + case data[p] >= 154: + goto tr148 + } + default: + goto tr148 + } + goto tr2985 + st4532: + if p++; p == pe { + goto _test_eof4532 + } + st_case_4532: + switch data[p] { + case 138: + goto tr4086 + case 150: + goto tr4086 + } + switch { + case data[p] < 152: + switch { + case data[p] > 134: + if 143 <= data[p] && data[p] <= 148 { + goto tr4086 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 178 <= data[p] && data[p] <= 179 { + goto tr4086 + } + case data[p] >= 166: + goto tr421 + } + default: + goto tr4086 + } + goto tr2985 + st4533: + if p++; p == pe { + goto _test_eof4533 + } + st_case_4533: + if data[p] == 177 { + goto tr4086 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr4086 + } + goto tr2985 + st4534: + if p++; p == pe { + goto _test_eof4534 + } + st_case_4534: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 135: + goto tr4086 + } + goto tr2985 + st4535: + if p++; p == pe { + goto _test_eof4535 + } + st_case_4535: + if data[p] == 177 { + goto tr4086 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr4086 + } + case data[p] >= 180: + goto tr4086 + } + goto tr2985 + st4536: + if p++; p == pe { + goto _test_eof4536 + } + st_case_4536: + switch { + case data[p] > 141: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 136: + goto tr4086 + } + goto tr2985 + st4537: + if p++; p == pe { + goto _test_eof4537 + } + st_case_4537: + switch data[p] { + case 128: + goto tr148 + case 181: + goto tr4086 + case 183: + goto tr4086 + case 185: + goto tr4086 + } + switch { + case data[p] < 160: + if 152 <= data[p] && data[p] <= 153 { + goto tr4086 + } + case data[p] > 169: + if 190 <= data[p] && data[p] <= 191 { + goto tr4086 + } + default: + goto tr421 + } + goto tr2985 + st4538: + if p++; p == pe { + goto _test_eof4538 + } + st_case_4538: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 172: + if 177 <= data[p] && data[p] <= 191 { + goto tr4086 + } + default: + goto tr148 + } + goto tr2985 + st4539: + if p++; p == pe { + goto _test_eof4539 + } + st_case_4539: + switch { + case data[p] < 136: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 135 { + goto tr4086 + } + case data[p] >= 128: + goto tr4086 + } + case data[p] > 140: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr4086 + } + case data[p] >= 141: + goto tr4086 + } + default: + goto tr148 + } + goto tr2985 + st4540: + if p++; p == pe { + goto _test_eof4540 + } + st_case_4540: + if data[p] == 134 { + goto tr4086 + } + goto tr2985 + st4541: + if p++; p == pe { + goto _test_eof4541 + } + st_case_4541: + switch data[p] { + case 128: + goto st4542 + case 129: + goto st4543 + case 130: + goto st4544 + case 131: + goto st202 + case 132: + goto st3268 + case 135: + goto st3319 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st4545 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st4546 + case 157: + goto st4547 + case 158: + goto st4548 + case 159: + goto st4549 + case 160: + goto st4550 + case 161: + goto st219 + case 162: + goto st4551 + case 163: + goto st221 + case 164: + goto st4552 + case 165: + goto st468 + case 167: + goto st469 + case 168: + goto st4553 + case 169: + goto st4554 + case 170: + goto st4555 + case 172: + goto st4556 + case 173: + goto st4557 + case 174: + goto st4558 + case 175: + goto st4559 + case 176: + goto st4560 + case 177: + goto st640 + case 179: + goto st4561 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st4562 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + } + switch { + case data[p] < 136: + if 133 <= data[p] && data[p] <= 134 { + goto st3318 + } + case data[p] > 152: + switch { + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + case data[p] >= 180: + goto st147 + } + default: + goto st145 + } + goto tr2985 + st4542: + if p++; p == pe { + goto _test_eof4542 + } + st_case_4542: + if 171 <= data[p] && data[p] <= 190 { + goto tr4086 + } + goto tr2985 + st4543: + if p++; p == pe { + goto _test_eof4543 + } + st_case_4543: + switch { + case data[p] < 158: + switch { + case data[p] > 137: + if 150 <= data[p] && data[p] <= 153 { + goto tr4086 + } + case data[p] >= 128: + goto tr421 + } + case data[p] > 160: + switch { + case data[p] < 167: + if 162 <= data[p] && data[p] <= 164 { + goto tr4086 + } + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr4086 + } + default: + goto tr4086 + } + default: + goto tr4086 + } + goto tr2985 + st4544: + if p++; p == pe { + goto _test_eof4544 + } + st_case_4544: + if data[p] == 143 { + goto tr4086 + } + switch { + case data[p] < 144: + if 130 <= data[p] && data[p] <= 141 { + goto tr4086 + } + case data[p] > 153: + switch { + case data[p] > 157: + if 160 <= data[p] { + goto tr148 + } + case data[p] >= 154: + goto tr4086 + } + default: + goto tr421 + } + goto tr2985 + st4545: + if p++; p == pe { + goto _test_eof4545 + } + st_case_4545: + switch { + case data[p] < 157: + if 155 <= data[p] && data[p] <= 156 { + goto tr2985 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr2985 + } + default: + goto tr4086 + } + goto tr148 + st4546: + if p++; p == pe { + goto _test_eof4546 + } + st_case_4546: + switch { + case data[p] < 146: + switch { + case data[p] > 140: + if 142 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] > 177: + if 178 <= data[p] && data[p] <= 180 { + goto tr4086 + } + case data[p] >= 160: + goto tr148 + } + default: + goto tr4086 + } + goto tr2985 + st4547: + if p++; p == pe { + goto _test_eof4547 + } + st_case_4547: + switch { + case data[p] < 160: + switch { + case data[p] > 145: + if 146 <= data[p] && data[p] <= 147 { + goto tr4086 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 172: + switch { + case data[p] > 176: + if 178 <= data[p] && data[p] <= 179 { + goto tr4086 + } + case data[p] >= 174: + goto tr148 + } + default: + goto tr148 + } + goto tr2985 + st4548: + if p++; p == pe { + goto _test_eof4548 + } + st_case_4548: + if 180 <= data[p] { + goto tr4086 + } + goto tr2985 + st4549: + if p++; p == pe { + goto _test_eof4549 + } + st_case_4549: + switch { + case data[p] < 158: + if 148 <= data[p] && data[p] <= 156 { + goto tr2985 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 170 <= data[p] { + goto tr2985 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr2985 + } + goto tr4086 + st4550: + if p++; p == pe { + goto _test_eof4550 + } + st_case_4550: + switch { + case data[p] < 144: + if 139 <= data[p] && data[p] <= 142 { + goto tr4086 + } + case data[p] > 153: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + goto tr2985 + st4551: + if p++; p == pe { + goto _test_eof4551 + } + st_case_4551: + if data[p] == 169 { + goto tr4086 + } + switch { + case data[p] > 170: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + goto tr2985 + st4552: + if p++; p == pe { + goto _test_eof4552 + } + st_case_4552: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 158 { + goto tr148 + } + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr4086 + } + default: + goto tr4086 + } + goto tr2985 + st4553: + if p++; p == pe { + goto _test_eof4553 + } + st_case_4553: + switch { + case data[p] > 150: + if 151 <= data[p] && data[p] <= 155 { + goto tr4086 + } + case data[p] >= 128: + goto tr148 + } + goto tr2985 + st4554: + if p++; p == pe { + goto _test_eof4554 + } + st_case_4554: + if data[p] == 191 { + goto tr4086 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr4086 + } + case data[p] >= 149: + goto tr4086 + } + goto tr2985 + st4555: + if p++; p == pe { + goto _test_eof4555 + } + st_case_4555: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 153: + if 176 <= data[p] && data[p] <= 190 { + goto tr4086 + } + default: + goto tr421 + } + goto tr2985 + st4556: + if p++; p == pe { + goto _test_eof4556 + } + st_case_4556: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 132 { + goto tr4086 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr4086 + } + default: + goto tr148 + } + goto tr2985 + st4557: + if p++; p == pe { + goto _test_eof4557 + } + st_case_4557: + switch { + case data[p] < 144: + switch { + case data[p] > 139: + if 140 <= data[p] && data[p] <= 143 { + goto tr2985 + } + case data[p] >= 133: + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr2985 + } + case data[p] >= 154: + goto tr2985 + } + default: + goto tr421 + } + goto tr4086 + st4558: + if p++; p == pe { + goto _test_eof4558 + } + st_case_4558: + switch { + case data[p] < 161: + switch { + case data[p] > 130: + if 131 <= data[p] && data[p] <= 160 { + goto tr148 + } + case data[p] >= 128: + goto tr4086 + } + case data[p] > 173: + switch { + case data[p] < 176: + if 174 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr148 + } + default: + goto tr421 + } + default: + goto tr4086 + } + goto tr2985 + st4559: + if p++; p == pe { + goto _test_eof4559 + } + st_case_4559: + switch { + case data[p] > 179: + if 180 <= data[p] { + goto tr2985 + } + case data[p] >= 166: + goto tr4086 + } + goto tr148 + st4560: + if p++; p == pe { + goto _test_eof4560 + } + st_case_4560: + switch { + case data[p] > 163: + if 164 <= data[p] && data[p] <= 183 { + goto tr4086 + } + case data[p] >= 128: + goto tr148 + } + goto tr2985 + st4561: + if p++; p == pe { + goto _test_eof4561 + } + st_case_4561: + if data[p] == 173 { + goto tr4086 + } + switch { + case data[p] < 169: + switch { + case data[p] > 146: + if 148 <= data[p] && data[p] <= 168 { + goto tr4086 + } + case data[p] >= 144: + goto tr4086 + } + case data[p] > 177: + switch { + case data[p] < 181: + if 178 <= data[p] && data[p] <= 180 { + goto tr4086 + } + case data[p] > 182: + if 184 <= data[p] && data[p] <= 185 { + goto tr4086 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2985 + st4562: + if p++; p == pe { + goto _test_eof4562 + } + st_case_4562: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr4086 + } + case data[p] >= 128: + goto tr4086 + } + goto tr2985 + st4563: + if p++; p == pe { + goto _test_eof4563 + } + st_case_4563: + switch data[p] { + case 128: + goto st4564 + case 129: + goto st4565 + case 130: + goto st241 + case 131: + goto st4566 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st4567 + case 180: + goto st251 + case 181: + goto st4568 + case 182: + goto st253 + case 183: + goto st4569 + case 184: + goto st255 + } + goto tr2985 + st4564: + if p++; p == pe { + goto _test_eof4564 + } + st_case_4564: + switch data[p] { + case 164: + goto st142 + case 167: + goto st142 + } + switch { + case data[p] < 152: + if 140 <= data[p] && data[p] <= 143 { + goto tr4086 + } + case data[p] > 153: + switch { + case data[p] > 174: + if 191 <= data[p] { + goto tr571 + } + case data[p] >= 170: + goto tr4086 + } + default: + goto st142 + } + goto tr2985 + st4565: + if p++; p == pe { + goto _test_eof4565 + } + st_case_4565: + switch data[p] { + case 165: + goto tr2985 + case 177: + goto tr148 + case 191: + goto tr148 + } + switch { + case data[p] < 149: + if 129 <= data[p] && data[p] <= 147 { + goto tr2985 + } + case data[p] > 159: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr2985 + } + case data[p] >= 160: + goto tr4086 + } + default: + goto tr2985 + } + goto tr571 + st4566: + if p++; p == pe { + goto _test_eof4566 + } + st_case_4566: + if 144 <= data[p] && data[p] <= 176 { + goto tr4086 + } + goto tr2985 + st4567: + if p++; p == pe { + goto _test_eof4567 + } + st_case_4567: + switch { + case data[p] < 175: + if 165 <= data[p] && data[p] <= 170 { + goto tr2985 + } + case data[p] > 177: + if 180 <= data[p] { + goto tr2985 + } + default: + goto tr4086 + } + goto tr148 + st4568: + if p++; p == pe { + goto _test_eof4568 + } + st_case_4568: + if data[p] == 191 { + goto tr4086 + } + switch { + case data[p] > 174: + if 176 <= data[p] { + goto tr2985 + } + case data[p] >= 168: + goto tr2985 + } + goto tr148 + st4569: + if p++; p == pe { + goto _test_eof4569 + } + st_case_4569: + switch { + case data[p] < 144: + switch { + case data[p] > 134: + if 136 <= data[p] && data[p] <= 142 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 150: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 191 { + goto tr4086 + } + case data[p] >= 152: + goto tr148 + } + default: + goto tr148 + } + goto tr2985 + st4570: + if p++; p == pe { + goto _test_eof4570 + } + st_case_4570: + switch data[p] { + case 128: + goto st4571 + case 130: + goto st4572 + case 132: + goto st3348 + case 133: + goto st3318 + case 134: + goto st3349 + case 136: + goto st3350 + case 137: + goto st3429 + } + goto tr2985 + st4571: + if p++; p == pe { + goto _test_eof4571 + } + st_case_4571: + if data[p] == 133 { + goto tr148 + } + switch { + case data[p] > 175: + if 187 <= data[p] && data[p] <= 188 { + goto tr148 + } + case data[p] >= 170: + goto tr4086 + } + goto tr2985 + st4572: + if p++; p == pe { + goto _test_eof4572 + } + st_case_4572: + if 153 <= data[p] && data[p] <= 154 { + goto tr4086 + } + goto tr2985 + st4573: + if p++; p == pe { + goto _test_eof4573 + } + st_case_4573: + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st654 + case 153: + goto st4574 + case 154: + goto st4575 + case 155: + goto st4576 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st4577 + case 161: + goto st272 + case 162: + goto st4578 + case 163: + goto st4579 + case 164: + goto st4580 + case 165: + goto st4581 + case 166: + goto st4582 + case 167: + goto st4583 + case 168: + goto st4584 + case 169: + goto st4585 + case 170: + goto st4586 + case 171: + goto st4587 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st4588 + case 176: + goto st3270 + } + switch { + case data[p] > 157: + if 177 <= data[p] { + goto st3318 + } + case data[p] >= 129: + goto st145 + } + goto tr2985 + st4574: + if p++; p == pe { + goto _test_eof4574 + } + st_case_4574: + if data[p] == 191 { + goto tr148 + } + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr4086 + } + default: + goto tr4086 + } + goto tr2985 + st4575: + if p++; p == pe { + goto _test_eof4575 + } + st_case_4575: + switch { + case data[p] < 158: + if 128 <= data[p] && data[p] <= 157 { + goto tr148 + } + case data[p] > 159: + if 160 <= data[p] { + goto tr148 + } + default: + goto tr4086 + } + goto tr2985 + st4576: + if p++; p == pe { + goto _test_eof4576 + } + st_case_4576: + switch { + case data[p] > 177: + if 178 <= data[p] { + goto tr2985 + } + case data[p] >= 176: + goto tr4086 + } + goto tr148 + st4577: + if p++; p == pe { + goto _test_eof4577 + } + st_case_4577: + switch data[p] { + case 130: + goto tr4086 + case 134: + goto tr4086 + case 139: + goto tr4086 + } + switch { + case data[p] > 167: + if 168 <= data[p] { + goto tr2985 + } + case data[p] >= 163: + goto tr4086 + } + goto tr148 + st4578: + if p++; p == pe { + goto _test_eof4578 + } + st_case_4578: + switch { + case data[p] < 130: + if 128 <= data[p] && data[p] <= 129 { + goto tr4086 + } + case data[p] > 179: + if 180 <= data[p] { + goto tr4086 + } + default: + goto tr148 + } + goto tr2985 + st4579: + if p++; p == pe { + goto _test_eof4579 + } + st_case_4579: + switch data[p] { + case 187: + goto tr148 + case 189: + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 143: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 133: + goto tr2985 + } + case data[p] > 159: + switch { + case data[p] > 183: + if 184 <= data[p] { + goto tr2985 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr2985 + } + goto tr4086 + st4580: + if p++; p == pe { + goto _test_eof4580 + } + st_case_4580: + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 165: + switch { + case data[p] > 173: + if 176 <= data[p] { + goto tr148 + } + case data[p] >= 166: + goto tr4086 + } + default: + goto tr148 + } + goto tr2985 + st4581: + if p++; p == pe { + goto _test_eof4581 + } + st_case_4581: + switch { + case data[p] < 148: + if 135 <= data[p] && data[p] <= 147 { + goto tr4086 + } + case data[p] > 159: + switch { + case data[p] > 188: + if 189 <= data[p] { + goto tr2985 + } + case data[p] >= 160: + goto tr2984 + } + default: + goto tr2985 + } + goto tr148 + st4582: + if p++; p == pe { + goto _test_eof4582 + } + st_case_4582: + switch { + case data[p] < 132: + if 128 <= data[p] && data[p] <= 131 { + goto tr4086 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr4086 + } + default: + goto tr148 + } + goto tr2985 + st4583: + if p++; p == pe { + goto _test_eof4583 + } + st_case_4583: + if data[p] == 143 { + goto tr148 + } + switch { + case data[p] < 154: + switch { + case data[p] > 142: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] >= 129: + goto tr2985 + } + case data[p] > 164: + switch { + case data[p] < 176: + if 166 <= data[p] && data[p] <= 175 { + goto tr2985 + } + case data[p] > 185: + if 186 <= data[p] { + goto tr2985 + } + default: + goto tr421 + } + default: + goto tr2985 + } + goto tr4086 + st4584: + if p++; p == pe { + goto _test_eof4584 + } + st_case_4584: + switch { + case data[p] > 168: + if 169 <= data[p] && data[p] <= 182 { + goto tr4086 + } + case data[p] >= 128: + goto tr148 + } + goto tr2985 + st4585: + if p++; p == pe { + goto _test_eof4585 + } + st_case_4585: + if data[p] == 131 { + goto tr4086 + } + switch { + case data[p] < 140: + if 128 <= data[p] && data[p] <= 139 { + goto tr148 + } + case data[p] > 141: + switch { + case data[p] > 153: + if 187 <= data[p] && data[p] <= 189 { + goto tr4086 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr4086 + } + goto tr2985 + st4586: + if p++; p == pe { + goto _test_eof4586 + } + st_case_4586: + if data[p] == 176 { + goto tr4086 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr4086 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr4086 + } + default: + goto tr4086 + } + goto tr2985 + st4587: + if p++; p == pe { + goto _test_eof4587 + } + st_case_4587: + if data[p] == 129 { + goto tr4086 + } + switch { + case data[p] < 171: + if 160 <= data[p] && data[p] <= 170 { + goto tr148 + } + case data[p] > 175: + switch { + case data[p] > 180: + if 181 <= data[p] && data[p] <= 182 { + goto tr4086 + } + case data[p] >= 178: + goto tr148 + } + default: + goto tr4086 + } + goto tr2985 + st4588: + if p++; p == pe { + goto _test_eof4588 + } + st_case_4588: + switch { + case data[p] < 163: + if 128 <= data[p] && data[p] <= 162 { + goto tr148 + } + case data[p] > 170: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 172: + goto tr4086 + } + default: + goto tr4086 + } + goto tr2985 + st4589: + if p++; p == pe { + goto _test_eof4589 + } + st_case_4589: + switch data[p] { + case 172: + goto st4590 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st4591 + case 185: + goto st967 + case 187: + goto st4592 + case 188: + goto st969 + case 189: + goto st303 + case 190: + goto st4593 + case 191: + goto st4594 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr2985 + st4590: + if p++; p == pe { + goto _test_eof4590 + } + st_case_4590: + switch data[p] { + case 158: + goto tr4086 + case 190: + goto tr572 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 170: + goto tr572 + } + default: + goto tr572 + } + goto tr2985 + st4591: + if p++; p == pe { + goto _test_eof4591 + } + st_case_4591: + if data[p] == 147 { + goto st142 + } + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr4086 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr571 + } + default: + goto tr4086 + } + goto tr2985 + st4592: + if p++; p == pe { + goto _test_eof4592 + } + st_case_4592: + if data[p] == 191 { + goto tr4086 + } + if 189 <= data[p] { + goto tr2985 + } + goto tr148 + st4593: + if p++; p == pe { + goto _test_eof4593 + } + st_case_4593: + switch { + case data[p] > 159: + if 160 <= data[p] && data[p] <= 190 { + goto tr2984 + } + case data[p] >= 158: + goto tr4086 + } + goto tr2985 + st4594: + if p++; p == pe { + goto _test_eof4594 + } + st_case_4594: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr2984 + } + case data[p] >= 130: + goto tr2984 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr4086 + } + case data[p] >= 154: + goto tr2984 + } + default: + goto tr2984 + } + goto tr2985 + st4595: + if p++; p == pe { + goto _test_eof4595 + } + st_case_4595: + switch data[p] { + case 144: + goto st4596 + case 145: + goto st4602 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st4621 + case 155: + goto st4626 + case 157: + goto st4628 + case 158: + goto st4635 + case 159: + goto st403 + } + goto tr2985 + st4596: + if p++; p == pe { + goto _test_eof4596 + } + st_case_4596: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st4597 + case 138: + goto st313 + case 139: + goto st4598 + case 140: + goto st315 + case 141: + goto st4599 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st684 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st4600 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st4601 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr2985 + st4597: + if p++; p == pe { + goto _test_eof4597 + } + st_case_4597: + if data[p] == 189 { + goto tr4086 + } + goto tr2985 + st4598: + if p++; p == pe { + goto _test_eof4598 + } + st_case_4598: + if data[p] == 160 { + goto tr4086 + } + if 145 <= data[p] { + goto tr2985 + } + goto tr148 + st4599: + if p++; p == pe { + goto _test_eof4599 + } + st_case_4599: + switch { + case data[p] < 182: + if 139 <= data[p] && data[p] <= 143 { + goto tr2985 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr2985 + } + default: + goto tr4086 + } + goto tr148 + st4600: + if p++; p == pe { + goto _test_eof4600 + } + st_case_4600: + switch data[p] { + case 128: + goto tr148 + case 191: + goto tr4086 + } + switch { + case data[p] < 144: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr4086 + } + case data[p] > 134: + if 140 <= data[p] && data[p] <= 143 { + goto tr4086 + } + default: + goto tr4086 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto tr4086 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2985 + st4601: + if p++; p == pe { + goto _test_eof4601 + } + st_case_4601: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 164: + if 165 <= data[p] && data[p] <= 166 { + goto tr4086 + } + default: + goto tr148 + } + goto tr2985 + st4602: + if p++; p == pe { + goto _test_eof4602 + } + st_case_4602: + switch data[p] { + case 128: + goto st4603 + case 129: + goto st4604 + case 130: + goto st4605 + case 131: + goto st691 + case 132: + goto st4606 + case 133: + goto st4607 + case 134: + goto st4608 + case 135: + goto st4609 + case 136: + goto st4610 + case 138: + goto st348 + case 139: + goto st4611 + case 140: + goto st4612 + case 141: + goto st4613 + case 146: + goto st4614 + case 147: + goto st4615 + case 150: + goto st4616 + case 151: + goto st4617 + case 152: + goto st4614 + case 153: + goto st4618 + case 154: + goto st4619 + case 155: + goto st538 + case 156: + goto st4620 + case 162: + goto st359 + case 163: + goto st707 + case 171: + goto st361 + } + goto tr2985 + st4603: + if p++; p == pe { + goto _test_eof4603 + } + st_case_4603: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr4086 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr4086 + } + default: + goto tr148 + } + goto tr2985 + st4604: + if p++; p == pe { + goto _test_eof4604 + } + st_case_4604: + switch { + case data[p] < 166: + if 135 <= data[p] && data[p] <= 165 { + goto tr2985 + } + case data[p] > 175: + if 176 <= data[p] && data[p] <= 190 { + goto tr2985 + } + default: + goto tr421 + } + goto tr4086 + st4605: + if p++; p == pe { + goto _test_eof4605 + } + st_case_4605: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr2985 + } + default: + goto tr2985 + } + goto tr4086 + st4606: + if p++; p == pe { + goto _test_eof4606 + } + st_case_4606: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr4086 + } + case data[p] > 166: + switch { + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr421 + } + case data[p] >= 167: + goto tr4086 + } + default: + goto tr148 + } + goto tr2985 + st4607: + if p++; p == pe { + goto _test_eof4607 + } + st_case_4607: + switch data[p] { + case 179: + goto tr4086 + case 182: + goto tr148 + } + if 144 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr2985 + st4608: + if p++; p == pe { + goto _test_eof4608 + } + st_case_4608: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr4086 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr4086 + } + default: + goto tr148 + } + goto tr2985 + st4609: + if p++; p == pe { + goto _test_eof4609 + } + st_case_4609: + if data[p] == 155 { + goto tr2985 + } + switch { + case data[p] < 141: + switch { + case data[p] > 132: + if 133 <= data[p] && data[p] <= 137 { + goto tr2985 + } + case data[p] >= 129: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] < 154: + if 144 <= data[p] && data[p] <= 153 { + goto tr421 + } + case data[p] > 156: + if 157 <= data[p] { + goto tr2985 + } + default: + goto tr148 + } + default: + goto tr2985 + } + goto tr4086 + st4610: + if p++; p == pe { + goto _test_eof4610 + } + st_case_4610: + switch { + case data[p] < 147: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] > 171: + if 172 <= data[p] && data[p] <= 183 { + goto tr4086 + } + default: + goto tr148 + } + goto tr2985 + st4611: + if p++; p == pe { + goto _test_eof4611 + } + st_case_4611: + switch { + case data[p] < 171: + if 159 <= data[p] && data[p] <= 170 { + goto tr4086 + } + case data[p] > 175: + switch { + case data[p] > 185: + if 186 <= data[p] { + goto tr2985 + } + case data[p] >= 176: + goto tr421 + } + default: + goto tr2985 + } + goto tr148 + st4612: + if p++; p == pe { + goto _test_eof4612 + } + st_case_4612: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto tr4086 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr4086 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr2985 + st4613: + if p++; p == pe { + goto _test_eof4613 + } + st_case_4613: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr4086 + } + switch { + case data[p] < 157: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr4086 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr4086 + } + default: + goto tr4086 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr4086 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr4086 + } + default: + goto tr4086 + } + default: + goto tr148 + } + goto tr2985 + st4614: + if p++; p == pe { + goto _test_eof4614 + } + st_case_4614: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr4086 + } + case data[p] >= 128: + goto tr148 + } + goto tr2985 + st4615: + if p++; p == pe { + goto _test_eof4615 + } + st_case_4615: + if data[p] == 134 { + goto tr2985 + } + switch { + case data[p] < 136: + if 132 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] { + goto tr2985 + } + case data[p] >= 144: + goto tr421 + } + default: + goto tr2985 + } + goto tr4086 + st4616: + if p++; p == pe { + goto _test_eof4616 + } + st_case_4616: + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 181: + if 184 <= data[p] { + goto tr4086 + } + default: + goto tr4086 + } + goto tr2985 + st4617: + if p++; p == pe { + goto _test_eof4617 + } + st_case_4617: + switch { + case data[p] < 152: + if 129 <= data[p] && data[p] <= 151 { + goto tr2985 + } + case data[p] > 155: + if 158 <= data[p] { + goto tr2985 + } + default: + goto tr148 + } + goto tr4086 + st4618: + if p++; p == pe { + goto _test_eof4618 + } + st_case_4618: + if data[p] == 132 { + goto tr148 + } + switch { + case data[p] < 144: + if 129 <= data[p] && data[p] <= 143 { + goto tr2985 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr2985 + } + default: + goto tr421 + } + goto tr4086 + st4619: + if p++; p == pe { + goto _test_eof4619 + } + st_case_4619: + switch { + case data[p] > 170: + if 171 <= data[p] && data[p] <= 183 { + goto tr4086 + } + case data[p] >= 128: + goto tr148 + } + goto tr2985 + st4620: + if p++; p == pe { + goto _test_eof4620 + } + st_case_4620: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr421 + } + case data[p] >= 157: + goto tr4086 + } + goto tr2985 + st4621: + if p++; p == pe { + goto _test_eof4621 + } + st_case_4621: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st709 + case 171: + goto st4622 + case 172: + goto st4623 + case 173: + goto st712 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st4624 + case 190: + goto st4625 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr2985 + st4622: + if p++; p == pe { + goto _test_eof4622 + } + st_case_4622: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto tr4086 + } + case data[p] >= 144: + goto tr148 + } + goto tr2985 + st4623: + if p++; p == pe { + goto _test_eof4623 + } + st_case_4623: + switch { + case data[p] > 175: + if 176 <= data[p] && data[p] <= 182 { + goto tr4086 + } + case data[p] >= 128: + goto tr148 + } + goto tr2985 + st4624: + if p++; p == pe { + goto _test_eof4624 + } + st_case_4624: + switch { + case data[p] < 145: + if 133 <= data[p] && data[p] <= 143 { + goto tr2985 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr2985 + } + default: + goto tr4086 + } + goto tr148 + st4625: + if p++; p == pe { + goto _test_eof4625 + } + st_case_4625: + switch { + case data[p] > 146: + if 147 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 143: + goto tr4086 + } + goto tr2985 + st4626: + if p++; p == pe { + goto _test_eof4626 + } + st_case_4626: + switch data[p] { + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st4627 + } + goto tr2985 + st4627: + if p++; p == pe { + goto _test_eof4627 + } + st_case_4627: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr4086 + } + case data[p] >= 157: + goto tr4086 + } + default: + goto tr148 + } + goto tr2985 + st4628: + if p++; p == pe { + goto _test_eof4628 + } + st_case_4628: + switch data[p] { + case 133: + goto st4629 + case 134: + goto st4630 + case 137: + goto st4631 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st721 + case 168: + goto st4632 + case 169: + goto st4633 + case 170: + goto st4634 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr2985 + st4629: + if p++; p == pe { + goto _test_eof4629 + } + st_case_4629: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr4086 + } + case data[p] >= 165: + goto tr4086 + } + goto tr2985 + st4630: + if p++; p == pe { + goto _test_eof4630 + } + st_case_4630: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr2985 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr2985 + } + default: + goto tr2985 + } + goto tr4086 + st4631: + if p++; p == pe { + goto _test_eof4631 + } + st_case_4631: + if 130 <= data[p] && data[p] <= 132 { + goto tr4086 + } + goto tr2985 + st4632: + if p++; p == pe { + goto _test_eof4632 + } + st_case_4632: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr4086 + } + case data[p] >= 128: + goto tr4086 + } + goto tr2985 + st4633: + if p++; p == pe { + goto _test_eof4633 + } + st_case_4633: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr2985 + } + case data[p] >= 173: + goto tr2985 + } + goto tr4086 + st4634: + if p++; p == pe { + goto _test_eof4634 + } + st_case_4634: + if data[p] == 132 { + goto tr4086 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr4086 + } + case data[p] >= 155: + goto tr4086 + } + goto tr2985 + st4635: + if p++; p == pe { + goto _test_eof4635 + } + st_case_4635: + switch data[p] { + case 160: + goto st147 + case 163: + goto st4636 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr2985 + st4636: + if p++; p == pe { + goto _test_eof4636 + } + st_case_4636: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr2985 + } + case data[p] > 150: + if 151 <= data[p] { + goto tr2985 + } + default: + goto tr4086 + } + goto tr148 + st4637: + if p++; p == pe { + goto _test_eof4637 + } + st_case_4637: + if data[p] == 160 { + goto st4638 + } + goto tr2985 + st4638: + if p++; p == pe { + goto _test_eof4638 + } + st_case_4638: + switch data[p] { + case 128: + goto st4639 + case 129: + goto st4640 + case 132: + goto st4497 + case 135: + goto st4642 + } + if 133 <= data[p] && data[p] <= 134 { + goto st4641 + } + goto tr2985 + st4639: + if p++; p == pe { + goto _test_eof4639 + } + st_case_4639: + if data[p] == 129 { + goto tr4086 + } + if 160 <= data[p] { + goto tr4086 + } + goto tr2985 + st4640: + if p++; p == pe { + goto _test_eof4640 + } + st_case_4640: + if 192 <= data[p] { + goto tr2985 + } + goto tr4086 + st4641: + if p++; p == pe { + goto _test_eof4641 + } + st_case_4641: + goto tr4086 + st4642: + if p++; p == pe { + goto _test_eof4642 + } + st_case_4642: + if 176 <= data[p] { + goto tr2985 + } + goto tr4086 + st4643: + if p++; p == pe { + goto _test_eof4643 + } + st_case_4643: + if data[p] <= 127 { + goto tr2984 + } + goto tr4086 + st4644: + if p++; p == pe { + goto _test_eof4644 + } + st_case_4644: + if 176 <= data[p] { + goto tr2984 + } + goto tr4086 + st4645: + if p++; p == pe { + goto _test_eof4645 + } + st_case_4645: + if 131 <= data[p] && data[p] <= 137 { + goto tr4086 + } + goto tr2984 + st4646: + if p++; p == pe { + goto _test_eof4646 + } + st_case_4646: + if data[p] == 191 { + goto tr4086 + } + if 145 <= data[p] && data[p] <= 189 { + goto tr4086 + } + goto tr2984 + st4647: + if p++; p == pe { + goto _test_eof4647 + } + st_case_4647: + if data[p] == 135 { + goto tr4086 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto tr4086 + } + case data[p] >= 129: + goto tr4086 + } + goto tr2984 + st4648: + if p++; p == pe { + goto _test_eof4648 + } + st_case_4648: + if data[p] == 156 { + goto tr4086 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto tr4086 + } + case data[p] >= 128: + goto tr4086 + } + goto tr2984 + st4649: + if p++; p == pe { + goto _test_eof4649 + } + st_case_4649: + if data[p] == 176 { + goto tr4086 + } + if 139 <= data[p] && data[p] <= 159 { + goto tr4086 + } + goto tr2984 + st4650: + if p++; p == pe { + goto _test_eof4650 + } + st_case_4650: + switch { + case data[p] < 159: + if 150 <= data[p] && data[p] <= 157 { + goto tr4086 + } + case data[p] > 164: + switch { + case data[p] > 168: + if 170 <= data[p] && data[p] <= 173 { + goto tr4086 + } + case data[p] >= 167: + goto tr4086 + } + default: + goto tr4086 + } + goto tr2984 + st4651: + if p++; p == pe { + goto _test_eof4651 + } + st_case_4651: + switch data[p] { + case 143: + goto tr4086 + case 145: + goto tr4086 + } + if 176 <= data[p] { + goto tr4086 + } + goto tr2984 + st4652: + if p++; p == pe { + goto _test_eof4652 + } + st_case_4652: + if 139 <= data[p] { + goto tr2984 + } + goto tr4086 + st4653: + if p++; p == pe { + goto _test_eof4653 + } + st_case_4653: + if 166 <= data[p] && data[p] <= 176 { + goto tr4086 + } + goto tr2984 + st4654: + if p++; p == pe { + goto _test_eof4654 + } + st_case_4654: + if 171 <= data[p] && data[p] <= 179 { + goto tr4086 + } + goto tr2984 + st4655: + if p++; p == pe { + goto _test_eof4655 + } + st_case_4655: + switch data[p] { + case 160: + goto tr4214 + case 161: + goto tr4215 + case 163: + goto tr4216 + case 164: + goto tr4217 + case 165: + goto tr4218 + case 167: + goto tr4220 + case 169: + goto tr4221 + case 171: + goto tr4222 + case 173: + goto tr4224 + case 174: + goto tr4225 + case 175: + goto tr4226 + case 176: + goto tr4227 + case 177: + goto tr4228 + case 179: + goto tr4229 + case 180: + goto tr4230 + case 181: + goto tr4231 + case 182: + goto tr4232 + case 183: + goto tr4233 + case 184: + goto tr4234 + case 185: + goto tr4235 + case 186: + goto tr4236 + case 187: + goto tr4237 + case 188: + goto tr4238 + case 189: + goto tr4239 + case 190: + goto tr4240 + case 191: + goto tr4241 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto tr4223 + } + case data[p] >= 166: + goto tr4219 + } + goto tr2984 +tr4214: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5212 + st5212: + if p++; p == pe { + goto _test_eof5212 + } + st_case_5212: +//line segment_words_prod.go:139420 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 155: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 150 <= data[p] && data[p] <= 153 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 163: + switch { + case data[p] < 169: + if 165 <= data[p] && data[p] <= 167 { + goto tr1 + } + case data[p] > 173: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr4215: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5213 + st5213: + if p++; p == pe { + goto _test_eof5213 + } + st_case_5213: +//line segment_words_prod.go:139548 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 153 <= data[p] && data[p] <= 155 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4216: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5214 + st5214: + if p++; p == pe { + goto _test_eof5214 + } + st_case_5214: +//line segment_words_prod.go:139662 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto tr5294 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr5295 + case 205: + goto tr5296 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr5297 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr5298 + case 215: + goto tr5299 + case 216: + goto tr5300 + case 217: + goto tr5301 + case 219: + goto tr5302 + case 220: + goto tr5303 + case 221: + goto tr5304 + case 222: + goto tr5305 + case 223: + goto tr5306 + case 224: + goto tr5307 + case 225: + goto tr5308 + case 226: + goto tr5309 + case 227: + goto tr5310 + case 234: + goto tr5311 + case 237: + goto tr5313 + case 239: + goto tr5314 + case 240: + goto tr5315 + case 243: + goto tr5316 + } + switch { + case data[p] < 163: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto tr4806 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr1 + } + case data[p] >= 235: + goto tr5312 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr5294: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5215 + st5215: + if p++; p == pe { + goto _test_eof5215 + } + st_case_5215: +//line segment_words_prod.go:139785 + switch data[p] { + case 170: + goto tr148 + case 173: + goto tr2984 + case 181: + goto tr148 + case 183: + goto st142 + case 186: + goto tr148 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr5295: +//line segment_words.rl:72 + + endPos = p + + goto st5216 + st5216: + if p++; p == pe { + goto _test_eof5216 + } + st_case_5216: +//line segment_words_prod.go:139852 + switch data[p] { + case 194: + goto tr5317 + case 204: + goto tr5318 + case 205: + goto tr5319 + case 210: + goto tr5320 + case 214: + goto tr5321 + case 215: + goto tr5322 + case 216: + goto tr5323 + case 217: + goto tr5324 + case 219: + goto tr5325 + case 220: + goto tr5326 + case 221: + goto tr5327 + case 222: + goto tr5328 + case 223: + goto tr5329 + case 224: + goto tr5330 + case 225: + goto tr5331 + case 226: + goto tr5332 + case 227: + goto tr5333 + case 234: + goto tr5334 + case 239: + goto tr5335 + case 240: + goto tr5336 + case 243: + goto tr5337 + } + if 128 <= data[p] { + goto tr2984 + } + goto tr4499 +tr5317: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5217 + st5217: + if p++; p == pe { + goto _test_eof5217 + } + st_case_5217: +//line segment_words_prod.go:139917 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 173: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr5318: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5218 + st5218: + if p++; p == pe { + goto _test_eof5218 + } + st_case_5218: +//line segment_words_prod.go:140029 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto tr5294 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr5295 + case 205: + goto tr5296 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr5297 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr5298 + case 215: + goto tr5299 + case 216: + goto tr5300 + case 217: + goto tr5301 + case 219: + goto tr5302 + case 220: + goto tr5303 + case 221: + goto tr5304 + case 222: + goto tr5305 + case 223: + goto tr5306 + case 224: + goto tr5307 + case 225: + goto tr5308 + case 226: + goto tr5309 + case 227: + goto tr5310 + case 234: + goto tr5311 + case 237: + goto tr5313 + case 239: + goto tr5314 + case 240: + goto tr5315 + case 243: + goto tr5316 + } + switch { + case data[p] < 91: + switch { + case data[p] < 48: + if data[p] <= 47 { + goto tr5002 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 59: + goto tr5002 + } + default: + goto tr421 + } + case data[p] > 96: + switch { + case data[p] < 123: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + case data[p] > 127: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto tr5312 + } + case data[p] >= 196: + goto tr4806 + } + default: + goto tr5002 + } + default: + goto tr5002 + } + goto tr1 +tr5296: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5219 + st5219: + if p++; p == pe { + goto _test_eof5219 + } + st_case_5219: +//line segment_words_prod.go:140157 + switch data[p] { + case 181: + goto tr4499 + case 190: + goto tr4499 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 184: + if 176 <= data[p] && data[p] <= 183 { + goto tr148 + } + case data[p] > 185: + switch { + case data[p] > 191: + if 192 <= data[p] { + goto tr4499 + } + case data[p] >= 186: + goto tr148 + } + default: + goto tr4499 + } + goto tr2984 +tr5297: +//line segment_words.rl:72 + + endPos = p + + goto st5220 + st5220: + if p++; p == pe { + goto _test_eof5220 + } + st_case_5220: +//line segment_words_prod.go:140235 + switch data[p] { + case 130: + goto tr4499 + case 194: + goto tr4783 + case 204: + goto tr4784 + case 205: + goto tr4785 + case 210: + goto tr4786 + case 214: + goto tr4787 + case 215: + goto tr4788 + case 216: + goto tr4789 + case 217: + goto tr4790 + case 219: + goto tr4791 + case 220: + goto tr4792 + case 221: + goto tr4793 + case 222: + goto tr4794 + case 223: + goto tr4795 + case 224: + goto tr4796 + case 225: + goto tr4797 + case 226: + goto tr4798 + case 227: + goto tr4799 + case 234: + goto tr4800 + case 239: + goto tr4801 + case 240: + goto tr4802 + case 243: + goto tr4803 + } + if 131 <= data[p] && data[p] <= 137 { + goto tr2984 + } + goto tr148 +tr5298: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5221 + st5221: + if p++; p == pe { + goto _test_eof5221 + } + st_case_5221: +//line segment_words_prod.go:140302 + switch data[p] { + case 190: + goto tr4499 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 145: + if 136 <= data[p] && data[p] <= 144 { + goto tr4499 + } + case data[p] > 191: + if 192 <= data[p] { + goto tr4499 + } + default: + goto tr2984 + } + goto tr148 +tr5299: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5222 + st5222: + if p++; p == pe { + goto _test_eof5222 + } + st_case_5222: +//line segment_words_prod.go:140378 + switch data[p] { + case 135: + goto tr2984 + case 179: + goto tr148 + case 180: + goto st142 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 132: + if 129 <= data[p] && data[p] <= 130 { + goto tr2984 + } + case data[p] > 133: + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 178 { + goto tr572 + } + case data[p] >= 144: + goto tr572 + } + default: + goto tr2984 + } + goto tr4499 +tr5300: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5223 + st5223: + if p++; p == pe { + goto _test_eof5223 + } + st_case_5223: +//line segment_words_prod.go:140463 + switch data[p] { + case 156: + goto tr2984 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 133 { + goto tr2984 + } + case data[p] > 154: + if 160 <= data[p] && data[p] <= 191 { + goto tr148 + } + default: + goto tr2984 + } + goto tr4499 +tr5301: +//line segment_words.rl:72 + + endPos = p + + goto st5224 + st5224: + if p++; p == pe { + goto _test_eof5224 + } + st_case_5224: +//line segment_words_prod.go:140534 + switch data[p] { + case 171: + goto tr421 + case 176: + goto tr2984 + case 194: + goto tr4783 + case 204: + goto tr4784 + case 205: + goto tr4785 + case 210: + goto tr4786 + case 214: + goto tr4787 + case 215: + goto tr4788 + case 216: + goto tr4789 + case 217: + goto tr4790 + case 219: + goto tr4791 + case 220: + goto tr4792 + case 221: + goto tr4793 + case 222: + goto tr4794 + case 223: + goto tr4795 + case 224: + goto tr4796 + case 225: + goto tr4797 + case 226: + goto tr4798 + case 227: + goto tr4799 + case 234: + goto tr4800 + case 239: + goto tr4801 + case 240: + goto tr4802 + case 243: + goto tr4803 + } + switch { + case data[p] < 139: + if 128 <= data[p] && data[p] <= 138 { + goto tr148 + } + case data[p] > 159: + switch { + case data[p] > 169: + if 174 <= data[p] { + goto tr148 + } + case data[p] >= 160: + goto tr421 + } + default: + goto tr2984 + } + goto tr4499 +tr5302: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5225 + st5225: + if p++; p == pe { + goto _test_eof5225 + } + st_case_5225: +//line segment_words_prod.go:140617 + switch data[p] { + case 148: + goto tr4499 + case 158: + goto tr4499 + case 169: + goto tr4499 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 176: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr2984 + } + case data[p] >= 150: + goto tr2984 + } + case data[p] > 185: + switch { + case data[p] > 190: + if 192 <= data[p] { + goto tr4499 + } + case data[p] >= 189: + goto tr4499 + } + default: + goto tr421 + } + goto tr148 +tr5303: +//line segment_words.rl:72 + + endPos = p + + goto st5226 + st5226: + if p++; p == pe { + goto _test_eof5226 + } + st_case_5226: +//line segment_words_prod.go:140702 + switch data[p] { + case 144: + goto tr148 + case 194: + goto tr5317 + case 204: + goto tr5318 + case 205: + goto tr5319 + case 210: + goto tr5320 + case 214: + goto tr5321 + case 215: + goto tr5322 + case 216: + goto tr5323 + case 217: + goto tr5324 + case 219: + goto tr5325 + case 220: + goto tr5326 + case 221: + goto tr5327 + case 222: + goto tr5328 + case 223: + goto tr5329 + case 224: + goto tr5330 + case 225: + goto tr5331 + case 226: + goto tr5332 + case 227: + goto tr5333 + case 234: + goto tr5334 + case 239: + goto tr5335 + case 240: + goto tr5336 + case 243: + goto tr5337 + } + switch { + case data[p] < 146: + if 143 <= data[p] && data[p] <= 145 { + goto tr2984 + } + case data[p] > 175: + if 176 <= data[p] { + goto tr2984 + } + default: + goto tr148 + } + goto tr4499 +tr5319: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5227 + st5227: + if p++; p == pe { + goto _test_eof5227 + } + st_case_5227: +//line segment_words_prod.go:140778 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 176: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr2646 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto st145 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr5002 + } + case data[p] >= 235: + goto st3516 + } + default: + goto tr5002 + } + default: + goto tr5002 + } + goto tr1 +tr5320: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5228 + st5228: + if p++; p == pe { + goto _test_eof5228 + } + st_case_5228: +//line segment_words_prod.go:140901 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 131 <= data[p] && data[p] <= 137 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr5321: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5229 + st5229: + if p++; p == pe { + goto _test_eof5229 + } + st_case_5229: +//line segment_words_prod.go:141015 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 191: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 145 <= data[p] && data[p] <= 189 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr5322: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5230 + st5230: + if p++; p == pe { + goto _test_eof5230 + } + st_case_5230: +//line segment_words_prod.go:141131 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 135: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 129: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 130: + switch { + case data[p] < 196: + if 132 <= data[p] && data[p] <= 133 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 +tr5323: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5231 + st5231: + if p++; p == pe { + goto _test_eof5231 + } + st_case_5231: +//line segment_words_prod.go:141251 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 156: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 128: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 133: + switch { + case data[p] < 196: + if 144 <= data[p] && data[p] <= 154 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 +tr5324: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5232 + st5232: + if p++; p == pe { + goto _test_eof5232 + } + st_case_5232: +//line segment_words_prod.go:141371 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 176: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 139 <= data[p] && data[p] <= 159 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr5325: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5233 + st5233: + if p++; p == pe { + goto _test_eof5233 + } + st_case_5233: +//line segment_words_prod.go:141487 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 159: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 150 <= data[p] && data[p] <= 157 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 164: + switch { + case data[p] < 170: + if 167 <= data[p] && data[p] <= 168 { + goto tr1 + } + case data[p] > 173: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr5326: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5234 + st5234: + if p++; p == pe { + goto _test_eof5234 + } + st_case_5234: +//line segment_words_prod.go:141615 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 143: + goto tr1 + case 145: + goto tr1 + case 194: + goto tr5294 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr5295 + case 205: + goto tr5296 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr5297 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr5298 + case 215: + goto tr5299 + case 216: + goto tr5300 + case 217: + goto tr5301 + case 219: + goto tr5302 + case 220: + goto tr5303 + case 221: + goto tr5304 + case 222: + goto tr5305 + case 223: + goto tr5306 + case 224: + goto tr5307 + case 225: + goto tr5308 + case 226: + goto tr5309 + case 227: + goto tr5310 + case 234: + goto tr5311 + case 237: + goto tr5313 + case 239: + goto tr5314 + case 240: + goto tr5315 + case 243: + goto tr5316 + } + switch { + case data[p] < 176: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto tr4806 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr1 + } + case data[p] >= 235: + goto tr5312 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr5304: +//line segment_words.rl:72 + + endPos = p + + goto st5235 + st5235: + if p++; p == pe { + goto _test_eof5235 + } + st_case_5235: +//line segment_words_prod.go:141737 + switch data[p] { + case 194: + goto tr4783 + case 204: + goto tr4784 + case 205: + goto tr4785 + case 210: + goto tr4786 + case 214: + goto tr4787 + case 215: + goto tr4788 + case 216: + goto tr4789 + case 217: + goto tr4790 + case 219: + goto tr4791 + case 220: + goto tr4792 + case 221: + goto tr4793 + case 222: + goto tr4794 + case 223: + goto tr4795 + case 224: + goto tr4796 + case 225: + goto tr4797 + case 226: + goto tr4798 + case 227: + goto tr4799 + case 234: + goto tr4800 + case 239: + goto tr4801 + case 240: + goto tr4802 + case 243: + goto tr4803 + } + switch { + case data[p] > 140: + if 141 <= data[p] { + goto tr148 + } + case data[p] >= 139: + goto tr4499 + } + goto tr2984 +tr5305: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5236 + st5236: + if p++; p == pe { + goto _test_eof5236 + } + st_case_5236: +//line segment_words_prod.go:141807 + switch data[p] { + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] > 176: + if 178 <= data[p] { + goto tr4499 + } + case data[p] >= 166: + goto tr2984 + } + goto tr148 +tr5306: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5237 + st5237: + if p++; p == pe { + goto _test_eof5237 + } + st_case_5237: +//line segment_words_prod.go:141877 + switch data[p] { + case 186: + goto tr148 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 138: + if 128 <= data[p] && data[p] <= 137 { + goto tr421 + } + case data[p] > 170: + switch { + case data[p] > 179: + if 180 <= data[p] && data[p] <= 181 { + goto tr148 + } + case data[p] >= 171: + goto tr2984 + } + default: + goto tr148 + } + goto tr4499 +tr5307: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5238 + st5238: + if p++; p == pe { + goto _test_eof5238 + } + st_case_5238: +//line segment_words_prod.go:141958 + switch data[p] { + case 160: + goto st3283 + case 161: + goto st3284 + case 162: + goto st168 + case 163: + goto st3285 + case 164: + goto st3286 + case 165: + goto st3287 + case 166: + goto st3288 + case 167: + goto st3289 + case 168: + goto st3290 + case 169: + goto st3291 + case 170: + goto st3292 + case 171: + goto st3293 + case 172: + goto st3294 + case 173: + goto st3295 + case 174: + goto st3296 + case 175: + goto st3297 + case 176: + goto st3298 + case 177: + goto st3299 + case 178: + goto st3300 + case 179: + goto st3301 + case 180: + goto st3302 + case 181: + goto st3303 + case 182: + goto st3304 + case 183: + goto st3305 + case 184: + goto st3306 + case 185: + goto st3307 + case 186: + goto st3308 + case 187: + goto st3309 + case 188: + goto st3310 + case 189: + goto st3311 + case 190: + goto st3312 + case 191: + goto st3313 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr5308: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5239 + st5239: + if p++; p == pe { + goto _test_eof5239 + } + st_case_5239: +//line segment_words_prod.go:142084 + switch data[p] { + case 128: + goto st3315 + case 129: + goto st3316 + case 130: + goto st3317 + case 131: + goto st202 + case 132: + goto st3268 + case 135: + goto st3319 + case 137: + goto st203 + case 138: + goto st204 + case 139: + goto st205 + case 140: + goto st206 + case 141: + goto st3320 + case 142: + goto st208 + case 143: + goto st209 + case 144: + goto st210 + case 153: + goto st211 + case 154: + goto st212 + case 155: + goto st213 + case 156: + goto st3321 + case 157: + goto st3322 + case 158: + goto st3323 + case 159: + goto st3324 + case 160: + goto st3325 + case 161: + goto st219 + case 162: + goto st3326 + case 163: + goto st221 + case 164: + goto st3327 + case 165: + goto st468 + case 167: + goto st469 + case 168: + goto st3328 + case 169: + goto st3329 + case 170: + goto st3330 + case 172: + goto st3331 + case 173: + goto st3332 + case 174: + goto st3333 + case 175: + goto st3334 + case 176: + goto st3335 + case 177: + goto st640 + case 179: + goto st3336 + case 181: + goto st145 + case 182: + goto st146 + case 183: + goto st3337 + case 188: + goto st234 + case 189: + goto st235 + case 190: + goto st236 + case 191: + goto st237 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] < 136: + if 133 <= data[p] && data[p] <= 134 { + goto st3318 + } + case data[p] > 152: + switch { + case data[p] > 184: + if 185 <= data[p] && data[p] <= 187 { + goto st145 + } + case data[p] >= 180: + goto st147 + } + default: + goto st145 + } + goto tr4499 +tr5309: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5240 + st5240: + if p++; p == pe { + goto _test_eof5240 + } + st_case_5240: +//line segment_words_prod.go:142253 + switch data[p] { + case 128: + goto st3339 + case 129: + goto st3340 + case 130: + goto st241 + case 131: + goto st3341 + case 132: + goto st243 + case 133: + goto st244 + case 134: + goto st245 + case 146: + goto st246 + case 147: + goto st247 + case 176: + goto st248 + case 177: + goto st249 + case 178: + goto st145 + case 179: + goto st3342 + case 180: + goto st251 + case 181: + goto st3343 + case 182: + goto st253 + case 183: + goto st3344 + case 184: + goto st255 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr5310: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5241 + st5241: + if p++; p == pe { + goto _test_eof5241 + } + st_case_5241: +//line segment_words_prod.go:142351 + switch data[p] { + case 128: + goto st3346 + case 130: + goto st3347 + case 132: + goto st3348 + case 133: + goto st3318 + case 134: + goto st3349 + case 136: + goto st3350 + case 137: + goto st3429 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr5311: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5242 + st5242: + if p++; p == pe { + goto _test_eof5242 + } + st_case_5242: +//line segment_words_prod.go:142427 + switch data[p] { + case 128: + goto st147 + case 146: + goto st262 + case 147: + goto st263 + case 148: + goto st147 + case 152: + goto st654 + case 153: + goto st3501 + case 154: + goto st3502 + case 155: + goto st3503 + case 156: + goto st268 + case 158: + goto st269 + case 159: + goto st270 + case 160: + goto st3504 + case 161: + goto st272 + case 162: + goto st3505 + case 163: + goto st3506 + case 164: + goto st3507 + case 165: + goto st3508 + case 166: + goto st3509 + case 167: + goto st3510 + case 168: + goto st3511 + case 169: + goto st3512 + case 170: + goto st3513 + case 171: + goto st3514 + case 172: + goto st283 + case 173: + goto st284 + case 174: + goto st146 + case 175: + goto st3515 + case 176: + goto st3270 + case 194: + goto st4495 + case 204: + goto st4643 + case 205: + goto st4644 + case 210: + goto st4645 + case 214: + goto st4646 + case 215: + goto st4647 + case 216: + goto st4648 + case 217: + goto st4649 + case 219: + goto st4650 + case 220: + goto st4651 + case 221: + goto st4652 + case 222: + goto st4653 + case 223: + goto st4654 + case 224: + goto st4655 + case 225: + goto st4656 + case 226: + goto st4657 + case 227: + goto st4658 + case 234: + goto st4659 + case 239: + goto st4660 + case 240: + goto st4661 + case 243: + goto st4662 + } + switch { + case data[p] > 157: + if 177 <= data[p] { + goto st3318 + } + case data[p] >= 129: + goto st145 + } + goto tr4499 + st4656: + if p++; p == pe { + goto _test_eof4656 + } + st_case_4656: + switch data[p] { + case 128: + goto tr4242 + case 129: + goto tr4243 + case 130: + goto tr4244 + case 141: + goto tr4245 + case 156: + goto tr4246 + case 157: + goto tr4247 + case 158: + goto tr4248 + case 159: + goto tr4249 + case 160: + goto tr4250 + case 162: + goto tr4251 + case 164: + goto tr4252 + case 168: + goto tr4253 + case 169: + goto tr4254 + case 170: + goto tr4255 + case 172: + goto tr4256 + case 173: + goto tr4257 + case 174: + goto tr4258 + case 175: + goto tr4259 + case 176: + goto tr4260 + case 179: + goto tr4261 + case 183: + goto tr4262 + } + goto tr2984 +tr4242: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5243 + st5243: + if p++; p == pe { + goto _test_eof5243 + } + st_case_5243: +//line segment_words_prod.go:142603 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 171 <= data[p] && data[p] <= 190 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4243: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5244 + st5244: + if p++; p == pe { + goto _test_eof5244 + } + st_case_5244: +//line segment_words_prod.go:142717 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 158: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 150 <= data[p] && data[p] <= 153 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 160: + switch { + case data[p] < 177: + switch { + case data[p] > 164: + if 167 <= data[p] && data[p] <= 173 { + goto tr1 + } + case data[p] >= 162: + goto tr1 + } + case data[p] > 180: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr4244: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5245 + st5245: + if p++; p == pe { + goto _test_eof5245 + } + st_case_5245: +//line segment_words_prod.go:142850 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 143: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 130: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 141: + switch { + case data[p] < 196: + if 154 <= data[p] && data[p] <= 157 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 +tr4245: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5246 + st5246: + if p++; p == pe { + goto _test_eof5246 + } + st_case_5246: +//line segment_words_prod.go:142970 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 157 <= data[p] && data[p] <= 159 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4246: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5247 + st5247: + if p++; p == pe { + goto _test_eof5247 + } + st_case_5247: +//line segment_words_prod.go:143084 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 146: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] < 196: + if 178 <= data[p] && data[p] <= 180 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 +tr4247: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5248 + st5248: + if p++; p == pe { + goto _test_eof5248 + } + st_case_5248: +//line segment_words_prod.go:143202 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 146: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 147: + switch { + case data[p] < 196: + if 178 <= data[p] && data[p] <= 179 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 +tr4248: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5249 + st5249: + if p++; p == pe { + goto _test_eof5249 + } + st_case_5249: +//line segment_words_prod.go:143320 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto tr5294 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr5295 + case 205: + goto tr5296 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr5297 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr5298 + case 215: + goto tr5299 + case 216: + goto tr5300 + case 217: + goto tr5301 + case 219: + goto tr5302 + case 220: + goto tr5303 + case 221: + goto tr5304 + case 222: + goto tr5305 + case 223: + goto tr5306 + case 224: + goto tr5307 + case 225: + goto tr5308 + case 226: + goto tr5309 + case 227: + goto tr5310 + case 234: + goto tr5311 + case 237: + goto tr5313 + case 239: + goto tr5314 + case 240: + goto tr5315 + case 243: + goto tr5316 + } + switch { + case data[p] < 180: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto tr4806 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr1 + } + case data[p] >= 235: + goto tr5312 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr5312: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5250 +tr4494: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5250 + st5250: + if p++; p == pe { + goto _test_eof5250 + } + st_case_5250: +//line segment_words_prod.go:143458 + switch data[p] { + case 194: + goto st4495 + case 204: + goto st4643 + case 205: + goto st4644 + case 210: + goto st4645 + case 214: + goto st4646 + case 215: + goto st4647 + case 216: + goto st4648 + case 217: + goto st4649 + case 219: + goto st4650 + case 220: + goto st4651 + case 221: + goto st4652 + case 222: + goto st4653 + case 223: + goto st4654 + case 224: + goto st4655 + case 225: + goto st4656 + case 226: + goto st4657 + case 227: + goto st4658 + case 234: + goto st4659 + case 239: + goto st4660 + case 240: + goto st4661 + case 243: + goto st4662 + } + goto st3318 + st4657: + if p++; p == pe { + goto _test_eof4657 + } + st_case_4657: + switch data[p] { + case 128: + goto tr4263 + case 129: + goto tr4264 + case 131: + goto tr4265 + case 179: + goto tr4266 + case 181: + goto tr4267 + case 183: + goto tr4268 + } + goto tr2984 +tr4263: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5251 + st5251: + if p++; p == pe { + goto _test_eof5251 + } + st_case_5251: +//line segment_words_prod.go:143540 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 140: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] < 196: + if 170 <= data[p] && data[p] <= 174 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 +tr4264: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5252 + st5252: + if p++; p == pe { + goto _test_eof5252 + } + st_case_5252: +//line segment_words_prod.go:143658 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 160: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 164: + switch { + case data[p] < 196: + if 166 <= data[p] && data[p] <= 175 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 +tr4265: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5253 + st5253: + if p++; p == pe { + goto _test_eof5253 + } + st_case_5253: +//line segment_words_prod.go:143776 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 144 <= data[p] && data[p] <= 176 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4266: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5254 + st5254: + if p++; p == pe { + goto _test_eof5254 + } + st_case_5254: +//line segment_words_prod.go:143890 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 175 <= data[p] && data[p] <= 177 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4267: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5255 + st5255: + if p++; p == pe { + goto _test_eof5255 + } + st_case_5255: +//line segment_words_prod.go:144004 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 191: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4268: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5256 + st5256: + if p++; p == pe { + goto _test_eof5256 + } + st_case_5256: +//line segment_words_prod.go:144116 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 160 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 + st4658: + if p++; p == pe { + goto _test_eof4658 + } + st_case_4658: + switch data[p] { + case 128: + goto tr4269 + case 130: + goto tr4270 + } + goto tr2984 +tr4269: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5257 + st5257: + if p++; p == pe { + goto _test_eof5257 + } + st_case_5257: +//line segment_words_prod.go:144242 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 170 <= data[p] && data[p] <= 175 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4270: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5258 + st5258: + if p++; p == pe { + goto _test_eof5258 + } + st_case_5258: +//line segment_words_prod.go:144356 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 153 <= data[p] && data[p] <= 154 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 + st4659: + if p++; p == pe { + goto _test_eof4659 + } + st_case_4659: + switch data[p] { + case 153: + goto tr4271 + case 154: + goto tr4272 + case 155: + goto tr4273 + case 160: + goto tr4274 + case 162: + goto tr4275 + case 163: + goto tr4276 + case 164: + goto tr4277 + case 165: + goto tr4278 + case 166: + goto tr4279 + case 167: + goto tr4280 + case 168: + goto tr4281 + case 169: + goto tr4282 + case 170: + goto tr4283 + case 171: + goto tr4284 + case 175: + goto tr4285 + } + goto tr2984 +tr4271: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5259 + st5259: + if p++; p == pe { + goto _test_eof5259 + } + st_case_5259: +//line segment_words_prod.go:144508 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 175: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 178: + switch { + case data[p] < 196: + if 180 <= data[p] && data[p] <= 189 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 +tr4272: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5260 + st5260: + if p++; p == pe { + goto _test_eof5260 + } + st_case_5260: +//line segment_words_prod.go:144626 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 158 <= data[p] && data[p] <= 159 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4273: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5261 + st5261: + if p++; p == pe { + goto _test_eof5261 + } + st_case_5261: +//line segment_words_prod.go:144740 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 176 <= data[p] && data[p] <= 177 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4274: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5262 + st5262: + if p++; p == pe { + goto _test_eof5262 + } + st_case_5262: +//line segment_words_prod.go:144854 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 130: + goto tr1 + case 134: + goto tr1 + case 139: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 163 <= data[p] && data[p] <= 167 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4275: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5263 + st5263: + if p++; p == pe { + goto _test_eof5263 + } + st_case_5263: +//line segment_words_prod.go:144974 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto tr5294 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr5295 + case 205: + goto tr5296 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr5297 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr5298 + case 215: + goto tr5299 + case 216: + goto tr5300 + case 217: + goto tr5301 + case 219: + goto tr5302 + case 220: + goto tr5303 + case 221: + goto tr5304 + case 222: + goto tr5305 + case 223: + goto tr5306 + case 224: + goto tr5307 + case 225: + goto tr5308 + case 226: + goto tr5309 + case 227: + goto tr5310 + case 234: + goto tr5311 + case 237: + goto tr5313 + case 239: + goto tr5314 + case 240: + goto tr5315 + case 243: + goto tr5316 + } + switch { + case data[p] < 180: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 128 <= data[p] && data[p] <= 129 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto tr4806 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr1 + } + case data[p] >= 235: + goto tr5312 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr5313: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5264 +tr4495: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5264 + st5264: + if p++; p == pe { + goto _test_eof5264 + } + st_case_5264: +//line segment_words_prod.go:145117 + switch data[p] { + case 158: + goto st3518 + case 159: + goto st3519 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 160 <= data[p] { + goto tr4499 + } + goto st3318 +tr5314: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5265 + st5265: + if p++; p == pe { + goto _test_eof5265 + } + st_case_5265: +//line segment_words_prod.go:145186 + switch data[p] { + case 172: + goto st3521 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st3522 + case 185: + goto st967 + case 187: + goto st3523 + case 188: + goto st969 + case 189: + goto st303 + case 190: + goto st3524 + case 191: + goto st3525 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + goto tr4499 +tr5315: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5266 + st5266: + if p++; p == pe { + goto _test_eof5266 + } + st_case_5266: +//line segment_words_prod.go:145281 + switch data[p] { + case 144: + goto st3527 + case 145: + goto st3533 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st3552 + case 155: + goto st3557 + case 157: + goto st3559 + case 158: + goto st3566 + case 159: + goto st403 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr5316: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5267 + st5267: + if p++; p == pe { + goto _test_eof5267 + } + st_case_5267: +//line segment_words_prod.go:145363 + switch data[p] { + case 160: + goto st3569 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + goto tr4499 +tr4276: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5268 + st5268: + if p++; p == pe { + goto _test_eof5268 + } + st_case_5268: +//line segment_words_prod.go:145427 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 178: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr2646 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 133 <= data[p] && data[p] <= 159 { + goto tr5002 + } + case data[p] >= 97: + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto st145 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr5002 + } + case data[p] >= 235: + goto st3516 + } + default: + goto tr5002 + } + default: + goto tr5002 + } + goto tr1 +tr4277: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5269 + st5269: + if p++; p == pe { + goto _test_eof5269 + } + st_case_5269: +//line segment_words_prod.go:145555 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 166 <= data[p] && data[p] <= 173 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4278: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5270 + st5270: + if p++; p == pe { + goto _test_eof5270 + } + st_case_5270: +//line segment_words_prod.go:145669 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 135 <= data[p] && data[p] <= 147 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4279: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5271 + st5271: + if p++; p == pe { + goto _test_eof5271 + } + st_case_5271: +//line segment_words_prod.go:145783 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto tr5294 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr5295 + case 205: + goto tr5296 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr5297 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr5298 + case 215: + goto tr5299 + case 216: + goto tr5300 + case 217: + goto tr5301 + case 219: + goto tr5302 + case 220: + goto tr5303 + case 221: + goto tr5304 + case 222: + goto tr5305 + case 223: + goto tr5306 + case 224: + goto tr5307 + case 225: + goto tr5308 + case 226: + goto tr5309 + case 227: + goto tr5310 + case 234: + goto tr5311 + case 237: + goto tr5313 + case 239: + goto tr5314 + case 240: + goto tr5315 + case 243: + goto tr5316 + } + switch { + case data[p] < 179: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 128 <= data[p] && data[p] <= 131 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto tr4806 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr1 + } + case data[p] >= 235: + goto tr5312 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr4280: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5272 + st5272: + if p++; p == pe { + goto _test_eof5272 + } + st_case_5272: +//line segment_words_prod.go:145911 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 165: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 91: + switch { + case data[p] < 48: + if data[p] <= 47 { + goto tr1 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 90 { + goto tr2008 + } + case data[p] >= 59: + goto tr1 + } + default: + goto tr2646 + } + case data[p] > 96: + switch { + case data[p] < 123: + if 97 <= data[p] && data[p] <= 122 { + goto tr2008 + } + case data[p] > 128: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr4281: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5273 + st5273: + if p++; p == pe { + goto _test_eof5273 + } + st_case_5273: +//line segment_words_prod.go:146041 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 169 <= data[p] && data[p] <= 182 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4282: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5274 + st5274: + if p++; p == pe { + goto _test_eof5274 + } + st_case_5274: +//line segment_words_prod.go:146155 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 131: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 140: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 141: + switch { + case data[p] < 196: + if 187 <= data[p] && data[p] <= 189 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 +tr4283: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5275 + st5275: + if p++; p == pe { + goto _test_eof5275 + } + st_case_5275: +//line segment_words_prod.go:146275 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 176: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 178: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 180: + switch { + case data[p] < 190: + if 183 <= data[p] && data[p] <= 184 { + goto tr1 + } + case data[p] > 191: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr4284: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5276 + st5276: + if p++; p == pe { + goto _test_eof5276 + } + st_case_5276: +//line segment_words_prod.go:146400 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 129: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 171: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 175: + switch { + case data[p] < 196: + if 181 <= data[p] && data[p] <= 182 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 +tr4285: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5277 + st5277: + if p++; p == pe { + goto _test_eof5277 + } + st_case_5277: +//line segment_words_prod.go:146520 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 163: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 170: + switch { + case data[p] < 196: + if 172 <= data[p] && data[p] <= 173 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 + st4660: + if p++; p == pe { + goto _test_eof4660 + } + st_case_4660: + switch data[p] { + case 172: + goto tr4286 + case 184: + goto tr4287 + case 187: + goto tr4267 + case 190: + goto tr4272 + case 191: + goto tr4288 + } + goto tr2984 +tr4286: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5278 + st5278: + if p++; p == pe { + goto _test_eof5278 + } + st_case_5278: +//line segment_words_prod.go:146656 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 158: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4287: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5279 + st5279: + if p++; p == pe { + goto _test_eof5279 + } + st_case_5279: +//line segment_words_prod.go:146768 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 128: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] < 196: + if 160 <= data[p] && data[p] <= 175 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 +tr4288: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5280 + st5280: + if p++; p == pe { + goto _test_eof5280 + } + st_case_5280: +//line segment_words_prod.go:146886 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 185 <= data[p] && data[p] <= 187 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 + st4661: + if p++; p == pe { + goto _test_eof4661 + } + st_case_4661: + switch data[p] { + case 144: + goto tr4289 + case 145: + goto tr4290 + case 150: + goto tr4291 + case 155: + goto tr4292 + case 157: + goto tr4293 + case 158: + goto tr4294 + } + goto tr2984 +tr4289: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5281 + st5281: + if p++; p == pe { + goto _test_eof5281 + } + st_case_5281: +//line segment_words_prod.go:147020 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 135: + goto st96 + case 139: + goto st97 + case 141: + goto st98 + case 168: + goto st99 + case 171: + goto st100 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4290: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5282 + st5282: + if p++; p == pe { + goto _test_eof5282 + } + st_case_5282: +//line segment_words_prod.go:147140 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 128: + goto st102 + case 129: + goto st103 + case 130: + goto st104 + case 132: + goto st105 + case 133: + goto st106 + case 134: + goto st107 + case 135: + goto st108 + case 136: + goto st109 + case 139: + goto st110 + case 140: + goto st111 + case 141: + goto st112 + case 146: + goto st113 + case 147: + goto st114 + case 150: + goto st115 + case 151: + goto st116 + case 152: + goto st113 + case 153: + goto st117 + case 154: + goto st118 + case 156: + goto st119 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4291: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5283 + st5283: + if p++; p == pe { + goto _test_eof5283 + } + st_case_5283: +//line segment_words_prod.go:147288 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 171: + goto st121 + case 172: + goto st122 + case 189: + goto st123 + case 190: + goto st124 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4292: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5284 + st5284: + if p++; p == pe { + goto _test_eof5284 + } + st_case_5284: +//line segment_words_prod.go:147406 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 178: + goto st126 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4293: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5285 + st5285: + if p++; p == pe { + goto _test_eof5285 + } + st_case_5285: +//line segment_words_prod.go:147518 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 133: + goto st128 + case 134: + goto st129 + case 137: + goto st130 + case 168: + goto st131 + case 169: + goto st132 + case 170: + goto st133 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4294: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5286 + st5286: + if p++; p == pe { + goto _test_eof5286 + } + st_case_5286: +//line segment_words_prod.go:147640 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 163: + goto st135 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 + st4662: + if p++; p == pe { + goto _test_eof4662 + } + st_case_4662: + if data[p] == 160 { + goto tr4295 + } + goto tr2984 +tr4295: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5287 + st5287: + if p++; p == pe { + goto _test_eof5287 + } + st_case_5287: +//line segment_words_prod.go:147761 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 128: + goto st138 + case 129: + goto st139 + case 132: + goto st1 + case 135: + goto st2 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 133 <= data[p] && data[p] <= 134 { + goto st140 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4249: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5288 + st5288: + if p++; p == pe { + goto _test_eof5288 + } + st_case_5288: +//line segment_words_prod.go:147883 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 158: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr2646 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 148 <= data[p] && data[p] <= 156 { + goto tr5002 + } + case data[p] >= 97: + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto st145 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr5002 + } + case data[p] >= 235: + goto st3516 + } + default: + goto tr5002 + } + default: + goto tr5002 + } + goto tr1 +tr4250: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5289 + st5289: + if p++; p == pe { + goto _test_eof5289 + } + st_case_5289: +//line segment_words_prod.go:148011 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 139 <= data[p] && data[p] <= 142 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4251: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5290 + st5290: + if p++; p == pe { + goto _test_eof5290 + } + st_case_5290: +//line segment_words_prod.go:148125 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 169: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4252: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5291 + st5291: + if p++; p == pe { + goto _test_eof5291 + } + st_case_5291: +//line segment_words_prod.go:148237 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 160: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 171: + switch { + case data[p] < 196: + if 176 <= data[p] && data[p] <= 187 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 +tr4253: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5292 + st5292: + if p++; p == pe { + goto _test_eof5292 + } + st_case_5292: +//line segment_words_prod.go:148355 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 151 <= data[p] && data[p] <= 155 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4254: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5293 + st5293: + if p++; p == pe { + goto _test_eof5293 + } + st_case_5293: +//line segment_words_prod.go:148469 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 191: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 149: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 158: + switch { + case data[p] < 196: + if 160 <= data[p] && data[p] <= 188 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 +tr4255: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5294 + st5294: + if p++; p == pe { + goto _test_eof5294 + } + st_case_5294: +//line segment_words_prod.go:148589 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 176 <= data[p] && data[p] <= 190 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4256: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5295 + st5295: + if p++; p == pe { + goto _test_eof5295 + } + st_case_5295: +//line segment_words_prod.go:148703 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto tr5294 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr5295 + case 205: + goto tr5296 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr5297 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr5298 + case 215: + goto tr5299 + case 216: + goto tr5300 + case 217: + goto tr5301 + case 219: + goto tr5302 + case 220: + goto tr5303 + case 221: + goto tr5304 + case 222: + goto tr5305 + case 223: + goto tr5306 + case 224: + goto tr5307 + case 225: + goto tr5308 + case 226: + goto tr5309 + case 227: + goto tr5310 + case 234: + goto tr5311 + case 237: + goto tr5313 + case 239: + goto tr5314 + case 240: + goto tr5315 + case 243: + goto tr5316 + } + switch { + case data[p] < 180: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 128 <= data[p] && data[p] <= 132 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto tr4806 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr1 + } + case data[p] >= 235: + goto tr5312 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr4257: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5296 + st5296: + if p++; p == pe { + goto _test_eof5296 + } + st_case_5296: +//line segment_words_prod.go:148831 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 180: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr2646 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 133 <= data[p] && data[p] <= 170 { + goto tr5002 + } + case data[p] >= 97: + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto st145 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr5002 + } + case data[p] >= 235: + goto st3516 + } + default: + goto tr5002 + } + default: + goto tr5002 + } + goto tr1 +tr4258: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5297 + st5297: + if p++; p == pe { + goto _test_eof5297 + } + st_case_5297: +//line segment_words_prod.go:148959 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 128: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 130: + switch { + case data[p] < 196: + if 161 <= data[p] && data[p] <= 173 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 +tr4259: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5298 + st5298: + if p++; p == pe { + goto _test_eof5298 + } + st_case_5298: +//line segment_words_prod.go:149077 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 166 <= data[p] && data[p] <= 179 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4260: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5299 + st5299: + if p++; p == pe { + goto _test_eof5299 + } + st_case_5299: +//line segment_words_prod.go:149191 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 164 <= data[p] && data[p] <= 183 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4261: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5300 + st5300: + if p++; p == pe { + goto _test_eof5300 + } + st_case_5300: +//line segment_words_prod.go:149305 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 173: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 148: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 144 <= data[p] && data[p] <= 146 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 184: + if 178 <= data[p] && data[p] <= 180 { + goto tr1 + } + case data[p] > 185: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr4262: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5301 + st5301: + if p++; p == pe { + goto _test_eof5301 + } + st_case_5301: +//line segment_words_prod.go:149435 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 128: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 181: + switch { + case data[p] < 196: + if 188 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 +tr5327: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5302 + st5302: + if p++; p == pe { + goto _test_eof5302 + } + st_case_5302: +//line segment_words_prod.go:149553 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 91: + switch { + case data[p] < 48: + if data[p] <= 47 { + goto tr1 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 90 { + goto tr2008 + } + case data[p] >= 59: + goto tr1 + } + default: + goto tr2646 + } + case data[p] > 96: + switch { + case data[p] < 123: + if 97 <= data[p] && data[p] <= 122 { + goto tr2008 + } + case data[p] > 138: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr5328: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5303 + st5303: + if p++; p == pe { + goto _test_eof5303 + } + st_case_5303: +//line segment_words_prod.go:149681 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 166 <= data[p] && data[p] <= 176 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr5329: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5304 + st5304: + if p++; p == pe { + goto _test_eof5304 + } + st_case_5304: +//line segment_words_prod.go:149795 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 171 <= data[p] && data[p] <= 179 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr5330: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5305 + st5305: + if p++; p == pe { + goto _test_eof5305 + } + st_case_5305: +//line segment_words_prod.go:149909 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 160: + goto st14 + case 161: + goto st15 + case 163: + goto st16 + case 164: + goto st17 + case 165: + goto st18 + case 167: + goto st20 + case 169: + goto st21 + case 171: + goto st22 + case 173: + goto st24 + case 174: + goto st25 + case 175: + goto st26 + case 176: + goto st27 + case 177: + goto st28 + case 179: + goto st29 + case 180: + goto st30 + case 181: + goto st31 + case 182: + goto st32 + case 183: + goto st33 + case 184: + goto st34 + case 185: + goto st35 + case 186: + goto st36 + case 187: + goto st37 + case 188: + goto st38 + case 189: + goto st39 + case 190: + goto st40 + case 191: + goto st41 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 166: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 170: + switch { + case data[p] < 196: + if 172 <= data[p] && data[p] <= 178 { + goto st23 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto st19 + } + goto tr5002 +tr5331: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5306 + st5306: + if p++; p == pe { + goto _test_eof5306 + } + st_case_5306: +//line segment_words_prod.go:150079 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 128: + goto st43 + case 129: + goto st44 + case 130: + goto st45 + case 141: + goto st46 + case 156: + goto st47 + case 157: + goto st48 + case 158: + goto st49 + case 159: + goto st50 + case 160: + goto st51 + case 162: + goto st52 + case 164: + goto st53 + case 168: + goto st54 + case 169: + goto st55 + case 170: + goto st56 + case 172: + goto st57 + case 173: + goto st58 + case 174: + goto st59 + case 175: + goto st60 + case 176: + goto st61 + case 179: + goto st62 + case 183: + goto st63 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr5332: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5307 + st5307: + if p++; p == pe { + goto _test_eof5307 + } + st_case_5307: +//line segment_words_prod.go:150231 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 128: + goto st65 + case 129: + goto st66 + case 131: + goto st67 + case 179: + goto st68 + case 181: + goto st69 + case 183: + goto st70 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr5333: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5308 + st5308: + if p++; p == pe { + goto _test_eof5308 + } + st_case_5308: +//line segment_words_prod.go:150353 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 128: + goto st72 + case 130: + goto st73 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr5334: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5309 + st5309: + if p++; p == pe { + goto _test_eof5309 + } + st_case_5309: +//line segment_words_prod.go:150467 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 153: + goto st75 + case 154: + goto st76 + case 155: + goto st77 + case 160: + goto st78 + case 162: + goto st79 + case 163: + goto st80 + case 164: + goto st81 + case 165: + goto st82 + case 166: + goto st83 + case 167: + goto st84 + case 168: + goto st85 + case 169: + goto st86 + case 170: + goto st87 + case 171: + goto st88 + case 175: + goto st89 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr5335: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5310 + st5310: + if p++; p == pe { + goto _test_eof5310 + } + st_case_5310: +//line segment_words_prod.go:150607 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 172: + goto st91 + case 184: + goto st92 + case 187: + goto st69 + case 190: + goto st76 + case 191: + goto st93 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr5336: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5311 + st5311: + if p++; p == pe { + goto _test_eof5311 + } + st_case_5311: +//line segment_words_prod.go:150727 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 144: + goto st95 + case 145: + goto st101 + case 150: + goto st120 + case 155: + goto st125 + case 157: + goto st127 + case 158: + goto st134 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr5337: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5312 + st5312: + if p++; p == pe { + goto _test_eof5312 + } + st_case_5312: +//line segment_words_prod.go:150849 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 160: + goto st137 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4217: +//line segment_words.rl:72 + + endPos = p + + goto st5313 + st5313: + if p++; p == pe { + goto _test_eof5313 + } + st_case_5313: +//line segment_words_prod.go:150956 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 189: + goto tr5002 + case 194: + goto tr5294 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr5295 + case 205: + goto tr5296 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr5297 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr5298 + case 215: + goto tr5299 + case 216: + goto tr5300 + case 217: + goto tr5301 + case 219: + goto tr5302 + case 220: + goto tr5303 + case 221: + goto tr5304 + case 222: + goto tr5305 + case 223: + goto tr5306 + case 224: + goto tr5307 + case 225: + goto tr5308 + case 226: + goto tr5309 + case 227: + goto tr5310 + case 234: + goto tr5311 + case 237: + goto tr5313 + case 239: + goto tr5314 + case 240: + goto tr5315 + case 243: + goto tr5316 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr2008 + } + case data[p] >= 48: + goto tr2646 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 132 <= data[p] && data[p] <= 185 { + goto tr5002 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto tr5312 + } + default: + goto tr4806 + } + default: + goto tr2008 + } + goto tr1 +tr4218: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5314 + st5314: + if p++; p == pe { + goto _test_eof5314 + } + st_case_5314: +//line segment_words_prod.go:151072 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 144: + goto tr5002 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 164: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr2646 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 152 <= data[p] && data[p] <= 161 { + goto tr5002 + } + case data[p] >= 97: + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto st145 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr5002 + } + case data[p] >= 235: + goto st3516 + } + default: + goto tr5002 + } + default: + goto tr5002 + } + goto tr1 +tr4219: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5315 + st5315: + if p++; p == pe { + goto _test_eof5315 + } + st_case_5315: +//line segment_words_prod.go:151202 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 188: + goto tr1 + case 194: + goto tr5294 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr5295 + case 205: + goto tr5296 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr5297 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr5298 + case 215: + goto tr5299 + case 216: + goto tr5300 + case 217: + goto tr5301 + case 219: + goto tr5302 + case 220: + goto tr5303 + case 221: + goto tr5304 + case 222: + goto tr5305 + case 223: + goto tr5306 + case 224: + goto tr5307 + case 225: + goto tr5308 + case 226: + goto tr5309 + case 227: + goto tr5310 + case 234: + goto tr5311 + case 237: + goto tr5313 + case 239: + goto tr5314 + case 240: + goto tr5315 + case 243: + goto tr5316 + } + switch { + case data[p] < 190: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 129 <= data[p] && data[p] <= 131 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto tr4806 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr1 + } + case data[p] >= 235: + goto tr5312 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr4220: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5316 + st5316: + if p++; p == pe { + goto _test_eof5316 + } + st_case_5316: +//line segment_words_prod.go:151332 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 142: + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr2008 + } + case data[p] >= 48: + goto tr2646 + } + case data[p] > 122: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr5002 + } + case data[p] >= 133: + goto tr5002 + } + default: + goto tr2008 + } + case data[p] > 150: + switch { + case data[p] < 196: + switch { + case data[p] > 161: + if 164 <= data[p] && data[p] <= 193 { + goto tr5002 + } + case data[p] >= 152: + goto tr5002 + } + case data[p] > 218: + switch { + case data[p] < 235: + if 228 <= data[p] && data[p] <= 233 { + goto tr5002 + } + case data[p] > 236: + if 238 <= data[p] { + goto tr5002 + } + default: + goto st3516 + } + default: + goto st145 + } + default: + goto tr5002 + } + goto tr1 +tr4221: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5317 + st5317: + if p++; p == pe { + goto _test_eof5317 + } + st_case_5317: +//line segment_words_prod.go:151474 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 145: + goto tr1 + case 181: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] < 59: + switch { + case data[p] > 47: + if 48 <= data[p] && data[p] <= 57 { + goto tr2646 + } + default: + goto tr1 + } + case data[p] > 64: + switch { + case data[p] > 90: + if 91 <= data[p] && data[p] <= 96 { + goto tr1 + } + case data[p] >= 65: + goto tr2008 + } + default: + goto tr1 + } + case data[p] > 122: + switch { + case data[p] < 139: + switch { + case data[p] > 130: + if 135 <= data[p] && data[p] <= 136 { + goto tr1 + } + case data[p] >= 123: + goto tr1 + } + case data[p] > 141: + switch { + case data[p] < 196: + if 176 <= data[p] && data[p] <= 177 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + default: + goto tr2008 + } + goto tr5002 +tr4222: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5318 + st5318: + if p++; p == pe { + goto _test_eof5318 + } + st_case_5318: +//line segment_words_prod.go:151620 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 134: + goto tr5002 + case 138: + goto tr5002 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 164: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr2646 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 142 <= data[p] && data[p] <= 161 { + goto tr5002 + } + case data[p] >= 97: + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto st145 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr5002 + } + case data[p] >= 235: + goto st3516 + } + default: + goto tr5002 + } + default: + goto tr5002 + } + goto tr1 +tr4223: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5319 + st5319: + if p++; p == pe { + goto _test_eof5319 + } + st_case_5319: +//line segment_words_prod.go:151752 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 188: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 129: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 131: + switch { + case data[p] < 196: + if 190 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 +tr4224: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5320 + st5320: + if p++; p == pe { + goto _test_eof5320 + } + st_case_5320: +//line segment_words_prod.go:151872 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 135: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 128 <= data[p] && data[p] <= 132 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 136: + switch { + case data[p] < 162: + switch { + case data[p] > 141: + if 150 <= data[p] && data[p] <= 151 { + goto tr1 + } + case data[p] >= 139: + goto tr1 + } + case data[p] > 163: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr4225: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5321 + st5321: + if p++; p == pe { + goto _test_eof5321 + } + st_case_5321: +//line segment_words_prod.go:152005 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 130: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 190 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4226: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5322 + st5322: + if p++; p == pe { + goto _test_eof5322 + } + st_case_5322: +//line segment_words_prod.go:152121 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 151: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 128: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 130: + switch { + case data[p] < 138: + if 134 <= data[p] && data[p] <= 136 { + goto tr1 + } + case data[p] > 141: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr4227: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5323 + st5323: + if p++; p == pe { + goto _test_eof5323 + } + st_case_5323: +//line segment_words_prod.go:152246 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto tr5294 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr5295 + case 205: + goto tr5296 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr5297 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr5298 + case 215: + goto tr5299 + case 216: + goto tr5300 + case 217: + goto tr5301 + case 219: + goto tr5302 + case 220: + goto tr5303 + case 221: + goto tr5304 + case 222: + goto tr5305 + case 223: + goto tr5306 + case 224: + goto tr5307 + case 225: + goto tr5308 + case 226: + goto tr5309 + case 227: + goto tr5310 + case 234: + goto tr5311 + case 237: + goto tr5313 + case 239: + goto tr5314 + case 240: + goto tr5315 + case 243: + goto tr5316 + } + switch { + case data[p] < 190: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 128 <= data[p] && data[p] <= 131 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto tr4806 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr1 + } + case data[p] >= 235: + goto tr5312 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr4228: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5324 + st5324: + if p++; p == pe { + goto _test_eof5324 + } + st_case_5324: +//line segment_words_prod.go:152374 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 133: + goto tr5002 + case 137: + goto tr5002 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 151: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr2646 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 142 <= data[p] && data[p] <= 148 { + goto tr5002 + } + case data[p] >= 97: + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 161: + switch { + case data[p] < 228: + switch { + case data[p] > 193: + if 196 <= data[p] && data[p] <= 218 { + goto st145 + } + case data[p] >= 164: + goto tr5002 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr5002 + } + case data[p] >= 235: + goto st3516 + } + default: + goto tr5002 + } + default: + goto tr5002 + } + goto tr1 +tr4229: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5325 + st5325: + if p++; p == pe { + goto _test_eof5325 + } + st_case_5325: +//line segment_words_prod.go:152511 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 134: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 128 <= data[p] && data[p] <= 132 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 136: + switch { + case data[p] < 162: + switch { + case data[p] > 141: + if 149 <= data[p] && data[p] <= 150 { + goto tr1 + } + case data[p] >= 138: + goto tr1 + } + case data[p] > 163: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr4230: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5326 + st5326: + if p++; p == pe { + goto _test_eof5326 + } + st_case_5326: +//line segment_words_prod.go:152644 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto tr5294 + case 195: + goto tr4805 + case 198: + goto tr4807 + case 199: + goto tr4808 + case 203: + goto tr4809 + case 204: + goto tr5295 + case 205: + goto tr5296 + case 206: + goto tr4811 + case 207: + goto tr4812 + case 210: + goto tr5297 + case 212: + goto tr4814 + case 213: + goto tr4815 + case 214: + goto tr5298 + case 215: + goto tr5299 + case 216: + goto tr5300 + case 217: + goto tr5301 + case 219: + goto tr5302 + case 220: + goto tr5303 + case 221: + goto tr5304 + case 222: + goto tr5305 + case 223: + goto tr5306 + case 224: + goto tr5307 + case 225: + goto tr5308 + case 226: + goto tr5309 + case 227: + goto tr5310 + case 234: + goto tr5311 + case 237: + goto tr5313 + case 239: + goto tr5314 + case 240: + goto tr5315 + case 243: + goto tr5316 + } + switch { + case data[p] < 190: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 129 <= data[p] && data[p] <= 131 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 193: + switch { + case data[p] < 228: + if 196 <= data[p] && data[p] <= 218 { + goto tr4806 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr1 + } + case data[p] >= 235: + goto tr5312 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr4231: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5327 + st5327: + if p++; p == pe { + goto _test_eof5327 + } + st_case_5327: +//line segment_words_prod.go:152772 + switch data[p] { + case 39: + goto tr2518 + case 46: + goto tr2518 + case 58: + goto tr2518 + case 95: + goto tr2774 + case 133: + goto tr5002 + case 137: + goto tr5002 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 152: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr2646 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 142 <= data[p] && data[p] <= 150 { + goto tr5002 + } + case data[p] >= 97: + goto tr2008 + } + default: + goto tr2008 + } + case data[p] > 161: + switch { + case data[p] < 228: + switch { + case data[p] > 193: + if 196 <= data[p] && data[p] <= 218 { + goto st145 + } + case data[p] >= 164: + goto tr5002 + } + case data[p] > 233: + switch { + case data[p] > 236: + if 238 <= data[p] { + goto tr5002 + } + case data[p] >= 235: + goto st3516 + } + default: + goto tr5002 + } + default: + goto tr5002 + } + goto tr1 +tr4232: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5328 + st5328: + if p++; p == pe { + goto _test_eof5328 + } + st_case_5328: +//line segment_words_prod.go:152909 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 130 <= data[p] && data[p] <= 131 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4233: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5329 + st5329: + if p++; p == pe { + goto _test_eof5329 + } + st_case_5329: +//line segment_words_prod.go:153023 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 138: + goto tr1 + case 150: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 143: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 148: + switch { + case data[p] < 178: + if 152 <= data[p] && data[p] <= 159 { + goto tr1 + } + case data[p] > 179: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr4234: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5330 + st5330: + if p++; p == pe { + goto _test_eof5330 + } + st_case_5330: +//line segment_words_prod.go:153150 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 177: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 180 <= data[p] && data[p] <= 186 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4235: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5331 + st5331: + if p++; p == pe { + goto _test_eof5331 + } + st_case_5331: +//line segment_words_prod.go:153266 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 135 <= data[p] && data[p] <= 142 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4236: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5332 + st5332: + if p++; p == pe { + goto _test_eof5332 + } + st_case_5332: +//line segment_words_prod.go:153380 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 177: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 180: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 185: + switch { + case data[p] < 196: + if 187 <= data[p] && data[p] <= 188 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 +tr4237: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5333 + st5333: + if p++; p == pe { + goto _test_eof5333 + } + st_case_5333: +//line segment_words_prod.go:153500 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 136 <= data[p] && data[p] <= 141 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4238: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5334 + st5334: + if p++; p == pe { + goto _test_eof5334 + } + st_case_5334: +//line segment_words_prod.go:153614 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 181: + goto tr1 + case 183: + goto tr1 + case 185: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 152: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 153: + switch { + case data[p] < 196: + if 190 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr1 + } + goto tr5002 +tr4239: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5335 + st5335: + if p++; p == pe { + goto _test_eof5335 + } + st_case_5335: +//line segment_words_prod.go:153738 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] < 196: + if 177 <= data[p] && data[p] <= 191 { + goto tr1 + } + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + default: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4240: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5336 + st5336: + if p++; p == pe { + goto _test_eof5336 + } + st_case_5336: +//line segment_words_prod.go:153852 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 134: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto tr421 + } + case data[p] > 90: + switch { + case data[p] > 122: + if 128 <= data[p] && data[p] <= 132 { + goto tr1 + } + case data[p] >= 97: + goto tr148 + } + default: + goto tr148 + } + case data[p] > 135: + switch { + case data[p] < 153: + if 141 <= data[p] && data[p] <= 151 { + goto tr1 + } + case data[p] > 188: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr1 + } + default: + goto tr1 + } + goto tr5002 +tr4241: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:89 +act = 2; + goto st5337 + st5337: + if p++; p == pe { + goto _test_eof5337 + } + st_case_5337: +//line segment_words_prod.go:153980 + switch data[p] { + case 39: + goto st142 + case 46: + goto st142 + case 58: + goto st142 + case 95: + goto tr571 + case 134: + goto tr1 + case 194: + goto st3269 + case 195: + goto st144 + case 198: + goto st146 + case 199: + goto st147 + case 203: + goto st870 + case 204: + goto st3270 + case 205: + goto st3271 + case 206: + goto st873 + case 207: + goto st152 + case 210: + goto st3272 + case 212: + goto st154 + case 213: + goto st155 + case 214: + goto st3273 + case 215: + goto st3274 + case 216: + goto st3275 + case 217: + goto st3276 + case 219: + goto st3277 + case 220: + goto st3278 + case 221: + goto st3279 + case 222: + goto st3280 + case 223: + goto st3281 + case 224: + goto st3282 + case 225: + goto st3314 + case 226: + goto st3338 + case 227: + goto st3345 + case 234: + goto st3500 + case 237: + goto st3517 + case 239: + goto st3520 + case 240: + goto st3526 + case 243: + goto st3568 + } + switch { + case data[p] < 97: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 90 { + goto tr148 + } + case data[p] >= 48: + goto tr421 + } + case data[p] > 122: + switch { + case data[p] > 218: + if 235 <= data[p] && data[p] <= 236 { + goto st3516 + } + case data[p] >= 196: + goto st145 + } + default: + goto tr148 + } + goto tr5002 +tr4496: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5338 + st5338: + if p++; p == pe { + goto _test_eof5338 + } + st_case_5338: +//line segment_words_prod.go:154096 + switch data[p] { + case 164: + goto st3595 + case 169: + goto st4663 + case 171: + goto st4664 + case 172: + goto st4665 + case 173: + goto st672 + case 174: + goto st293 + case 175: + goto st294 + case 180: + goto st295 + case 181: + goto st296 + case 182: + goto st297 + case 183: + goto st298 + case 184: + goto st4666 + case 185: + goto st2436 + case 187: + goto st4667 + case 188: + goto st2438 + case 189: + goto st4668 + case 190: + goto st4669 + case 191: + goto st4670 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + switch { + case data[p] > 170: + if 176 <= data[p] && data[p] <= 186 { + goto st145 + } + case data[p] >= 165: + goto st3734 + } + goto tr4499 + st4663: + if p++; p == pe { + goto _test_eof4663 + } + st_case_4663: + if 174 <= data[p] && data[p] <= 175 { + goto tr0 + } + goto tr3250 + st4664: + if p++; p == pe { + goto _test_eof4664 + } + st_case_4664: + if 154 <= data[p] { + goto tr0 + } + goto tr3250 + st4665: + if p++; p == pe { + goto _test_eof4665 + } + st_case_4665: + switch data[p] { + case 158: + goto tr2395 + case 190: + goto tr572 + } + switch { + case data[p] < 157: + switch { + case data[p] > 134: + if 147 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] >= 128: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] > 182: + if 184 <= data[p] && data[p] <= 188 { + goto tr572 + } + case data[p] >= 170: + goto tr572 + } + default: + goto tr572 + } + goto tr0 + st4666: + if p++; p == pe { + goto _test_eof4666 + } + st_case_4666: + switch { + case data[p] < 160: + if 128 <= data[p] && data[p] <= 143 { + goto tr2395 + } + case data[p] > 175: + if 179 <= data[p] && data[p] <= 180 { + goto tr2136 + } + default: + goto tr2395 + } + goto tr0 + st4667: + if p++; p == pe { + goto _test_eof4667 + } + st_case_4667: + if data[p] == 191 { + goto tr2395 + } + if 189 <= data[p] { + goto tr0 + } + goto tr148 + st4668: + if p++; p == pe { + goto _test_eof4668 + } + st_case_4668: + switch { + case data[p] > 154: + if 166 <= data[p] { + goto tr3376 + } + case data[p] >= 129: + goto tr148 + } + goto tr0 + st4669: + if p++; p == pe { + goto _test_eof4669 + } + st_case_4669: + switch { + case data[p] < 160: + if 158 <= data[p] && data[p] <= 159 { + goto tr2395 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr0 + } + default: + goto tr2984 + } + goto tr3376 + st4670: + if p++; p == pe { + goto _test_eof4670 + } + st_case_4670: + switch { + case data[p] < 146: + switch { + case data[p] > 135: + if 138 <= data[p] && data[p] <= 143 { + goto tr2984 + } + case data[p] >= 130: + goto tr2984 + } + case data[p] > 151: + switch { + case data[p] > 156: + if 185 <= data[p] && data[p] <= 187 { + goto tr2395 + } + case data[p] >= 154: + goto tr2984 + } + default: + goto tr2984 + } + goto tr0 +tr4497: +//line NONE:1 +te = p+1 + +//line segment_words.rl:68 + + startPos = p + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 13; + goto st5339 + st5339: + if p++; p == pe { + goto _test_eof5339 + } + st_case_5339: +//line segment_words_prod.go:154348 + switch data[p] { + case 144: + goto st4671 + case 145: + goto st4676 + case 146: + goto st362 + case 147: + goto st366 + case 148: + goto st367 + case 150: + goto st4695 + case 155: + goto st4700 + case 157: + goto st4703 + case 158: + goto st4704 + case 159: + goto st4706 + case 160: + goto st4851 + case 170: + goto st4853 + case 171: + goto st4855 + case 172: + goto st4858 + case 175: + goto st4860 + case 194: + goto st0 + case 204: + goto st1 + case 205: + goto st2 + case 210: + goto st3 + case 214: + goto st4 + case 215: + goto st5 + case 216: + goto st6 + case 217: + goto st7 + case 219: + goto st8 + case 220: + goto st9 + case 221: + goto st10 + case 222: + goto st11 + case 223: + goto st12 + case 224: + goto st13 + case 225: + goto st42 + case 226: + goto st64 + case 227: + goto st71 + case 234: + goto st74 + case 239: + goto st90 + case 240: + goto st94 + case 243: + goto st136 + } + if 161 <= data[p] && data[p] <= 169 { + goto st4852 + } + goto tr4499 + st4671: + if p++; p == pe { + goto _test_eof4671 + } + st_case_4671: + switch data[p] { + case 128: + goto st308 + case 129: + goto st309 + case 130: + goto st147 + case 131: + goto st310 + case 133: + goto st311 + case 135: + goto st2732 + case 138: + goto st313 + case 139: + goto st4672 + case 140: + goto st315 + case 141: + goto st4673 + case 142: + goto st317 + case 143: + goto st318 + case 144: + goto st147 + case 145: + goto st145 + case 146: + goto st1702 + case 148: + goto st320 + case 149: + goto st321 + case 152: + goto st147 + case 156: + goto st322 + case 157: + goto st323 + case 160: + goto st324 + case 161: + goto st325 + case 162: + goto st326 + case 163: + goto st327 + case 164: + goto st328 + case 166: + goto st329 + case 168: + goto st4674 + case 169: + goto st331 + case 170: + goto st332 + case 171: + goto st4675 + case 172: + goto st334 + case 173: + goto st335 + case 174: + goto st336 + case 176: + goto st147 + case 177: + goto st245 + } + switch { + case data[p] > 155: + if 178 <= data[p] && data[p] <= 179 { + goto st337 + } + case data[p] >= 153: + goto st145 + } + goto tr0 + st4672: + if p++; p == pe { + goto _test_eof4672 + } + st_case_4672: + if data[p] == 160 { + goto tr2395 + } + if 145 <= data[p] { + goto tr0 + } + goto tr148 + st4673: + if p++; p == pe { + goto _test_eof4673 + } + st_case_4673: + switch { + case data[p] < 182: + if 139 <= data[p] && data[p] <= 143 { + goto tr0 + } + case data[p] > 186: + if 187 <= data[p] { + goto tr0 + } + default: + goto tr2395 + } + goto tr148 + st4674: + if p++; p == pe { + goto _test_eof4674 + } + st_case_4674: + switch data[p] { + case 128: + goto tr148 + case 191: + goto tr2395 + } + switch { + case data[p] < 144: + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr2395 + } + case data[p] > 134: + if 140 <= data[p] && data[p] <= 143 { + goto tr2395 + } + default: + goto tr2395 + } + case data[p] > 147: + switch { + case data[p] < 153: + if 149 <= data[p] && data[p] <= 151 { + goto tr148 + } + case data[p] > 179: + if 184 <= data[p] && data[p] <= 186 { + goto tr2395 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st4675: + if p++; p == pe { + goto _test_eof4675 + } + st_case_4675: + switch { + case data[p] < 137: + if 128 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 164: + if 165 <= data[p] && data[p] <= 166 { + goto tr2395 + } + default: + goto tr148 + } + goto tr0 + st4676: + if p++; p == pe { + goto _test_eof4676 + } + st_case_4676: + switch data[p] { + case 128: + goto st4677 + case 129: + goto st4678 + case 130: + goto st4679 + case 131: + goto st1709 + case 132: + goto st4680 + case 133: + goto st4681 + case 134: + goto st4682 + case 135: + goto st4683 + case 136: + goto st4684 + case 138: + goto st348 + case 139: + goto st4685 + case 140: + goto st4686 + case 141: + goto st4687 + case 146: + goto st4688 + case 147: + goto st4689 + case 150: + goto st4690 + case 151: + goto st4691 + case 152: + goto st4688 + case 153: + goto st4692 + case 154: + goto st4693 + case 155: + goto st1724 + case 156: + goto st4694 + case 162: + goto st359 + case 163: + goto st1726 + case 171: + goto st361 + } + goto tr0 + st4677: + if p++; p == pe { + goto _test_eof4677 + } + st_case_4677: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2395 + } + case data[p] > 183: + if 184 <= data[p] { + goto tr2395 + } + default: + goto tr148 + } + goto tr0 + st4678: + if p++; p == pe { + goto _test_eof4678 + } + st_case_4678: + switch { + case data[p] < 166: + if 135 <= data[p] && data[p] <= 165 { + goto tr0 + } + case data[p] > 175: + if 176 <= data[p] && data[p] <= 190 { + goto tr0 + } + default: + goto tr126 + } + goto tr2395 + st4679: + if p++; p == pe { + goto _test_eof4679 + } + st_case_4679: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr148 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr0 + } + default: + goto tr0 + } + goto tr2395 + st4680: + if p++; p == pe { + goto _test_eof4680 + } + st_case_4680: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2395 + } + case data[p] > 166: + switch { + case data[p] > 180: + if 182 <= data[p] && data[p] <= 191 { + goto tr126 + } + case data[p] >= 167: + goto tr2395 + } + default: + goto tr148 + } + goto tr0 + st4681: + if p++; p == pe { + goto _test_eof4681 + } + st_case_4681: + switch data[p] { + case 179: + goto tr2395 + case 182: + goto tr148 + } + if 144 <= data[p] && data[p] <= 178 { + goto tr148 + } + goto tr0 + st4682: + if p++; p == pe { + goto _test_eof4682 + } + st_case_4682: + switch { + case data[p] < 131: + if 128 <= data[p] && data[p] <= 130 { + goto tr2395 + } + case data[p] > 178: + if 179 <= data[p] { + goto tr2395 + } + default: + goto tr148 + } + goto tr0 + st4683: + if p++; p == pe { + goto _test_eof4683 + } + st_case_4683: + if data[p] == 155 { + goto tr0 + } + switch { + case data[p] < 141: + switch { + case data[p] > 132: + if 133 <= data[p] && data[p] <= 137 { + goto tr0 + } + case data[p] >= 129: + goto tr148 + } + case data[p] > 143: + switch { + case data[p] < 154: + if 144 <= data[p] && data[p] <= 153 { + goto tr126 + } + case data[p] > 156: + if 157 <= data[p] { + goto tr0 + } + default: + goto tr148 + } + default: + goto tr0 + } + goto tr2395 + st4684: + if p++; p == pe { + goto _test_eof4684 + } + st_case_4684: + switch { + case data[p] < 147: + if 128 <= data[p] && data[p] <= 145 { + goto tr148 + } + case data[p] > 171: + if 172 <= data[p] && data[p] <= 183 { + goto tr2395 + } + default: + goto tr148 + } + goto tr0 + st4685: + if p++; p == pe { + goto _test_eof4685 + } + st_case_4685: + switch { + case data[p] < 171: + if 159 <= data[p] && data[p] <= 170 { + goto tr2395 + } + case data[p] > 175: + switch { + case data[p] > 185: + if 186 <= data[p] { + goto tr0 + } + case data[p] >= 176: + goto tr126 + } + default: + goto tr0 + } + goto tr148 + st4686: + if p++; p == pe { + goto _test_eof4686 + } + st_case_4686: + if data[p] == 189 { + goto tr148 + } + switch { + case data[p] < 147: + switch { + case data[p] < 133: + if 128 <= data[p] && data[p] <= 131 { + goto tr2395 + } + case data[p] > 140: + if 143 <= data[p] && data[p] <= 144 { + goto tr148 + } + default: + goto tr148 + } + case data[p] > 168: + switch { + case data[p] < 178: + if 170 <= data[p] && data[p] <= 176 { + goto tr148 + } + case data[p] > 179: + switch { + case data[p] > 185: + if 188 <= data[p] && data[p] <= 191 { + goto tr2395 + } + case data[p] >= 181: + goto tr148 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto tr0 + st4687: + if p++; p == pe { + goto _test_eof4687 + } + st_case_4687: + switch data[p] { + case 144: + goto tr148 + case 151: + goto tr2395 + } + switch { + case data[p] < 157: + switch { + case data[p] < 135: + if 128 <= data[p] && data[p] <= 132 { + goto tr2395 + } + case data[p] > 136: + if 139 <= data[p] && data[p] <= 141 { + goto tr2395 + } + default: + goto tr2395 + } + case data[p] > 161: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr2395 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr2395 + } + default: + goto tr2395 + } + default: + goto tr148 + } + goto tr0 + st4688: + if p++; p == pe { + goto _test_eof4688 + } + st_case_4688: + switch { + case data[p] > 175: + if 176 <= data[p] { + goto tr2395 + } + case data[p] >= 128: + goto tr148 + } + goto tr0 + st4689: + if p++; p == pe { + goto _test_eof4689 + } + st_case_4689: + if data[p] == 134 { + goto tr0 + } + switch { + case data[p] < 136: + if 132 <= data[p] && data[p] <= 135 { + goto tr148 + } + case data[p] > 143: + switch { + case data[p] > 153: + if 154 <= data[p] { + goto tr0 + } + case data[p] >= 144: + goto tr126 + } + default: + goto tr0 + } + goto tr2395 + st4690: + if p++; p == pe { + goto _test_eof4690 + } + st_case_4690: + switch { + case data[p] < 175: + if 128 <= data[p] && data[p] <= 174 { + goto tr148 + } + case data[p] > 181: + if 184 <= data[p] { + goto tr2395 + } + default: + goto tr2395 + } + goto tr0 + st4691: + if p++; p == pe { + goto _test_eof4691 + } + st_case_4691: + switch { + case data[p] < 152: + if 129 <= data[p] && data[p] <= 151 { + goto tr0 + } + case data[p] > 155: + if 158 <= data[p] { + goto tr0 + } + default: + goto tr148 + } + goto tr2395 + st4692: + if p++; p == pe { + goto _test_eof4692 + } + st_case_4692: + if data[p] == 132 { + goto tr148 + } + switch { + case data[p] < 144: + if 129 <= data[p] && data[p] <= 143 { + goto tr0 + } + case data[p] > 153: + if 154 <= data[p] { + goto tr0 + } + default: + goto tr126 + } + goto tr2395 + st4693: + if p++; p == pe { + goto _test_eof4693 + } + st_case_4693: + switch { + case data[p] > 170: + if 171 <= data[p] && data[p] <= 183 { + goto tr2395 + } + case data[p] >= 128: + goto tr148 + } + goto tr0 + st4694: + if p++; p == pe { + goto _test_eof4694 + } + st_case_4694: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 185 { + goto tr126 + } + case data[p] >= 157: + goto tr2395 + } + goto tr0 + st4695: + if p++; p == pe { + goto _test_eof4695 + } + st_case_4695: + switch data[p] { + case 160: + goto st147 + case 168: + goto st370 + case 169: + goto st1728 + case 171: + goto st4696 + case 172: + goto st4697 + case 173: + goto st1731 + case 174: + goto st374 + case 188: + goto st147 + case 189: + goto st4698 + case 190: + goto st4699 + } + if 161 <= data[p] && data[p] <= 167 { + goto st145 + } + goto tr0 + st4696: + if p++; p == pe { + goto _test_eof4696 + } + st_case_4696: + switch { + case data[p] > 173: + if 176 <= data[p] && data[p] <= 180 { + goto tr2395 + } + case data[p] >= 144: + goto tr148 + } + goto tr0 + st4697: + if p++; p == pe { + goto _test_eof4697 + } + st_case_4697: + switch { + case data[p] > 175: + if 176 <= data[p] && data[p] <= 182 { + goto tr2395 + } + case data[p] >= 128: + goto tr148 + } + goto tr0 + st4698: + if p++; p == pe { + goto _test_eof4698 + } + st_case_4698: + switch { + case data[p] < 145: + if 133 <= data[p] && data[p] <= 143 { + goto tr0 + } + case data[p] > 190: + if 191 <= data[p] { + goto tr0 + } + default: + goto tr2395 + } + goto tr148 + st4699: + if p++; p == pe { + goto _test_eof4699 + } + st_case_4699: + switch { + case data[p] > 146: + if 147 <= data[p] && data[p] <= 159 { + goto tr148 + } + case data[p] >= 143: + goto tr2395 + } + goto tr0 + st4700: + if p++; p == pe { + goto _test_eof4700 + } + st_case_4700: + switch data[p] { + case 128: + goto st4701 + case 176: + goto st147 + case 177: + goto st378 + case 178: + goto st4702 + } + goto tr0 + st4701: + if p++; p == pe { + goto _test_eof4701 + } + st_case_4701: + switch data[p] { + case 128: + goto tr3376 + case 129: + goto tr3757 + } + goto tr0 + st4702: + if p++; p == pe { + goto _test_eof4702 + } + st_case_4702: + switch { + case data[p] < 144: + if 128 <= data[p] && data[p] <= 136 { + goto tr148 + } + case data[p] > 153: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr2395 + } + case data[p] >= 157: + goto tr2395 + } + default: + goto tr148 + } + goto tr0 + st4703: + if p++; p == pe { + goto _test_eof4703 + } + st_case_4703: + switch data[p] { + case 133: + goto st2764 + case 134: + goto st2765 + case 137: + goto st2766 + case 144: + goto st147 + case 145: + goto st384 + case 146: + goto st385 + case 147: + goto st386 + case 148: + goto st387 + case 149: + goto st388 + case 154: + goto st389 + case 155: + goto st390 + case 156: + goto st391 + case 157: + goto st392 + case 158: + goto st393 + case 159: + goto st1740 + case 168: + goto st2767 + case 169: + goto st2768 + case 170: + goto st2769 + } + if 150 <= data[p] && data[p] <= 153 { + goto st145 + } + goto tr0 + st4704: + if p++; p == pe { + goto _test_eof4704 + } + st_case_4704: + switch data[p] { + case 160: + goto st147 + case 163: + goto st4705 + case 184: + goto st400 + case 185: + goto st401 + case 186: + goto st402 + } + if 161 <= data[p] && data[p] <= 162 { + goto st145 + } + goto tr0 + st4705: + if p++; p == pe { + goto _test_eof4705 + } + st_case_4705: + switch { + case data[p] < 144: + if 133 <= data[p] && data[p] <= 143 { + goto tr0 + } + case data[p] > 150: + if 151 <= data[p] { + goto tr0 + } + default: + goto tr2395 + } + goto tr148 + st4706: + if p++; p == pe { + goto _test_eof4706 + } + st_case_4706: + switch data[p] { + case 132: + goto st404 + case 133: + goto st405 + case 134: + goto st406 + case 135: + goto st4707 + case 136: + goto st4850 + } + goto tr0 + st4707: + if p++; p == pe { + goto _test_eof4707 + } + st_case_4707: + if 166 <= data[p] && data[p] <= 191 { + goto tr4327 + } + goto tr2 +tr4327: +//line NONE:1 +te = p+1 + +//line segment_words.rl:72 + + endPos = p + +//line segment_words.rl:161 +act = 7; + goto st5340 + st5340: + if p++; p == pe { + goto _test_eof5340 + } + st_case_5340: +//line segment_words_prod.go:155329 + switch data[p] { + case 194: + goto st4708 + case 204: + goto st4709 + case 205: + goto st4710 + case 210: + goto st4711 + case 214: + goto st4712 + case 215: + goto st4713 + case 216: + goto st4714 + case 217: + goto st4715 + case 219: + goto st4716 + case 220: + goto st4717 + case 221: + goto st4718 + case 222: + goto st4719 + case 223: + goto st4720 + case 224: + goto st4721 + case 225: + goto st4750 + case 226: + goto st4772 + case 227: + goto st4779 + case 234: + goto st4782 + case 239: + goto st4798 + case 240: + goto st4802 + case 243: + goto st4845 + } + goto tr5359 + st4708: + if p++; p == pe { + goto _test_eof4708 + } + st_case_4708: + if data[p] == 173 { + goto tr4327 + } + goto tr4328 + st4709: + if p++; p == pe { + goto _test_eof4709 + } + st_case_4709: + if data[p] <= 127 { + goto tr4328 + } + goto tr4327 + st4710: + if p++; p == pe { + goto _test_eof4710 + } + st_case_4710: + if 176 <= data[p] { + goto tr4328 + } + goto tr4327 + st4711: + if p++; p == pe { + goto _test_eof4711 + } + st_case_4711: + if 131 <= data[p] && data[p] <= 137 { + goto tr4327 + } + goto tr4328 + st4712: + if p++; p == pe { + goto _test_eof4712 + } + st_case_4712: + if data[p] == 191 { + goto tr4327 + } + if 145 <= data[p] && data[p] <= 189 { + goto tr4327 + } + goto tr4328 + st4713: + if p++; p == pe { + goto _test_eof4713 + } + st_case_4713: + if data[p] == 135 { + goto tr4327 + } + switch { + case data[p] > 130: + if 132 <= data[p] && data[p] <= 133 { + goto tr4327 + } + case data[p] >= 129: + goto tr4327 + } + goto tr4328 + st4714: + if p++; p == pe { + goto _test_eof4714 + } + st_case_4714: + if data[p] == 156 { + goto tr4327 + } + switch { + case data[p] > 133: + if 144 <= data[p] && data[p] <= 154 { + goto tr4327 + } + case data[p] >= 128: + goto tr4327 + } + goto tr4328 + st4715: + if p++; p == pe { + goto _test_eof4715 + } + st_case_4715: + if data[p] == 176 { + goto tr4327 + } + if 139 <= data[p] && data[p] <= 159 { + goto tr4327 + } + goto tr4328 + st4716: + if p++; p == pe { + goto _test_eof4716 + } + st_case_4716: + switch { + case data[p] < 159: + if 150 <= data[p] && data[p] <= 157 { + goto tr4327 + } + case data[p] > 164: + switch { + case data[p] > 168: + if 170 <= data[p] && data[p] <= 173 { + goto tr4327 + } + case data[p] >= 167: + goto tr4327 + } + default: + goto tr4327 + } + goto tr4328 + st4717: + if p++; p == pe { + goto _test_eof4717 + } + st_case_4717: + switch data[p] { + case 143: + goto tr4327 + case 145: + goto tr4327 + } + if 176 <= data[p] { + goto tr4327 + } + goto tr4328 + st4718: + if p++; p == pe { + goto _test_eof4718 + } + st_case_4718: + if 139 <= data[p] { + goto tr4328 + } + goto tr4327 + st4719: + if p++; p == pe { + goto _test_eof4719 + } + st_case_4719: + if 166 <= data[p] && data[p] <= 176 { + goto tr4327 + } + goto tr4328 + st4720: + if p++; p == pe { + goto _test_eof4720 + } + st_case_4720: + if 171 <= data[p] && data[p] <= 179 { + goto tr4327 + } + goto tr4328 + st4721: + if p++; p == pe { + goto _test_eof4721 + } + st_case_4721: + switch data[p] { + case 160: + goto st4722 + case 161: + goto st4723 + case 163: + goto st4724 + case 164: + goto st4725 + case 165: + goto st4726 + case 167: + goto st4728 + case 169: + goto st4729 + case 171: + goto st4730 + case 173: + goto st4732 + case 174: + goto st4733 + case 175: + goto st4734 + case 176: + goto st4735 + case 177: + goto st4736 + case 179: + goto st4737 + case 180: + goto st4738 + case 181: + goto st4739 + case 182: + goto st4740 + case 183: + goto st4741 + case 184: + goto st4742 + case 185: + goto st4743 + case 186: + goto st4744 + case 187: + goto st4745 + case 188: + goto st4746 + case 189: + goto st4747 + case 190: + goto st4748 + case 191: + goto st4749 + } + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 178 { + goto st4731 + } + case data[p] >= 166: + goto st4727 + } + goto tr4328 + st4722: + if p++; p == pe { + goto _test_eof4722 + } + st_case_4722: + switch { + case data[p] < 155: + if 150 <= data[p] && data[p] <= 153 { + goto tr4327 + } + case data[p] > 163: + switch { + case data[p] > 167: + if 169 <= data[p] && data[p] <= 173 { + goto tr4327 + } + case data[p] >= 165: + goto tr4327 + } + default: + goto tr4327 + } + goto tr4328 + st4723: + if p++; p == pe { + goto _test_eof4723 + } + st_case_4723: + if 153 <= data[p] && data[p] <= 155 { + goto tr4327 + } + goto tr4328 + st4724: + if p++; p == pe { + goto _test_eof4724 + } + st_case_4724: + if 163 <= data[p] { + goto tr4327 + } + goto tr4328 + st4725: + if p++; p == pe { + goto _test_eof4725 + } + st_case_4725: + if data[p] == 189 { + goto tr4328 + } + if 132 <= data[p] && data[p] <= 185 { + goto tr4328 + } + goto tr4327 + st4726: + if p++; p == pe { + goto _test_eof4726 + } + st_case_4726: + if data[p] == 144 { + goto tr4328 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr4328 + } + case data[p] >= 152: + goto tr4328 + } + goto tr4327 + st4727: + if p++; p == pe { + goto _test_eof4727 + } + st_case_4727: + if data[p] == 188 { + goto tr4327 + } + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr4327 + } + case data[p] >= 129: + goto tr4327 + } + goto tr4328 + st4728: + if p++; p == pe { + goto _test_eof4728 + } + st_case_4728: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr4328 + } + case data[p] >= 133: + goto tr4328 + } + case data[p] > 150: + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr4328 + } + case data[p] >= 152: + goto tr4328 + } + default: + goto tr4328 + } + goto tr4327 + st4729: + if p++; p == pe { + goto _test_eof4729 + } + st_case_4729: + switch { + case data[p] < 142: + switch { + case data[p] > 134: + if 137 <= data[p] && data[p] <= 138 { + goto tr4328 + } + case data[p] >= 131: + goto tr4328 + } + case data[p] > 144: + switch { + case data[p] < 178: + if 146 <= data[p] && data[p] <= 175 { + goto tr4328 + } + case data[p] > 180: + if 182 <= data[p] { + goto tr4328 + } + default: + goto tr4328 + } + default: + goto tr4328 + } + goto tr4327 + st4730: + if p++; p == pe { + goto _test_eof4730 + } + st_case_4730: + switch data[p] { + case 134: + goto tr4328 + case 138: + goto tr4328 + } + switch { + case data[p] > 161: + if 164 <= data[p] { + goto tr4328 + } + case data[p] >= 142: + goto tr4328 + } + goto tr4327 + st4731: + if p++; p == pe { + goto _test_eof4731 + } + st_case_4731: + if data[p] == 188 { + goto tr4327 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr4327 + } + case data[p] >= 129: + goto tr4327 + } + goto tr4328 + st4732: + if p++; p == pe { + goto _test_eof4732 + } + st_case_4732: + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr4327 + } + case data[p] >= 128: + goto tr4327 + } + case data[p] > 141: + switch { + case data[p] > 151: + if 162 <= data[p] && data[p] <= 163 { + goto tr4327 + } + case data[p] >= 150: + goto tr4327 + } + default: + goto tr4327 + } + goto tr4328 + st4733: + if p++; p == pe { + goto _test_eof4733 + } + st_case_4733: + if data[p] == 130 { + goto tr4327 + } + if 190 <= data[p] && data[p] <= 191 { + goto tr4327 + } + goto tr4328 + st4734: + if p++; p == pe { + goto _test_eof4734 + } + st_case_4734: + if data[p] == 151 { + goto tr4327 + } + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 130 { + goto tr4327 + } + case data[p] > 136: + if 138 <= data[p] && data[p] <= 141 { + goto tr4327 + } + default: + goto tr4327 + } + goto tr4328 + st4735: + if p++; p == pe { + goto _test_eof4735 + } + st_case_4735: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr4327 + } + case data[p] >= 128: + goto tr4327 + } + goto tr4328 + st4736: + if p++; p == pe { + goto _test_eof4736 + } + st_case_4736: + switch data[p] { + case 133: + goto tr4328 + case 137: + goto tr4328 + } + switch { + case data[p] < 151: + if 142 <= data[p] && data[p] <= 148 { + goto tr4328 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr4328 + } + default: + goto tr4328 + } + goto tr4327 + st4737: + if p++; p == pe { + goto _test_eof4737 + } + st_case_4737: + switch { + case data[p] < 138: + switch { + case data[p] > 132: + if 134 <= data[p] && data[p] <= 136 { + goto tr4327 + } + case data[p] >= 128: + goto tr4327 + } + case data[p] > 141: + switch { + case data[p] > 150: + if 162 <= data[p] && data[p] <= 163 { + goto tr4327 + } + case data[p] >= 149: + goto tr4327 + } + default: + goto tr4327 + } + goto tr4328 + st4738: + if p++; p == pe { + goto _test_eof4738 + } + st_case_4738: + switch { + case data[p] > 131: + if 190 <= data[p] { + goto tr4327 + } + case data[p] >= 129: + goto tr4327 + } + goto tr4328 + st4739: + if p++; p == pe { + goto _test_eof4739 + } + st_case_4739: + switch data[p] { + case 133: + goto tr4328 + case 137: + goto tr4328 + } + switch { + case data[p] < 152: + if 142 <= data[p] && data[p] <= 150 { + goto tr4328 + } + case data[p] > 161: + if 164 <= data[p] { + goto tr4328 + } + default: + goto tr4328 + } + goto tr4327 + st4740: + if p++; p == pe { + goto _test_eof4740 + } + st_case_4740: + if 130 <= data[p] && data[p] <= 131 { + goto tr4327 + } + goto tr4328 + st4741: + if p++; p == pe { + goto _test_eof4741 + } + st_case_4741: + switch data[p] { + case 138: + goto tr4327 + case 150: + goto tr4327 + } + switch { + case data[p] < 152: + if 143 <= data[p] && data[p] <= 148 { + goto tr4327 + } + case data[p] > 159: + if 178 <= data[p] && data[p] <= 179 { + goto tr4327 + } + default: + goto tr4327 + } + goto tr4328 + st4742: + if p++; p == pe { + goto _test_eof4742 + } + st_case_4742: + if data[p] == 177 { + goto tr4327 + } + if 180 <= data[p] && data[p] <= 186 { + goto tr4327 + } + goto tr4328 + st4743: + if p++; p == pe { + goto _test_eof4743 + } + st_case_4743: + if 135 <= data[p] && data[p] <= 142 { + goto tr4327 + } + goto tr4328 + st4744: + if p++; p == pe { + goto _test_eof4744 + } + st_case_4744: + if data[p] == 177 { + goto tr4327 + } + switch { + case data[p] > 185: + if 187 <= data[p] && data[p] <= 188 { + goto tr4327 + } + case data[p] >= 180: + goto tr4327 + } + goto tr4328 + st4745: + if p++; p == pe { + goto _test_eof4745 + } + st_case_4745: + if 136 <= data[p] && data[p] <= 141 { + goto tr4327 + } + goto tr4328 + st4746: + if p++; p == pe { + goto _test_eof4746 + } + st_case_4746: + switch data[p] { + case 181: + goto tr4327 + case 183: + goto tr4327 + case 185: + goto tr4327 + } + switch { + case data[p] > 153: + if 190 <= data[p] && data[p] <= 191 { + goto tr4327 + } + case data[p] >= 152: + goto tr4327 + } + goto tr4328 + st4747: + if p++; p == pe { + goto _test_eof4747 + } + st_case_4747: + if 177 <= data[p] && data[p] <= 191 { + goto tr4327 + } + goto tr4328 + st4748: + if p++; p == pe { + goto _test_eof4748 + } + st_case_4748: + switch { + case data[p] < 134: + if 128 <= data[p] && data[p] <= 132 { + goto tr4327 + } + case data[p] > 135: + switch { + case data[p] > 151: + if 153 <= data[p] && data[p] <= 188 { + goto tr4327 + } + case data[p] >= 141: + goto tr4327 + } + default: + goto tr4327 + } + goto tr4328 + st4749: + if p++; p == pe { + goto _test_eof4749 + } + st_case_4749: + if data[p] == 134 { + goto tr4327 + } + goto tr4328 + st4750: + if p++; p == pe { + goto _test_eof4750 + } + st_case_4750: + switch data[p] { + case 128: + goto st4751 + case 129: + goto st4752 + case 130: + goto st4753 + case 141: + goto st4754 + case 156: + goto st4755 + case 157: + goto st4756 + case 158: + goto st4757 + case 159: + goto st4758 + case 160: + goto st4759 + case 162: + goto st4760 + case 164: + goto st4761 + case 168: + goto st4762 + case 169: + goto st4763 + case 170: + goto st4764 + case 172: + goto st4765 + case 173: + goto st4766 + case 174: + goto st4767 + case 175: + goto st4768 + case 176: + goto st4769 + case 179: + goto st4770 + case 183: + goto st4771 + } + goto tr4328 + st4751: + if p++; p == pe { + goto _test_eof4751 + } + st_case_4751: + if 171 <= data[p] && data[p] <= 190 { + goto tr4327 + } + goto tr4328 + st4752: + if p++; p == pe { + goto _test_eof4752 + } + st_case_4752: + switch { + case data[p] < 162: + switch { + case data[p] > 153: + if 158 <= data[p] && data[p] <= 160 { + goto tr4327 + } + case data[p] >= 150: + goto tr4327 + } + case data[p] > 164: + switch { + case data[p] > 173: + if 177 <= data[p] && data[p] <= 180 { + goto tr4327 + } + case data[p] >= 167: + goto tr4327 + } + default: + goto tr4327 + } + goto tr4328 + st4753: + if p++; p == pe { + goto _test_eof4753 + } + st_case_4753: + if data[p] == 143 { + goto tr4327 + } + switch { + case data[p] > 141: + if 154 <= data[p] && data[p] <= 157 { + goto tr4327 + } + case data[p] >= 130: + goto tr4327 + } + goto tr4328 + st4754: + if p++; p == pe { + goto _test_eof4754 + } + st_case_4754: + if 157 <= data[p] && data[p] <= 159 { + goto tr4327 + } + goto tr4328 + st4755: + if p++; p == pe { + goto _test_eof4755 + } + st_case_4755: + switch { + case data[p] > 148: + if 178 <= data[p] && data[p] <= 180 { + goto tr4327 + } + case data[p] >= 146: + goto tr4327 + } + goto tr4328 + st4756: + if p++; p == pe { + goto _test_eof4756 + } + st_case_4756: + switch { + case data[p] > 147: + if 178 <= data[p] && data[p] <= 179 { + goto tr4327 + } + case data[p] >= 146: + goto tr4327 + } + goto tr4328 + st4757: + if p++; p == pe { + goto _test_eof4757 + } + st_case_4757: + if 180 <= data[p] { + goto tr4327 + } + goto tr4328 + st4758: + if p++; p == pe { + goto _test_eof4758 + } + st_case_4758: + switch { + case data[p] > 156: + if 158 <= data[p] { + goto tr4328 + } + case data[p] >= 148: + goto tr4328 + } + goto tr4327 + st4759: + if p++; p == pe { + goto _test_eof4759 + } + st_case_4759: + if 139 <= data[p] && data[p] <= 142 { + goto tr4327 + } + goto tr4328 + st4760: + if p++; p == pe { + goto _test_eof4760 + } + st_case_4760: + if data[p] == 169 { + goto tr4327 + } + goto tr4328 + st4761: + if p++; p == pe { + goto _test_eof4761 + } + st_case_4761: + switch { + case data[p] > 171: + if 176 <= data[p] && data[p] <= 187 { + goto tr4327 + } + case data[p] >= 160: + goto tr4327 + } + goto tr4328 + st4762: + if p++; p == pe { + goto _test_eof4762 + } + st_case_4762: + if 151 <= data[p] && data[p] <= 155 { + goto tr4327 + } + goto tr4328 + st4763: + if p++; p == pe { + goto _test_eof4763 + } + st_case_4763: + if data[p] == 191 { + goto tr4327 + } + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 188 { + goto tr4327 + } + case data[p] >= 149: + goto tr4327 + } + goto tr4328 + st4764: + if p++; p == pe { + goto _test_eof4764 + } + st_case_4764: + if 176 <= data[p] && data[p] <= 190 { + goto tr4327 + } + goto tr4328 + st4765: + if p++; p == pe { + goto _test_eof4765 + } + st_case_4765: + switch { + case data[p] > 132: + if 180 <= data[p] { + goto tr4327 + } + case data[p] >= 128: + goto tr4327 + } + goto tr4328 + st4766: + if p++; p == pe { + goto _test_eof4766 + } + st_case_4766: + switch { + case data[p] > 170: + if 180 <= data[p] { + goto tr4328 + } + case data[p] >= 133: + goto tr4328 + } + goto tr4327 + st4767: + if p++; p == pe { + goto _test_eof4767 + } + st_case_4767: + switch { + case data[p] > 130: + if 161 <= data[p] && data[p] <= 173 { + goto tr4327 + } + case data[p] >= 128: + goto tr4327 + } + goto tr4328 + st4768: + if p++; p == pe { + goto _test_eof4768 + } + st_case_4768: + if 166 <= data[p] && data[p] <= 179 { + goto tr4327 + } + goto tr4328 + st4769: + if p++; p == pe { + goto _test_eof4769 + } + st_case_4769: + if 164 <= data[p] && data[p] <= 183 { + goto tr4327 + } + goto tr4328 + st4770: + if p++; p == pe { + goto _test_eof4770 + } + st_case_4770: + if data[p] == 173 { + goto tr4327 + } + switch { + case data[p] < 148: + if 144 <= data[p] && data[p] <= 146 { + goto tr4327 + } + case data[p] > 168: + switch { + case data[p] > 180: + if 184 <= data[p] && data[p] <= 185 { + goto tr4327 + } + case data[p] >= 178: + goto tr4327 + } + default: + goto tr4327 + } + goto tr4328 + st4771: + if p++; p == pe { + goto _test_eof4771 + } + st_case_4771: + switch { + case data[p] > 181: + if 188 <= data[p] && data[p] <= 191 { + goto tr4327 + } + case data[p] >= 128: + goto tr4327 + } + goto tr4328 + st4772: + if p++; p == pe { + goto _test_eof4772 + } + st_case_4772: + switch data[p] { + case 128: + goto st4773 + case 129: + goto st4774 + case 131: + goto st4775 + case 179: + goto st4776 + case 181: + goto st4777 + case 183: + goto st4778 + } + goto tr4328 + st4773: + if p++; p == pe { + goto _test_eof4773 + } + st_case_4773: + switch { + case data[p] > 143: + if 170 <= data[p] && data[p] <= 174 { + goto tr4327 + } + case data[p] >= 140: + goto tr4327 + } + goto tr4328 + st4774: + if p++; p == pe { + goto _test_eof4774 + } + st_case_4774: + switch { + case data[p] > 164: + if 166 <= data[p] && data[p] <= 175 { + goto tr4327 + } + case data[p] >= 160: + goto tr4327 + } + goto tr4328 + st4775: + if p++; p == pe { + goto _test_eof4775 + } + st_case_4775: + if 144 <= data[p] && data[p] <= 176 { + goto tr4327 + } + goto tr4328 + st4776: + if p++; p == pe { + goto _test_eof4776 + } + st_case_4776: + if 175 <= data[p] && data[p] <= 177 { + goto tr4327 + } + goto tr4328 + st4777: + if p++; p == pe { + goto _test_eof4777 + } + st_case_4777: + if data[p] == 191 { + goto tr4327 + } + goto tr4328 + st4778: + if p++; p == pe { + goto _test_eof4778 + } + st_case_4778: + if 160 <= data[p] && data[p] <= 191 { + goto tr4327 + } + goto tr4328 + st4779: + if p++; p == pe { + goto _test_eof4779 + } + st_case_4779: + switch data[p] { + case 128: + goto st4780 + case 130: + goto st4781 + } + goto tr4328 + st4780: + if p++; p == pe { + goto _test_eof4780 + } + st_case_4780: + if 170 <= data[p] && data[p] <= 175 { + goto tr4327 + } + goto tr4328 + st4781: + if p++; p == pe { + goto _test_eof4781 + } + st_case_4781: + if 153 <= data[p] && data[p] <= 154 { + goto tr4327 + } + goto tr4328 + st4782: + if p++; p == pe { + goto _test_eof4782 + } + st_case_4782: + switch data[p] { + case 153: + goto st4783 + case 154: + goto st4784 + case 155: + goto st4785 + case 160: + goto st4786 + case 162: + goto st4787 + case 163: + goto st4788 + case 164: + goto st4789 + case 165: + goto st4790 + case 166: + goto st4791 + case 167: + goto st4792 + case 168: + goto st4793 + case 169: + goto st4794 + case 170: + goto st4795 + case 171: + goto st4796 + case 175: + goto st4797 + } + goto tr4328 + st4783: + if p++; p == pe { + goto _test_eof4783 + } + st_case_4783: + switch { + case data[p] > 178: + if 180 <= data[p] && data[p] <= 189 { + goto tr4327 + } + case data[p] >= 175: + goto tr4327 + } + goto tr4328 + st4784: + if p++; p == pe { + goto _test_eof4784 + } + st_case_4784: + if 158 <= data[p] && data[p] <= 159 { + goto tr4327 + } + goto tr4328 + st4785: + if p++; p == pe { + goto _test_eof4785 + } + st_case_4785: + if 176 <= data[p] && data[p] <= 177 { + goto tr4327 + } + goto tr4328 + st4786: + if p++; p == pe { + goto _test_eof4786 + } + st_case_4786: + switch data[p] { + case 130: + goto tr4327 + case 134: + goto tr4327 + case 139: + goto tr4327 + } + if 163 <= data[p] && data[p] <= 167 { + goto tr4327 + } + goto tr4328 + st4787: + if p++; p == pe { + goto _test_eof4787 + } + st_case_4787: + switch { + case data[p] > 129: + if 180 <= data[p] { + goto tr4327 + } + case data[p] >= 128: + goto tr4327 + } + goto tr4328 + st4788: + if p++; p == pe { + goto _test_eof4788 + } + st_case_4788: + switch { + case data[p] > 159: + if 178 <= data[p] { + goto tr4328 + } + case data[p] >= 133: + goto tr4328 + } + goto tr4327 + st4789: + if p++; p == pe { + goto _test_eof4789 + } + st_case_4789: + if 166 <= data[p] && data[p] <= 173 { + goto tr4327 + } + goto tr4328 + st4790: + if p++; p == pe { + goto _test_eof4790 + } + st_case_4790: + if 135 <= data[p] && data[p] <= 147 { + goto tr4327 + } + goto tr4328 + st4791: + if p++; p == pe { + goto _test_eof4791 + } + st_case_4791: + switch { + case data[p] > 131: + if 179 <= data[p] { + goto tr4327 + } + case data[p] >= 128: + goto tr4327 + } + goto tr4328 + st4792: + if p++; p == pe { + goto _test_eof4792 + } + st_case_4792: + switch { + case data[p] > 164: + if 166 <= data[p] { + goto tr4328 + } + case data[p] >= 129: + goto tr4328 + } + goto tr4327 + st4793: + if p++; p == pe { + goto _test_eof4793 + } + st_case_4793: + if 169 <= data[p] && data[p] <= 182 { + goto tr4327 + } + goto tr4328 + st4794: + if p++; p == pe { + goto _test_eof4794 + } + st_case_4794: + if data[p] == 131 { + goto tr4327 + } + switch { + case data[p] > 141: + if 187 <= data[p] && data[p] <= 189 { + goto tr4327 + } + case data[p] >= 140: + goto tr4327 + } + goto tr4328 + st4795: + if p++; p == pe { + goto _test_eof4795 + } + st_case_4795: + if data[p] == 176 { + goto tr4327 + } + switch { + case data[p] < 183: + if 178 <= data[p] && data[p] <= 180 { + goto tr4327 + } + case data[p] > 184: + if 190 <= data[p] && data[p] <= 191 { + goto tr4327 + } + default: + goto tr4327 + } + goto tr4328 + st4796: + if p++; p == pe { + goto _test_eof4796 + } + st_case_4796: + if data[p] == 129 { + goto tr4327 + } + switch { + case data[p] > 175: + if 181 <= data[p] && data[p] <= 182 { + goto tr4327 + } + case data[p] >= 171: + goto tr4327 + } + goto tr4328 + st4797: + if p++; p == pe { + goto _test_eof4797 + } + st_case_4797: + switch { + case data[p] > 170: + if 172 <= data[p] && data[p] <= 173 { + goto tr4327 + } + case data[p] >= 163: + goto tr4327 + } + goto tr4328 + st4798: + if p++; p == pe { + goto _test_eof4798 + } + st_case_4798: + switch data[p] { + case 172: + goto st4799 + case 184: + goto st4800 + case 187: + goto st4777 + case 190: + goto st4784 + case 191: + goto st4801 + } + goto tr4328 + st4799: + if p++; p == pe { + goto _test_eof4799 + } + st_case_4799: + if data[p] == 158 { + goto tr4327 + } + goto tr4328 + st4800: + if p++; p == pe { + goto _test_eof4800 + } + st_case_4800: + switch { + case data[p] > 143: + if 160 <= data[p] && data[p] <= 175 { + goto tr4327 + } + case data[p] >= 128: + goto tr4327 + } + goto tr4328 + st4801: + if p++; p == pe { + goto _test_eof4801 + } + st_case_4801: + if 185 <= data[p] && data[p] <= 187 { + goto tr4327 + } + goto tr4328 + st4802: + if p++; p == pe { + goto _test_eof4802 + } + st_case_4802: + switch data[p] { + case 144: + goto st4803 + case 145: + goto st4809 + case 150: + goto st4828 + case 155: + goto st4833 + case 157: + goto st4835 + case 158: + goto st4842 + case 159: + goto st4844 + } + goto tr4328 + st4803: + if p++; p == pe { + goto _test_eof4803 + } + st_case_4803: + switch data[p] { + case 135: + goto st4804 + case 139: + goto st4805 + case 141: + goto st4806 + case 168: + goto st4807 + case 171: + goto st4808 + } + goto tr4328 + st4804: + if p++; p == pe { + goto _test_eof4804 + } + st_case_4804: + if data[p] == 189 { + goto tr4327 + } + goto tr4328 + st4805: + if p++; p == pe { + goto _test_eof4805 + } + st_case_4805: + if data[p] == 160 { + goto tr4327 + } + goto tr4328 + st4806: + if p++; p == pe { + goto _test_eof4806 + } + st_case_4806: + if 182 <= data[p] && data[p] <= 186 { + goto tr4327 + } + goto tr4328 + st4807: + if p++; p == pe { + goto _test_eof4807 + } + st_case_4807: + if data[p] == 191 { + goto tr4327 + } + switch { + case data[p] < 133: + if 129 <= data[p] && data[p] <= 131 { + goto tr4327 + } + case data[p] > 134: + switch { + case data[p] > 143: + if 184 <= data[p] && data[p] <= 186 { + goto tr4327 + } + case data[p] >= 140: + goto tr4327 + } + default: + goto tr4327 + } + goto tr4328 + st4808: + if p++; p == pe { + goto _test_eof4808 + } + st_case_4808: + if 165 <= data[p] && data[p] <= 166 { + goto tr4327 + } + goto tr4328 + st4809: + if p++; p == pe { + goto _test_eof4809 + } + st_case_4809: + switch data[p] { + case 128: + goto st4810 + case 129: + goto st4811 + case 130: + goto st4812 + case 132: + goto st4813 + case 133: + goto st4814 + case 134: + goto st4815 + case 135: + goto st4816 + case 136: + goto st4817 + case 139: + goto st4818 + case 140: + goto st4819 + case 141: + goto st4820 + case 146: + goto st4821 + case 147: + goto st4822 + case 150: + goto st4823 + case 151: + goto st4824 + case 152: + goto st4821 + case 153: + goto st4825 + case 154: + goto st4826 + case 156: + goto st4827 + } + goto tr4328 + st4810: + if p++; p == pe { + goto _test_eof4810 + } + st_case_4810: + switch { + case data[p] > 130: + if 184 <= data[p] { + goto tr4327 + } + case data[p] >= 128: + goto tr4327 + } + goto tr4328 + st4811: + if p++; p == pe { + goto _test_eof4811 + } + st_case_4811: + if 135 <= data[p] && data[p] <= 190 { + goto tr4328 + } + goto tr4327 + st4812: + if p++; p == pe { + goto _test_eof4812 + } + st_case_4812: + switch { + case data[p] < 187: + if 131 <= data[p] && data[p] <= 175 { + goto tr4328 + } + case data[p] > 188: + if 190 <= data[p] { + goto tr4328 + } + default: + goto tr4328 + } + goto tr4327 + st4813: + if p++; p == pe { + goto _test_eof4813 + } + st_case_4813: + switch { + case data[p] > 130: + if 167 <= data[p] && data[p] <= 180 { + goto tr4327 + } + case data[p] >= 128: + goto tr4327 + } + goto tr4328 + st4814: + if p++; p == pe { + goto _test_eof4814 + } + st_case_4814: + if data[p] == 179 { + goto tr4327 + } + goto tr4328 + st4815: + if p++; p == pe { + goto _test_eof4815 + } + st_case_4815: + switch { + case data[p] > 130: + if 179 <= data[p] { + goto tr4327 + } + case data[p] >= 128: + goto tr4327 + } + goto tr4328 + st4816: + if p++; p == pe { + goto _test_eof4816 + } + st_case_4816: + switch { + case data[p] > 137: + if 141 <= data[p] { + goto tr4328 + } + case data[p] >= 129: + goto tr4328 + } + goto tr4327 + st4817: + if p++; p == pe { + goto _test_eof4817 + } + st_case_4817: + if 172 <= data[p] && data[p] <= 183 { + goto tr4327 + } + goto tr4328 + st4818: + if p++; p == pe { + goto _test_eof4818 + } + st_case_4818: + if 159 <= data[p] && data[p] <= 170 { + goto tr4327 + } + goto tr4328 + st4819: + if p++; p == pe { + goto _test_eof4819 + } + st_case_4819: + if data[p] == 188 { + goto tr4327 + } + switch { + case data[p] > 131: + if 190 <= data[p] && data[p] <= 191 { + goto tr4327 + } + case data[p] >= 128: + goto tr4327 + } + goto tr4328 + st4820: + if p++; p == pe { + goto _test_eof4820 + } + st_case_4820: + if data[p] == 151 { + goto tr4327 + } + switch { + case data[p] < 139: + switch { + case data[p] > 132: + if 135 <= data[p] && data[p] <= 136 { + goto tr4327 + } + case data[p] >= 128: + goto tr4327 + } + case data[p] > 141: + switch { + case data[p] < 166: + if 162 <= data[p] && data[p] <= 163 { + goto tr4327 + } + case data[p] > 172: + if 176 <= data[p] && data[p] <= 180 { + goto tr4327 + } + default: + goto tr4327 + } + default: + goto tr4327 + } + goto tr4328 + st4821: + if p++; p == pe { + goto _test_eof4821 + } + st_case_4821: + if 176 <= data[p] { + goto tr4327 + } + goto tr4328 + st4822: + if p++; p == pe { + goto _test_eof4822 + } + st_case_4822: + if 132 <= data[p] { + goto tr4328 + } + goto tr4327 + st4823: + if p++; p == pe { + goto _test_eof4823 + } + st_case_4823: + switch { + case data[p] > 181: + if 184 <= data[p] { + goto tr4327 + } + case data[p] >= 175: + goto tr4327 + } + goto tr4328 + st4824: + if p++; p == pe { + goto _test_eof4824 + } + st_case_4824: + switch { + case data[p] > 155: + if 158 <= data[p] { + goto tr4328 + } + case data[p] >= 129: + goto tr4328 + } + goto tr4327 + st4825: + if p++; p == pe { + goto _test_eof4825 + } + st_case_4825: + if 129 <= data[p] { + goto tr4328 + } + goto tr4327 + st4826: + if p++; p == pe { + goto _test_eof4826 + } + st_case_4826: + if 171 <= data[p] && data[p] <= 183 { + goto tr4327 + } + goto tr4328 + st4827: + if p++; p == pe { + goto _test_eof4827 + } + st_case_4827: + if 157 <= data[p] && data[p] <= 171 { + goto tr4327 + } + goto tr4328 + st4828: + if p++; p == pe { + goto _test_eof4828 + } + st_case_4828: + switch data[p] { + case 171: + goto st4829 + case 172: + goto st4830 + case 189: + goto st4831 + case 190: + goto st4832 + } + goto tr4328 + st4829: + if p++; p == pe { + goto _test_eof4829 + } + st_case_4829: + if 176 <= data[p] && data[p] <= 180 { + goto tr4327 + } + goto tr4328 + st4830: + if p++; p == pe { + goto _test_eof4830 + } + st_case_4830: + if 176 <= data[p] && data[p] <= 182 { + goto tr4327 + } + goto tr4328 + st4831: + if p++; p == pe { + goto _test_eof4831 + } + st_case_4831: + if 145 <= data[p] && data[p] <= 190 { + goto tr4327 + } + goto tr4328 + st4832: + if p++; p == pe { + goto _test_eof4832 + } + st_case_4832: + if 143 <= data[p] && data[p] <= 146 { + goto tr4327 + } + goto tr4328 + st4833: + if p++; p == pe { + goto _test_eof4833 + } + st_case_4833: + if data[p] == 178 { + goto st4834 + } + goto tr4328 + st4834: + if p++; p == pe { + goto _test_eof4834 + } + st_case_4834: + switch { + case data[p] > 158: + if 160 <= data[p] && data[p] <= 163 { + goto tr4327 + } + case data[p] >= 157: + goto tr4327 + } + goto tr4328 + st4835: + if p++; p == pe { + goto _test_eof4835 + } + st_case_4835: + switch data[p] { + case 133: + goto st4836 + case 134: + goto st4837 + case 137: + goto st4838 + case 168: + goto st4839 + case 169: + goto st4840 + case 170: + goto st4841 + } + goto tr4328 + st4836: + if p++; p == pe { + goto _test_eof4836 + } + st_case_4836: + switch { + case data[p] > 169: + if 173 <= data[p] { + goto tr4327 + } + case data[p] >= 165: + goto tr4327 + } + goto tr4328 + st4837: + if p++; p == pe { + goto _test_eof4837 + } + st_case_4837: + switch { + case data[p] < 140: + if 131 <= data[p] && data[p] <= 132 { + goto tr4328 + } + case data[p] > 169: + if 174 <= data[p] { + goto tr4328 + } + default: + goto tr4328 + } + goto tr4327 + st4838: + if p++; p == pe { + goto _test_eof4838 + } + st_case_4838: + if 130 <= data[p] && data[p] <= 132 { + goto tr4327 + } + goto tr4328 + st4839: + if p++; p == pe { + goto _test_eof4839 + } + st_case_4839: + switch { + case data[p] > 182: + if 187 <= data[p] { + goto tr4327 + } + case data[p] >= 128: + goto tr4327 + } + goto tr4328 + st4840: + if p++; p == pe { + goto _test_eof4840 + } + st_case_4840: + switch { + case data[p] > 180: + if 182 <= data[p] { + goto tr4328 + } + case data[p] >= 173: + goto tr4328 + } + goto tr4327 + st4841: + if p++; p == pe { + goto _test_eof4841 + } + st_case_4841: + if data[p] == 132 { + goto tr4327 + } + switch { + case data[p] > 159: + if 161 <= data[p] && data[p] <= 175 { + goto tr4327 + } + case data[p] >= 155: + goto tr4327 + } + goto tr4328 + st4842: + if p++; p == pe { + goto _test_eof4842 + } + st_case_4842: + if data[p] == 163 { + goto st4843 + } + goto tr4328 + st4843: + if p++; p == pe { + goto _test_eof4843 + } + st_case_4843: + if 144 <= data[p] && data[p] <= 150 { + goto tr4327 + } + goto tr4328 + st4844: + if p++; p == pe { + goto _test_eof4844 + } + st_case_4844: + if data[p] == 135 { + goto st4707 + } + goto tr4328 + st4845: + if p++; p == pe { + goto _test_eof4845 + } + st_case_4845: + if data[p] == 160 { + goto st4846 + } + goto tr4328 + st4846: + if p++; p == pe { + goto _test_eof4846 + } + st_case_4846: + switch data[p] { + case 128: + goto st4847 + case 129: + goto st4848 + case 132: + goto st4709 + case 135: + goto st4710 + } + if 133 <= data[p] && data[p] <= 134 { + goto st4849 + } + goto tr4328 + st4847: + if p++; p == pe { + goto _test_eof4847 + } + st_case_4847: + if data[p] == 129 { + goto tr4327 + } + if 160 <= data[p] { + goto tr4327 + } + goto tr4328 + st4848: + if p++; p == pe { + goto _test_eof4848 + } + st_case_4848: + if 192 <= data[p] { + goto tr4328 + } + goto tr4327 + st4849: + if p++; p == pe { + goto _test_eof4849 + } + st_case_4849: + goto tr4327 + st4850: + if p++; p == pe { + goto _test_eof4850 + } + st_case_4850: + if data[p] == 128 { + goto tr3757 + } + goto tr0 + st4851: + if p++; p == pe { + goto _test_eof4851 + } + st_case_4851: + if data[p] == 128 { + goto st3595 + } + if 129 <= data[p] { + goto st3734 + } + goto tr0 + st4852: + if p++; p == pe { + goto _test_eof4852 + } + st_case_4852: + goto st3734 + st4853: + if p++; p == pe { + goto _test_eof4853 + } + st_case_4853: + switch data[p] { + case 155: + goto st4854 + case 156: + goto st3595 + } + goto st3734 + st4854: + if p++; p == pe { + goto _test_eof4854 + } + st_case_4854: + if 151 <= data[p] { + goto tr0 + } + goto tr3250 + st4855: + if p++; p == pe { + goto _test_eof4855 + } + st_case_4855: + switch data[p] { + case 156: + goto st4856 + case 157: + goto st3595 + case 160: + goto st4857 + } + goto st3734 + st4856: + if p++; p == pe { + goto _test_eof4856 + } + st_case_4856: + if 181 <= data[p] { + goto tr0 + } + goto tr3250 + st4857: + if p++; p == pe { + goto _test_eof4857 + } + st_case_4857: + if 158 <= data[p] && data[p] <= 159 { + goto tr0 + } + goto tr3250 + st4858: + if p++; p == pe { + goto _test_eof4858 + } + st_case_4858: + if data[p] == 186 { + goto st4859 + } + if 187 <= data[p] { + goto tr0 + } + goto st3734 + st4859: + if p++; p == pe { + goto _test_eof4859 + } + st_case_4859: + if 162 <= data[p] { + goto tr0 + } + goto tr3250 + st4860: + if p++; p == pe { + goto _test_eof4860 + } + st_case_4860: + switch data[p] { + case 160: + goto st3595 + case 168: + goto st4861 + } + if 161 <= data[p] && data[p] <= 167 { + goto st3734 + } + goto tr0 + st4861: + if p++; p == pe { + goto _test_eof4861 + } + st_case_4861: + if 158 <= data[p] { + goto tr0 + } + goto tr3250 + st_out: + _test_eof4862: cs = 4862; goto _test_eof + _test_eof4863: cs = 4863; goto _test_eof + _test_eof0: cs = 0; goto _test_eof + _test_eof1: cs = 1; goto _test_eof + _test_eof2: cs = 2; goto _test_eof + _test_eof3: cs = 3; goto _test_eof + _test_eof4: cs = 4; goto _test_eof + _test_eof5: cs = 5; goto _test_eof + _test_eof6: cs = 6; goto _test_eof + _test_eof7: cs = 7; goto _test_eof + _test_eof8: cs = 8; goto _test_eof + _test_eof9: cs = 9; goto _test_eof + _test_eof10: cs = 10; goto _test_eof + _test_eof11: cs = 11; goto _test_eof + _test_eof12: cs = 12; goto _test_eof + _test_eof13: cs = 13; goto _test_eof + _test_eof14: cs = 14; goto _test_eof + _test_eof15: cs = 15; goto _test_eof + _test_eof16: cs = 16; goto _test_eof + _test_eof17: cs = 17; goto _test_eof + _test_eof18: cs = 18; goto _test_eof + _test_eof19: cs = 19; goto _test_eof + _test_eof20: cs = 20; goto _test_eof + _test_eof21: cs = 21; goto _test_eof + _test_eof22: cs = 22; goto _test_eof + _test_eof23: cs = 23; goto _test_eof + _test_eof24: cs = 24; goto _test_eof + _test_eof25: cs = 25; goto _test_eof + _test_eof26: cs = 26; goto _test_eof + _test_eof27: cs = 27; goto _test_eof + _test_eof28: cs = 28; goto _test_eof + _test_eof29: cs = 29; goto _test_eof + _test_eof30: cs = 30; goto _test_eof + _test_eof31: cs = 31; goto _test_eof + _test_eof32: cs = 32; goto _test_eof + _test_eof33: cs = 33; goto _test_eof + _test_eof34: cs = 34; goto _test_eof + _test_eof35: cs = 35; goto _test_eof + _test_eof36: cs = 36; goto _test_eof + _test_eof37: cs = 37; goto _test_eof + _test_eof38: cs = 38; goto _test_eof + _test_eof39: cs = 39; goto _test_eof + _test_eof40: cs = 40; goto _test_eof + _test_eof41: cs = 41; goto _test_eof + _test_eof42: cs = 42; goto _test_eof + _test_eof43: cs = 43; goto _test_eof + _test_eof44: cs = 44; goto _test_eof + _test_eof45: cs = 45; goto _test_eof + _test_eof46: cs = 46; goto _test_eof + _test_eof47: cs = 47; goto _test_eof + _test_eof48: cs = 48; goto _test_eof + _test_eof49: cs = 49; goto _test_eof + _test_eof50: cs = 50; goto _test_eof + _test_eof51: cs = 51; goto _test_eof + _test_eof52: cs = 52; goto _test_eof + _test_eof53: cs = 53; goto _test_eof + _test_eof54: cs = 54; goto _test_eof + _test_eof55: cs = 55; goto _test_eof + _test_eof56: cs = 56; goto _test_eof + _test_eof57: cs = 57; goto _test_eof + _test_eof58: cs = 58; goto _test_eof + _test_eof59: cs = 59; goto _test_eof + _test_eof60: cs = 60; goto _test_eof + _test_eof61: cs = 61; goto _test_eof + _test_eof62: cs = 62; goto _test_eof + _test_eof63: cs = 63; goto _test_eof + _test_eof64: cs = 64; goto _test_eof + _test_eof65: cs = 65; goto _test_eof + _test_eof66: cs = 66; goto _test_eof + _test_eof67: cs = 67; goto _test_eof + _test_eof68: cs = 68; goto _test_eof + _test_eof69: cs = 69; goto _test_eof + _test_eof70: cs = 70; goto _test_eof + _test_eof71: cs = 71; goto _test_eof + _test_eof72: cs = 72; goto _test_eof + _test_eof73: cs = 73; goto _test_eof + _test_eof74: cs = 74; goto _test_eof + _test_eof75: cs = 75; goto _test_eof + _test_eof76: cs = 76; goto _test_eof + _test_eof77: cs = 77; goto _test_eof + _test_eof78: cs = 78; goto _test_eof + _test_eof79: cs = 79; goto _test_eof + _test_eof80: cs = 80; goto _test_eof + _test_eof81: cs = 81; goto _test_eof + _test_eof82: cs = 82; goto _test_eof + _test_eof83: cs = 83; goto _test_eof + _test_eof84: cs = 84; goto _test_eof + _test_eof85: cs = 85; goto _test_eof + _test_eof86: cs = 86; goto _test_eof + _test_eof87: cs = 87; goto _test_eof + _test_eof88: cs = 88; goto _test_eof + _test_eof89: cs = 89; goto _test_eof + _test_eof90: cs = 90; goto _test_eof + _test_eof91: cs = 91; goto _test_eof + _test_eof92: cs = 92; goto _test_eof + _test_eof93: cs = 93; goto _test_eof + _test_eof94: cs = 94; goto _test_eof + _test_eof95: cs = 95; goto _test_eof + _test_eof96: cs = 96; goto _test_eof + _test_eof97: cs = 97; goto _test_eof + _test_eof98: cs = 98; goto _test_eof + _test_eof99: cs = 99; goto _test_eof + _test_eof100: cs = 100; goto _test_eof + _test_eof101: cs = 101; goto _test_eof + _test_eof102: cs = 102; goto _test_eof + _test_eof103: cs = 103; goto _test_eof + _test_eof104: cs = 104; goto _test_eof + _test_eof105: cs = 105; goto _test_eof + _test_eof106: cs = 106; goto _test_eof + _test_eof107: cs = 107; goto _test_eof + _test_eof108: cs = 108; goto _test_eof + _test_eof109: cs = 109; goto _test_eof + _test_eof110: cs = 110; goto _test_eof + _test_eof111: cs = 111; goto _test_eof + _test_eof112: cs = 112; goto _test_eof + _test_eof113: cs = 113; goto _test_eof + _test_eof114: cs = 114; goto _test_eof + _test_eof115: cs = 115; goto _test_eof + _test_eof116: cs = 116; goto _test_eof + _test_eof117: cs = 117; goto _test_eof + _test_eof118: cs = 118; goto _test_eof + _test_eof119: cs = 119; goto _test_eof + _test_eof120: cs = 120; goto _test_eof + _test_eof121: cs = 121; goto _test_eof + _test_eof122: cs = 122; goto _test_eof + _test_eof123: cs = 123; goto _test_eof + _test_eof124: cs = 124; goto _test_eof + _test_eof125: cs = 125; goto _test_eof + _test_eof126: cs = 126; goto _test_eof + _test_eof127: cs = 127; goto _test_eof + _test_eof128: cs = 128; goto _test_eof + _test_eof129: cs = 129; goto _test_eof + _test_eof130: cs = 130; goto _test_eof + _test_eof131: cs = 131; goto _test_eof + _test_eof132: cs = 132; goto _test_eof + _test_eof133: cs = 133; goto _test_eof + _test_eof134: cs = 134; goto _test_eof + _test_eof135: cs = 135; goto _test_eof + _test_eof136: cs = 136; goto _test_eof + _test_eof137: cs = 137; goto _test_eof + _test_eof138: cs = 138; goto _test_eof + _test_eof139: cs = 139; goto _test_eof + _test_eof140: cs = 140; goto _test_eof + _test_eof4864: cs = 4864; goto _test_eof + _test_eof4865: cs = 4865; goto _test_eof + _test_eof141: cs = 141; goto _test_eof + _test_eof4866: cs = 4866; goto _test_eof + _test_eof4867: cs = 4867; goto _test_eof + _test_eof142: cs = 142; goto _test_eof + _test_eof143: cs = 143; goto _test_eof + _test_eof144: cs = 144; goto _test_eof + _test_eof145: cs = 145; goto _test_eof + _test_eof146: cs = 146; goto _test_eof + _test_eof147: cs = 147; goto _test_eof + _test_eof148: cs = 148; goto _test_eof + _test_eof149: cs = 149; goto _test_eof + _test_eof150: cs = 150; goto _test_eof + _test_eof151: cs = 151; goto _test_eof + _test_eof152: cs = 152; goto _test_eof + _test_eof153: cs = 153; goto _test_eof + _test_eof154: cs = 154; goto _test_eof + _test_eof155: cs = 155; goto _test_eof + _test_eof156: cs = 156; goto _test_eof + _test_eof157: cs = 157; goto _test_eof + _test_eof158: cs = 158; goto _test_eof + _test_eof159: cs = 159; goto _test_eof + _test_eof160: cs = 160; goto _test_eof + _test_eof161: cs = 161; goto _test_eof + _test_eof162: cs = 162; goto _test_eof + _test_eof163: cs = 163; goto _test_eof + _test_eof164: cs = 164; goto _test_eof + _test_eof165: cs = 165; goto _test_eof + _test_eof166: cs = 166; goto _test_eof + _test_eof167: cs = 167; goto _test_eof + _test_eof168: cs = 168; goto _test_eof + _test_eof169: cs = 169; goto _test_eof + _test_eof170: cs = 170; goto _test_eof + _test_eof171: cs = 171; goto _test_eof + _test_eof172: cs = 172; goto _test_eof + _test_eof173: cs = 173; goto _test_eof + _test_eof174: cs = 174; goto _test_eof + _test_eof175: cs = 175; goto _test_eof + _test_eof176: cs = 176; goto _test_eof + _test_eof177: cs = 177; goto _test_eof + _test_eof178: cs = 178; goto _test_eof + _test_eof179: cs = 179; goto _test_eof + _test_eof180: cs = 180; goto _test_eof + _test_eof181: cs = 181; goto _test_eof + _test_eof182: cs = 182; goto _test_eof + _test_eof183: cs = 183; goto _test_eof + _test_eof184: cs = 184; goto _test_eof + _test_eof185: cs = 185; goto _test_eof + _test_eof186: cs = 186; goto _test_eof + _test_eof187: cs = 187; goto _test_eof + _test_eof188: cs = 188; goto _test_eof + _test_eof189: cs = 189; goto _test_eof + _test_eof190: cs = 190; goto _test_eof + _test_eof191: cs = 191; goto _test_eof + _test_eof192: cs = 192; goto _test_eof + _test_eof193: cs = 193; goto _test_eof + _test_eof194: cs = 194; goto _test_eof + _test_eof195: cs = 195; goto _test_eof + _test_eof196: cs = 196; goto _test_eof + _test_eof197: cs = 197; goto _test_eof + _test_eof198: cs = 198; goto _test_eof + _test_eof199: cs = 199; goto _test_eof + _test_eof200: cs = 200; goto _test_eof + _test_eof201: cs = 201; goto _test_eof + _test_eof202: cs = 202; goto _test_eof + _test_eof203: cs = 203; goto _test_eof + _test_eof204: cs = 204; goto _test_eof + _test_eof205: cs = 205; goto _test_eof + _test_eof206: cs = 206; goto _test_eof + _test_eof207: cs = 207; goto _test_eof + _test_eof208: cs = 208; goto _test_eof + _test_eof209: cs = 209; goto _test_eof + _test_eof210: cs = 210; goto _test_eof + _test_eof211: cs = 211; goto _test_eof + _test_eof212: cs = 212; goto _test_eof + _test_eof213: cs = 213; goto _test_eof + _test_eof214: cs = 214; goto _test_eof + _test_eof215: cs = 215; goto _test_eof + _test_eof216: cs = 216; goto _test_eof + _test_eof217: cs = 217; goto _test_eof + _test_eof218: cs = 218; goto _test_eof + _test_eof219: cs = 219; goto _test_eof + _test_eof220: cs = 220; goto _test_eof + _test_eof221: cs = 221; goto _test_eof + _test_eof222: cs = 222; goto _test_eof + _test_eof223: cs = 223; goto _test_eof + _test_eof224: cs = 224; goto _test_eof + _test_eof225: cs = 225; goto _test_eof + _test_eof226: cs = 226; goto _test_eof + _test_eof227: cs = 227; goto _test_eof + _test_eof228: cs = 228; goto _test_eof + _test_eof229: cs = 229; goto _test_eof + _test_eof230: cs = 230; goto _test_eof + _test_eof231: cs = 231; goto _test_eof + _test_eof232: cs = 232; goto _test_eof + _test_eof233: cs = 233; goto _test_eof + _test_eof234: cs = 234; goto _test_eof + _test_eof235: cs = 235; goto _test_eof + _test_eof236: cs = 236; goto _test_eof + _test_eof237: cs = 237; goto _test_eof + _test_eof238: cs = 238; goto _test_eof + _test_eof239: cs = 239; goto _test_eof + _test_eof240: cs = 240; goto _test_eof + _test_eof241: cs = 241; goto _test_eof + _test_eof242: cs = 242; goto _test_eof + _test_eof243: cs = 243; goto _test_eof + _test_eof244: cs = 244; goto _test_eof + _test_eof245: cs = 245; goto _test_eof + _test_eof246: cs = 246; goto _test_eof + _test_eof247: cs = 247; goto _test_eof + _test_eof248: cs = 248; goto _test_eof + _test_eof249: cs = 249; goto _test_eof + _test_eof250: cs = 250; goto _test_eof + _test_eof251: cs = 251; goto _test_eof + _test_eof252: cs = 252; goto _test_eof + _test_eof253: cs = 253; goto _test_eof + _test_eof254: cs = 254; goto _test_eof + _test_eof255: cs = 255; goto _test_eof + _test_eof256: cs = 256; goto _test_eof + _test_eof257: cs = 257; goto _test_eof + _test_eof258: cs = 258; goto _test_eof + _test_eof259: cs = 259; goto _test_eof + _test_eof260: cs = 260; goto _test_eof + _test_eof261: cs = 261; goto _test_eof + _test_eof262: cs = 262; goto _test_eof + _test_eof263: cs = 263; goto _test_eof + _test_eof264: cs = 264; goto _test_eof + _test_eof265: cs = 265; goto _test_eof + _test_eof266: cs = 266; goto _test_eof + _test_eof267: cs = 267; goto _test_eof + _test_eof268: cs = 268; goto _test_eof + _test_eof269: cs = 269; goto _test_eof + _test_eof270: cs = 270; goto _test_eof + _test_eof271: cs = 271; goto _test_eof + _test_eof272: cs = 272; goto _test_eof + _test_eof273: cs = 273; goto _test_eof + _test_eof274: cs = 274; goto _test_eof + _test_eof275: cs = 275; goto _test_eof + _test_eof276: cs = 276; goto _test_eof + _test_eof277: cs = 277; goto _test_eof + _test_eof278: cs = 278; goto _test_eof + _test_eof279: cs = 279; goto _test_eof + _test_eof280: cs = 280; goto _test_eof + _test_eof281: cs = 281; goto _test_eof + _test_eof282: cs = 282; goto _test_eof + _test_eof283: cs = 283; goto _test_eof + _test_eof284: cs = 284; goto _test_eof + _test_eof285: cs = 285; goto _test_eof + _test_eof286: cs = 286; goto _test_eof + _test_eof287: cs = 287; goto _test_eof + _test_eof288: cs = 288; goto _test_eof + _test_eof289: cs = 289; goto _test_eof + _test_eof290: cs = 290; goto _test_eof + _test_eof291: cs = 291; goto _test_eof + _test_eof292: cs = 292; goto _test_eof + _test_eof293: cs = 293; goto _test_eof + _test_eof294: cs = 294; goto _test_eof + _test_eof295: cs = 295; goto _test_eof + _test_eof296: cs = 296; goto _test_eof + _test_eof297: cs = 297; goto _test_eof + _test_eof298: cs = 298; goto _test_eof + _test_eof299: cs = 299; goto _test_eof + _test_eof300: cs = 300; goto _test_eof + _test_eof301: cs = 301; goto _test_eof + _test_eof302: cs = 302; goto _test_eof + _test_eof303: cs = 303; goto _test_eof + _test_eof304: cs = 304; goto _test_eof + _test_eof305: cs = 305; goto _test_eof + _test_eof306: cs = 306; goto _test_eof + _test_eof307: cs = 307; goto _test_eof + _test_eof308: cs = 308; goto _test_eof + _test_eof309: cs = 309; goto _test_eof + _test_eof310: cs = 310; goto _test_eof + _test_eof311: cs = 311; goto _test_eof + _test_eof312: cs = 312; goto _test_eof + _test_eof313: cs = 313; goto _test_eof + _test_eof314: cs = 314; goto _test_eof + _test_eof315: cs = 315; goto _test_eof + _test_eof316: cs = 316; goto _test_eof + _test_eof317: cs = 317; goto _test_eof + _test_eof318: cs = 318; goto _test_eof + _test_eof319: cs = 319; goto _test_eof + _test_eof320: cs = 320; goto _test_eof + _test_eof321: cs = 321; goto _test_eof + _test_eof322: cs = 322; goto _test_eof + _test_eof323: cs = 323; goto _test_eof + _test_eof324: cs = 324; goto _test_eof + _test_eof325: cs = 325; goto _test_eof + _test_eof326: cs = 326; goto _test_eof + _test_eof327: cs = 327; goto _test_eof + _test_eof328: cs = 328; goto _test_eof + _test_eof329: cs = 329; goto _test_eof + _test_eof330: cs = 330; goto _test_eof + _test_eof331: cs = 331; goto _test_eof + _test_eof332: cs = 332; goto _test_eof + _test_eof333: cs = 333; goto _test_eof + _test_eof334: cs = 334; goto _test_eof + _test_eof335: cs = 335; goto _test_eof + _test_eof336: cs = 336; goto _test_eof + _test_eof337: cs = 337; goto _test_eof + _test_eof338: cs = 338; goto _test_eof + _test_eof339: cs = 339; goto _test_eof + _test_eof340: cs = 340; goto _test_eof + _test_eof341: cs = 341; goto _test_eof + _test_eof342: cs = 342; goto _test_eof + _test_eof343: cs = 343; goto _test_eof + _test_eof344: cs = 344; goto _test_eof + _test_eof345: cs = 345; goto _test_eof + _test_eof346: cs = 346; goto _test_eof + _test_eof347: cs = 347; goto _test_eof + _test_eof348: cs = 348; goto _test_eof + _test_eof349: cs = 349; goto _test_eof + _test_eof350: cs = 350; goto _test_eof + _test_eof351: cs = 351; goto _test_eof + _test_eof352: cs = 352; goto _test_eof + _test_eof353: cs = 353; goto _test_eof + _test_eof354: cs = 354; goto _test_eof + _test_eof355: cs = 355; goto _test_eof + _test_eof356: cs = 356; goto _test_eof + _test_eof357: cs = 357; goto _test_eof + _test_eof358: cs = 358; goto _test_eof + _test_eof359: cs = 359; goto _test_eof + _test_eof360: cs = 360; goto _test_eof + _test_eof361: cs = 361; goto _test_eof + _test_eof362: cs = 362; goto _test_eof + _test_eof363: cs = 363; goto _test_eof + _test_eof364: cs = 364; goto _test_eof + _test_eof365: cs = 365; goto _test_eof + _test_eof366: cs = 366; goto _test_eof + _test_eof367: cs = 367; goto _test_eof + _test_eof368: cs = 368; goto _test_eof + _test_eof369: cs = 369; goto _test_eof + _test_eof370: cs = 370; goto _test_eof + _test_eof371: cs = 371; goto _test_eof + _test_eof372: cs = 372; goto _test_eof + _test_eof373: cs = 373; goto _test_eof + _test_eof374: cs = 374; goto _test_eof + _test_eof375: cs = 375; goto _test_eof + _test_eof376: cs = 376; goto _test_eof + _test_eof377: cs = 377; goto _test_eof + _test_eof378: cs = 378; goto _test_eof + _test_eof379: cs = 379; goto _test_eof + _test_eof380: cs = 380; goto _test_eof + _test_eof381: cs = 381; goto _test_eof + _test_eof382: cs = 382; goto _test_eof + _test_eof383: cs = 383; goto _test_eof + _test_eof384: cs = 384; goto _test_eof + _test_eof385: cs = 385; goto _test_eof + _test_eof386: cs = 386; goto _test_eof + _test_eof387: cs = 387; goto _test_eof + _test_eof388: cs = 388; goto _test_eof + _test_eof389: cs = 389; goto _test_eof + _test_eof390: cs = 390; goto _test_eof + _test_eof391: cs = 391; goto _test_eof + _test_eof392: cs = 392; goto _test_eof + _test_eof393: cs = 393; goto _test_eof + _test_eof394: cs = 394; goto _test_eof + _test_eof395: cs = 395; goto _test_eof + _test_eof396: cs = 396; goto _test_eof + _test_eof397: cs = 397; goto _test_eof + _test_eof398: cs = 398; goto _test_eof + _test_eof399: cs = 399; goto _test_eof + _test_eof400: cs = 400; goto _test_eof + _test_eof401: cs = 401; goto _test_eof + _test_eof402: cs = 402; goto _test_eof + _test_eof403: cs = 403; goto _test_eof + _test_eof404: cs = 404; goto _test_eof + _test_eof405: cs = 405; goto _test_eof + _test_eof406: cs = 406; goto _test_eof + _test_eof407: cs = 407; goto _test_eof + _test_eof408: cs = 408; goto _test_eof + _test_eof409: cs = 409; goto _test_eof + _test_eof410: cs = 410; goto _test_eof + _test_eof411: cs = 411; goto _test_eof + _test_eof412: cs = 412; goto _test_eof + _test_eof4868: cs = 4868; goto _test_eof + _test_eof413: cs = 413; goto _test_eof + _test_eof414: cs = 414; goto _test_eof + _test_eof415: cs = 415; goto _test_eof + _test_eof416: cs = 416; goto _test_eof + _test_eof417: cs = 417; goto _test_eof + _test_eof418: cs = 418; goto _test_eof + _test_eof419: cs = 419; goto _test_eof + _test_eof420: cs = 420; goto _test_eof + _test_eof421: cs = 421; goto _test_eof + _test_eof422: cs = 422; goto _test_eof + _test_eof423: cs = 423; goto _test_eof + _test_eof424: cs = 424; goto _test_eof + _test_eof425: cs = 425; goto _test_eof + _test_eof426: cs = 426; goto _test_eof + _test_eof427: cs = 427; goto _test_eof + _test_eof428: cs = 428; goto _test_eof + _test_eof429: cs = 429; goto _test_eof + _test_eof430: cs = 430; goto _test_eof + _test_eof431: cs = 431; goto _test_eof + _test_eof432: cs = 432; goto _test_eof + _test_eof433: cs = 433; goto _test_eof + _test_eof434: cs = 434; goto _test_eof + _test_eof435: cs = 435; goto _test_eof + _test_eof436: cs = 436; goto _test_eof + _test_eof437: cs = 437; goto _test_eof + _test_eof438: cs = 438; goto _test_eof + _test_eof439: cs = 439; goto _test_eof + _test_eof440: cs = 440; goto _test_eof + _test_eof441: cs = 441; goto _test_eof + _test_eof442: cs = 442; goto _test_eof + _test_eof443: cs = 443; goto _test_eof + _test_eof444: cs = 444; goto _test_eof + _test_eof445: cs = 445; goto _test_eof + _test_eof446: cs = 446; goto _test_eof + _test_eof447: cs = 447; goto _test_eof + _test_eof448: cs = 448; goto _test_eof + _test_eof449: cs = 449; goto _test_eof + _test_eof450: cs = 450; goto _test_eof + _test_eof451: cs = 451; goto _test_eof + _test_eof452: cs = 452; goto _test_eof + _test_eof453: cs = 453; goto _test_eof + _test_eof454: cs = 454; goto _test_eof + _test_eof455: cs = 455; goto _test_eof + _test_eof456: cs = 456; goto _test_eof + _test_eof457: cs = 457; goto _test_eof + _test_eof458: cs = 458; goto _test_eof + _test_eof459: cs = 459; goto _test_eof + _test_eof460: cs = 460; goto _test_eof + _test_eof461: cs = 461; goto _test_eof + _test_eof462: cs = 462; goto _test_eof + _test_eof463: cs = 463; goto _test_eof + _test_eof464: cs = 464; goto _test_eof + _test_eof465: cs = 465; goto _test_eof + _test_eof466: cs = 466; goto _test_eof + _test_eof467: cs = 467; goto _test_eof + _test_eof468: cs = 468; goto _test_eof + _test_eof469: cs = 469; goto _test_eof + _test_eof470: cs = 470; goto _test_eof + _test_eof471: cs = 471; goto _test_eof + _test_eof472: cs = 472; goto _test_eof + _test_eof473: cs = 473; goto _test_eof + _test_eof474: cs = 474; goto _test_eof + _test_eof475: cs = 475; goto _test_eof + _test_eof476: cs = 476; goto _test_eof + _test_eof477: cs = 477; goto _test_eof + _test_eof478: cs = 478; goto _test_eof + _test_eof479: cs = 479; goto _test_eof + _test_eof480: cs = 480; goto _test_eof + _test_eof481: cs = 481; goto _test_eof + _test_eof482: cs = 482; goto _test_eof + _test_eof483: cs = 483; goto _test_eof + _test_eof484: cs = 484; goto _test_eof + _test_eof485: cs = 485; goto _test_eof + _test_eof486: cs = 486; goto _test_eof + _test_eof487: cs = 487; goto _test_eof + _test_eof488: cs = 488; goto _test_eof + _test_eof489: cs = 489; goto _test_eof + _test_eof490: cs = 490; goto _test_eof + _test_eof491: cs = 491; goto _test_eof + _test_eof492: cs = 492; goto _test_eof + _test_eof493: cs = 493; goto _test_eof + _test_eof494: cs = 494; goto _test_eof + _test_eof495: cs = 495; goto _test_eof + _test_eof496: cs = 496; goto _test_eof + _test_eof497: cs = 497; goto _test_eof + _test_eof498: cs = 498; goto _test_eof + _test_eof499: cs = 499; goto _test_eof + _test_eof500: cs = 500; goto _test_eof + _test_eof501: cs = 501; goto _test_eof + _test_eof502: cs = 502; goto _test_eof + _test_eof503: cs = 503; goto _test_eof + _test_eof504: cs = 504; goto _test_eof + _test_eof505: cs = 505; goto _test_eof + _test_eof506: cs = 506; goto _test_eof + _test_eof507: cs = 507; goto _test_eof + _test_eof508: cs = 508; goto _test_eof + _test_eof509: cs = 509; goto _test_eof + _test_eof510: cs = 510; goto _test_eof + _test_eof511: cs = 511; goto _test_eof + _test_eof512: cs = 512; goto _test_eof + _test_eof513: cs = 513; goto _test_eof + _test_eof514: cs = 514; goto _test_eof + _test_eof515: cs = 515; goto _test_eof + _test_eof516: cs = 516; goto _test_eof + _test_eof517: cs = 517; goto _test_eof + _test_eof518: cs = 518; goto _test_eof + _test_eof519: cs = 519; goto _test_eof + _test_eof520: cs = 520; goto _test_eof + _test_eof521: cs = 521; goto _test_eof + _test_eof522: cs = 522; goto _test_eof + _test_eof523: cs = 523; goto _test_eof + _test_eof524: cs = 524; goto _test_eof + _test_eof525: cs = 525; goto _test_eof + _test_eof526: cs = 526; goto _test_eof + _test_eof527: cs = 527; goto _test_eof + _test_eof528: cs = 528; goto _test_eof + _test_eof529: cs = 529; goto _test_eof + _test_eof530: cs = 530; goto _test_eof + _test_eof531: cs = 531; goto _test_eof + _test_eof532: cs = 532; goto _test_eof + _test_eof533: cs = 533; goto _test_eof + _test_eof534: cs = 534; goto _test_eof + _test_eof535: cs = 535; goto _test_eof + _test_eof536: cs = 536; goto _test_eof + _test_eof537: cs = 537; goto _test_eof + _test_eof538: cs = 538; goto _test_eof + _test_eof539: cs = 539; goto _test_eof + _test_eof540: cs = 540; goto _test_eof + _test_eof541: cs = 541; goto _test_eof + _test_eof542: cs = 542; goto _test_eof + _test_eof543: cs = 543; goto _test_eof + _test_eof544: cs = 544; goto _test_eof + _test_eof545: cs = 545; goto _test_eof + _test_eof546: cs = 546; goto _test_eof + _test_eof547: cs = 547; goto _test_eof + _test_eof548: cs = 548; goto _test_eof + _test_eof549: cs = 549; goto _test_eof + _test_eof550: cs = 550; goto _test_eof + _test_eof551: cs = 551; goto _test_eof + _test_eof552: cs = 552; goto _test_eof + _test_eof553: cs = 553; goto _test_eof + _test_eof554: cs = 554; goto _test_eof + _test_eof555: cs = 555; goto _test_eof + _test_eof556: cs = 556; goto _test_eof + _test_eof557: cs = 557; goto _test_eof + _test_eof558: cs = 558; goto _test_eof + _test_eof559: cs = 559; goto _test_eof + _test_eof560: cs = 560; goto _test_eof + _test_eof561: cs = 561; goto _test_eof + _test_eof4869: cs = 4869; goto _test_eof + _test_eof562: cs = 562; goto _test_eof + _test_eof563: cs = 563; goto _test_eof + _test_eof564: cs = 564; goto _test_eof + _test_eof565: cs = 565; goto _test_eof + _test_eof566: cs = 566; goto _test_eof + _test_eof567: cs = 567; goto _test_eof + _test_eof4870: cs = 4870; goto _test_eof + _test_eof568: cs = 568; goto _test_eof + _test_eof569: cs = 569; goto _test_eof + _test_eof570: cs = 570; goto _test_eof + _test_eof571: cs = 571; goto _test_eof + _test_eof572: cs = 572; goto _test_eof + _test_eof573: cs = 573; goto _test_eof + _test_eof574: cs = 574; goto _test_eof + _test_eof4871: cs = 4871; goto _test_eof + _test_eof575: cs = 575; goto _test_eof + _test_eof576: cs = 576; goto _test_eof + _test_eof577: cs = 577; goto _test_eof + _test_eof578: cs = 578; goto _test_eof + _test_eof579: cs = 579; goto _test_eof + _test_eof580: cs = 580; goto _test_eof + _test_eof581: cs = 581; goto _test_eof + _test_eof582: cs = 582; goto _test_eof + _test_eof583: cs = 583; goto _test_eof + _test_eof584: cs = 584; goto _test_eof + _test_eof585: cs = 585; goto _test_eof + _test_eof586: cs = 586; goto _test_eof + _test_eof587: cs = 587; goto _test_eof + _test_eof588: cs = 588; goto _test_eof + _test_eof589: cs = 589; goto _test_eof + _test_eof590: cs = 590; goto _test_eof + _test_eof591: cs = 591; goto _test_eof + _test_eof592: cs = 592; goto _test_eof + _test_eof593: cs = 593; goto _test_eof + _test_eof594: cs = 594; goto _test_eof + _test_eof595: cs = 595; goto _test_eof + _test_eof596: cs = 596; goto _test_eof + _test_eof597: cs = 597; goto _test_eof + _test_eof598: cs = 598; goto _test_eof + _test_eof599: cs = 599; goto _test_eof + _test_eof600: cs = 600; goto _test_eof + _test_eof601: cs = 601; goto _test_eof + _test_eof602: cs = 602; goto _test_eof + _test_eof603: cs = 603; goto _test_eof + _test_eof604: cs = 604; goto _test_eof + _test_eof605: cs = 605; goto _test_eof + _test_eof606: cs = 606; goto _test_eof + _test_eof607: cs = 607; goto _test_eof + _test_eof608: cs = 608; goto _test_eof + _test_eof609: cs = 609; goto _test_eof + _test_eof610: cs = 610; goto _test_eof + _test_eof611: cs = 611; goto _test_eof + _test_eof612: cs = 612; goto _test_eof + _test_eof613: cs = 613; goto _test_eof + _test_eof614: cs = 614; goto _test_eof + _test_eof615: cs = 615; goto _test_eof + _test_eof616: cs = 616; goto _test_eof + _test_eof617: cs = 617; goto _test_eof + _test_eof618: cs = 618; goto _test_eof + _test_eof619: cs = 619; goto _test_eof + _test_eof620: cs = 620; goto _test_eof + _test_eof621: cs = 621; goto _test_eof + _test_eof622: cs = 622; goto _test_eof + _test_eof623: cs = 623; goto _test_eof + _test_eof624: cs = 624; goto _test_eof + _test_eof625: cs = 625; goto _test_eof + _test_eof626: cs = 626; goto _test_eof + _test_eof627: cs = 627; goto _test_eof + _test_eof628: cs = 628; goto _test_eof + _test_eof629: cs = 629; goto _test_eof + _test_eof630: cs = 630; goto _test_eof + _test_eof631: cs = 631; goto _test_eof + _test_eof632: cs = 632; goto _test_eof + _test_eof633: cs = 633; goto _test_eof + _test_eof634: cs = 634; goto _test_eof + _test_eof635: cs = 635; goto _test_eof + _test_eof636: cs = 636; goto _test_eof + _test_eof637: cs = 637; goto _test_eof + _test_eof638: cs = 638; goto _test_eof + _test_eof639: cs = 639; goto _test_eof + _test_eof640: cs = 640; goto _test_eof + _test_eof641: cs = 641; goto _test_eof + _test_eof642: cs = 642; goto _test_eof + _test_eof643: cs = 643; goto _test_eof + _test_eof644: cs = 644; goto _test_eof + _test_eof645: cs = 645; goto _test_eof + _test_eof646: cs = 646; goto _test_eof + _test_eof647: cs = 647; goto _test_eof + _test_eof648: cs = 648; goto _test_eof + _test_eof649: cs = 649; goto _test_eof + _test_eof650: cs = 650; goto _test_eof + _test_eof651: cs = 651; goto _test_eof + _test_eof652: cs = 652; goto _test_eof + _test_eof653: cs = 653; goto _test_eof + _test_eof654: cs = 654; goto _test_eof + _test_eof655: cs = 655; goto _test_eof + _test_eof656: cs = 656; goto _test_eof + _test_eof657: cs = 657; goto _test_eof + _test_eof658: cs = 658; goto _test_eof + _test_eof659: cs = 659; goto _test_eof + _test_eof660: cs = 660; goto _test_eof + _test_eof661: cs = 661; goto _test_eof + _test_eof662: cs = 662; goto _test_eof + _test_eof663: cs = 663; goto _test_eof + _test_eof664: cs = 664; goto _test_eof + _test_eof665: cs = 665; goto _test_eof + _test_eof666: cs = 666; goto _test_eof + _test_eof667: cs = 667; goto _test_eof + _test_eof668: cs = 668; goto _test_eof + _test_eof669: cs = 669; goto _test_eof + _test_eof670: cs = 670; goto _test_eof + _test_eof671: cs = 671; goto _test_eof + _test_eof672: cs = 672; goto _test_eof + _test_eof673: cs = 673; goto _test_eof + _test_eof674: cs = 674; goto _test_eof + _test_eof675: cs = 675; goto _test_eof + _test_eof676: cs = 676; goto _test_eof + _test_eof677: cs = 677; goto _test_eof + _test_eof678: cs = 678; goto _test_eof + _test_eof679: cs = 679; goto _test_eof + _test_eof680: cs = 680; goto _test_eof + _test_eof681: cs = 681; goto _test_eof + _test_eof682: cs = 682; goto _test_eof + _test_eof683: cs = 683; goto _test_eof + _test_eof684: cs = 684; goto _test_eof + _test_eof685: cs = 685; goto _test_eof + _test_eof686: cs = 686; goto _test_eof + _test_eof687: cs = 687; goto _test_eof + _test_eof688: cs = 688; goto _test_eof + _test_eof689: cs = 689; goto _test_eof + _test_eof690: cs = 690; goto _test_eof + _test_eof691: cs = 691; goto _test_eof + _test_eof692: cs = 692; goto _test_eof + _test_eof693: cs = 693; goto _test_eof + _test_eof694: cs = 694; goto _test_eof + _test_eof695: cs = 695; goto _test_eof + _test_eof696: cs = 696; goto _test_eof + _test_eof697: cs = 697; goto _test_eof + _test_eof698: cs = 698; goto _test_eof + _test_eof699: cs = 699; goto _test_eof + _test_eof700: cs = 700; goto _test_eof + _test_eof701: cs = 701; goto _test_eof + _test_eof702: cs = 702; goto _test_eof + _test_eof703: cs = 703; goto _test_eof + _test_eof704: cs = 704; goto _test_eof + _test_eof705: cs = 705; goto _test_eof + _test_eof706: cs = 706; goto _test_eof + _test_eof707: cs = 707; goto _test_eof + _test_eof708: cs = 708; goto _test_eof + _test_eof709: cs = 709; goto _test_eof + _test_eof710: cs = 710; goto _test_eof + _test_eof711: cs = 711; goto _test_eof + _test_eof712: cs = 712; goto _test_eof + _test_eof713: cs = 713; goto _test_eof + _test_eof714: cs = 714; goto _test_eof + _test_eof715: cs = 715; goto _test_eof + _test_eof716: cs = 716; goto _test_eof + _test_eof717: cs = 717; goto _test_eof + _test_eof718: cs = 718; goto _test_eof + _test_eof719: cs = 719; goto _test_eof + _test_eof720: cs = 720; goto _test_eof + _test_eof721: cs = 721; goto _test_eof + _test_eof722: cs = 722; goto _test_eof + _test_eof723: cs = 723; goto _test_eof + _test_eof724: cs = 724; goto _test_eof + _test_eof725: cs = 725; goto _test_eof + _test_eof726: cs = 726; goto _test_eof + _test_eof727: cs = 727; goto _test_eof + _test_eof728: cs = 728; goto _test_eof + _test_eof729: cs = 729; goto _test_eof + _test_eof730: cs = 730; goto _test_eof + _test_eof731: cs = 731; goto _test_eof + _test_eof732: cs = 732; goto _test_eof + _test_eof733: cs = 733; goto _test_eof + _test_eof734: cs = 734; goto _test_eof + _test_eof735: cs = 735; goto _test_eof + _test_eof736: cs = 736; goto _test_eof + _test_eof737: cs = 737; goto _test_eof + _test_eof738: cs = 738; goto _test_eof + _test_eof739: cs = 739; goto _test_eof + _test_eof740: cs = 740; goto _test_eof + _test_eof741: cs = 741; goto _test_eof + _test_eof742: cs = 742; goto _test_eof + _test_eof743: cs = 743; goto _test_eof + _test_eof744: cs = 744; goto _test_eof + _test_eof745: cs = 745; goto _test_eof + _test_eof746: cs = 746; goto _test_eof + _test_eof747: cs = 747; goto _test_eof + _test_eof748: cs = 748; goto _test_eof + _test_eof749: cs = 749; goto _test_eof + _test_eof750: cs = 750; goto _test_eof + _test_eof751: cs = 751; goto _test_eof + _test_eof752: cs = 752; goto _test_eof + _test_eof753: cs = 753; goto _test_eof + _test_eof754: cs = 754; goto _test_eof + _test_eof755: cs = 755; goto _test_eof + _test_eof756: cs = 756; goto _test_eof + _test_eof757: cs = 757; goto _test_eof + _test_eof758: cs = 758; goto _test_eof + _test_eof759: cs = 759; goto _test_eof + _test_eof760: cs = 760; goto _test_eof + _test_eof761: cs = 761; goto _test_eof + _test_eof762: cs = 762; goto _test_eof + _test_eof763: cs = 763; goto _test_eof + _test_eof764: cs = 764; goto _test_eof + _test_eof765: cs = 765; goto _test_eof + _test_eof766: cs = 766; goto _test_eof + _test_eof767: cs = 767; goto _test_eof + _test_eof768: cs = 768; goto _test_eof + _test_eof769: cs = 769; goto _test_eof + _test_eof770: cs = 770; goto _test_eof + _test_eof771: cs = 771; goto _test_eof + _test_eof772: cs = 772; goto _test_eof + _test_eof773: cs = 773; goto _test_eof + _test_eof774: cs = 774; goto _test_eof + _test_eof775: cs = 775; goto _test_eof + _test_eof776: cs = 776; goto _test_eof + _test_eof777: cs = 777; goto _test_eof + _test_eof778: cs = 778; goto _test_eof + _test_eof779: cs = 779; goto _test_eof + _test_eof780: cs = 780; goto _test_eof + _test_eof781: cs = 781; goto _test_eof + _test_eof782: cs = 782; goto _test_eof + _test_eof783: cs = 783; goto _test_eof + _test_eof784: cs = 784; goto _test_eof + _test_eof785: cs = 785; goto _test_eof + _test_eof786: cs = 786; goto _test_eof + _test_eof787: cs = 787; goto _test_eof + _test_eof788: cs = 788; goto _test_eof + _test_eof789: cs = 789; goto _test_eof + _test_eof790: cs = 790; goto _test_eof + _test_eof791: cs = 791; goto _test_eof + _test_eof792: cs = 792; goto _test_eof + _test_eof793: cs = 793; goto _test_eof + _test_eof794: cs = 794; goto _test_eof + _test_eof795: cs = 795; goto _test_eof + _test_eof796: cs = 796; goto _test_eof + _test_eof797: cs = 797; goto _test_eof + _test_eof798: cs = 798; goto _test_eof + _test_eof799: cs = 799; goto _test_eof + _test_eof800: cs = 800; goto _test_eof + _test_eof801: cs = 801; goto _test_eof + _test_eof802: cs = 802; goto _test_eof + _test_eof803: cs = 803; goto _test_eof + _test_eof804: cs = 804; goto _test_eof + _test_eof805: cs = 805; goto _test_eof + _test_eof806: cs = 806; goto _test_eof + _test_eof807: cs = 807; goto _test_eof + _test_eof808: cs = 808; goto _test_eof + _test_eof809: cs = 809; goto _test_eof + _test_eof810: cs = 810; goto _test_eof + _test_eof811: cs = 811; goto _test_eof + _test_eof812: cs = 812; goto _test_eof + _test_eof813: cs = 813; goto _test_eof + _test_eof814: cs = 814; goto _test_eof + _test_eof815: cs = 815; goto _test_eof + _test_eof816: cs = 816; goto _test_eof + _test_eof817: cs = 817; goto _test_eof + _test_eof818: cs = 818; goto _test_eof + _test_eof819: cs = 819; goto _test_eof + _test_eof820: cs = 820; goto _test_eof + _test_eof821: cs = 821; goto _test_eof + _test_eof822: cs = 822; goto _test_eof + _test_eof823: cs = 823; goto _test_eof + _test_eof824: cs = 824; goto _test_eof + _test_eof825: cs = 825; goto _test_eof + _test_eof826: cs = 826; goto _test_eof + _test_eof827: cs = 827; goto _test_eof + _test_eof828: cs = 828; goto _test_eof + _test_eof829: cs = 829; goto _test_eof + _test_eof830: cs = 830; goto _test_eof + _test_eof831: cs = 831; goto _test_eof + _test_eof832: cs = 832; goto _test_eof + _test_eof833: cs = 833; goto _test_eof + _test_eof834: cs = 834; goto _test_eof + _test_eof835: cs = 835; goto _test_eof + _test_eof836: cs = 836; goto _test_eof + _test_eof837: cs = 837; goto _test_eof + _test_eof838: cs = 838; goto _test_eof + _test_eof839: cs = 839; goto _test_eof + _test_eof840: cs = 840; goto _test_eof + _test_eof841: cs = 841; goto _test_eof + _test_eof842: cs = 842; goto _test_eof + _test_eof843: cs = 843; goto _test_eof + _test_eof844: cs = 844; goto _test_eof + _test_eof845: cs = 845; goto _test_eof + _test_eof846: cs = 846; goto _test_eof + _test_eof847: cs = 847; goto _test_eof + _test_eof848: cs = 848; goto _test_eof + _test_eof849: cs = 849; goto _test_eof + _test_eof850: cs = 850; goto _test_eof + _test_eof851: cs = 851; goto _test_eof + _test_eof852: cs = 852; goto _test_eof + _test_eof853: cs = 853; goto _test_eof + _test_eof854: cs = 854; goto _test_eof + _test_eof855: cs = 855; goto _test_eof + _test_eof856: cs = 856; goto _test_eof + _test_eof857: cs = 857; goto _test_eof + _test_eof858: cs = 858; goto _test_eof + _test_eof859: cs = 859; goto _test_eof + _test_eof860: cs = 860; goto _test_eof + _test_eof861: cs = 861; goto _test_eof + _test_eof862: cs = 862; goto _test_eof + _test_eof863: cs = 863; goto _test_eof + _test_eof864: cs = 864; goto _test_eof + _test_eof865: cs = 865; goto _test_eof + _test_eof866: cs = 866; goto _test_eof + _test_eof867: cs = 867; goto _test_eof + _test_eof868: cs = 868; goto _test_eof + _test_eof869: cs = 869; goto _test_eof + _test_eof870: cs = 870; goto _test_eof + _test_eof871: cs = 871; goto _test_eof + _test_eof872: cs = 872; goto _test_eof + _test_eof873: cs = 873; goto _test_eof + _test_eof874: cs = 874; goto _test_eof + _test_eof875: cs = 875; goto _test_eof + _test_eof876: cs = 876; goto _test_eof + _test_eof877: cs = 877; goto _test_eof + _test_eof878: cs = 878; goto _test_eof + _test_eof879: cs = 879; goto _test_eof + _test_eof880: cs = 880; goto _test_eof + _test_eof881: cs = 881; goto _test_eof + _test_eof882: cs = 882; goto _test_eof + _test_eof883: cs = 883; goto _test_eof + _test_eof884: cs = 884; goto _test_eof + _test_eof885: cs = 885; goto _test_eof + _test_eof886: cs = 886; goto _test_eof + _test_eof887: cs = 887; goto _test_eof + _test_eof888: cs = 888; goto _test_eof + _test_eof889: cs = 889; goto _test_eof + _test_eof890: cs = 890; goto _test_eof + _test_eof891: cs = 891; goto _test_eof + _test_eof892: cs = 892; goto _test_eof + _test_eof893: cs = 893; goto _test_eof + _test_eof894: cs = 894; goto _test_eof + _test_eof895: cs = 895; goto _test_eof + _test_eof896: cs = 896; goto _test_eof + _test_eof897: cs = 897; goto _test_eof + _test_eof898: cs = 898; goto _test_eof + _test_eof899: cs = 899; goto _test_eof + _test_eof900: cs = 900; goto _test_eof + _test_eof901: cs = 901; goto _test_eof + _test_eof902: cs = 902; goto _test_eof + _test_eof903: cs = 903; goto _test_eof + _test_eof904: cs = 904; goto _test_eof + _test_eof905: cs = 905; goto _test_eof + _test_eof906: cs = 906; goto _test_eof + _test_eof907: cs = 907; goto _test_eof + _test_eof908: cs = 908; goto _test_eof + _test_eof909: cs = 909; goto _test_eof + _test_eof910: cs = 910; goto _test_eof + _test_eof911: cs = 911; goto _test_eof + _test_eof912: cs = 912; goto _test_eof + _test_eof913: cs = 913; goto _test_eof + _test_eof914: cs = 914; goto _test_eof + _test_eof915: cs = 915; goto _test_eof + _test_eof916: cs = 916; goto _test_eof + _test_eof917: cs = 917; goto _test_eof + _test_eof918: cs = 918; goto _test_eof + _test_eof919: cs = 919; goto _test_eof + _test_eof920: cs = 920; goto _test_eof + _test_eof921: cs = 921; goto _test_eof + _test_eof922: cs = 922; goto _test_eof + _test_eof923: cs = 923; goto _test_eof + _test_eof924: cs = 924; goto _test_eof + _test_eof925: cs = 925; goto _test_eof + _test_eof926: cs = 926; goto _test_eof + _test_eof927: cs = 927; goto _test_eof + _test_eof928: cs = 928; goto _test_eof + _test_eof929: cs = 929; goto _test_eof + _test_eof930: cs = 930; goto _test_eof + _test_eof931: cs = 931; goto _test_eof + _test_eof932: cs = 932; goto _test_eof + _test_eof933: cs = 933; goto _test_eof + _test_eof934: cs = 934; goto _test_eof + _test_eof935: cs = 935; goto _test_eof + _test_eof936: cs = 936; goto _test_eof + _test_eof937: cs = 937; goto _test_eof + _test_eof938: cs = 938; goto _test_eof + _test_eof939: cs = 939; goto _test_eof + _test_eof940: cs = 940; goto _test_eof + _test_eof941: cs = 941; goto _test_eof + _test_eof942: cs = 942; goto _test_eof + _test_eof943: cs = 943; goto _test_eof + _test_eof944: cs = 944; goto _test_eof + _test_eof945: cs = 945; goto _test_eof + _test_eof946: cs = 946; goto _test_eof + _test_eof947: cs = 947; goto _test_eof + _test_eof948: cs = 948; goto _test_eof + _test_eof949: cs = 949; goto _test_eof + _test_eof950: cs = 950; goto _test_eof + _test_eof951: cs = 951; goto _test_eof + _test_eof952: cs = 952; goto _test_eof + _test_eof953: cs = 953; goto _test_eof + _test_eof954: cs = 954; goto _test_eof + _test_eof955: cs = 955; goto _test_eof + _test_eof956: cs = 956; goto _test_eof + _test_eof957: cs = 957; goto _test_eof + _test_eof958: cs = 958; goto _test_eof + _test_eof959: cs = 959; goto _test_eof + _test_eof960: cs = 960; goto _test_eof + _test_eof961: cs = 961; goto _test_eof + _test_eof962: cs = 962; goto _test_eof + _test_eof963: cs = 963; goto _test_eof + _test_eof964: cs = 964; goto _test_eof + _test_eof965: cs = 965; goto _test_eof + _test_eof966: cs = 966; goto _test_eof + _test_eof967: cs = 967; goto _test_eof + _test_eof968: cs = 968; goto _test_eof + _test_eof969: cs = 969; goto _test_eof + _test_eof970: cs = 970; goto _test_eof + _test_eof971: cs = 971; goto _test_eof + _test_eof972: cs = 972; goto _test_eof + _test_eof973: cs = 973; goto _test_eof + _test_eof974: cs = 974; goto _test_eof + _test_eof975: cs = 975; goto _test_eof + _test_eof976: cs = 976; goto _test_eof + _test_eof977: cs = 977; goto _test_eof + _test_eof978: cs = 978; goto _test_eof + _test_eof979: cs = 979; goto _test_eof + _test_eof980: cs = 980; goto _test_eof + _test_eof981: cs = 981; goto _test_eof + _test_eof982: cs = 982; goto _test_eof + _test_eof983: cs = 983; goto _test_eof + _test_eof984: cs = 984; goto _test_eof + _test_eof985: cs = 985; goto _test_eof + _test_eof986: cs = 986; goto _test_eof + _test_eof987: cs = 987; goto _test_eof + _test_eof988: cs = 988; goto _test_eof + _test_eof989: cs = 989; goto _test_eof + _test_eof990: cs = 990; goto _test_eof + _test_eof991: cs = 991; goto _test_eof + _test_eof992: cs = 992; goto _test_eof + _test_eof993: cs = 993; goto _test_eof + _test_eof994: cs = 994; goto _test_eof + _test_eof995: cs = 995; goto _test_eof + _test_eof996: cs = 996; goto _test_eof + _test_eof997: cs = 997; goto _test_eof + _test_eof998: cs = 998; goto _test_eof + _test_eof999: cs = 999; goto _test_eof + _test_eof1000: cs = 1000; goto _test_eof + _test_eof1001: cs = 1001; goto _test_eof + _test_eof1002: cs = 1002; goto _test_eof + _test_eof1003: cs = 1003; goto _test_eof + _test_eof1004: cs = 1004; goto _test_eof + _test_eof1005: cs = 1005; goto _test_eof + _test_eof1006: cs = 1006; goto _test_eof + _test_eof1007: cs = 1007; goto _test_eof + _test_eof1008: cs = 1008; goto _test_eof + _test_eof1009: cs = 1009; goto _test_eof + _test_eof1010: cs = 1010; goto _test_eof + _test_eof1011: cs = 1011; goto _test_eof + _test_eof1012: cs = 1012; goto _test_eof + _test_eof1013: cs = 1013; goto _test_eof + _test_eof1014: cs = 1014; goto _test_eof + _test_eof1015: cs = 1015; goto _test_eof + _test_eof1016: cs = 1016; goto _test_eof + _test_eof1017: cs = 1017; goto _test_eof + _test_eof1018: cs = 1018; goto _test_eof + _test_eof1019: cs = 1019; goto _test_eof + _test_eof1020: cs = 1020; goto _test_eof + _test_eof1021: cs = 1021; goto _test_eof + _test_eof1022: cs = 1022; goto _test_eof + _test_eof1023: cs = 1023; goto _test_eof + _test_eof1024: cs = 1024; goto _test_eof + _test_eof1025: cs = 1025; goto _test_eof + _test_eof1026: cs = 1026; goto _test_eof + _test_eof1027: cs = 1027; goto _test_eof + _test_eof1028: cs = 1028; goto _test_eof + _test_eof1029: cs = 1029; goto _test_eof + _test_eof1030: cs = 1030; goto _test_eof + _test_eof1031: cs = 1031; goto _test_eof + _test_eof1032: cs = 1032; goto _test_eof + _test_eof1033: cs = 1033; goto _test_eof + _test_eof1034: cs = 1034; goto _test_eof + _test_eof1035: cs = 1035; goto _test_eof + _test_eof1036: cs = 1036; goto _test_eof + _test_eof1037: cs = 1037; goto _test_eof + _test_eof1038: cs = 1038; goto _test_eof + _test_eof1039: cs = 1039; goto _test_eof + _test_eof1040: cs = 1040; goto _test_eof + _test_eof1041: cs = 1041; goto _test_eof + _test_eof1042: cs = 1042; goto _test_eof + _test_eof1043: cs = 1043; goto _test_eof + _test_eof1044: cs = 1044; goto _test_eof + _test_eof1045: cs = 1045; goto _test_eof + _test_eof1046: cs = 1046; goto _test_eof + _test_eof1047: cs = 1047; goto _test_eof + _test_eof1048: cs = 1048; goto _test_eof + _test_eof1049: cs = 1049; goto _test_eof + _test_eof1050: cs = 1050; goto _test_eof + _test_eof1051: cs = 1051; goto _test_eof + _test_eof1052: cs = 1052; goto _test_eof + _test_eof1053: cs = 1053; goto _test_eof + _test_eof1054: cs = 1054; goto _test_eof + _test_eof1055: cs = 1055; goto _test_eof + _test_eof1056: cs = 1056; goto _test_eof + _test_eof1057: cs = 1057; goto _test_eof + _test_eof1058: cs = 1058; goto _test_eof + _test_eof1059: cs = 1059; goto _test_eof + _test_eof1060: cs = 1060; goto _test_eof + _test_eof1061: cs = 1061; goto _test_eof + _test_eof1062: cs = 1062; goto _test_eof + _test_eof1063: cs = 1063; goto _test_eof + _test_eof1064: cs = 1064; goto _test_eof + _test_eof1065: cs = 1065; goto _test_eof + _test_eof1066: cs = 1066; goto _test_eof + _test_eof1067: cs = 1067; goto _test_eof + _test_eof1068: cs = 1068; goto _test_eof + _test_eof1069: cs = 1069; goto _test_eof + _test_eof1070: cs = 1070; goto _test_eof + _test_eof1071: cs = 1071; goto _test_eof + _test_eof1072: cs = 1072; goto _test_eof + _test_eof1073: cs = 1073; goto _test_eof + _test_eof1074: cs = 1074; goto _test_eof + _test_eof1075: cs = 1075; goto _test_eof + _test_eof1076: cs = 1076; goto _test_eof + _test_eof1077: cs = 1077; goto _test_eof + _test_eof1078: cs = 1078; goto _test_eof + _test_eof1079: cs = 1079; goto _test_eof + _test_eof1080: cs = 1080; goto _test_eof + _test_eof1081: cs = 1081; goto _test_eof + _test_eof1082: cs = 1082; goto _test_eof + _test_eof1083: cs = 1083; goto _test_eof + _test_eof1084: cs = 1084; goto _test_eof + _test_eof1085: cs = 1085; goto _test_eof + _test_eof1086: cs = 1086; goto _test_eof + _test_eof1087: cs = 1087; goto _test_eof + _test_eof1088: cs = 1088; goto _test_eof + _test_eof1089: cs = 1089; goto _test_eof + _test_eof4872: cs = 4872; goto _test_eof + _test_eof1090: cs = 1090; goto _test_eof + _test_eof1091: cs = 1091; goto _test_eof + _test_eof1092: cs = 1092; goto _test_eof + _test_eof1093: cs = 1093; goto _test_eof + _test_eof1094: cs = 1094; goto _test_eof + _test_eof1095: cs = 1095; goto _test_eof + _test_eof1096: cs = 1096; goto _test_eof + _test_eof1097: cs = 1097; goto _test_eof + _test_eof1098: cs = 1098; goto _test_eof + _test_eof1099: cs = 1099; goto _test_eof + _test_eof1100: cs = 1100; goto _test_eof + _test_eof1101: cs = 1101; goto _test_eof + _test_eof1102: cs = 1102; goto _test_eof + _test_eof1103: cs = 1103; goto _test_eof + _test_eof1104: cs = 1104; goto _test_eof + _test_eof1105: cs = 1105; goto _test_eof + _test_eof1106: cs = 1106; goto _test_eof + _test_eof1107: cs = 1107; goto _test_eof + _test_eof1108: cs = 1108; goto _test_eof + _test_eof1109: cs = 1109; goto _test_eof + _test_eof1110: cs = 1110; goto _test_eof + _test_eof1111: cs = 1111; goto _test_eof + _test_eof1112: cs = 1112; goto _test_eof + _test_eof1113: cs = 1113; goto _test_eof + _test_eof1114: cs = 1114; goto _test_eof + _test_eof1115: cs = 1115; goto _test_eof + _test_eof1116: cs = 1116; goto _test_eof + _test_eof1117: cs = 1117; goto _test_eof + _test_eof1118: cs = 1118; goto _test_eof + _test_eof1119: cs = 1119; goto _test_eof + _test_eof1120: cs = 1120; goto _test_eof + _test_eof1121: cs = 1121; goto _test_eof + _test_eof1122: cs = 1122; goto _test_eof + _test_eof1123: cs = 1123; goto _test_eof + _test_eof1124: cs = 1124; goto _test_eof + _test_eof1125: cs = 1125; goto _test_eof + _test_eof1126: cs = 1126; goto _test_eof + _test_eof1127: cs = 1127; goto _test_eof + _test_eof1128: cs = 1128; goto _test_eof + _test_eof1129: cs = 1129; goto _test_eof + _test_eof1130: cs = 1130; goto _test_eof + _test_eof1131: cs = 1131; goto _test_eof + _test_eof1132: cs = 1132; goto _test_eof + _test_eof1133: cs = 1133; goto _test_eof + _test_eof1134: cs = 1134; goto _test_eof + _test_eof1135: cs = 1135; goto _test_eof + _test_eof1136: cs = 1136; goto _test_eof + _test_eof1137: cs = 1137; goto _test_eof + _test_eof1138: cs = 1138; goto _test_eof + _test_eof1139: cs = 1139; goto _test_eof + _test_eof1140: cs = 1140; goto _test_eof + _test_eof1141: cs = 1141; goto _test_eof + _test_eof1142: cs = 1142; goto _test_eof + _test_eof1143: cs = 1143; goto _test_eof + _test_eof1144: cs = 1144; goto _test_eof + _test_eof1145: cs = 1145; goto _test_eof + _test_eof1146: cs = 1146; goto _test_eof + _test_eof1147: cs = 1147; goto _test_eof + _test_eof1148: cs = 1148; goto _test_eof + _test_eof1149: cs = 1149; goto _test_eof + _test_eof1150: cs = 1150; goto _test_eof + _test_eof1151: cs = 1151; goto _test_eof + _test_eof1152: cs = 1152; goto _test_eof + _test_eof1153: cs = 1153; goto _test_eof + _test_eof1154: cs = 1154; goto _test_eof + _test_eof1155: cs = 1155; goto _test_eof + _test_eof1156: cs = 1156; goto _test_eof + _test_eof1157: cs = 1157; goto _test_eof + _test_eof1158: cs = 1158; goto _test_eof + _test_eof1159: cs = 1159; goto _test_eof + _test_eof1160: cs = 1160; goto _test_eof + _test_eof1161: cs = 1161; goto _test_eof + _test_eof1162: cs = 1162; goto _test_eof + _test_eof1163: cs = 1163; goto _test_eof + _test_eof1164: cs = 1164; goto _test_eof + _test_eof1165: cs = 1165; goto _test_eof + _test_eof1166: cs = 1166; goto _test_eof + _test_eof1167: cs = 1167; goto _test_eof + _test_eof1168: cs = 1168; goto _test_eof + _test_eof1169: cs = 1169; goto _test_eof + _test_eof1170: cs = 1170; goto _test_eof + _test_eof1171: cs = 1171; goto _test_eof + _test_eof1172: cs = 1172; goto _test_eof + _test_eof1173: cs = 1173; goto _test_eof + _test_eof1174: cs = 1174; goto _test_eof + _test_eof1175: cs = 1175; goto _test_eof + _test_eof1176: cs = 1176; goto _test_eof + _test_eof1177: cs = 1177; goto _test_eof + _test_eof1178: cs = 1178; goto _test_eof + _test_eof1179: cs = 1179; goto _test_eof + _test_eof1180: cs = 1180; goto _test_eof + _test_eof1181: cs = 1181; goto _test_eof + _test_eof1182: cs = 1182; goto _test_eof + _test_eof1183: cs = 1183; goto _test_eof + _test_eof1184: cs = 1184; goto _test_eof + _test_eof1185: cs = 1185; goto _test_eof + _test_eof1186: cs = 1186; goto _test_eof + _test_eof1187: cs = 1187; goto _test_eof + _test_eof1188: cs = 1188; goto _test_eof + _test_eof1189: cs = 1189; goto _test_eof + _test_eof1190: cs = 1190; goto _test_eof + _test_eof1191: cs = 1191; goto _test_eof + _test_eof1192: cs = 1192; goto _test_eof + _test_eof1193: cs = 1193; goto _test_eof + _test_eof1194: cs = 1194; goto _test_eof + _test_eof1195: cs = 1195; goto _test_eof + _test_eof1196: cs = 1196; goto _test_eof + _test_eof1197: cs = 1197; goto _test_eof + _test_eof1198: cs = 1198; goto _test_eof + _test_eof1199: cs = 1199; goto _test_eof + _test_eof1200: cs = 1200; goto _test_eof + _test_eof1201: cs = 1201; goto _test_eof + _test_eof1202: cs = 1202; goto _test_eof + _test_eof1203: cs = 1203; goto _test_eof + _test_eof1204: cs = 1204; goto _test_eof + _test_eof1205: cs = 1205; goto _test_eof + _test_eof1206: cs = 1206; goto _test_eof + _test_eof1207: cs = 1207; goto _test_eof + _test_eof1208: cs = 1208; goto _test_eof + _test_eof1209: cs = 1209; goto _test_eof + _test_eof1210: cs = 1210; goto _test_eof + _test_eof1211: cs = 1211; goto _test_eof + _test_eof1212: cs = 1212; goto _test_eof + _test_eof1213: cs = 1213; goto _test_eof + _test_eof1214: cs = 1214; goto _test_eof + _test_eof1215: cs = 1215; goto _test_eof + _test_eof1216: cs = 1216; goto _test_eof + _test_eof1217: cs = 1217; goto _test_eof + _test_eof1218: cs = 1218; goto _test_eof + _test_eof1219: cs = 1219; goto _test_eof + _test_eof1220: cs = 1220; goto _test_eof + _test_eof1221: cs = 1221; goto _test_eof + _test_eof1222: cs = 1222; goto _test_eof + _test_eof1223: cs = 1223; goto _test_eof + _test_eof1224: cs = 1224; goto _test_eof + _test_eof1225: cs = 1225; goto _test_eof + _test_eof1226: cs = 1226; goto _test_eof + _test_eof1227: cs = 1227; goto _test_eof + _test_eof1228: cs = 1228; goto _test_eof + _test_eof1229: cs = 1229; goto _test_eof + _test_eof1230: cs = 1230; goto _test_eof + _test_eof1231: cs = 1231; goto _test_eof + _test_eof1232: cs = 1232; goto _test_eof + _test_eof1233: cs = 1233; goto _test_eof + _test_eof1234: cs = 1234; goto _test_eof + _test_eof1235: cs = 1235; goto _test_eof + _test_eof1236: cs = 1236; goto _test_eof + _test_eof1237: cs = 1237; goto _test_eof + _test_eof1238: cs = 1238; goto _test_eof + _test_eof1239: cs = 1239; goto _test_eof + _test_eof1240: cs = 1240; goto _test_eof + _test_eof1241: cs = 1241; goto _test_eof + _test_eof1242: cs = 1242; goto _test_eof + _test_eof1243: cs = 1243; goto _test_eof + _test_eof1244: cs = 1244; goto _test_eof + _test_eof1245: cs = 1245; goto _test_eof + _test_eof1246: cs = 1246; goto _test_eof + _test_eof1247: cs = 1247; goto _test_eof + _test_eof1248: cs = 1248; goto _test_eof + _test_eof1249: cs = 1249; goto _test_eof + _test_eof1250: cs = 1250; goto _test_eof + _test_eof1251: cs = 1251; goto _test_eof + _test_eof1252: cs = 1252; goto _test_eof + _test_eof1253: cs = 1253; goto _test_eof + _test_eof1254: cs = 1254; goto _test_eof + _test_eof1255: cs = 1255; goto _test_eof + _test_eof1256: cs = 1256; goto _test_eof + _test_eof1257: cs = 1257; goto _test_eof + _test_eof1258: cs = 1258; goto _test_eof + _test_eof1259: cs = 1259; goto _test_eof + _test_eof1260: cs = 1260; goto _test_eof + _test_eof1261: cs = 1261; goto _test_eof + _test_eof1262: cs = 1262; goto _test_eof + _test_eof1263: cs = 1263; goto _test_eof + _test_eof1264: cs = 1264; goto _test_eof + _test_eof1265: cs = 1265; goto _test_eof + _test_eof1266: cs = 1266; goto _test_eof + _test_eof1267: cs = 1267; goto _test_eof + _test_eof1268: cs = 1268; goto _test_eof + _test_eof1269: cs = 1269; goto _test_eof + _test_eof1270: cs = 1270; goto _test_eof + _test_eof1271: cs = 1271; goto _test_eof + _test_eof1272: cs = 1272; goto _test_eof + _test_eof1273: cs = 1273; goto _test_eof + _test_eof1274: cs = 1274; goto _test_eof + _test_eof1275: cs = 1275; goto _test_eof + _test_eof1276: cs = 1276; goto _test_eof + _test_eof1277: cs = 1277; goto _test_eof + _test_eof1278: cs = 1278; goto _test_eof + _test_eof1279: cs = 1279; goto _test_eof + _test_eof1280: cs = 1280; goto _test_eof + _test_eof1281: cs = 1281; goto _test_eof + _test_eof1282: cs = 1282; goto _test_eof + _test_eof1283: cs = 1283; goto _test_eof + _test_eof1284: cs = 1284; goto _test_eof + _test_eof1285: cs = 1285; goto _test_eof + _test_eof1286: cs = 1286; goto _test_eof + _test_eof1287: cs = 1287; goto _test_eof + _test_eof1288: cs = 1288; goto _test_eof + _test_eof1289: cs = 1289; goto _test_eof + _test_eof1290: cs = 1290; goto _test_eof + _test_eof1291: cs = 1291; goto _test_eof + _test_eof1292: cs = 1292; goto _test_eof + _test_eof1293: cs = 1293; goto _test_eof + _test_eof1294: cs = 1294; goto _test_eof + _test_eof1295: cs = 1295; goto _test_eof + _test_eof1296: cs = 1296; goto _test_eof + _test_eof1297: cs = 1297; goto _test_eof + _test_eof1298: cs = 1298; goto _test_eof + _test_eof1299: cs = 1299; goto _test_eof + _test_eof1300: cs = 1300; goto _test_eof + _test_eof1301: cs = 1301; goto _test_eof + _test_eof1302: cs = 1302; goto _test_eof + _test_eof1303: cs = 1303; goto _test_eof + _test_eof1304: cs = 1304; goto _test_eof + _test_eof1305: cs = 1305; goto _test_eof + _test_eof1306: cs = 1306; goto _test_eof + _test_eof1307: cs = 1307; goto _test_eof + _test_eof1308: cs = 1308; goto _test_eof + _test_eof1309: cs = 1309; goto _test_eof + _test_eof1310: cs = 1310; goto _test_eof + _test_eof1311: cs = 1311; goto _test_eof + _test_eof1312: cs = 1312; goto _test_eof + _test_eof1313: cs = 1313; goto _test_eof + _test_eof1314: cs = 1314; goto _test_eof + _test_eof1315: cs = 1315; goto _test_eof + _test_eof1316: cs = 1316; goto _test_eof + _test_eof1317: cs = 1317; goto _test_eof + _test_eof1318: cs = 1318; goto _test_eof + _test_eof1319: cs = 1319; goto _test_eof + _test_eof1320: cs = 1320; goto _test_eof + _test_eof1321: cs = 1321; goto _test_eof + _test_eof1322: cs = 1322; goto _test_eof + _test_eof1323: cs = 1323; goto _test_eof + _test_eof1324: cs = 1324; goto _test_eof + _test_eof1325: cs = 1325; goto _test_eof + _test_eof1326: cs = 1326; goto _test_eof + _test_eof1327: cs = 1327; goto _test_eof + _test_eof1328: cs = 1328; goto _test_eof + _test_eof1329: cs = 1329; goto _test_eof + _test_eof1330: cs = 1330; goto _test_eof + _test_eof1331: cs = 1331; goto _test_eof + _test_eof1332: cs = 1332; goto _test_eof + _test_eof1333: cs = 1333; goto _test_eof + _test_eof1334: cs = 1334; goto _test_eof + _test_eof1335: cs = 1335; goto _test_eof + _test_eof1336: cs = 1336; goto _test_eof + _test_eof1337: cs = 1337; goto _test_eof + _test_eof1338: cs = 1338; goto _test_eof + _test_eof1339: cs = 1339; goto _test_eof + _test_eof1340: cs = 1340; goto _test_eof + _test_eof1341: cs = 1341; goto _test_eof + _test_eof1342: cs = 1342; goto _test_eof + _test_eof1343: cs = 1343; goto _test_eof + _test_eof1344: cs = 1344; goto _test_eof + _test_eof1345: cs = 1345; goto _test_eof + _test_eof1346: cs = 1346; goto _test_eof + _test_eof1347: cs = 1347; goto _test_eof + _test_eof1348: cs = 1348; goto _test_eof + _test_eof1349: cs = 1349; goto _test_eof + _test_eof1350: cs = 1350; goto _test_eof + _test_eof1351: cs = 1351; goto _test_eof + _test_eof1352: cs = 1352; goto _test_eof + _test_eof1353: cs = 1353; goto _test_eof + _test_eof1354: cs = 1354; goto _test_eof + _test_eof1355: cs = 1355; goto _test_eof + _test_eof1356: cs = 1356; goto _test_eof + _test_eof1357: cs = 1357; goto _test_eof + _test_eof1358: cs = 1358; goto _test_eof + _test_eof1359: cs = 1359; goto _test_eof + _test_eof1360: cs = 1360; goto _test_eof + _test_eof1361: cs = 1361; goto _test_eof + _test_eof1362: cs = 1362; goto _test_eof + _test_eof1363: cs = 1363; goto _test_eof + _test_eof1364: cs = 1364; goto _test_eof + _test_eof1365: cs = 1365; goto _test_eof + _test_eof1366: cs = 1366; goto _test_eof + _test_eof1367: cs = 1367; goto _test_eof + _test_eof1368: cs = 1368; goto _test_eof + _test_eof1369: cs = 1369; goto _test_eof + _test_eof1370: cs = 1370; goto _test_eof + _test_eof1371: cs = 1371; goto _test_eof + _test_eof1372: cs = 1372; goto _test_eof + _test_eof1373: cs = 1373; goto _test_eof + _test_eof1374: cs = 1374; goto _test_eof + _test_eof1375: cs = 1375; goto _test_eof + _test_eof1376: cs = 1376; goto _test_eof + _test_eof1377: cs = 1377; goto _test_eof + _test_eof1378: cs = 1378; goto _test_eof + _test_eof1379: cs = 1379; goto _test_eof + _test_eof1380: cs = 1380; goto _test_eof + _test_eof1381: cs = 1381; goto _test_eof + _test_eof1382: cs = 1382; goto _test_eof + _test_eof1383: cs = 1383; goto _test_eof + _test_eof1384: cs = 1384; goto _test_eof + _test_eof1385: cs = 1385; goto _test_eof + _test_eof1386: cs = 1386; goto _test_eof + _test_eof1387: cs = 1387; goto _test_eof + _test_eof1388: cs = 1388; goto _test_eof + _test_eof1389: cs = 1389; goto _test_eof + _test_eof1390: cs = 1390; goto _test_eof + _test_eof1391: cs = 1391; goto _test_eof + _test_eof1392: cs = 1392; goto _test_eof + _test_eof1393: cs = 1393; goto _test_eof + _test_eof1394: cs = 1394; goto _test_eof + _test_eof1395: cs = 1395; goto _test_eof + _test_eof1396: cs = 1396; goto _test_eof + _test_eof1397: cs = 1397; goto _test_eof + _test_eof1398: cs = 1398; goto _test_eof + _test_eof1399: cs = 1399; goto _test_eof + _test_eof1400: cs = 1400; goto _test_eof + _test_eof1401: cs = 1401; goto _test_eof + _test_eof1402: cs = 1402; goto _test_eof + _test_eof1403: cs = 1403; goto _test_eof + _test_eof1404: cs = 1404; goto _test_eof + _test_eof1405: cs = 1405; goto _test_eof + _test_eof1406: cs = 1406; goto _test_eof + _test_eof1407: cs = 1407; goto _test_eof + _test_eof1408: cs = 1408; goto _test_eof + _test_eof1409: cs = 1409; goto _test_eof + _test_eof1410: cs = 1410; goto _test_eof + _test_eof1411: cs = 1411; goto _test_eof + _test_eof1412: cs = 1412; goto _test_eof + _test_eof1413: cs = 1413; goto _test_eof + _test_eof1414: cs = 1414; goto _test_eof + _test_eof1415: cs = 1415; goto _test_eof + _test_eof1416: cs = 1416; goto _test_eof + _test_eof1417: cs = 1417; goto _test_eof + _test_eof1418: cs = 1418; goto _test_eof + _test_eof1419: cs = 1419; goto _test_eof + _test_eof1420: cs = 1420; goto _test_eof + _test_eof1421: cs = 1421; goto _test_eof + _test_eof1422: cs = 1422; goto _test_eof + _test_eof1423: cs = 1423; goto _test_eof + _test_eof1424: cs = 1424; goto _test_eof + _test_eof1425: cs = 1425; goto _test_eof + _test_eof1426: cs = 1426; goto _test_eof + _test_eof1427: cs = 1427; goto _test_eof + _test_eof1428: cs = 1428; goto _test_eof + _test_eof1429: cs = 1429; goto _test_eof + _test_eof1430: cs = 1430; goto _test_eof + _test_eof1431: cs = 1431; goto _test_eof + _test_eof1432: cs = 1432; goto _test_eof + _test_eof1433: cs = 1433; goto _test_eof + _test_eof1434: cs = 1434; goto _test_eof + _test_eof1435: cs = 1435; goto _test_eof + _test_eof1436: cs = 1436; goto _test_eof + _test_eof1437: cs = 1437; goto _test_eof + _test_eof1438: cs = 1438; goto _test_eof + _test_eof1439: cs = 1439; goto _test_eof + _test_eof1440: cs = 1440; goto _test_eof + _test_eof1441: cs = 1441; goto _test_eof + _test_eof1442: cs = 1442; goto _test_eof + _test_eof1443: cs = 1443; goto _test_eof + _test_eof1444: cs = 1444; goto _test_eof + _test_eof1445: cs = 1445; goto _test_eof + _test_eof1446: cs = 1446; goto _test_eof + _test_eof1447: cs = 1447; goto _test_eof + _test_eof1448: cs = 1448; goto _test_eof + _test_eof1449: cs = 1449; goto _test_eof + _test_eof1450: cs = 1450; goto _test_eof + _test_eof1451: cs = 1451; goto _test_eof + _test_eof1452: cs = 1452; goto _test_eof + _test_eof1453: cs = 1453; goto _test_eof + _test_eof1454: cs = 1454; goto _test_eof + _test_eof1455: cs = 1455; goto _test_eof + _test_eof1456: cs = 1456; goto _test_eof + _test_eof1457: cs = 1457; goto _test_eof + _test_eof1458: cs = 1458; goto _test_eof + _test_eof1459: cs = 1459; goto _test_eof + _test_eof1460: cs = 1460; goto _test_eof + _test_eof1461: cs = 1461; goto _test_eof + _test_eof1462: cs = 1462; goto _test_eof + _test_eof1463: cs = 1463; goto _test_eof + _test_eof1464: cs = 1464; goto _test_eof + _test_eof1465: cs = 1465; goto _test_eof + _test_eof1466: cs = 1466; goto _test_eof + _test_eof1467: cs = 1467; goto _test_eof + _test_eof1468: cs = 1468; goto _test_eof + _test_eof1469: cs = 1469; goto _test_eof + _test_eof1470: cs = 1470; goto _test_eof + _test_eof1471: cs = 1471; goto _test_eof + _test_eof1472: cs = 1472; goto _test_eof + _test_eof1473: cs = 1473; goto _test_eof + _test_eof1474: cs = 1474; goto _test_eof + _test_eof1475: cs = 1475; goto _test_eof + _test_eof1476: cs = 1476; goto _test_eof + _test_eof1477: cs = 1477; goto _test_eof + _test_eof1478: cs = 1478; goto _test_eof + _test_eof1479: cs = 1479; goto _test_eof + _test_eof1480: cs = 1480; goto _test_eof + _test_eof1481: cs = 1481; goto _test_eof + _test_eof1482: cs = 1482; goto _test_eof + _test_eof1483: cs = 1483; goto _test_eof + _test_eof1484: cs = 1484; goto _test_eof + _test_eof1485: cs = 1485; goto _test_eof + _test_eof1486: cs = 1486; goto _test_eof + _test_eof1487: cs = 1487; goto _test_eof + _test_eof1488: cs = 1488; goto _test_eof + _test_eof1489: cs = 1489; goto _test_eof + _test_eof1490: cs = 1490; goto _test_eof + _test_eof1491: cs = 1491; goto _test_eof + _test_eof1492: cs = 1492; goto _test_eof + _test_eof1493: cs = 1493; goto _test_eof + _test_eof1494: cs = 1494; goto _test_eof + _test_eof1495: cs = 1495; goto _test_eof + _test_eof1496: cs = 1496; goto _test_eof + _test_eof1497: cs = 1497; goto _test_eof + _test_eof1498: cs = 1498; goto _test_eof + _test_eof1499: cs = 1499; goto _test_eof + _test_eof1500: cs = 1500; goto _test_eof + _test_eof1501: cs = 1501; goto _test_eof + _test_eof1502: cs = 1502; goto _test_eof + _test_eof1503: cs = 1503; goto _test_eof + _test_eof1504: cs = 1504; goto _test_eof + _test_eof1505: cs = 1505; goto _test_eof + _test_eof1506: cs = 1506; goto _test_eof + _test_eof1507: cs = 1507; goto _test_eof + _test_eof1508: cs = 1508; goto _test_eof + _test_eof1509: cs = 1509; goto _test_eof + _test_eof1510: cs = 1510; goto _test_eof + _test_eof1511: cs = 1511; goto _test_eof + _test_eof1512: cs = 1512; goto _test_eof + _test_eof1513: cs = 1513; goto _test_eof + _test_eof1514: cs = 1514; goto _test_eof + _test_eof1515: cs = 1515; goto _test_eof + _test_eof1516: cs = 1516; goto _test_eof + _test_eof1517: cs = 1517; goto _test_eof + _test_eof1518: cs = 1518; goto _test_eof + _test_eof1519: cs = 1519; goto _test_eof + _test_eof1520: cs = 1520; goto _test_eof + _test_eof1521: cs = 1521; goto _test_eof + _test_eof1522: cs = 1522; goto _test_eof + _test_eof1523: cs = 1523; goto _test_eof + _test_eof1524: cs = 1524; goto _test_eof + _test_eof1525: cs = 1525; goto _test_eof + _test_eof1526: cs = 1526; goto _test_eof + _test_eof1527: cs = 1527; goto _test_eof + _test_eof1528: cs = 1528; goto _test_eof + _test_eof1529: cs = 1529; goto _test_eof + _test_eof1530: cs = 1530; goto _test_eof + _test_eof1531: cs = 1531; goto _test_eof + _test_eof1532: cs = 1532; goto _test_eof + _test_eof1533: cs = 1533; goto _test_eof + _test_eof1534: cs = 1534; goto _test_eof + _test_eof1535: cs = 1535; goto _test_eof + _test_eof1536: cs = 1536; goto _test_eof + _test_eof1537: cs = 1537; goto _test_eof + _test_eof1538: cs = 1538; goto _test_eof + _test_eof1539: cs = 1539; goto _test_eof + _test_eof1540: cs = 1540; goto _test_eof + _test_eof1541: cs = 1541; goto _test_eof + _test_eof1542: cs = 1542; goto _test_eof + _test_eof1543: cs = 1543; goto _test_eof + _test_eof1544: cs = 1544; goto _test_eof + _test_eof1545: cs = 1545; goto _test_eof + _test_eof1546: cs = 1546; goto _test_eof + _test_eof1547: cs = 1547; goto _test_eof + _test_eof1548: cs = 1548; goto _test_eof + _test_eof1549: cs = 1549; goto _test_eof + _test_eof1550: cs = 1550; goto _test_eof + _test_eof1551: cs = 1551; goto _test_eof + _test_eof1552: cs = 1552; goto _test_eof + _test_eof1553: cs = 1553; goto _test_eof + _test_eof1554: cs = 1554; goto _test_eof + _test_eof1555: cs = 1555; goto _test_eof + _test_eof1556: cs = 1556; goto _test_eof + _test_eof1557: cs = 1557; goto _test_eof + _test_eof1558: cs = 1558; goto _test_eof + _test_eof1559: cs = 1559; goto _test_eof + _test_eof1560: cs = 1560; goto _test_eof + _test_eof1561: cs = 1561; goto _test_eof + _test_eof1562: cs = 1562; goto _test_eof + _test_eof1563: cs = 1563; goto _test_eof + _test_eof1564: cs = 1564; goto _test_eof + _test_eof1565: cs = 1565; goto _test_eof + _test_eof1566: cs = 1566; goto _test_eof + _test_eof1567: cs = 1567; goto _test_eof + _test_eof1568: cs = 1568; goto _test_eof + _test_eof1569: cs = 1569; goto _test_eof + _test_eof1570: cs = 1570; goto _test_eof + _test_eof1571: cs = 1571; goto _test_eof + _test_eof1572: cs = 1572; goto _test_eof + _test_eof1573: cs = 1573; goto _test_eof + _test_eof1574: cs = 1574; goto _test_eof + _test_eof1575: cs = 1575; goto _test_eof + _test_eof1576: cs = 1576; goto _test_eof + _test_eof1577: cs = 1577; goto _test_eof + _test_eof1578: cs = 1578; goto _test_eof + _test_eof1579: cs = 1579; goto _test_eof + _test_eof1580: cs = 1580; goto _test_eof + _test_eof1581: cs = 1581; goto _test_eof + _test_eof1582: cs = 1582; goto _test_eof + _test_eof1583: cs = 1583; goto _test_eof + _test_eof1584: cs = 1584; goto _test_eof + _test_eof1585: cs = 1585; goto _test_eof + _test_eof1586: cs = 1586; goto _test_eof + _test_eof1587: cs = 1587; goto _test_eof + _test_eof1588: cs = 1588; goto _test_eof + _test_eof1589: cs = 1589; goto _test_eof + _test_eof1590: cs = 1590; goto _test_eof + _test_eof1591: cs = 1591; goto _test_eof + _test_eof4873: cs = 4873; goto _test_eof + _test_eof1592: cs = 1592; goto _test_eof + _test_eof1593: cs = 1593; goto _test_eof + _test_eof1594: cs = 1594; goto _test_eof + _test_eof1595: cs = 1595; goto _test_eof + _test_eof1596: cs = 1596; goto _test_eof + _test_eof1597: cs = 1597; goto _test_eof + _test_eof1598: cs = 1598; goto _test_eof + _test_eof1599: cs = 1599; goto _test_eof + _test_eof1600: cs = 1600; goto _test_eof + _test_eof1601: cs = 1601; goto _test_eof + _test_eof1602: cs = 1602; goto _test_eof + _test_eof1603: cs = 1603; goto _test_eof + _test_eof1604: cs = 1604; goto _test_eof + _test_eof1605: cs = 1605; goto _test_eof + _test_eof1606: cs = 1606; goto _test_eof + _test_eof1607: cs = 1607; goto _test_eof + _test_eof1608: cs = 1608; goto _test_eof + _test_eof1609: cs = 1609; goto _test_eof + _test_eof1610: cs = 1610; goto _test_eof + _test_eof1611: cs = 1611; goto _test_eof + _test_eof1612: cs = 1612; goto _test_eof + _test_eof1613: cs = 1613; goto _test_eof + _test_eof1614: cs = 1614; goto _test_eof + _test_eof1615: cs = 1615; goto _test_eof + _test_eof1616: cs = 1616; goto _test_eof + _test_eof1617: cs = 1617; goto _test_eof + _test_eof1618: cs = 1618; goto _test_eof + _test_eof1619: cs = 1619; goto _test_eof + _test_eof1620: cs = 1620; goto _test_eof + _test_eof1621: cs = 1621; goto _test_eof + _test_eof1622: cs = 1622; goto _test_eof + _test_eof1623: cs = 1623; goto _test_eof + _test_eof1624: cs = 1624; goto _test_eof + _test_eof1625: cs = 1625; goto _test_eof + _test_eof1626: cs = 1626; goto _test_eof + _test_eof1627: cs = 1627; goto _test_eof + _test_eof1628: cs = 1628; goto _test_eof + _test_eof1629: cs = 1629; goto _test_eof + _test_eof1630: cs = 1630; goto _test_eof + _test_eof1631: cs = 1631; goto _test_eof + _test_eof1632: cs = 1632; goto _test_eof + _test_eof1633: cs = 1633; goto _test_eof + _test_eof1634: cs = 1634; goto _test_eof + _test_eof1635: cs = 1635; goto _test_eof + _test_eof1636: cs = 1636; goto _test_eof + _test_eof1637: cs = 1637; goto _test_eof + _test_eof1638: cs = 1638; goto _test_eof + _test_eof1639: cs = 1639; goto _test_eof + _test_eof1640: cs = 1640; goto _test_eof + _test_eof1641: cs = 1641; goto _test_eof + _test_eof1642: cs = 1642; goto _test_eof + _test_eof1643: cs = 1643; goto _test_eof + _test_eof1644: cs = 1644; goto _test_eof + _test_eof1645: cs = 1645; goto _test_eof + _test_eof1646: cs = 1646; goto _test_eof + _test_eof1647: cs = 1647; goto _test_eof + _test_eof1648: cs = 1648; goto _test_eof + _test_eof1649: cs = 1649; goto _test_eof + _test_eof1650: cs = 1650; goto _test_eof + _test_eof1651: cs = 1651; goto _test_eof + _test_eof1652: cs = 1652; goto _test_eof + _test_eof1653: cs = 1653; goto _test_eof + _test_eof1654: cs = 1654; goto _test_eof + _test_eof1655: cs = 1655; goto _test_eof + _test_eof1656: cs = 1656; goto _test_eof + _test_eof1657: cs = 1657; goto _test_eof + _test_eof1658: cs = 1658; goto _test_eof + _test_eof1659: cs = 1659; goto _test_eof + _test_eof1660: cs = 1660; goto _test_eof + _test_eof1661: cs = 1661; goto _test_eof + _test_eof1662: cs = 1662; goto _test_eof + _test_eof1663: cs = 1663; goto _test_eof + _test_eof1664: cs = 1664; goto _test_eof + _test_eof1665: cs = 1665; goto _test_eof + _test_eof1666: cs = 1666; goto _test_eof + _test_eof1667: cs = 1667; goto _test_eof + _test_eof1668: cs = 1668; goto _test_eof + _test_eof1669: cs = 1669; goto _test_eof + _test_eof1670: cs = 1670; goto _test_eof + _test_eof1671: cs = 1671; goto _test_eof + _test_eof1672: cs = 1672; goto _test_eof + _test_eof1673: cs = 1673; goto _test_eof + _test_eof1674: cs = 1674; goto _test_eof + _test_eof1675: cs = 1675; goto _test_eof + _test_eof1676: cs = 1676; goto _test_eof + _test_eof1677: cs = 1677; goto _test_eof + _test_eof1678: cs = 1678; goto _test_eof + _test_eof1679: cs = 1679; goto _test_eof + _test_eof1680: cs = 1680; goto _test_eof + _test_eof1681: cs = 1681; goto _test_eof + _test_eof1682: cs = 1682; goto _test_eof + _test_eof1683: cs = 1683; goto _test_eof + _test_eof1684: cs = 1684; goto _test_eof + _test_eof1685: cs = 1685; goto _test_eof + _test_eof1686: cs = 1686; goto _test_eof + _test_eof1687: cs = 1687; goto _test_eof + _test_eof1688: cs = 1688; goto _test_eof + _test_eof1689: cs = 1689; goto _test_eof + _test_eof1690: cs = 1690; goto _test_eof + _test_eof1691: cs = 1691; goto _test_eof + _test_eof1692: cs = 1692; goto _test_eof + _test_eof1693: cs = 1693; goto _test_eof + _test_eof1694: cs = 1694; goto _test_eof + _test_eof1695: cs = 1695; goto _test_eof + _test_eof1696: cs = 1696; goto _test_eof + _test_eof1697: cs = 1697; goto _test_eof + _test_eof1698: cs = 1698; goto _test_eof + _test_eof1699: cs = 1699; goto _test_eof + _test_eof1700: cs = 1700; goto _test_eof + _test_eof1701: cs = 1701; goto _test_eof + _test_eof1702: cs = 1702; goto _test_eof + _test_eof1703: cs = 1703; goto _test_eof + _test_eof1704: cs = 1704; goto _test_eof + _test_eof1705: cs = 1705; goto _test_eof + _test_eof1706: cs = 1706; goto _test_eof + _test_eof1707: cs = 1707; goto _test_eof + _test_eof1708: cs = 1708; goto _test_eof + _test_eof1709: cs = 1709; goto _test_eof + _test_eof1710: cs = 1710; goto _test_eof + _test_eof1711: cs = 1711; goto _test_eof + _test_eof1712: cs = 1712; goto _test_eof + _test_eof1713: cs = 1713; goto _test_eof + _test_eof1714: cs = 1714; goto _test_eof + _test_eof1715: cs = 1715; goto _test_eof + _test_eof1716: cs = 1716; goto _test_eof + _test_eof1717: cs = 1717; goto _test_eof + _test_eof1718: cs = 1718; goto _test_eof + _test_eof1719: cs = 1719; goto _test_eof + _test_eof1720: cs = 1720; goto _test_eof + _test_eof1721: cs = 1721; goto _test_eof + _test_eof1722: cs = 1722; goto _test_eof + _test_eof1723: cs = 1723; goto _test_eof + _test_eof1724: cs = 1724; goto _test_eof + _test_eof1725: cs = 1725; goto _test_eof + _test_eof1726: cs = 1726; goto _test_eof + _test_eof1727: cs = 1727; goto _test_eof + _test_eof1728: cs = 1728; goto _test_eof + _test_eof1729: cs = 1729; goto _test_eof + _test_eof1730: cs = 1730; goto _test_eof + _test_eof1731: cs = 1731; goto _test_eof + _test_eof1732: cs = 1732; goto _test_eof + _test_eof1733: cs = 1733; goto _test_eof + _test_eof1734: cs = 1734; goto _test_eof + _test_eof1735: cs = 1735; goto _test_eof + _test_eof1736: cs = 1736; goto _test_eof + _test_eof1737: cs = 1737; goto _test_eof + _test_eof1738: cs = 1738; goto _test_eof + _test_eof1739: cs = 1739; goto _test_eof + _test_eof1740: cs = 1740; goto _test_eof + _test_eof1741: cs = 1741; goto _test_eof + _test_eof1742: cs = 1742; goto _test_eof + _test_eof1743: cs = 1743; goto _test_eof + _test_eof1744: cs = 1744; goto _test_eof + _test_eof1745: cs = 1745; goto _test_eof + _test_eof1746: cs = 1746; goto _test_eof + _test_eof1747: cs = 1747; goto _test_eof + _test_eof1748: cs = 1748; goto _test_eof + _test_eof1749: cs = 1749; goto _test_eof + _test_eof1750: cs = 1750; goto _test_eof + _test_eof1751: cs = 1751; goto _test_eof + _test_eof1752: cs = 1752; goto _test_eof + _test_eof1753: cs = 1753; goto _test_eof + _test_eof1754: cs = 1754; goto _test_eof + _test_eof1755: cs = 1755; goto _test_eof + _test_eof1756: cs = 1756; goto _test_eof + _test_eof1757: cs = 1757; goto _test_eof + _test_eof1758: cs = 1758; goto _test_eof + _test_eof1759: cs = 1759; goto _test_eof + _test_eof1760: cs = 1760; goto _test_eof + _test_eof1761: cs = 1761; goto _test_eof + _test_eof1762: cs = 1762; goto _test_eof + _test_eof1763: cs = 1763; goto _test_eof + _test_eof1764: cs = 1764; goto _test_eof + _test_eof1765: cs = 1765; goto _test_eof + _test_eof1766: cs = 1766; goto _test_eof + _test_eof1767: cs = 1767; goto _test_eof + _test_eof1768: cs = 1768; goto _test_eof + _test_eof1769: cs = 1769; goto _test_eof + _test_eof1770: cs = 1770; goto _test_eof + _test_eof1771: cs = 1771; goto _test_eof + _test_eof1772: cs = 1772; goto _test_eof + _test_eof1773: cs = 1773; goto _test_eof + _test_eof1774: cs = 1774; goto _test_eof + _test_eof1775: cs = 1775; goto _test_eof + _test_eof1776: cs = 1776; goto _test_eof + _test_eof1777: cs = 1777; goto _test_eof + _test_eof1778: cs = 1778; goto _test_eof + _test_eof1779: cs = 1779; goto _test_eof + _test_eof1780: cs = 1780; goto _test_eof + _test_eof1781: cs = 1781; goto _test_eof + _test_eof1782: cs = 1782; goto _test_eof + _test_eof1783: cs = 1783; goto _test_eof + _test_eof1784: cs = 1784; goto _test_eof + _test_eof1785: cs = 1785; goto _test_eof + _test_eof1786: cs = 1786; goto _test_eof + _test_eof1787: cs = 1787; goto _test_eof + _test_eof1788: cs = 1788; goto _test_eof + _test_eof1789: cs = 1789; goto _test_eof + _test_eof1790: cs = 1790; goto _test_eof + _test_eof1791: cs = 1791; goto _test_eof + _test_eof1792: cs = 1792; goto _test_eof + _test_eof1793: cs = 1793; goto _test_eof + _test_eof1794: cs = 1794; goto _test_eof + _test_eof1795: cs = 1795; goto _test_eof + _test_eof1796: cs = 1796; goto _test_eof + _test_eof1797: cs = 1797; goto _test_eof + _test_eof1798: cs = 1798; goto _test_eof + _test_eof1799: cs = 1799; goto _test_eof + _test_eof1800: cs = 1800; goto _test_eof + _test_eof1801: cs = 1801; goto _test_eof + _test_eof1802: cs = 1802; goto _test_eof + _test_eof1803: cs = 1803; goto _test_eof + _test_eof1804: cs = 1804; goto _test_eof + _test_eof1805: cs = 1805; goto _test_eof + _test_eof1806: cs = 1806; goto _test_eof + _test_eof1807: cs = 1807; goto _test_eof + _test_eof1808: cs = 1808; goto _test_eof + _test_eof1809: cs = 1809; goto _test_eof + _test_eof1810: cs = 1810; goto _test_eof + _test_eof1811: cs = 1811; goto _test_eof + _test_eof1812: cs = 1812; goto _test_eof + _test_eof1813: cs = 1813; goto _test_eof + _test_eof1814: cs = 1814; goto _test_eof + _test_eof1815: cs = 1815; goto _test_eof + _test_eof1816: cs = 1816; goto _test_eof + _test_eof1817: cs = 1817; goto _test_eof + _test_eof1818: cs = 1818; goto _test_eof + _test_eof1819: cs = 1819; goto _test_eof + _test_eof1820: cs = 1820; goto _test_eof + _test_eof1821: cs = 1821; goto _test_eof + _test_eof1822: cs = 1822; goto _test_eof + _test_eof1823: cs = 1823; goto _test_eof + _test_eof1824: cs = 1824; goto _test_eof + _test_eof1825: cs = 1825; goto _test_eof + _test_eof1826: cs = 1826; goto _test_eof + _test_eof1827: cs = 1827; goto _test_eof + _test_eof1828: cs = 1828; goto _test_eof + _test_eof1829: cs = 1829; goto _test_eof + _test_eof1830: cs = 1830; goto _test_eof + _test_eof1831: cs = 1831; goto _test_eof + _test_eof1832: cs = 1832; goto _test_eof + _test_eof1833: cs = 1833; goto _test_eof + _test_eof1834: cs = 1834; goto _test_eof + _test_eof1835: cs = 1835; goto _test_eof + _test_eof1836: cs = 1836; goto _test_eof + _test_eof1837: cs = 1837; goto _test_eof + _test_eof1838: cs = 1838; goto _test_eof + _test_eof1839: cs = 1839; goto _test_eof + _test_eof1840: cs = 1840; goto _test_eof + _test_eof1841: cs = 1841; goto _test_eof + _test_eof1842: cs = 1842; goto _test_eof + _test_eof1843: cs = 1843; goto _test_eof + _test_eof1844: cs = 1844; goto _test_eof + _test_eof1845: cs = 1845; goto _test_eof + _test_eof1846: cs = 1846; goto _test_eof + _test_eof1847: cs = 1847; goto _test_eof + _test_eof1848: cs = 1848; goto _test_eof + _test_eof1849: cs = 1849; goto _test_eof + _test_eof1850: cs = 1850; goto _test_eof + _test_eof1851: cs = 1851; goto _test_eof + _test_eof1852: cs = 1852; goto _test_eof + _test_eof1853: cs = 1853; goto _test_eof + _test_eof1854: cs = 1854; goto _test_eof + _test_eof1855: cs = 1855; goto _test_eof + _test_eof1856: cs = 1856; goto _test_eof + _test_eof1857: cs = 1857; goto _test_eof + _test_eof1858: cs = 1858; goto _test_eof + _test_eof1859: cs = 1859; goto _test_eof + _test_eof1860: cs = 1860; goto _test_eof + _test_eof1861: cs = 1861; goto _test_eof + _test_eof1862: cs = 1862; goto _test_eof + _test_eof1863: cs = 1863; goto _test_eof + _test_eof1864: cs = 1864; goto _test_eof + _test_eof1865: cs = 1865; goto _test_eof + _test_eof1866: cs = 1866; goto _test_eof + _test_eof1867: cs = 1867; goto _test_eof + _test_eof1868: cs = 1868; goto _test_eof + _test_eof1869: cs = 1869; goto _test_eof + _test_eof1870: cs = 1870; goto _test_eof + _test_eof1871: cs = 1871; goto _test_eof + _test_eof1872: cs = 1872; goto _test_eof + _test_eof1873: cs = 1873; goto _test_eof + _test_eof1874: cs = 1874; goto _test_eof + _test_eof1875: cs = 1875; goto _test_eof + _test_eof1876: cs = 1876; goto _test_eof + _test_eof1877: cs = 1877; goto _test_eof + _test_eof1878: cs = 1878; goto _test_eof + _test_eof1879: cs = 1879; goto _test_eof + _test_eof1880: cs = 1880; goto _test_eof + _test_eof1881: cs = 1881; goto _test_eof + _test_eof1882: cs = 1882; goto _test_eof + _test_eof1883: cs = 1883; goto _test_eof + _test_eof1884: cs = 1884; goto _test_eof + _test_eof1885: cs = 1885; goto _test_eof + _test_eof1886: cs = 1886; goto _test_eof + _test_eof1887: cs = 1887; goto _test_eof + _test_eof1888: cs = 1888; goto _test_eof + _test_eof1889: cs = 1889; goto _test_eof + _test_eof1890: cs = 1890; goto _test_eof + _test_eof1891: cs = 1891; goto _test_eof + _test_eof1892: cs = 1892; goto _test_eof + _test_eof1893: cs = 1893; goto _test_eof + _test_eof1894: cs = 1894; goto _test_eof + _test_eof1895: cs = 1895; goto _test_eof + _test_eof1896: cs = 1896; goto _test_eof + _test_eof1897: cs = 1897; goto _test_eof + _test_eof1898: cs = 1898; goto _test_eof + _test_eof1899: cs = 1899; goto _test_eof + _test_eof1900: cs = 1900; goto _test_eof + _test_eof1901: cs = 1901; goto _test_eof + _test_eof1902: cs = 1902; goto _test_eof + _test_eof1903: cs = 1903; goto _test_eof + _test_eof1904: cs = 1904; goto _test_eof + _test_eof1905: cs = 1905; goto _test_eof + _test_eof1906: cs = 1906; goto _test_eof + _test_eof1907: cs = 1907; goto _test_eof + _test_eof1908: cs = 1908; goto _test_eof + _test_eof1909: cs = 1909; goto _test_eof + _test_eof1910: cs = 1910; goto _test_eof + _test_eof1911: cs = 1911; goto _test_eof + _test_eof1912: cs = 1912; goto _test_eof + _test_eof1913: cs = 1913; goto _test_eof + _test_eof1914: cs = 1914; goto _test_eof + _test_eof1915: cs = 1915; goto _test_eof + _test_eof1916: cs = 1916; goto _test_eof + _test_eof1917: cs = 1917; goto _test_eof + _test_eof1918: cs = 1918; goto _test_eof + _test_eof1919: cs = 1919; goto _test_eof + _test_eof1920: cs = 1920; goto _test_eof + _test_eof1921: cs = 1921; goto _test_eof + _test_eof1922: cs = 1922; goto _test_eof + _test_eof1923: cs = 1923; goto _test_eof + _test_eof1924: cs = 1924; goto _test_eof + _test_eof1925: cs = 1925; goto _test_eof + _test_eof1926: cs = 1926; goto _test_eof + _test_eof1927: cs = 1927; goto _test_eof + _test_eof1928: cs = 1928; goto _test_eof + _test_eof1929: cs = 1929; goto _test_eof + _test_eof1930: cs = 1930; goto _test_eof + _test_eof1931: cs = 1931; goto _test_eof + _test_eof1932: cs = 1932; goto _test_eof + _test_eof1933: cs = 1933; goto _test_eof + _test_eof1934: cs = 1934; goto _test_eof + _test_eof1935: cs = 1935; goto _test_eof + _test_eof1936: cs = 1936; goto _test_eof + _test_eof1937: cs = 1937; goto _test_eof + _test_eof1938: cs = 1938; goto _test_eof + _test_eof1939: cs = 1939; goto _test_eof + _test_eof1940: cs = 1940; goto _test_eof + _test_eof1941: cs = 1941; goto _test_eof + _test_eof1942: cs = 1942; goto _test_eof + _test_eof1943: cs = 1943; goto _test_eof + _test_eof1944: cs = 1944; goto _test_eof + _test_eof1945: cs = 1945; goto _test_eof + _test_eof1946: cs = 1946; goto _test_eof + _test_eof1947: cs = 1947; goto _test_eof + _test_eof1948: cs = 1948; goto _test_eof + _test_eof1949: cs = 1949; goto _test_eof + _test_eof1950: cs = 1950; goto _test_eof + _test_eof1951: cs = 1951; goto _test_eof + _test_eof1952: cs = 1952; goto _test_eof + _test_eof1953: cs = 1953; goto _test_eof + _test_eof1954: cs = 1954; goto _test_eof + _test_eof1955: cs = 1955; goto _test_eof + _test_eof1956: cs = 1956; goto _test_eof + _test_eof1957: cs = 1957; goto _test_eof + _test_eof1958: cs = 1958; goto _test_eof + _test_eof1959: cs = 1959; goto _test_eof + _test_eof1960: cs = 1960; goto _test_eof + _test_eof1961: cs = 1961; goto _test_eof + _test_eof1962: cs = 1962; goto _test_eof + _test_eof1963: cs = 1963; goto _test_eof + _test_eof1964: cs = 1964; goto _test_eof + _test_eof1965: cs = 1965; goto _test_eof + _test_eof1966: cs = 1966; goto _test_eof + _test_eof1967: cs = 1967; goto _test_eof + _test_eof1968: cs = 1968; goto _test_eof + _test_eof1969: cs = 1969; goto _test_eof + _test_eof1970: cs = 1970; goto _test_eof + _test_eof1971: cs = 1971; goto _test_eof + _test_eof1972: cs = 1972; goto _test_eof + _test_eof1973: cs = 1973; goto _test_eof + _test_eof1974: cs = 1974; goto _test_eof + _test_eof1975: cs = 1975; goto _test_eof + _test_eof1976: cs = 1976; goto _test_eof + _test_eof1977: cs = 1977; goto _test_eof + _test_eof1978: cs = 1978; goto _test_eof + _test_eof1979: cs = 1979; goto _test_eof + _test_eof1980: cs = 1980; goto _test_eof + _test_eof1981: cs = 1981; goto _test_eof + _test_eof1982: cs = 1982; goto _test_eof + _test_eof1983: cs = 1983; goto _test_eof + _test_eof1984: cs = 1984; goto _test_eof + _test_eof1985: cs = 1985; goto _test_eof + _test_eof1986: cs = 1986; goto _test_eof + _test_eof1987: cs = 1987; goto _test_eof + _test_eof1988: cs = 1988; goto _test_eof + _test_eof1989: cs = 1989; goto _test_eof + _test_eof1990: cs = 1990; goto _test_eof + _test_eof1991: cs = 1991; goto _test_eof + _test_eof1992: cs = 1992; goto _test_eof + _test_eof1993: cs = 1993; goto _test_eof + _test_eof1994: cs = 1994; goto _test_eof + _test_eof1995: cs = 1995; goto _test_eof + _test_eof1996: cs = 1996; goto _test_eof + _test_eof1997: cs = 1997; goto _test_eof + _test_eof1998: cs = 1998; goto _test_eof + _test_eof1999: cs = 1999; goto _test_eof + _test_eof2000: cs = 2000; goto _test_eof + _test_eof2001: cs = 2001; goto _test_eof + _test_eof2002: cs = 2002; goto _test_eof + _test_eof2003: cs = 2003; goto _test_eof + _test_eof2004: cs = 2004; goto _test_eof + _test_eof2005: cs = 2005; goto _test_eof + _test_eof2006: cs = 2006; goto _test_eof + _test_eof2007: cs = 2007; goto _test_eof + _test_eof2008: cs = 2008; goto _test_eof + _test_eof2009: cs = 2009; goto _test_eof + _test_eof2010: cs = 2010; goto _test_eof + _test_eof2011: cs = 2011; goto _test_eof + _test_eof2012: cs = 2012; goto _test_eof + _test_eof2013: cs = 2013; goto _test_eof + _test_eof2014: cs = 2014; goto _test_eof + _test_eof2015: cs = 2015; goto _test_eof + _test_eof2016: cs = 2016; goto _test_eof + _test_eof2017: cs = 2017; goto _test_eof + _test_eof2018: cs = 2018; goto _test_eof + _test_eof2019: cs = 2019; goto _test_eof + _test_eof2020: cs = 2020; goto _test_eof + _test_eof2021: cs = 2021; goto _test_eof + _test_eof2022: cs = 2022; goto _test_eof + _test_eof2023: cs = 2023; goto _test_eof + _test_eof2024: cs = 2024; goto _test_eof + _test_eof2025: cs = 2025; goto _test_eof + _test_eof2026: cs = 2026; goto _test_eof + _test_eof2027: cs = 2027; goto _test_eof + _test_eof2028: cs = 2028; goto _test_eof + _test_eof2029: cs = 2029; goto _test_eof + _test_eof2030: cs = 2030; goto _test_eof + _test_eof2031: cs = 2031; goto _test_eof + _test_eof2032: cs = 2032; goto _test_eof + _test_eof2033: cs = 2033; goto _test_eof + _test_eof2034: cs = 2034; goto _test_eof + _test_eof2035: cs = 2035; goto _test_eof + _test_eof2036: cs = 2036; goto _test_eof + _test_eof2037: cs = 2037; goto _test_eof + _test_eof2038: cs = 2038; goto _test_eof + _test_eof2039: cs = 2039; goto _test_eof + _test_eof2040: cs = 2040; goto _test_eof + _test_eof2041: cs = 2041; goto _test_eof + _test_eof2042: cs = 2042; goto _test_eof + _test_eof2043: cs = 2043; goto _test_eof + _test_eof2044: cs = 2044; goto _test_eof + _test_eof2045: cs = 2045; goto _test_eof + _test_eof2046: cs = 2046; goto _test_eof + _test_eof2047: cs = 2047; goto _test_eof + _test_eof2048: cs = 2048; goto _test_eof + _test_eof2049: cs = 2049; goto _test_eof + _test_eof2050: cs = 2050; goto _test_eof + _test_eof2051: cs = 2051; goto _test_eof + _test_eof2052: cs = 2052; goto _test_eof + _test_eof2053: cs = 2053; goto _test_eof + _test_eof2054: cs = 2054; goto _test_eof + _test_eof2055: cs = 2055; goto _test_eof + _test_eof2056: cs = 2056; goto _test_eof + _test_eof2057: cs = 2057; goto _test_eof + _test_eof2058: cs = 2058; goto _test_eof + _test_eof2059: cs = 2059; goto _test_eof + _test_eof2060: cs = 2060; goto _test_eof + _test_eof2061: cs = 2061; goto _test_eof + _test_eof2062: cs = 2062; goto _test_eof + _test_eof2063: cs = 2063; goto _test_eof + _test_eof2064: cs = 2064; goto _test_eof + _test_eof2065: cs = 2065; goto _test_eof + _test_eof2066: cs = 2066; goto _test_eof + _test_eof2067: cs = 2067; goto _test_eof + _test_eof2068: cs = 2068; goto _test_eof + _test_eof2069: cs = 2069; goto _test_eof + _test_eof2070: cs = 2070; goto _test_eof + _test_eof2071: cs = 2071; goto _test_eof + _test_eof2072: cs = 2072; goto _test_eof + _test_eof2073: cs = 2073; goto _test_eof + _test_eof2074: cs = 2074; goto _test_eof + _test_eof2075: cs = 2075; goto _test_eof + _test_eof2076: cs = 2076; goto _test_eof + _test_eof2077: cs = 2077; goto _test_eof + _test_eof2078: cs = 2078; goto _test_eof + _test_eof2079: cs = 2079; goto _test_eof + _test_eof2080: cs = 2080; goto _test_eof + _test_eof2081: cs = 2081; goto _test_eof + _test_eof2082: cs = 2082; goto _test_eof + _test_eof2083: cs = 2083; goto _test_eof + _test_eof2084: cs = 2084; goto _test_eof + _test_eof2085: cs = 2085; goto _test_eof + _test_eof2086: cs = 2086; goto _test_eof + _test_eof2087: cs = 2087; goto _test_eof + _test_eof2088: cs = 2088; goto _test_eof + _test_eof2089: cs = 2089; goto _test_eof + _test_eof2090: cs = 2090; goto _test_eof + _test_eof2091: cs = 2091; goto _test_eof + _test_eof2092: cs = 2092; goto _test_eof + _test_eof2093: cs = 2093; goto _test_eof + _test_eof2094: cs = 2094; goto _test_eof + _test_eof2095: cs = 2095; goto _test_eof + _test_eof2096: cs = 2096; goto _test_eof + _test_eof2097: cs = 2097; goto _test_eof + _test_eof2098: cs = 2098; goto _test_eof + _test_eof2099: cs = 2099; goto _test_eof + _test_eof2100: cs = 2100; goto _test_eof + _test_eof2101: cs = 2101; goto _test_eof + _test_eof2102: cs = 2102; goto _test_eof + _test_eof2103: cs = 2103; goto _test_eof + _test_eof2104: cs = 2104; goto _test_eof + _test_eof2105: cs = 2105; goto _test_eof + _test_eof2106: cs = 2106; goto _test_eof + _test_eof2107: cs = 2107; goto _test_eof + _test_eof2108: cs = 2108; goto _test_eof + _test_eof2109: cs = 2109; goto _test_eof + _test_eof2110: cs = 2110; goto _test_eof + _test_eof2111: cs = 2111; goto _test_eof + _test_eof2112: cs = 2112; goto _test_eof + _test_eof2113: cs = 2113; goto _test_eof + _test_eof2114: cs = 2114; goto _test_eof + _test_eof2115: cs = 2115; goto _test_eof + _test_eof2116: cs = 2116; goto _test_eof + _test_eof2117: cs = 2117; goto _test_eof + _test_eof2118: cs = 2118; goto _test_eof + _test_eof2119: cs = 2119; goto _test_eof + _test_eof2120: cs = 2120; goto _test_eof + _test_eof2121: cs = 2121; goto _test_eof + _test_eof2122: cs = 2122; goto _test_eof + _test_eof2123: cs = 2123; goto _test_eof + _test_eof2124: cs = 2124; goto _test_eof + _test_eof2125: cs = 2125; goto _test_eof + _test_eof2126: cs = 2126; goto _test_eof + _test_eof2127: cs = 2127; goto _test_eof + _test_eof2128: cs = 2128; goto _test_eof + _test_eof2129: cs = 2129; goto _test_eof + _test_eof2130: cs = 2130; goto _test_eof + _test_eof2131: cs = 2131; goto _test_eof + _test_eof2132: cs = 2132; goto _test_eof + _test_eof2133: cs = 2133; goto _test_eof + _test_eof2134: cs = 2134; goto _test_eof + _test_eof2135: cs = 2135; goto _test_eof + _test_eof2136: cs = 2136; goto _test_eof + _test_eof2137: cs = 2137; goto _test_eof + _test_eof2138: cs = 2138; goto _test_eof + _test_eof2139: cs = 2139; goto _test_eof + _test_eof2140: cs = 2140; goto _test_eof + _test_eof2141: cs = 2141; goto _test_eof + _test_eof2142: cs = 2142; goto _test_eof + _test_eof2143: cs = 2143; goto _test_eof + _test_eof2144: cs = 2144; goto _test_eof + _test_eof2145: cs = 2145; goto _test_eof + _test_eof2146: cs = 2146; goto _test_eof + _test_eof2147: cs = 2147; goto _test_eof + _test_eof2148: cs = 2148; goto _test_eof + _test_eof2149: cs = 2149; goto _test_eof + _test_eof2150: cs = 2150; goto _test_eof + _test_eof2151: cs = 2151; goto _test_eof + _test_eof2152: cs = 2152; goto _test_eof + _test_eof2153: cs = 2153; goto _test_eof + _test_eof2154: cs = 2154; goto _test_eof + _test_eof2155: cs = 2155; goto _test_eof + _test_eof2156: cs = 2156; goto _test_eof + _test_eof2157: cs = 2157; goto _test_eof + _test_eof2158: cs = 2158; goto _test_eof + _test_eof2159: cs = 2159; goto _test_eof + _test_eof2160: cs = 2160; goto _test_eof + _test_eof2161: cs = 2161; goto _test_eof + _test_eof2162: cs = 2162; goto _test_eof + _test_eof2163: cs = 2163; goto _test_eof + _test_eof2164: cs = 2164; goto _test_eof + _test_eof2165: cs = 2165; goto _test_eof + _test_eof2166: cs = 2166; goto _test_eof + _test_eof2167: cs = 2167; goto _test_eof + _test_eof2168: cs = 2168; goto _test_eof + _test_eof2169: cs = 2169; goto _test_eof + _test_eof2170: cs = 2170; goto _test_eof + _test_eof2171: cs = 2171; goto _test_eof + _test_eof2172: cs = 2172; goto _test_eof + _test_eof2173: cs = 2173; goto _test_eof + _test_eof2174: cs = 2174; goto _test_eof + _test_eof2175: cs = 2175; goto _test_eof + _test_eof2176: cs = 2176; goto _test_eof + _test_eof2177: cs = 2177; goto _test_eof + _test_eof2178: cs = 2178; goto _test_eof + _test_eof2179: cs = 2179; goto _test_eof + _test_eof2180: cs = 2180; goto _test_eof + _test_eof2181: cs = 2181; goto _test_eof + _test_eof2182: cs = 2182; goto _test_eof + _test_eof2183: cs = 2183; goto _test_eof + _test_eof2184: cs = 2184; goto _test_eof + _test_eof2185: cs = 2185; goto _test_eof + _test_eof2186: cs = 2186; goto _test_eof + _test_eof2187: cs = 2187; goto _test_eof + _test_eof2188: cs = 2188; goto _test_eof + _test_eof2189: cs = 2189; goto _test_eof + _test_eof2190: cs = 2190; goto _test_eof + _test_eof2191: cs = 2191; goto _test_eof + _test_eof2192: cs = 2192; goto _test_eof + _test_eof4874: cs = 4874; goto _test_eof + _test_eof2193: cs = 2193; goto _test_eof + _test_eof2194: cs = 2194; goto _test_eof + _test_eof2195: cs = 2195; goto _test_eof + _test_eof2196: cs = 2196; goto _test_eof + _test_eof2197: cs = 2197; goto _test_eof + _test_eof2198: cs = 2198; goto _test_eof + _test_eof2199: cs = 2199; goto _test_eof + _test_eof2200: cs = 2200; goto _test_eof + _test_eof2201: cs = 2201; goto _test_eof + _test_eof2202: cs = 2202; goto _test_eof + _test_eof2203: cs = 2203; goto _test_eof + _test_eof2204: cs = 2204; goto _test_eof + _test_eof2205: cs = 2205; goto _test_eof + _test_eof2206: cs = 2206; goto _test_eof + _test_eof2207: cs = 2207; goto _test_eof + _test_eof2208: cs = 2208; goto _test_eof + _test_eof2209: cs = 2209; goto _test_eof + _test_eof2210: cs = 2210; goto _test_eof + _test_eof2211: cs = 2211; goto _test_eof + _test_eof2212: cs = 2212; goto _test_eof + _test_eof2213: cs = 2213; goto _test_eof + _test_eof2214: cs = 2214; goto _test_eof + _test_eof2215: cs = 2215; goto _test_eof + _test_eof2216: cs = 2216; goto _test_eof + _test_eof2217: cs = 2217; goto _test_eof + _test_eof2218: cs = 2218; goto _test_eof + _test_eof2219: cs = 2219; goto _test_eof + _test_eof2220: cs = 2220; goto _test_eof + _test_eof2221: cs = 2221; goto _test_eof + _test_eof2222: cs = 2222; goto _test_eof + _test_eof2223: cs = 2223; goto _test_eof + _test_eof2224: cs = 2224; goto _test_eof + _test_eof2225: cs = 2225; goto _test_eof + _test_eof2226: cs = 2226; goto _test_eof + _test_eof2227: cs = 2227; goto _test_eof + _test_eof2228: cs = 2228; goto _test_eof + _test_eof2229: cs = 2229; goto _test_eof + _test_eof2230: cs = 2230; goto _test_eof + _test_eof2231: cs = 2231; goto _test_eof + _test_eof2232: cs = 2232; goto _test_eof + _test_eof2233: cs = 2233; goto _test_eof + _test_eof2234: cs = 2234; goto _test_eof + _test_eof2235: cs = 2235; goto _test_eof + _test_eof2236: cs = 2236; goto _test_eof + _test_eof2237: cs = 2237; goto _test_eof + _test_eof2238: cs = 2238; goto _test_eof + _test_eof2239: cs = 2239; goto _test_eof + _test_eof2240: cs = 2240; goto _test_eof + _test_eof2241: cs = 2241; goto _test_eof + _test_eof2242: cs = 2242; goto _test_eof + _test_eof2243: cs = 2243; goto _test_eof + _test_eof2244: cs = 2244; goto _test_eof + _test_eof2245: cs = 2245; goto _test_eof + _test_eof2246: cs = 2246; goto _test_eof + _test_eof2247: cs = 2247; goto _test_eof + _test_eof2248: cs = 2248; goto _test_eof + _test_eof2249: cs = 2249; goto _test_eof + _test_eof2250: cs = 2250; goto _test_eof + _test_eof2251: cs = 2251; goto _test_eof + _test_eof2252: cs = 2252; goto _test_eof + _test_eof2253: cs = 2253; goto _test_eof + _test_eof2254: cs = 2254; goto _test_eof + _test_eof2255: cs = 2255; goto _test_eof + _test_eof2256: cs = 2256; goto _test_eof + _test_eof2257: cs = 2257; goto _test_eof + _test_eof2258: cs = 2258; goto _test_eof + _test_eof2259: cs = 2259; goto _test_eof + _test_eof2260: cs = 2260; goto _test_eof + _test_eof2261: cs = 2261; goto _test_eof + _test_eof2262: cs = 2262; goto _test_eof + _test_eof2263: cs = 2263; goto _test_eof + _test_eof2264: cs = 2264; goto _test_eof + _test_eof2265: cs = 2265; goto _test_eof + _test_eof2266: cs = 2266; goto _test_eof + _test_eof2267: cs = 2267; goto _test_eof + _test_eof2268: cs = 2268; goto _test_eof + _test_eof2269: cs = 2269; goto _test_eof + _test_eof2270: cs = 2270; goto _test_eof + _test_eof2271: cs = 2271; goto _test_eof + _test_eof2272: cs = 2272; goto _test_eof + _test_eof2273: cs = 2273; goto _test_eof + _test_eof2274: cs = 2274; goto _test_eof + _test_eof2275: cs = 2275; goto _test_eof + _test_eof2276: cs = 2276; goto _test_eof + _test_eof2277: cs = 2277; goto _test_eof + _test_eof2278: cs = 2278; goto _test_eof + _test_eof2279: cs = 2279; goto _test_eof + _test_eof2280: cs = 2280; goto _test_eof + _test_eof2281: cs = 2281; goto _test_eof + _test_eof2282: cs = 2282; goto _test_eof + _test_eof2283: cs = 2283; goto _test_eof + _test_eof2284: cs = 2284; goto _test_eof + _test_eof2285: cs = 2285; goto _test_eof + _test_eof2286: cs = 2286; goto _test_eof + _test_eof2287: cs = 2287; goto _test_eof + _test_eof2288: cs = 2288; goto _test_eof + _test_eof2289: cs = 2289; goto _test_eof + _test_eof2290: cs = 2290; goto _test_eof + _test_eof2291: cs = 2291; goto _test_eof + _test_eof2292: cs = 2292; goto _test_eof + _test_eof2293: cs = 2293; goto _test_eof + _test_eof2294: cs = 2294; goto _test_eof + _test_eof2295: cs = 2295; goto _test_eof + _test_eof2296: cs = 2296; goto _test_eof + _test_eof2297: cs = 2297; goto _test_eof + _test_eof2298: cs = 2298; goto _test_eof + _test_eof2299: cs = 2299; goto _test_eof + _test_eof2300: cs = 2300; goto _test_eof + _test_eof2301: cs = 2301; goto _test_eof + _test_eof2302: cs = 2302; goto _test_eof + _test_eof2303: cs = 2303; goto _test_eof + _test_eof2304: cs = 2304; goto _test_eof + _test_eof2305: cs = 2305; goto _test_eof + _test_eof2306: cs = 2306; goto _test_eof + _test_eof2307: cs = 2307; goto _test_eof + _test_eof2308: cs = 2308; goto _test_eof + _test_eof2309: cs = 2309; goto _test_eof + _test_eof2310: cs = 2310; goto _test_eof + _test_eof2311: cs = 2311; goto _test_eof + _test_eof2312: cs = 2312; goto _test_eof + _test_eof2313: cs = 2313; goto _test_eof + _test_eof2314: cs = 2314; goto _test_eof + _test_eof2315: cs = 2315; goto _test_eof + _test_eof2316: cs = 2316; goto _test_eof + _test_eof2317: cs = 2317; goto _test_eof + _test_eof2318: cs = 2318; goto _test_eof + _test_eof2319: cs = 2319; goto _test_eof + _test_eof2320: cs = 2320; goto _test_eof + _test_eof2321: cs = 2321; goto _test_eof + _test_eof2322: cs = 2322; goto _test_eof + _test_eof2323: cs = 2323; goto _test_eof + _test_eof2324: cs = 2324; goto _test_eof + _test_eof2325: cs = 2325; goto _test_eof + _test_eof2326: cs = 2326; goto _test_eof + _test_eof2327: cs = 2327; goto _test_eof + _test_eof2328: cs = 2328; goto _test_eof + _test_eof2329: cs = 2329; goto _test_eof + _test_eof2330: cs = 2330; goto _test_eof + _test_eof2331: cs = 2331; goto _test_eof + _test_eof2332: cs = 2332; goto _test_eof + _test_eof2333: cs = 2333; goto _test_eof + _test_eof2334: cs = 2334; goto _test_eof + _test_eof2335: cs = 2335; goto _test_eof + _test_eof2336: cs = 2336; goto _test_eof + _test_eof2337: cs = 2337; goto _test_eof + _test_eof2338: cs = 2338; goto _test_eof + _test_eof2339: cs = 2339; goto _test_eof + _test_eof4875: cs = 4875; goto _test_eof + _test_eof4876: cs = 4876; goto _test_eof + _test_eof2340: cs = 2340; goto _test_eof + _test_eof2341: cs = 2341; goto _test_eof + _test_eof2342: cs = 2342; goto _test_eof + _test_eof2343: cs = 2343; goto _test_eof + _test_eof2344: cs = 2344; goto _test_eof + _test_eof2345: cs = 2345; goto _test_eof + _test_eof2346: cs = 2346; goto _test_eof + _test_eof2347: cs = 2347; goto _test_eof + _test_eof2348: cs = 2348; goto _test_eof + _test_eof2349: cs = 2349; goto _test_eof + _test_eof2350: cs = 2350; goto _test_eof + _test_eof2351: cs = 2351; goto _test_eof + _test_eof2352: cs = 2352; goto _test_eof + _test_eof2353: cs = 2353; goto _test_eof + _test_eof2354: cs = 2354; goto _test_eof + _test_eof2355: cs = 2355; goto _test_eof + _test_eof2356: cs = 2356; goto _test_eof + _test_eof2357: cs = 2357; goto _test_eof + _test_eof2358: cs = 2358; goto _test_eof + _test_eof2359: cs = 2359; goto _test_eof + _test_eof2360: cs = 2360; goto _test_eof + _test_eof2361: cs = 2361; goto _test_eof + _test_eof2362: cs = 2362; goto _test_eof + _test_eof2363: cs = 2363; goto _test_eof + _test_eof2364: cs = 2364; goto _test_eof + _test_eof2365: cs = 2365; goto _test_eof + _test_eof2366: cs = 2366; goto _test_eof + _test_eof2367: cs = 2367; goto _test_eof + _test_eof2368: cs = 2368; goto _test_eof + _test_eof2369: cs = 2369; goto _test_eof + _test_eof2370: cs = 2370; goto _test_eof + _test_eof2371: cs = 2371; goto _test_eof + _test_eof2372: cs = 2372; goto _test_eof + _test_eof2373: cs = 2373; goto _test_eof + _test_eof2374: cs = 2374; goto _test_eof + _test_eof2375: cs = 2375; goto _test_eof + _test_eof2376: cs = 2376; goto _test_eof + _test_eof2377: cs = 2377; goto _test_eof + _test_eof2378: cs = 2378; goto _test_eof + _test_eof2379: cs = 2379; goto _test_eof + _test_eof2380: cs = 2380; goto _test_eof + _test_eof2381: cs = 2381; goto _test_eof + _test_eof2382: cs = 2382; goto _test_eof + _test_eof2383: cs = 2383; goto _test_eof + _test_eof2384: cs = 2384; goto _test_eof + _test_eof2385: cs = 2385; goto _test_eof + _test_eof2386: cs = 2386; goto _test_eof + _test_eof2387: cs = 2387; goto _test_eof + _test_eof2388: cs = 2388; goto _test_eof + _test_eof2389: cs = 2389; goto _test_eof + _test_eof2390: cs = 2390; goto _test_eof + _test_eof2391: cs = 2391; goto _test_eof + _test_eof2392: cs = 2392; goto _test_eof + _test_eof2393: cs = 2393; goto _test_eof + _test_eof2394: cs = 2394; goto _test_eof + _test_eof2395: cs = 2395; goto _test_eof + _test_eof2396: cs = 2396; goto _test_eof + _test_eof2397: cs = 2397; goto _test_eof + _test_eof2398: cs = 2398; goto _test_eof + _test_eof2399: cs = 2399; goto _test_eof + _test_eof2400: cs = 2400; goto _test_eof + _test_eof2401: cs = 2401; goto _test_eof + _test_eof2402: cs = 2402; goto _test_eof + _test_eof2403: cs = 2403; goto _test_eof + _test_eof2404: cs = 2404; goto _test_eof + _test_eof2405: cs = 2405; goto _test_eof + _test_eof2406: cs = 2406; goto _test_eof + _test_eof2407: cs = 2407; goto _test_eof + _test_eof2408: cs = 2408; goto _test_eof + _test_eof2409: cs = 2409; goto _test_eof + _test_eof2410: cs = 2410; goto _test_eof + _test_eof2411: cs = 2411; goto _test_eof + _test_eof2412: cs = 2412; goto _test_eof + _test_eof2413: cs = 2413; goto _test_eof + _test_eof2414: cs = 2414; goto _test_eof + _test_eof2415: cs = 2415; goto _test_eof + _test_eof2416: cs = 2416; goto _test_eof + _test_eof2417: cs = 2417; goto _test_eof + _test_eof2418: cs = 2418; goto _test_eof + _test_eof2419: cs = 2419; goto _test_eof + _test_eof2420: cs = 2420; goto _test_eof + _test_eof2421: cs = 2421; goto _test_eof + _test_eof2422: cs = 2422; goto _test_eof + _test_eof2423: cs = 2423; goto _test_eof + _test_eof2424: cs = 2424; goto _test_eof + _test_eof2425: cs = 2425; goto _test_eof + _test_eof2426: cs = 2426; goto _test_eof + _test_eof2427: cs = 2427; goto _test_eof + _test_eof2428: cs = 2428; goto _test_eof + _test_eof2429: cs = 2429; goto _test_eof + _test_eof2430: cs = 2430; goto _test_eof + _test_eof2431: cs = 2431; goto _test_eof + _test_eof2432: cs = 2432; goto _test_eof + _test_eof2433: cs = 2433; goto _test_eof + _test_eof2434: cs = 2434; goto _test_eof + _test_eof2435: cs = 2435; goto _test_eof + _test_eof2436: cs = 2436; goto _test_eof + _test_eof2437: cs = 2437; goto _test_eof + _test_eof2438: cs = 2438; goto _test_eof + _test_eof2439: cs = 2439; goto _test_eof + _test_eof2440: cs = 2440; goto _test_eof + _test_eof2441: cs = 2441; goto _test_eof + _test_eof2442: cs = 2442; goto _test_eof + _test_eof2443: cs = 2443; goto _test_eof + _test_eof2444: cs = 2444; goto _test_eof + _test_eof2445: cs = 2445; goto _test_eof + _test_eof2446: cs = 2446; goto _test_eof + _test_eof2447: cs = 2447; goto _test_eof + _test_eof2448: cs = 2448; goto _test_eof + _test_eof2449: cs = 2449; goto _test_eof + _test_eof2450: cs = 2450; goto _test_eof + _test_eof2451: cs = 2451; goto _test_eof + _test_eof2452: cs = 2452; goto _test_eof + _test_eof2453: cs = 2453; goto _test_eof + _test_eof2454: cs = 2454; goto _test_eof + _test_eof2455: cs = 2455; goto _test_eof + _test_eof2456: cs = 2456; goto _test_eof + _test_eof2457: cs = 2457; goto _test_eof + _test_eof2458: cs = 2458; goto _test_eof + _test_eof2459: cs = 2459; goto _test_eof + _test_eof2460: cs = 2460; goto _test_eof + _test_eof2461: cs = 2461; goto _test_eof + _test_eof2462: cs = 2462; goto _test_eof + _test_eof2463: cs = 2463; goto _test_eof + _test_eof2464: cs = 2464; goto _test_eof + _test_eof2465: cs = 2465; goto _test_eof + _test_eof2466: cs = 2466; goto _test_eof + _test_eof2467: cs = 2467; goto _test_eof + _test_eof2468: cs = 2468; goto _test_eof + _test_eof2469: cs = 2469; goto _test_eof + _test_eof2470: cs = 2470; goto _test_eof + _test_eof2471: cs = 2471; goto _test_eof + _test_eof2472: cs = 2472; goto _test_eof + _test_eof2473: cs = 2473; goto _test_eof + _test_eof2474: cs = 2474; goto _test_eof + _test_eof2475: cs = 2475; goto _test_eof + _test_eof2476: cs = 2476; goto _test_eof + _test_eof2477: cs = 2477; goto _test_eof + _test_eof2478: cs = 2478; goto _test_eof + _test_eof2479: cs = 2479; goto _test_eof + _test_eof2480: cs = 2480; goto _test_eof + _test_eof2481: cs = 2481; goto _test_eof + _test_eof2482: cs = 2482; goto _test_eof + _test_eof2483: cs = 2483; goto _test_eof + _test_eof2484: cs = 2484; goto _test_eof + _test_eof2485: cs = 2485; goto _test_eof + _test_eof2486: cs = 2486; goto _test_eof + _test_eof2487: cs = 2487; goto _test_eof + _test_eof2488: cs = 2488; goto _test_eof + _test_eof2489: cs = 2489; goto _test_eof + _test_eof2490: cs = 2490; goto _test_eof + _test_eof2491: cs = 2491; goto _test_eof + _test_eof2492: cs = 2492; goto _test_eof + _test_eof2493: cs = 2493; goto _test_eof + _test_eof2494: cs = 2494; goto _test_eof + _test_eof2495: cs = 2495; goto _test_eof + _test_eof2496: cs = 2496; goto _test_eof + _test_eof2497: cs = 2497; goto _test_eof + _test_eof2498: cs = 2498; goto _test_eof + _test_eof2499: cs = 2499; goto _test_eof + _test_eof2500: cs = 2500; goto _test_eof + _test_eof2501: cs = 2501; goto _test_eof + _test_eof2502: cs = 2502; goto _test_eof + _test_eof2503: cs = 2503; goto _test_eof + _test_eof2504: cs = 2504; goto _test_eof + _test_eof2505: cs = 2505; goto _test_eof + _test_eof2506: cs = 2506; goto _test_eof + _test_eof2507: cs = 2507; goto _test_eof + _test_eof2508: cs = 2508; goto _test_eof + _test_eof2509: cs = 2509; goto _test_eof + _test_eof2510: cs = 2510; goto _test_eof + _test_eof2511: cs = 2511; goto _test_eof + _test_eof2512: cs = 2512; goto _test_eof + _test_eof2513: cs = 2513; goto _test_eof + _test_eof2514: cs = 2514; goto _test_eof + _test_eof2515: cs = 2515; goto _test_eof + _test_eof2516: cs = 2516; goto _test_eof + _test_eof2517: cs = 2517; goto _test_eof + _test_eof2518: cs = 2518; goto _test_eof + _test_eof2519: cs = 2519; goto _test_eof + _test_eof2520: cs = 2520; goto _test_eof + _test_eof2521: cs = 2521; goto _test_eof + _test_eof2522: cs = 2522; goto _test_eof + _test_eof2523: cs = 2523; goto _test_eof + _test_eof2524: cs = 2524; goto _test_eof + _test_eof2525: cs = 2525; goto _test_eof + _test_eof2526: cs = 2526; goto _test_eof + _test_eof2527: cs = 2527; goto _test_eof + _test_eof2528: cs = 2528; goto _test_eof + _test_eof2529: cs = 2529; goto _test_eof + _test_eof2530: cs = 2530; goto _test_eof + _test_eof2531: cs = 2531; goto _test_eof + _test_eof2532: cs = 2532; goto _test_eof + _test_eof2533: cs = 2533; goto _test_eof + _test_eof2534: cs = 2534; goto _test_eof + _test_eof2535: cs = 2535; goto _test_eof + _test_eof2536: cs = 2536; goto _test_eof + _test_eof2537: cs = 2537; goto _test_eof + _test_eof2538: cs = 2538; goto _test_eof + _test_eof2539: cs = 2539; goto _test_eof + _test_eof2540: cs = 2540; goto _test_eof + _test_eof2541: cs = 2541; goto _test_eof + _test_eof2542: cs = 2542; goto _test_eof + _test_eof2543: cs = 2543; goto _test_eof + _test_eof2544: cs = 2544; goto _test_eof + _test_eof2545: cs = 2545; goto _test_eof + _test_eof2546: cs = 2546; goto _test_eof + _test_eof2547: cs = 2547; goto _test_eof + _test_eof2548: cs = 2548; goto _test_eof + _test_eof2549: cs = 2549; goto _test_eof + _test_eof2550: cs = 2550; goto _test_eof + _test_eof2551: cs = 2551; goto _test_eof + _test_eof2552: cs = 2552; goto _test_eof + _test_eof2553: cs = 2553; goto _test_eof + _test_eof2554: cs = 2554; goto _test_eof + _test_eof2555: cs = 2555; goto _test_eof + _test_eof2556: cs = 2556; goto _test_eof + _test_eof2557: cs = 2557; goto _test_eof + _test_eof2558: cs = 2558; goto _test_eof + _test_eof2559: cs = 2559; goto _test_eof + _test_eof2560: cs = 2560; goto _test_eof + _test_eof2561: cs = 2561; goto _test_eof + _test_eof2562: cs = 2562; goto _test_eof + _test_eof2563: cs = 2563; goto _test_eof + _test_eof2564: cs = 2564; goto _test_eof + _test_eof2565: cs = 2565; goto _test_eof + _test_eof2566: cs = 2566; goto _test_eof + _test_eof2567: cs = 2567; goto _test_eof + _test_eof2568: cs = 2568; goto _test_eof + _test_eof2569: cs = 2569; goto _test_eof + _test_eof2570: cs = 2570; goto _test_eof + _test_eof2571: cs = 2571; goto _test_eof + _test_eof2572: cs = 2572; goto _test_eof + _test_eof2573: cs = 2573; goto _test_eof + _test_eof2574: cs = 2574; goto _test_eof + _test_eof2575: cs = 2575; goto _test_eof + _test_eof2576: cs = 2576; goto _test_eof + _test_eof2577: cs = 2577; goto _test_eof + _test_eof2578: cs = 2578; goto _test_eof + _test_eof2579: cs = 2579; goto _test_eof + _test_eof2580: cs = 2580; goto _test_eof + _test_eof2581: cs = 2581; goto _test_eof + _test_eof2582: cs = 2582; goto _test_eof + _test_eof2583: cs = 2583; goto _test_eof + _test_eof2584: cs = 2584; goto _test_eof + _test_eof2585: cs = 2585; goto _test_eof + _test_eof2586: cs = 2586; goto _test_eof + _test_eof2587: cs = 2587; goto _test_eof + _test_eof2588: cs = 2588; goto _test_eof + _test_eof2589: cs = 2589; goto _test_eof + _test_eof2590: cs = 2590; goto _test_eof + _test_eof2591: cs = 2591; goto _test_eof + _test_eof2592: cs = 2592; goto _test_eof + _test_eof2593: cs = 2593; goto _test_eof + _test_eof2594: cs = 2594; goto _test_eof + _test_eof2595: cs = 2595; goto _test_eof + _test_eof2596: cs = 2596; goto _test_eof + _test_eof2597: cs = 2597; goto _test_eof + _test_eof2598: cs = 2598; goto _test_eof + _test_eof2599: cs = 2599; goto _test_eof + _test_eof2600: cs = 2600; goto _test_eof + _test_eof2601: cs = 2601; goto _test_eof + _test_eof2602: cs = 2602; goto _test_eof + _test_eof2603: cs = 2603; goto _test_eof + _test_eof2604: cs = 2604; goto _test_eof + _test_eof2605: cs = 2605; goto _test_eof + _test_eof2606: cs = 2606; goto _test_eof + _test_eof2607: cs = 2607; goto _test_eof + _test_eof2608: cs = 2608; goto _test_eof + _test_eof2609: cs = 2609; goto _test_eof + _test_eof2610: cs = 2610; goto _test_eof + _test_eof2611: cs = 2611; goto _test_eof + _test_eof2612: cs = 2612; goto _test_eof + _test_eof2613: cs = 2613; goto _test_eof + _test_eof2614: cs = 2614; goto _test_eof + _test_eof2615: cs = 2615; goto _test_eof + _test_eof2616: cs = 2616; goto _test_eof + _test_eof2617: cs = 2617; goto _test_eof + _test_eof2618: cs = 2618; goto _test_eof + _test_eof2619: cs = 2619; goto _test_eof + _test_eof2620: cs = 2620; goto _test_eof + _test_eof2621: cs = 2621; goto _test_eof + _test_eof2622: cs = 2622; goto _test_eof + _test_eof2623: cs = 2623; goto _test_eof + _test_eof2624: cs = 2624; goto _test_eof + _test_eof2625: cs = 2625; goto _test_eof + _test_eof2626: cs = 2626; goto _test_eof + _test_eof2627: cs = 2627; goto _test_eof + _test_eof2628: cs = 2628; goto _test_eof + _test_eof2629: cs = 2629; goto _test_eof + _test_eof2630: cs = 2630; goto _test_eof + _test_eof2631: cs = 2631; goto _test_eof + _test_eof2632: cs = 2632; goto _test_eof + _test_eof2633: cs = 2633; goto _test_eof + _test_eof2634: cs = 2634; goto _test_eof + _test_eof2635: cs = 2635; goto _test_eof + _test_eof4877: cs = 4877; goto _test_eof + _test_eof4878: cs = 4878; goto _test_eof + _test_eof2636: cs = 2636; goto _test_eof + _test_eof2637: cs = 2637; goto _test_eof + _test_eof2638: cs = 2638; goto _test_eof + _test_eof2639: cs = 2639; goto _test_eof + _test_eof2640: cs = 2640; goto _test_eof + _test_eof2641: cs = 2641; goto _test_eof + _test_eof2642: cs = 2642; goto _test_eof + _test_eof2643: cs = 2643; goto _test_eof + _test_eof2644: cs = 2644; goto _test_eof + _test_eof2645: cs = 2645; goto _test_eof + _test_eof2646: cs = 2646; goto _test_eof + _test_eof2647: cs = 2647; goto _test_eof + _test_eof2648: cs = 2648; goto _test_eof + _test_eof2649: cs = 2649; goto _test_eof + _test_eof2650: cs = 2650; goto _test_eof + _test_eof2651: cs = 2651; goto _test_eof + _test_eof2652: cs = 2652; goto _test_eof + _test_eof2653: cs = 2653; goto _test_eof + _test_eof2654: cs = 2654; goto _test_eof + _test_eof2655: cs = 2655; goto _test_eof + _test_eof2656: cs = 2656; goto _test_eof + _test_eof2657: cs = 2657; goto _test_eof + _test_eof2658: cs = 2658; goto _test_eof + _test_eof2659: cs = 2659; goto _test_eof + _test_eof2660: cs = 2660; goto _test_eof + _test_eof2661: cs = 2661; goto _test_eof + _test_eof2662: cs = 2662; goto _test_eof + _test_eof2663: cs = 2663; goto _test_eof + _test_eof2664: cs = 2664; goto _test_eof + _test_eof2665: cs = 2665; goto _test_eof + _test_eof2666: cs = 2666; goto _test_eof + _test_eof2667: cs = 2667; goto _test_eof + _test_eof2668: cs = 2668; goto _test_eof + _test_eof2669: cs = 2669; goto _test_eof + _test_eof2670: cs = 2670; goto _test_eof + _test_eof2671: cs = 2671; goto _test_eof + _test_eof2672: cs = 2672; goto _test_eof + _test_eof2673: cs = 2673; goto _test_eof + _test_eof2674: cs = 2674; goto _test_eof + _test_eof2675: cs = 2675; goto _test_eof + _test_eof2676: cs = 2676; goto _test_eof + _test_eof2677: cs = 2677; goto _test_eof + _test_eof2678: cs = 2678; goto _test_eof + _test_eof2679: cs = 2679; goto _test_eof + _test_eof2680: cs = 2680; goto _test_eof + _test_eof2681: cs = 2681; goto _test_eof + _test_eof2682: cs = 2682; goto _test_eof + _test_eof2683: cs = 2683; goto _test_eof + _test_eof2684: cs = 2684; goto _test_eof + _test_eof2685: cs = 2685; goto _test_eof + _test_eof2686: cs = 2686; goto _test_eof + _test_eof2687: cs = 2687; goto _test_eof + _test_eof2688: cs = 2688; goto _test_eof + _test_eof2689: cs = 2689; goto _test_eof + _test_eof2690: cs = 2690; goto _test_eof + _test_eof2691: cs = 2691; goto _test_eof + _test_eof2692: cs = 2692; goto _test_eof + _test_eof2693: cs = 2693; goto _test_eof + _test_eof2694: cs = 2694; goto _test_eof + _test_eof2695: cs = 2695; goto _test_eof + _test_eof2696: cs = 2696; goto _test_eof + _test_eof2697: cs = 2697; goto _test_eof + _test_eof2698: cs = 2698; goto _test_eof + _test_eof2699: cs = 2699; goto _test_eof + _test_eof2700: cs = 2700; goto _test_eof + _test_eof2701: cs = 2701; goto _test_eof + _test_eof2702: cs = 2702; goto _test_eof + _test_eof2703: cs = 2703; goto _test_eof + _test_eof2704: cs = 2704; goto _test_eof + _test_eof2705: cs = 2705; goto _test_eof + _test_eof2706: cs = 2706; goto _test_eof + _test_eof2707: cs = 2707; goto _test_eof + _test_eof2708: cs = 2708; goto _test_eof + _test_eof2709: cs = 2709; goto _test_eof + _test_eof2710: cs = 2710; goto _test_eof + _test_eof2711: cs = 2711; goto _test_eof + _test_eof2712: cs = 2712; goto _test_eof + _test_eof2713: cs = 2713; goto _test_eof + _test_eof2714: cs = 2714; goto _test_eof + _test_eof2715: cs = 2715; goto _test_eof + _test_eof2716: cs = 2716; goto _test_eof + _test_eof2717: cs = 2717; goto _test_eof + _test_eof2718: cs = 2718; goto _test_eof + _test_eof2719: cs = 2719; goto _test_eof + _test_eof2720: cs = 2720; goto _test_eof + _test_eof2721: cs = 2721; goto _test_eof + _test_eof2722: cs = 2722; goto _test_eof + _test_eof2723: cs = 2723; goto _test_eof + _test_eof2724: cs = 2724; goto _test_eof + _test_eof2725: cs = 2725; goto _test_eof + _test_eof2726: cs = 2726; goto _test_eof + _test_eof2727: cs = 2727; goto _test_eof + _test_eof2728: cs = 2728; goto _test_eof + _test_eof2729: cs = 2729; goto _test_eof + _test_eof2730: cs = 2730; goto _test_eof + _test_eof2731: cs = 2731; goto _test_eof + _test_eof2732: cs = 2732; goto _test_eof + _test_eof2733: cs = 2733; goto _test_eof + _test_eof2734: cs = 2734; goto _test_eof + _test_eof2735: cs = 2735; goto _test_eof + _test_eof2736: cs = 2736; goto _test_eof + _test_eof2737: cs = 2737; goto _test_eof + _test_eof2738: cs = 2738; goto _test_eof + _test_eof2739: cs = 2739; goto _test_eof + _test_eof2740: cs = 2740; goto _test_eof + _test_eof2741: cs = 2741; goto _test_eof + _test_eof2742: cs = 2742; goto _test_eof + _test_eof2743: cs = 2743; goto _test_eof + _test_eof2744: cs = 2744; goto _test_eof + _test_eof2745: cs = 2745; goto _test_eof + _test_eof2746: cs = 2746; goto _test_eof + _test_eof2747: cs = 2747; goto _test_eof + _test_eof2748: cs = 2748; goto _test_eof + _test_eof2749: cs = 2749; goto _test_eof + _test_eof2750: cs = 2750; goto _test_eof + _test_eof2751: cs = 2751; goto _test_eof + _test_eof2752: cs = 2752; goto _test_eof + _test_eof2753: cs = 2753; goto _test_eof + _test_eof2754: cs = 2754; goto _test_eof + _test_eof2755: cs = 2755; goto _test_eof + _test_eof2756: cs = 2756; goto _test_eof + _test_eof2757: cs = 2757; goto _test_eof + _test_eof2758: cs = 2758; goto _test_eof + _test_eof2759: cs = 2759; goto _test_eof + _test_eof2760: cs = 2760; goto _test_eof + _test_eof2761: cs = 2761; goto _test_eof + _test_eof2762: cs = 2762; goto _test_eof + _test_eof2763: cs = 2763; goto _test_eof + _test_eof2764: cs = 2764; goto _test_eof + _test_eof2765: cs = 2765; goto _test_eof + _test_eof2766: cs = 2766; goto _test_eof + _test_eof2767: cs = 2767; goto _test_eof + _test_eof2768: cs = 2768; goto _test_eof + _test_eof2769: cs = 2769; goto _test_eof + _test_eof2770: cs = 2770; goto _test_eof + _test_eof2771: cs = 2771; goto _test_eof + _test_eof2772: cs = 2772; goto _test_eof + _test_eof2773: cs = 2773; goto _test_eof + _test_eof2774: cs = 2774; goto _test_eof + _test_eof2775: cs = 2775; goto _test_eof + _test_eof2776: cs = 2776; goto _test_eof + _test_eof4879: cs = 4879; goto _test_eof + _test_eof4880: cs = 4880; goto _test_eof + _test_eof4881: cs = 4881; goto _test_eof + _test_eof4882: cs = 4882; goto _test_eof + _test_eof4883: cs = 4883; goto _test_eof + _test_eof4884: cs = 4884; goto _test_eof + _test_eof4885: cs = 4885; goto _test_eof + _test_eof2777: cs = 2777; goto _test_eof + _test_eof2778: cs = 2778; goto _test_eof + _test_eof2779: cs = 2779; goto _test_eof + _test_eof2780: cs = 2780; goto _test_eof + _test_eof2781: cs = 2781; goto _test_eof + _test_eof2782: cs = 2782; goto _test_eof + _test_eof2783: cs = 2783; goto _test_eof + _test_eof2784: cs = 2784; goto _test_eof + _test_eof2785: cs = 2785; goto _test_eof + _test_eof2786: cs = 2786; goto _test_eof + _test_eof2787: cs = 2787; goto _test_eof + _test_eof2788: cs = 2788; goto _test_eof + _test_eof2789: cs = 2789; goto _test_eof + _test_eof2790: cs = 2790; goto _test_eof + _test_eof2791: cs = 2791; goto _test_eof + _test_eof2792: cs = 2792; goto _test_eof + _test_eof2793: cs = 2793; goto _test_eof + _test_eof2794: cs = 2794; goto _test_eof + _test_eof2795: cs = 2795; goto _test_eof + _test_eof2796: cs = 2796; goto _test_eof + _test_eof2797: cs = 2797; goto _test_eof + _test_eof2798: cs = 2798; goto _test_eof + _test_eof2799: cs = 2799; goto _test_eof + _test_eof2800: cs = 2800; goto _test_eof + _test_eof2801: cs = 2801; goto _test_eof + _test_eof2802: cs = 2802; goto _test_eof + _test_eof2803: cs = 2803; goto _test_eof + _test_eof2804: cs = 2804; goto _test_eof + _test_eof2805: cs = 2805; goto _test_eof + _test_eof2806: cs = 2806; goto _test_eof + _test_eof2807: cs = 2807; goto _test_eof + _test_eof2808: cs = 2808; goto _test_eof + _test_eof2809: cs = 2809; goto _test_eof + _test_eof2810: cs = 2810; goto _test_eof + _test_eof2811: cs = 2811; goto _test_eof + _test_eof2812: cs = 2812; goto _test_eof + _test_eof2813: cs = 2813; goto _test_eof + _test_eof2814: cs = 2814; goto _test_eof + _test_eof2815: cs = 2815; goto _test_eof + _test_eof2816: cs = 2816; goto _test_eof + _test_eof2817: cs = 2817; goto _test_eof + _test_eof2818: cs = 2818; goto _test_eof + _test_eof2819: cs = 2819; goto _test_eof + _test_eof2820: cs = 2820; goto _test_eof + _test_eof2821: cs = 2821; goto _test_eof + _test_eof2822: cs = 2822; goto _test_eof + _test_eof2823: cs = 2823; goto _test_eof + _test_eof2824: cs = 2824; goto _test_eof + _test_eof2825: cs = 2825; goto _test_eof + _test_eof2826: cs = 2826; goto _test_eof + _test_eof2827: cs = 2827; goto _test_eof + _test_eof2828: cs = 2828; goto _test_eof + _test_eof2829: cs = 2829; goto _test_eof + _test_eof2830: cs = 2830; goto _test_eof + _test_eof2831: cs = 2831; goto _test_eof + _test_eof2832: cs = 2832; goto _test_eof + _test_eof2833: cs = 2833; goto _test_eof + _test_eof2834: cs = 2834; goto _test_eof + _test_eof2835: cs = 2835; goto _test_eof + _test_eof2836: cs = 2836; goto _test_eof + _test_eof2837: cs = 2837; goto _test_eof + _test_eof2838: cs = 2838; goto _test_eof + _test_eof2839: cs = 2839; goto _test_eof + _test_eof2840: cs = 2840; goto _test_eof + _test_eof2841: cs = 2841; goto _test_eof + _test_eof2842: cs = 2842; goto _test_eof + _test_eof2843: cs = 2843; goto _test_eof + _test_eof2844: cs = 2844; goto _test_eof + _test_eof2845: cs = 2845; goto _test_eof + _test_eof2846: cs = 2846; goto _test_eof + _test_eof2847: cs = 2847; goto _test_eof + _test_eof2848: cs = 2848; goto _test_eof + _test_eof2849: cs = 2849; goto _test_eof + _test_eof2850: cs = 2850; goto _test_eof + _test_eof2851: cs = 2851; goto _test_eof + _test_eof2852: cs = 2852; goto _test_eof + _test_eof2853: cs = 2853; goto _test_eof + _test_eof2854: cs = 2854; goto _test_eof + _test_eof2855: cs = 2855; goto _test_eof + _test_eof2856: cs = 2856; goto _test_eof + _test_eof2857: cs = 2857; goto _test_eof + _test_eof2858: cs = 2858; goto _test_eof + _test_eof2859: cs = 2859; goto _test_eof + _test_eof2860: cs = 2860; goto _test_eof + _test_eof2861: cs = 2861; goto _test_eof + _test_eof2862: cs = 2862; goto _test_eof + _test_eof2863: cs = 2863; goto _test_eof + _test_eof2864: cs = 2864; goto _test_eof + _test_eof2865: cs = 2865; goto _test_eof + _test_eof2866: cs = 2866; goto _test_eof + _test_eof2867: cs = 2867; goto _test_eof + _test_eof2868: cs = 2868; goto _test_eof + _test_eof2869: cs = 2869; goto _test_eof + _test_eof2870: cs = 2870; goto _test_eof + _test_eof2871: cs = 2871; goto _test_eof + _test_eof2872: cs = 2872; goto _test_eof + _test_eof2873: cs = 2873; goto _test_eof + _test_eof2874: cs = 2874; goto _test_eof + _test_eof2875: cs = 2875; goto _test_eof + _test_eof2876: cs = 2876; goto _test_eof + _test_eof2877: cs = 2877; goto _test_eof + _test_eof2878: cs = 2878; goto _test_eof + _test_eof2879: cs = 2879; goto _test_eof + _test_eof2880: cs = 2880; goto _test_eof + _test_eof2881: cs = 2881; goto _test_eof + _test_eof2882: cs = 2882; goto _test_eof + _test_eof2883: cs = 2883; goto _test_eof + _test_eof2884: cs = 2884; goto _test_eof + _test_eof2885: cs = 2885; goto _test_eof + _test_eof2886: cs = 2886; goto _test_eof + _test_eof2887: cs = 2887; goto _test_eof + _test_eof2888: cs = 2888; goto _test_eof + _test_eof2889: cs = 2889; goto _test_eof + _test_eof2890: cs = 2890; goto _test_eof + _test_eof2891: cs = 2891; goto _test_eof + _test_eof2892: cs = 2892; goto _test_eof + _test_eof2893: cs = 2893; goto _test_eof + _test_eof2894: cs = 2894; goto _test_eof + _test_eof2895: cs = 2895; goto _test_eof + _test_eof2896: cs = 2896; goto _test_eof + _test_eof2897: cs = 2897; goto _test_eof + _test_eof2898: cs = 2898; goto _test_eof + _test_eof2899: cs = 2899; goto _test_eof + _test_eof2900: cs = 2900; goto _test_eof + _test_eof2901: cs = 2901; goto _test_eof + _test_eof2902: cs = 2902; goto _test_eof + _test_eof2903: cs = 2903; goto _test_eof + _test_eof2904: cs = 2904; goto _test_eof + _test_eof2905: cs = 2905; goto _test_eof + _test_eof2906: cs = 2906; goto _test_eof + _test_eof2907: cs = 2907; goto _test_eof + _test_eof2908: cs = 2908; goto _test_eof + _test_eof2909: cs = 2909; goto _test_eof + _test_eof2910: cs = 2910; goto _test_eof + _test_eof2911: cs = 2911; goto _test_eof + _test_eof2912: cs = 2912; goto _test_eof + _test_eof2913: cs = 2913; goto _test_eof + _test_eof2914: cs = 2914; goto _test_eof + _test_eof2915: cs = 2915; goto _test_eof + _test_eof2916: cs = 2916; goto _test_eof + _test_eof2917: cs = 2917; goto _test_eof + _test_eof2918: cs = 2918; goto _test_eof + _test_eof2919: cs = 2919; goto _test_eof + _test_eof2920: cs = 2920; goto _test_eof + _test_eof2921: cs = 2921; goto _test_eof + _test_eof2922: cs = 2922; goto _test_eof + _test_eof2923: cs = 2923; goto _test_eof + _test_eof4886: cs = 4886; goto _test_eof + _test_eof2924: cs = 2924; goto _test_eof + _test_eof2925: cs = 2925; goto _test_eof + _test_eof2926: cs = 2926; goto _test_eof + _test_eof2927: cs = 2927; goto _test_eof + _test_eof2928: cs = 2928; goto _test_eof + _test_eof2929: cs = 2929; goto _test_eof + _test_eof2930: cs = 2930; goto _test_eof + _test_eof2931: cs = 2931; goto _test_eof + _test_eof2932: cs = 2932; goto _test_eof + _test_eof2933: cs = 2933; goto _test_eof + _test_eof2934: cs = 2934; goto _test_eof + _test_eof2935: cs = 2935; goto _test_eof + _test_eof2936: cs = 2936; goto _test_eof + _test_eof2937: cs = 2937; goto _test_eof + _test_eof2938: cs = 2938; goto _test_eof + _test_eof2939: cs = 2939; goto _test_eof + _test_eof2940: cs = 2940; goto _test_eof + _test_eof2941: cs = 2941; goto _test_eof + _test_eof2942: cs = 2942; goto _test_eof + _test_eof2943: cs = 2943; goto _test_eof + _test_eof2944: cs = 2944; goto _test_eof + _test_eof2945: cs = 2945; goto _test_eof + _test_eof2946: cs = 2946; goto _test_eof + _test_eof2947: cs = 2947; goto _test_eof + _test_eof2948: cs = 2948; goto _test_eof + _test_eof2949: cs = 2949; goto _test_eof + _test_eof2950: cs = 2950; goto _test_eof + _test_eof2951: cs = 2951; goto _test_eof + _test_eof2952: cs = 2952; goto _test_eof + _test_eof2953: cs = 2953; goto _test_eof + _test_eof2954: cs = 2954; goto _test_eof + _test_eof2955: cs = 2955; goto _test_eof + _test_eof2956: cs = 2956; goto _test_eof + _test_eof2957: cs = 2957; goto _test_eof + _test_eof2958: cs = 2958; goto _test_eof + _test_eof2959: cs = 2959; goto _test_eof + _test_eof2960: cs = 2960; goto _test_eof + _test_eof2961: cs = 2961; goto _test_eof + _test_eof2962: cs = 2962; goto _test_eof + _test_eof2963: cs = 2963; goto _test_eof + _test_eof2964: cs = 2964; goto _test_eof + _test_eof2965: cs = 2965; goto _test_eof + _test_eof2966: cs = 2966; goto _test_eof + _test_eof2967: cs = 2967; goto _test_eof + _test_eof2968: cs = 2968; goto _test_eof + _test_eof2969: cs = 2969; goto _test_eof + _test_eof2970: cs = 2970; goto _test_eof + _test_eof2971: cs = 2971; goto _test_eof + _test_eof2972: cs = 2972; goto _test_eof + _test_eof2973: cs = 2973; goto _test_eof + _test_eof2974: cs = 2974; goto _test_eof + _test_eof2975: cs = 2975; goto _test_eof + _test_eof2976: cs = 2976; goto _test_eof + _test_eof2977: cs = 2977; goto _test_eof + _test_eof2978: cs = 2978; goto _test_eof + _test_eof2979: cs = 2979; goto _test_eof + _test_eof2980: cs = 2980; goto _test_eof + _test_eof2981: cs = 2981; goto _test_eof + _test_eof2982: cs = 2982; goto _test_eof + _test_eof2983: cs = 2983; goto _test_eof + _test_eof2984: cs = 2984; goto _test_eof + _test_eof2985: cs = 2985; goto _test_eof + _test_eof2986: cs = 2986; goto _test_eof + _test_eof2987: cs = 2987; goto _test_eof + _test_eof2988: cs = 2988; goto _test_eof + _test_eof2989: cs = 2989; goto _test_eof + _test_eof2990: cs = 2990; goto _test_eof + _test_eof2991: cs = 2991; goto _test_eof + _test_eof2992: cs = 2992; goto _test_eof + _test_eof2993: cs = 2993; goto _test_eof + _test_eof2994: cs = 2994; goto _test_eof + _test_eof2995: cs = 2995; goto _test_eof + _test_eof2996: cs = 2996; goto _test_eof + _test_eof2997: cs = 2997; goto _test_eof + _test_eof2998: cs = 2998; goto _test_eof + _test_eof2999: cs = 2999; goto _test_eof + _test_eof3000: cs = 3000; goto _test_eof + _test_eof3001: cs = 3001; goto _test_eof + _test_eof3002: cs = 3002; goto _test_eof + _test_eof3003: cs = 3003; goto _test_eof + _test_eof3004: cs = 3004; goto _test_eof + _test_eof3005: cs = 3005; goto _test_eof + _test_eof3006: cs = 3006; goto _test_eof + _test_eof3007: cs = 3007; goto _test_eof + _test_eof3008: cs = 3008; goto _test_eof + _test_eof3009: cs = 3009; goto _test_eof + _test_eof3010: cs = 3010; goto _test_eof + _test_eof3011: cs = 3011; goto _test_eof + _test_eof3012: cs = 3012; goto _test_eof + _test_eof3013: cs = 3013; goto _test_eof + _test_eof3014: cs = 3014; goto _test_eof + _test_eof3015: cs = 3015; goto _test_eof + _test_eof3016: cs = 3016; goto _test_eof + _test_eof3017: cs = 3017; goto _test_eof + _test_eof3018: cs = 3018; goto _test_eof + _test_eof3019: cs = 3019; goto _test_eof + _test_eof3020: cs = 3020; goto _test_eof + _test_eof3021: cs = 3021; goto _test_eof + _test_eof3022: cs = 3022; goto _test_eof + _test_eof3023: cs = 3023; goto _test_eof + _test_eof3024: cs = 3024; goto _test_eof + _test_eof3025: cs = 3025; goto _test_eof + _test_eof3026: cs = 3026; goto _test_eof + _test_eof3027: cs = 3027; goto _test_eof + _test_eof3028: cs = 3028; goto _test_eof + _test_eof3029: cs = 3029; goto _test_eof + _test_eof3030: cs = 3030; goto _test_eof + _test_eof3031: cs = 3031; goto _test_eof + _test_eof3032: cs = 3032; goto _test_eof + _test_eof3033: cs = 3033; goto _test_eof + _test_eof3034: cs = 3034; goto _test_eof + _test_eof3035: cs = 3035; goto _test_eof + _test_eof3036: cs = 3036; goto _test_eof + _test_eof3037: cs = 3037; goto _test_eof + _test_eof3038: cs = 3038; goto _test_eof + _test_eof3039: cs = 3039; goto _test_eof + _test_eof3040: cs = 3040; goto _test_eof + _test_eof3041: cs = 3041; goto _test_eof + _test_eof3042: cs = 3042; goto _test_eof + _test_eof3043: cs = 3043; goto _test_eof + _test_eof3044: cs = 3044; goto _test_eof + _test_eof3045: cs = 3045; goto _test_eof + _test_eof3046: cs = 3046; goto _test_eof + _test_eof3047: cs = 3047; goto _test_eof + _test_eof3048: cs = 3048; goto _test_eof + _test_eof3049: cs = 3049; goto _test_eof + _test_eof3050: cs = 3050; goto _test_eof + _test_eof3051: cs = 3051; goto _test_eof + _test_eof3052: cs = 3052; goto _test_eof + _test_eof3053: cs = 3053; goto _test_eof + _test_eof3054: cs = 3054; goto _test_eof + _test_eof3055: cs = 3055; goto _test_eof + _test_eof3056: cs = 3056; goto _test_eof + _test_eof3057: cs = 3057; goto _test_eof + _test_eof3058: cs = 3058; goto _test_eof + _test_eof3059: cs = 3059; goto _test_eof + _test_eof3060: cs = 3060; goto _test_eof + _test_eof3061: cs = 3061; goto _test_eof + _test_eof3062: cs = 3062; goto _test_eof + _test_eof3063: cs = 3063; goto _test_eof + _test_eof3064: cs = 3064; goto _test_eof + _test_eof3065: cs = 3065; goto _test_eof + _test_eof3066: cs = 3066; goto _test_eof + _test_eof3067: cs = 3067; goto _test_eof + _test_eof3068: cs = 3068; goto _test_eof + _test_eof3069: cs = 3069; goto _test_eof + _test_eof3070: cs = 3070; goto _test_eof + _test_eof4887: cs = 4887; goto _test_eof + _test_eof3071: cs = 3071; goto _test_eof + _test_eof3072: cs = 3072; goto _test_eof + _test_eof3073: cs = 3073; goto _test_eof + _test_eof3074: cs = 3074; goto _test_eof + _test_eof3075: cs = 3075; goto _test_eof + _test_eof3076: cs = 3076; goto _test_eof + _test_eof3077: cs = 3077; goto _test_eof + _test_eof3078: cs = 3078; goto _test_eof + _test_eof3079: cs = 3079; goto _test_eof + _test_eof3080: cs = 3080; goto _test_eof + _test_eof3081: cs = 3081; goto _test_eof + _test_eof3082: cs = 3082; goto _test_eof + _test_eof3083: cs = 3083; goto _test_eof + _test_eof3084: cs = 3084; goto _test_eof + _test_eof3085: cs = 3085; goto _test_eof + _test_eof3086: cs = 3086; goto _test_eof + _test_eof3087: cs = 3087; goto _test_eof + _test_eof3088: cs = 3088; goto _test_eof + _test_eof3089: cs = 3089; goto _test_eof + _test_eof3090: cs = 3090; goto _test_eof + _test_eof3091: cs = 3091; goto _test_eof + _test_eof3092: cs = 3092; goto _test_eof + _test_eof3093: cs = 3093; goto _test_eof + _test_eof3094: cs = 3094; goto _test_eof + _test_eof3095: cs = 3095; goto _test_eof + _test_eof3096: cs = 3096; goto _test_eof + _test_eof3097: cs = 3097; goto _test_eof + _test_eof3098: cs = 3098; goto _test_eof + _test_eof3099: cs = 3099; goto _test_eof + _test_eof3100: cs = 3100; goto _test_eof + _test_eof3101: cs = 3101; goto _test_eof + _test_eof3102: cs = 3102; goto _test_eof + _test_eof3103: cs = 3103; goto _test_eof + _test_eof3104: cs = 3104; goto _test_eof + _test_eof3105: cs = 3105; goto _test_eof + _test_eof3106: cs = 3106; goto _test_eof + _test_eof3107: cs = 3107; goto _test_eof + _test_eof3108: cs = 3108; goto _test_eof + _test_eof3109: cs = 3109; goto _test_eof + _test_eof3110: cs = 3110; goto _test_eof + _test_eof3111: cs = 3111; goto _test_eof + _test_eof3112: cs = 3112; goto _test_eof + _test_eof3113: cs = 3113; goto _test_eof + _test_eof3114: cs = 3114; goto _test_eof + _test_eof3115: cs = 3115; goto _test_eof + _test_eof3116: cs = 3116; goto _test_eof + _test_eof3117: cs = 3117; goto _test_eof + _test_eof3118: cs = 3118; goto _test_eof + _test_eof3119: cs = 3119; goto _test_eof + _test_eof3120: cs = 3120; goto _test_eof + _test_eof3121: cs = 3121; goto _test_eof + _test_eof3122: cs = 3122; goto _test_eof + _test_eof3123: cs = 3123; goto _test_eof + _test_eof3124: cs = 3124; goto _test_eof + _test_eof3125: cs = 3125; goto _test_eof + _test_eof3126: cs = 3126; goto _test_eof + _test_eof3127: cs = 3127; goto _test_eof + _test_eof3128: cs = 3128; goto _test_eof + _test_eof3129: cs = 3129; goto _test_eof + _test_eof3130: cs = 3130; goto _test_eof + _test_eof3131: cs = 3131; goto _test_eof + _test_eof3132: cs = 3132; goto _test_eof + _test_eof3133: cs = 3133; goto _test_eof + _test_eof3134: cs = 3134; goto _test_eof + _test_eof3135: cs = 3135; goto _test_eof + _test_eof3136: cs = 3136; goto _test_eof + _test_eof3137: cs = 3137; goto _test_eof + _test_eof3138: cs = 3138; goto _test_eof + _test_eof3139: cs = 3139; goto _test_eof + _test_eof3140: cs = 3140; goto _test_eof + _test_eof3141: cs = 3141; goto _test_eof + _test_eof3142: cs = 3142; goto _test_eof + _test_eof3143: cs = 3143; goto _test_eof + _test_eof3144: cs = 3144; goto _test_eof + _test_eof3145: cs = 3145; goto _test_eof + _test_eof3146: cs = 3146; goto _test_eof + _test_eof3147: cs = 3147; goto _test_eof + _test_eof3148: cs = 3148; goto _test_eof + _test_eof3149: cs = 3149; goto _test_eof + _test_eof3150: cs = 3150; goto _test_eof + _test_eof3151: cs = 3151; goto _test_eof + _test_eof3152: cs = 3152; goto _test_eof + _test_eof3153: cs = 3153; goto _test_eof + _test_eof3154: cs = 3154; goto _test_eof + _test_eof3155: cs = 3155; goto _test_eof + _test_eof3156: cs = 3156; goto _test_eof + _test_eof3157: cs = 3157; goto _test_eof + _test_eof3158: cs = 3158; goto _test_eof + _test_eof3159: cs = 3159; goto _test_eof + _test_eof3160: cs = 3160; goto _test_eof + _test_eof3161: cs = 3161; goto _test_eof + _test_eof3162: cs = 3162; goto _test_eof + _test_eof3163: cs = 3163; goto _test_eof + _test_eof3164: cs = 3164; goto _test_eof + _test_eof3165: cs = 3165; goto _test_eof + _test_eof3166: cs = 3166; goto _test_eof + _test_eof3167: cs = 3167; goto _test_eof + _test_eof3168: cs = 3168; goto _test_eof + _test_eof3169: cs = 3169; goto _test_eof + _test_eof3170: cs = 3170; goto _test_eof + _test_eof3171: cs = 3171; goto _test_eof + _test_eof3172: cs = 3172; goto _test_eof + _test_eof3173: cs = 3173; goto _test_eof + _test_eof3174: cs = 3174; goto _test_eof + _test_eof3175: cs = 3175; goto _test_eof + _test_eof3176: cs = 3176; goto _test_eof + _test_eof3177: cs = 3177; goto _test_eof + _test_eof3178: cs = 3178; goto _test_eof + _test_eof3179: cs = 3179; goto _test_eof + _test_eof3180: cs = 3180; goto _test_eof + _test_eof3181: cs = 3181; goto _test_eof + _test_eof3182: cs = 3182; goto _test_eof + _test_eof3183: cs = 3183; goto _test_eof + _test_eof3184: cs = 3184; goto _test_eof + _test_eof3185: cs = 3185; goto _test_eof + _test_eof3186: cs = 3186; goto _test_eof + _test_eof3187: cs = 3187; goto _test_eof + _test_eof3188: cs = 3188; goto _test_eof + _test_eof3189: cs = 3189; goto _test_eof + _test_eof3190: cs = 3190; goto _test_eof + _test_eof3191: cs = 3191; goto _test_eof + _test_eof3192: cs = 3192; goto _test_eof + _test_eof3193: cs = 3193; goto _test_eof + _test_eof3194: cs = 3194; goto _test_eof + _test_eof3195: cs = 3195; goto _test_eof + _test_eof3196: cs = 3196; goto _test_eof + _test_eof3197: cs = 3197; goto _test_eof + _test_eof3198: cs = 3198; goto _test_eof + _test_eof3199: cs = 3199; goto _test_eof + _test_eof3200: cs = 3200; goto _test_eof + _test_eof3201: cs = 3201; goto _test_eof + _test_eof3202: cs = 3202; goto _test_eof + _test_eof3203: cs = 3203; goto _test_eof + _test_eof3204: cs = 3204; goto _test_eof + _test_eof3205: cs = 3205; goto _test_eof + _test_eof3206: cs = 3206; goto _test_eof + _test_eof3207: cs = 3207; goto _test_eof + _test_eof3208: cs = 3208; goto _test_eof + _test_eof3209: cs = 3209; goto _test_eof + _test_eof3210: cs = 3210; goto _test_eof + _test_eof3211: cs = 3211; goto _test_eof + _test_eof3212: cs = 3212; goto _test_eof + _test_eof3213: cs = 3213; goto _test_eof + _test_eof3214: cs = 3214; goto _test_eof + _test_eof3215: cs = 3215; goto _test_eof + _test_eof3216: cs = 3216; goto _test_eof + _test_eof3217: cs = 3217; goto _test_eof + _test_eof4888: cs = 4888; goto _test_eof + _test_eof4889: cs = 4889; goto _test_eof + _test_eof4890: cs = 4890; goto _test_eof + _test_eof4891: cs = 4891; goto _test_eof + _test_eof4892: cs = 4892; goto _test_eof + _test_eof4893: cs = 4893; goto _test_eof + _test_eof4894: cs = 4894; goto _test_eof + _test_eof4895: cs = 4895; goto _test_eof + _test_eof4896: cs = 4896; goto _test_eof + _test_eof4897: cs = 4897; goto _test_eof + _test_eof4898: cs = 4898; goto _test_eof + _test_eof4899: cs = 4899; goto _test_eof + _test_eof4900: cs = 4900; goto _test_eof + _test_eof4901: cs = 4901; goto _test_eof + _test_eof4902: cs = 4902; goto _test_eof + _test_eof4903: cs = 4903; goto _test_eof + _test_eof4904: cs = 4904; goto _test_eof + _test_eof4905: cs = 4905; goto _test_eof + _test_eof4906: cs = 4906; goto _test_eof + _test_eof4907: cs = 4907; goto _test_eof + _test_eof4908: cs = 4908; goto _test_eof + _test_eof4909: cs = 4909; goto _test_eof + _test_eof4910: cs = 4910; goto _test_eof + _test_eof4911: cs = 4911; goto _test_eof + _test_eof4912: cs = 4912; goto _test_eof + _test_eof4913: cs = 4913; goto _test_eof + _test_eof4914: cs = 4914; goto _test_eof + _test_eof4915: cs = 4915; goto _test_eof + _test_eof4916: cs = 4916; goto _test_eof + _test_eof4917: cs = 4917; goto _test_eof + _test_eof4918: cs = 4918; goto _test_eof + _test_eof4919: cs = 4919; goto _test_eof + _test_eof4920: cs = 4920; goto _test_eof + _test_eof4921: cs = 4921; goto _test_eof + _test_eof4922: cs = 4922; goto _test_eof + _test_eof4923: cs = 4923; goto _test_eof + _test_eof4924: cs = 4924; goto _test_eof + _test_eof4925: cs = 4925; goto _test_eof + _test_eof4926: cs = 4926; goto _test_eof + _test_eof4927: cs = 4927; goto _test_eof + _test_eof4928: cs = 4928; goto _test_eof + _test_eof3218: cs = 3218; goto _test_eof + _test_eof3219: cs = 3219; goto _test_eof + _test_eof3220: cs = 3220; goto _test_eof + _test_eof3221: cs = 3221; goto _test_eof + _test_eof3222: cs = 3222; goto _test_eof + _test_eof3223: cs = 3223; goto _test_eof + _test_eof3224: cs = 3224; goto _test_eof + _test_eof3225: cs = 3225; goto _test_eof + _test_eof3226: cs = 3226; goto _test_eof + _test_eof3227: cs = 3227; goto _test_eof + _test_eof3228: cs = 3228; goto _test_eof + _test_eof3229: cs = 3229; goto _test_eof + _test_eof3230: cs = 3230; goto _test_eof + _test_eof3231: cs = 3231; goto _test_eof + _test_eof4929: cs = 4929; goto _test_eof + _test_eof4930: cs = 4930; goto _test_eof + _test_eof4931: cs = 4931; goto _test_eof + _test_eof4932: cs = 4932; goto _test_eof + _test_eof3232: cs = 3232; goto _test_eof + _test_eof4933: cs = 4933; goto _test_eof + _test_eof4934: cs = 4934; goto _test_eof + _test_eof4935: cs = 4935; goto _test_eof + _test_eof4936: cs = 4936; goto _test_eof + _test_eof4937: cs = 4937; goto _test_eof + _test_eof4938: cs = 4938; goto _test_eof + _test_eof4939: cs = 4939; goto _test_eof + _test_eof4940: cs = 4940; goto _test_eof + _test_eof4941: cs = 4941; goto _test_eof + _test_eof4942: cs = 4942; goto _test_eof + _test_eof4943: cs = 4943; goto _test_eof + _test_eof4944: cs = 4944; goto _test_eof + _test_eof4945: cs = 4945; goto _test_eof + _test_eof4946: cs = 4946; goto _test_eof + _test_eof4947: cs = 4947; goto _test_eof + _test_eof4948: cs = 4948; goto _test_eof + _test_eof4949: cs = 4949; goto _test_eof + _test_eof4950: cs = 4950; goto _test_eof + _test_eof4951: cs = 4951; goto _test_eof + _test_eof4952: cs = 4952; goto _test_eof + _test_eof4953: cs = 4953; goto _test_eof + _test_eof4954: cs = 4954; goto _test_eof + _test_eof4955: cs = 4955; goto _test_eof + _test_eof4956: cs = 4956; goto _test_eof + _test_eof4957: cs = 4957; goto _test_eof + _test_eof3233: cs = 3233; goto _test_eof + _test_eof4958: cs = 4958; goto _test_eof + _test_eof4959: cs = 4959; goto _test_eof + _test_eof4960: cs = 4960; goto _test_eof + _test_eof4961: cs = 4961; goto _test_eof + _test_eof4962: cs = 4962; goto _test_eof + _test_eof4963: cs = 4963; goto _test_eof + _test_eof3234: cs = 3234; goto _test_eof + _test_eof4964: cs = 4964; goto _test_eof + _test_eof4965: cs = 4965; goto _test_eof + _test_eof3235: cs = 3235; goto _test_eof + _test_eof4966: cs = 4966; goto _test_eof + _test_eof4967: cs = 4967; goto _test_eof + _test_eof4968: cs = 4968; goto _test_eof + _test_eof4969: cs = 4969; goto _test_eof + _test_eof4970: cs = 4970; goto _test_eof + _test_eof4971: cs = 4971; goto _test_eof + _test_eof4972: cs = 4972; goto _test_eof + _test_eof4973: cs = 4973; goto _test_eof + _test_eof4974: cs = 4974; goto _test_eof + _test_eof4975: cs = 4975; goto _test_eof + _test_eof4976: cs = 4976; goto _test_eof + _test_eof4977: cs = 4977; goto _test_eof + _test_eof4978: cs = 4978; goto _test_eof + _test_eof4979: cs = 4979; goto _test_eof + _test_eof4980: cs = 4980; goto _test_eof + _test_eof3236: cs = 3236; goto _test_eof + _test_eof4981: cs = 4981; goto _test_eof + _test_eof4982: cs = 4982; goto _test_eof + _test_eof4983: cs = 4983; goto _test_eof + _test_eof3237: cs = 3237; goto _test_eof + _test_eof4984: cs = 4984; goto _test_eof + _test_eof4985: cs = 4985; goto _test_eof + _test_eof4986: cs = 4986; goto _test_eof + _test_eof4987: cs = 4987; goto _test_eof + _test_eof4988: cs = 4988; goto _test_eof + _test_eof4989: cs = 4989; goto _test_eof + _test_eof3238: cs = 3238; goto _test_eof + _test_eof4990: cs = 4990; goto _test_eof + _test_eof4991: cs = 4991; goto _test_eof + _test_eof4992: cs = 4992; goto _test_eof + _test_eof4993: cs = 4993; goto _test_eof + _test_eof4994: cs = 4994; goto _test_eof + _test_eof4995: cs = 4995; goto _test_eof + _test_eof4996: cs = 4996; goto _test_eof + _test_eof4997: cs = 4997; goto _test_eof + _test_eof4998: cs = 4998; goto _test_eof + _test_eof4999: cs = 4999; goto _test_eof + _test_eof5000: cs = 5000; goto _test_eof + _test_eof5001: cs = 5001; goto _test_eof + _test_eof5002: cs = 5002; goto _test_eof + _test_eof5003: cs = 5003; goto _test_eof + _test_eof5004: cs = 5004; goto _test_eof + _test_eof5005: cs = 5005; goto _test_eof + _test_eof5006: cs = 5006; goto _test_eof + _test_eof5007: cs = 5007; goto _test_eof + _test_eof5008: cs = 5008; goto _test_eof + _test_eof5009: cs = 5009; goto _test_eof + _test_eof5010: cs = 5010; goto _test_eof + _test_eof5011: cs = 5011; goto _test_eof + _test_eof5012: cs = 5012; goto _test_eof + _test_eof5013: cs = 5013; goto _test_eof + _test_eof5014: cs = 5014; goto _test_eof + _test_eof5015: cs = 5015; goto _test_eof + _test_eof5016: cs = 5016; goto _test_eof + _test_eof5017: cs = 5017; goto _test_eof + _test_eof5018: cs = 5018; goto _test_eof + _test_eof5019: cs = 5019; goto _test_eof + _test_eof5020: cs = 5020; goto _test_eof + _test_eof5021: cs = 5021; goto _test_eof + _test_eof5022: cs = 5022; goto _test_eof + _test_eof5023: cs = 5023; goto _test_eof + _test_eof5024: cs = 5024; goto _test_eof + _test_eof5025: cs = 5025; goto _test_eof + _test_eof5026: cs = 5026; goto _test_eof + _test_eof5027: cs = 5027; goto _test_eof + _test_eof5028: cs = 5028; goto _test_eof + _test_eof5029: cs = 5029; goto _test_eof + _test_eof5030: cs = 5030; goto _test_eof + _test_eof5031: cs = 5031; goto _test_eof + _test_eof5032: cs = 5032; goto _test_eof + _test_eof5033: cs = 5033; goto _test_eof + _test_eof5034: cs = 5034; goto _test_eof + _test_eof5035: cs = 5035; goto _test_eof + _test_eof5036: cs = 5036; goto _test_eof + _test_eof5037: cs = 5037; goto _test_eof + _test_eof5038: cs = 5038; goto _test_eof + _test_eof5039: cs = 5039; goto _test_eof + _test_eof5040: cs = 5040; goto _test_eof + _test_eof5041: cs = 5041; goto _test_eof + _test_eof5042: cs = 5042; goto _test_eof + _test_eof5043: cs = 5043; goto _test_eof + _test_eof5044: cs = 5044; goto _test_eof + _test_eof5045: cs = 5045; goto _test_eof + _test_eof5046: cs = 5046; goto _test_eof + _test_eof5047: cs = 5047; goto _test_eof + _test_eof5048: cs = 5048; goto _test_eof + _test_eof5049: cs = 5049; goto _test_eof + _test_eof5050: cs = 5050; goto _test_eof + _test_eof5051: cs = 5051; goto _test_eof + _test_eof5052: cs = 5052; goto _test_eof + _test_eof5053: cs = 5053; goto _test_eof + _test_eof5054: cs = 5054; goto _test_eof + _test_eof5055: cs = 5055; goto _test_eof + _test_eof5056: cs = 5056; goto _test_eof + _test_eof5057: cs = 5057; goto _test_eof + _test_eof5058: cs = 5058; goto _test_eof + _test_eof5059: cs = 5059; goto _test_eof + _test_eof5060: cs = 5060; goto _test_eof + _test_eof5061: cs = 5061; goto _test_eof + _test_eof5062: cs = 5062; goto _test_eof + _test_eof5063: cs = 5063; goto _test_eof + _test_eof5064: cs = 5064; goto _test_eof + _test_eof5065: cs = 5065; goto _test_eof + _test_eof5066: cs = 5066; goto _test_eof + _test_eof5067: cs = 5067; goto _test_eof + _test_eof5068: cs = 5068; goto _test_eof + _test_eof5069: cs = 5069; goto _test_eof + _test_eof5070: cs = 5070; goto _test_eof + _test_eof5071: cs = 5071; goto _test_eof + _test_eof3239: cs = 3239; goto _test_eof + _test_eof3240: cs = 3240; goto _test_eof + _test_eof3241: cs = 3241; goto _test_eof + _test_eof3242: cs = 3242; goto _test_eof + _test_eof3243: cs = 3243; goto _test_eof + _test_eof3244: cs = 3244; goto _test_eof + _test_eof3245: cs = 3245; goto _test_eof + _test_eof3246: cs = 3246; goto _test_eof + _test_eof3247: cs = 3247; goto _test_eof + _test_eof3248: cs = 3248; goto _test_eof + _test_eof3249: cs = 3249; goto _test_eof + _test_eof3250: cs = 3250; goto _test_eof + _test_eof3251: cs = 3251; goto _test_eof + _test_eof3252: cs = 3252; goto _test_eof + _test_eof3253: cs = 3253; goto _test_eof + _test_eof3254: cs = 3254; goto _test_eof + _test_eof3255: cs = 3255; goto _test_eof + _test_eof3256: cs = 3256; goto _test_eof + _test_eof3257: cs = 3257; goto _test_eof + _test_eof3258: cs = 3258; goto _test_eof + _test_eof3259: cs = 3259; goto _test_eof + _test_eof3260: cs = 3260; goto _test_eof + _test_eof3261: cs = 3261; goto _test_eof + _test_eof3262: cs = 3262; goto _test_eof + _test_eof3263: cs = 3263; goto _test_eof + _test_eof3264: cs = 3264; goto _test_eof + _test_eof3265: cs = 3265; goto _test_eof + _test_eof5072: cs = 5072; goto _test_eof + _test_eof3266: cs = 3266; goto _test_eof + _test_eof3267: cs = 3267; goto _test_eof + _test_eof3268: cs = 3268; goto _test_eof + _test_eof5073: cs = 5073; goto _test_eof + _test_eof3269: cs = 3269; goto _test_eof + _test_eof3270: cs = 3270; goto _test_eof + _test_eof3271: cs = 3271; goto _test_eof + _test_eof3272: cs = 3272; goto _test_eof + _test_eof3273: cs = 3273; goto _test_eof + _test_eof3274: cs = 3274; goto _test_eof + _test_eof3275: cs = 3275; goto _test_eof + _test_eof3276: cs = 3276; goto _test_eof + _test_eof3277: cs = 3277; goto _test_eof + _test_eof3278: cs = 3278; goto _test_eof + _test_eof3279: cs = 3279; goto _test_eof + _test_eof3280: cs = 3280; goto _test_eof + _test_eof3281: cs = 3281; goto _test_eof + _test_eof3282: cs = 3282; goto _test_eof + _test_eof3283: cs = 3283; goto _test_eof + _test_eof3284: cs = 3284; goto _test_eof + _test_eof3285: cs = 3285; goto _test_eof + _test_eof3286: cs = 3286; goto _test_eof + _test_eof3287: cs = 3287; goto _test_eof + _test_eof3288: cs = 3288; goto _test_eof + _test_eof3289: cs = 3289; goto _test_eof + _test_eof3290: cs = 3290; goto _test_eof + _test_eof3291: cs = 3291; goto _test_eof + _test_eof3292: cs = 3292; goto _test_eof + _test_eof3293: cs = 3293; goto _test_eof + _test_eof3294: cs = 3294; goto _test_eof + _test_eof3295: cs = 3295; goto _test_eof + _test_eof3296: cs = 3296; goto _test_eof + _test_eof3297: cs = 3297; goto _test_eof + _test_eof3298: cs = 3298; goto _test_eof + _test_eof3299: cs = 3299; goto _test_eof + _test_eof3300: cs = 3300; goto _test_eof + _test_eof3301: cs = 3301; goto _test_eof + _test_eof3302: cs = 3302; goto _test_eof + _test_eof3303: cs = 3303; goto _test_eof + _test_eof3304: cs = 3304; goto _test_eof + _test_eof3305: cs = 3305; goto _test_eof + _test_eof3306: cs = 3306; goto _test_eof + _test_eof3307: cs = 3307; goto _test_eof + _test_eof3308: cs = 3308; goto _test_eof + _test_eof3309: cs = 3309; goto _test_eof + _test_eof3310: cs = 3310; goto _test_eof + _test_eof3311: cs = 3311; goto _test_eof + _test_eof3312: cs = 3312; goto _test_eof + _test_eof3313: cs = 3313; goto _test_eof + _test_eof3314: cs = 3314; goto _test_eof + _test_eof3315: cs = 3315; goto _test_eof + _test_eof3316: cs = 3316; goto _test_eof + _test_eof3317: cs = 3317; goto _test_eof + _test_eof3318: cs = 3318; goto _test_eof + _test_eof3319: cs = 3319; goto _test_eof + _test_eof3320: cs = 3320; goto _test_eof + _test_eof3321: cs = 3321; goto _test_eof + _test_eof3322: cs = 3322; goto _test_eof + _test_eof3323: cs = 3323; goto _test_eof + _test_eof3324: cs = 3324; goto _test_eof + _test_eof3325: cs = 3325; goto _test_eof + _test_eof3326: cs = 3326; goto _test_eof + _test_eof3327: cs = 3327; goto _test_eof + _test_eof3328: cs = 3328; goto _test_eof + _test_eof3329: cs = 3329; goto _test_eof + _test_eof3330: cs = 3330; goto _test_eof + _test_eof3331: cs = 3331; goto _test_eof + _test_eof3332: cs = 3332; goto _test_eof + _test_eof3333: cs = 3333; goto _test_eof + _test_eof3334: cs = 3334; goto _test_eof + _test_eof3335: cs = 3335; goto _test_eof + _test_eof3336: cs = 3336; goto _test_eof + _test_eof3337: cs = 3337; goto _test_eof + _test_eof3338: cs = 3338; goto _test_eof + _test_eof3339: cs = 3339; goto _test_eof + _test_eof3340: cs = 3340; goto _test_eof + _test_eof3341: cs = 3341; goto _test_eof + _test_eof3342: cs = 3342; goto _test_eof + _test_eof3343: cs = 3343; goto _test_eof + _test_eof3344: cs = 3344; goto _test_eof + _test_eof3345: cs = 3345; goto _test_eof + _test_eof3346: cs = 3346; goto _test_eof + _test_eof3347: cs = 3347; goto _test_eof + _test_eof3348: cs = 3348; goto _test_eof + _test_eof3349: cs = 3349; goto _test_eof + _test_eof3350: cs = 3350; goto _test_eof + _test_eof5074: cs = 5074; goto _test_eof + _test_eof3351: cs = 3351; goto _test_eof + _test_eof3352: cs = 3352; goto _test_eof + _test_eof3353: cs = 3353; goto _test_eof + _test_eof3354: cs = 3354; goto _test_eof + _test_eof3355: cs = 3355; goto _test_eof + _test_eof3356: cs = 3356; goto _test_eof + _test_eof3357: cs = 3357; goto _test_eof + _test_eof3358: cs = 3358; goto _test_eof + _test_eof3359: cs = 3359; goto _test_eof + _test_eof3360: cs = 3360; goto _test_eof + _test_eof3361: cs = 3361; goto _test_eof + _test_eof3362: cs = 3362; goto _test_eof + _test_eof3363: cs = 3363; goto _test_eof + _test_eof3364: cs = 3364; goto _test_eof + _test_eof3365: cs = 3365; goto _test_eof + _test_eof3366: cs = 3366; goto _test_eof + _test_eof3367: cs = 3367; goto _test_eof + _test_eof3368: cs = 3368; goto _test_eof + _test_eof3369: cs = 3369; goto _test_eof + _test_eof3370: cs = 3370; goto _test_eof + _test_eof3371: cs = 3371; goto _test_eof + _test_eof3372: cs = 3372; goto _test_eof + _test_eof3373: cs = 3373; goto _test_eof + _test_eof3374: cs = 3374; goto _test_eof + _test_eof3375: cs = 3375; goto _test_eof + _test_eof3376: cs = 3376; goto _test_eof + _test_eof3377: cs = 3377; goto _test_eof + _test_eof3378: cs = 3378; goto _test_eof + _test_eof3379: cs = 3379; goto _test_eof + _test_eof3380: cs = 3380; goto _test_eof + _test_eof3381: cs = 3381; goto _test_eof + _test_eof3382: cs = 3382; goto _test_eof + _test_eof3383: cs = 3383; goto _test_eof + _test_eof3384: cs = 3384; goto _test_eof + _test_eof3385: cs = 3385; goto _test_eof + _test_eof3386: cs = 3386; goto _test_eof + _test_eof3387: cs = 3387; goto _test_eof + _test_eof3388: cs = 3388; goto _test_eof + _test_eof3389: cs = 3389; goto _test_eof + _test_eof3390: cs = 3390; goto _test_eof + _test_eof3391: cs = 3391; goto _test_eof + _test_eof3392: cs = 3392; goto _test_eof + _test_eof3393: cs = 3393; goto _test_eof + _test_eof3394: cs = 3394; goto _test_eof + _test_eof3395: cs = 3395; goto _test_eof + _test_eof3396: cs = 3396; goto _test_eof + _test_eof3397: cs = 3397; goto _test_eof + _test_eof3398: cs = 3398; goto _test_eof + _test_eof3399: cs = 3399; goto _test_eof + _test_eof3400: cs = 3400; goto _test_eof + _test_eof3401: cs = 3401; goto _test_eof + _test_eof3402: cs = 3402; goto _test_eof + _test_eof3403: cs = 3403; goto _test_eof + _test_eof3404: cs = 3404; goto _test_eof + _test_eof3405: cs = 3405; goto _test_eof + _test_eof3406: cs = 3406; goto _test_eof + _test_eof3407: cs = 3407; goto _test_eof + _test_eof3408: cs = 3408; goto _test_eof + _test_eof3409: cs = 3409; goto _test_eof + _test_eof3410: cs = 3410; goto _test_eof + _test_eof3411: cs = 3411; goto _test_eof + _test_eof3412: cs = 3412; goto _test_eof + _test_eof3413: cs = 3413; goto _test_eof + _test_eof3414: cs = 3414; goto _test_eof + _test_eof3415: cs = 3415; goto _test_eof + _test_eof3416: cs = 3416; goto _test_eof + _test_eof3417: cs = 3417; goto _test_eof + _test_eof3418: cs = 3418; goto _test_eof + _test_eof3419: cs = 3419; goto _test_eof + _test_eof3420: cs = 3420; goto _test_eof + _test_eof3421: cs = 3421; goto _test_eof + _test_eof3422: cs = 3422; goto _test_eof + _test_eof3423: cs = 3423; goto _test_eof + _test_eof3424: cs = 3424; goto _test_eof + _test_eof3425: cs = 3425; goto _test_eof + _test_eof3426: cs = 3426; goto _test_eof + _test_eof3427: cs = 3427; goto _test_eof + _test_eof3428: cs = 3428; goto _test_eof + _test_eof3429: cs = 3429; goto _test_eof + _test_eof3430: cs = 3430; goto _test_eof + _test_eof3431: cs = 3431; goto _test_eof + _test_eof3432: cs = 3432; goto _test_eof + _test_eof3433: cs = 3433; goto _test_eof + _test_eof3434: cs = 3434; goto _test_eof + _test_eof3435: cs = 3435; goto _test_eof + _test_eof3436: cs = 3436; goto _test_eof + _test_eof3437: cs = 3437; goto _test_eof + _test_eof3438: cs = 3438; goto _test_eof + _test_eof3439: cs = 3439; goto _test_eof + _test_eof3440: cs = 3440; goto _test_eof + _test_eof3441: cs = 3441; goto _test_eof + _test_eof3442: cs = 3442; goto _test_eof + _test_eof3443: cs = 3443; goto _test_eof + _test_eof3444: cs = 3444; goto _test_eof + _test_eof3445: cs = 3445; goto _test_eof + _test_eof3446: cs = 3446; goto _test_eof + _test_eof3447: cs = 3447; goto _test_eof + _test_eof3448: cs = 3448; goto _test_eof + _test_eof3449: cs = 3449; goto _test_eof + _test_eof3450: cs = 3450; goto _test_eof + _test_eof3451: cs = 3451; goto _test_eof + _test_eof3452: cs = 3452; goto _test_eof + _test_eof3453: cs = 3453; goto _test_eof + _test_eof3454: cs = 3454; goto _test_eof + _test_eof3455: cs = 3455; goto _test_eof + _test_eof3456: cs = 3456; goto _test_eof + _test_eof3457: cs = 3457; goto _test_eof + _test_eof3458: cs = 3458; goto _test_eof + _test_eof3459: cs = 3459; goto _test_eof + _test_eof3460: cs = 3460; goto _test_eof + _test_eof3461: cs = 3461; goto _test_eof + _test_eof3462: cs = 3462; goto _test_eof + _test_eof3463: cs = 3463; goto _test_eof + _test_eof3464: cs = 3464; goto _test_eof + _test_eof3465: cs = 3465; goto _test_eof + _test_eof3466: cs = 3466; goto _test_eof + _test_eof3467: cs = 3467; goto _test_eof + _test_eof3468: cs = 3468; goto _test_eof + _test_eof3469: cs = 3469; goto _test_eof + _test_eof3470: cs = 3470; goto _test_eof + _test_eof3471: cs = 3471; goto _test_eof + _test_eof3472: cs = 3472; goto _test_eof + _test_eof3473: cs = 3473; goto _test_eof + _test_eof3474: cs = 3474; goto _test_eof + _test_eof3475: cs = 3475; goto _test_eof + _test_eof3476: cs = 3476; goto _test_eof + _test_eof3477: cs = 3477; goto _test_eof + _test_eof3478: cs = 3478; goto _test_eof + _test_eof3479: cs = 3479; goto _test_eof + _test_eof3480: cs = 3480; goto _test_eof + _test_eof3481: cs = 3481; goto _test_eof + _test_eof3482: cs = 3482; goto _test_eof + _test_eof3483: cs = 3483; goto _test_eof + _test_eof3484: cs = 3484; goto _test_eof + _test_eof3485: cs = 3485; goto _test_eof + _test_eof3486: cs = 3486; goto _test_eof + _test_eof3487: cs = 3487; goto _test_eof + _test_eof3488: cs = 3488; goto _test_eof + _test_eof3489: cs = 3489; goto _test_eof + _test_eof3490: cs = 3490; goto _test_eof + _test_eof3491: cs = 3491; goto _test_eof + _test_eof3492: cs = 3492; goto _test_eof + _test_eof3493: cs = 3493; goto _test_eof + _test_eof3494: cs = 3494; goto _test_eof + _test_eof3495: cs = 3495; goto _test_eof + _test_eof3496: cs = 3496; goto _test_eof + _test_eof3497: cs = 3497; goto _test_eof + _test_eof3498: cs = 3498; goto _test_eof + _test_eof3499: cs = 3499; goto _test_eof + _test_eof3500: cs = 3500; goto _test_eof + _test_eof3501: cs = 3501; goto _test_eof + _test_eof3502: cs = 3502; goto _test_eof + _test_eof3503: cs = 3503; goto _test_eof + _test_eof3504: cs = 3504; goto _test_eof + _test_eof3505: cs = 3505; goto _test_eof + _test_eof3506: cs = 3506; goto _test_eof + _test_eof3507: cs = 3507; goto _test_eof + _test_eof3508: cs = 3508; goto _test_eof + _test_eof3509: cs = 3509; goto _test_eof + _test_eof3510: cs = 3510; goto _test_eof + _test_eof3511: cs = 3511; goto _test_eof + _test_eof3512: cs = 3512; goto _test_eof + _test_eof3513: cs = 3513; goto _test_eof + _test_eof3514: cs = 3514; goto _test_eof + _test_eof3515: cs = 3515; goto _test_eof + _test_eof3516: cs = 3516; goto _test_eof + _test_eof3517: cs = 3517; goto _test_eof + _test_eof3518: cs = 3518; goto _test_eof + _test_eof3519: cs = 3519; goto _test_eof + _test_eof3520: cs = 3520; goto _test_eof + _test_eof3521: cs = 3521; goto _test_eof + _test_eof3522: cs = 3522; goto _test_eof + _test_eof3523: cs = 3523; goto _test_eof + _test_eof3524: cs = 3524; goto _test_eof + _test_eof3525: cs = 3525; goto _test_eof + _test_eof3526: cs = 3526; goto _test_eof + _test_eof3527: cs = 3527; goto _test_eof + _test_eof3528: cs = 3528; goto _test_eof + _test_eof3529: cs = 3529; goto _test_eof + _test_eof3530: cs = 3530; goto _test_eof + _test_eof3531: cs = 3531; goto _test_eof + _test_eof3532: cs = 3532; goto _test_eof + _test_eof3533: cs = 3533; goto _test_eof + _test_eof3534: cs = 3534; goto _test_eof + _test_eof3535: cs = 3535; goto _test_eof + _test_eof3536: cs = 3536; goto _test_eof + _test_eof3537: cs = 3537; goto _test_eof + _test_eof3538: cs = 3538; goto _test_eof + _test_eof3539: cs = 3539; goto _test_eof + _test_eof3540: cs = 3540; goto _test_eof + _test_eof3541: cs = 3541; goto _test_eof + _test_eof3542: cs = 3542; goto _test_eof + _test_eof3543: cs = 3543; goto _test_eof + _test_eof3544: cs = 3544; goto _test_eof + _test_eof3545: cs = 3545; goto _test_eof + _test_eof3546: cs = 3546; goto _test_eof + _test_eof3547: cs = 3547; goto _test_eof + _test_eof3548: cs = 3548; goto _test_eof + _test_eof3549: cs = 3549; goto _test_eof + _test_eof3550: cs = 3550; goto _test_eof + _test_eof3551: cs = 3551; goto _test_eof + _test_eof3552: cs = 3552; goto _test_eof + _test_eof3553: cs = 3553; goto _test_eof + _test_eof3554: cs = 3554; goto _test_eof + _test_eof3555: cs = 3555; goto _test_eof + _test_eof3556: cs = 3556; goto _test_eof + _test_eof3557: cs = 3557; goto _test_eof + _test_eof3558: cs = 3558; goto _test_eof + _test_eof3559: cs = 3559; goto _test_eof + _test_eof3560: cs = 3560; goto _test_eof + _test_eof3561: cs = 3561; goto _test_eof + _test_eof3562: cs = 3562; goto _test_eof + _test_eof3563: cs = 3563; goto _test_eof + _test_eof3564: cs = 3564; goto _test_eof + _test_eof3565: cs = 3565; goto _test_eof + _test_eof3566: cs = 3566; goto _test_eof + _test_eof3567: cs = 3567; goto _test_eof + _test_eof3568: cs = 3568; goto _test_eof + _test_eof3569: cs = 3569; goto _test_eof + _test_eof3570: cs = 3570; goto _test_eof + _test_eof3571: cs = 3571; goto _test_eof + _test_eof3572: cs = 3572; goto _test_eof + _test_eof3573: cs = 3573; goto _test_eof + _test_eof3574: cs = 3574; goto _test_eof + _test_eof3575: cs = 3575; goto _test_eof + _test_eof3576: cs = 3576; goto _test_eof + _test_eof3577: cs = 3577; goto _test_eof + _test_eof3578: cs = 3578; goto _test_eof + _test_eof3579: cs = 3579; goto _test_eof + _test_eof3580: cs = 3580; goto _test_eof + _test_eof3581: cs = 3581; goto _test_eof + _test_eof3582: cs = 3582; goto _test_eof + _test_eof3583: cs = 3583; goto _test_eof + _test_eof3584: cs = 3584; goto _test_eof + _test_eof3585: cs = 3585; goto _test_eof + _test_eof3586: cs = 3586; goto _test_eof + _test_eof3587: cs = 3587; goto _test_eof + _test_eof5075: cs = 5075; goto _test_eof + _test_eof3588: cs = 3588; goto _test_eof + _test_eof3589: cs = 3589; goto _test_eof + _test_eof3590: cs = 3590; goto _test_eof + _test_eof3591: cs = 3591; goto _test_eof + _test_eof3592: cs = 3592; goto _test_eof + _test_eof3593: cs = 3593; goto _test_eof + _test_eof5076: cs = 5076; goto _test_eof + _test_eof3594: cs = 3594; goto _test_eof + _test_eof3595: cs = 3595; goto _test_eof + _test_eof3596: cs = 3596; goto _test_eof + _test_eof3597: cs = 3597; goto _test_eof + _test_eof3598: cs = 3598; goto _test_eof + _test_eof3599: cs = 3599; goto _test_eof + _test_eof3600: cs = 3600; goto _test_eof + _test_eof3601: cs = 3601; goto _test_eof + _test_eof3602: cs = 3602; goto _test_eof + _test_eof3603: cs = 3603; goto _test_eof + _test_eof3604: cs = 3604; goto _test_eof + _test_eof3605: cs = 3605; goto _test_eof + _test_eof3606: cs = 3606; goto _test_eof + _test_eof3607: cs = 3607; goto _test_eof + _test_eof3608: cs = 3608; goto _test_eof + _test_eof3609: cs = 3609; goto _test_eof + _test_eof3610: cs = 3610; goto _test_eof + _test_eof3611: cs = 3611; goto _test_eof + _test_eof3612: cs = 3612; goto _test_eof + _test_eof3613: cs = 3613; goto _test_eof + _test_eof3614: cs = 3614; goto _test_eof + _test_eof3615: cs = 3615; goto _test_eof + _test_eof3616: cs = 3616; goto _test_eof + _test_eof3617: cs = 3617; goto _test_eof + _test_eof3618: cs = 3618; goto _test_eof + _test_eof3619: cs = 3619; goto _test_eof + _test_eof3620: cs = 3620; goto _test_eof + _test_eof3621: cs = 3621; goto _test_eof + _test_eof3622: cs = 3622; goto _test_eof + _test_eof3623: cs = 3623; goto _test_eof + _test_eof3624: cs = 3624; goto _test_eof + _test_eof3625: cs = 3625; goto _test_eof + _test_eof3626: cs = 3626; goto _test_eof + _test_eof3627: cs = 3627; goto _test_eof + _test_eof3628: cs = 3628; goto _test_eof + _test_eof3629: cs = 3629; goto _test_eof + _test_eof3630: cs = 3630; goto _test_eof + _test_eof3631: cs = 3631; goto _test_eof + _test_eof3632: cs = 3632; goto _test_eof + _test_eof3633: cs = 3633; goto _test_eof + _test_eof3634: cs = 3634; goto _test_eof + _test_eof3635: cs = 3635; goto _test_eof + _test_eof3636: cs = 3636; goto _test_eof + _test_eof3637: cs = 3637; goto _test_eof + _test_eof3638: cs = 3638; goto _test_eof + _test_eof3639: cs = 3639; goto _test_eof + _test_eof3640: cs = 3640; goto _test_eof + _test_eof3641: cs = 3641; goto _test_eof + _test_eof3642: cs = 3642; goto _test_eof + _test_eof3643: cs = 3643; goto _test_eof + _test_eof3644: cs = 3644; goto _test_eof + _test_eof3645: cs = 3645; goto _test_eof + _test_eof3646: cs = 3646; goto _test_eof + _test_eof3647: cs = 3647; goto _test_eof + _test_eof3648: cs = 3648; goto _test_eof + _test_eof3649: cs = 3649; goto _test_eof + _test_eof3650: cs = 3650; goto _test_eof + _test_eof3651: cs = 3651; goto _test_eof + _test_eof3652: cs = 3652; goto _test_eof + _test_eof3653: cs = 3653; goto _test_eof + _test_eof3654: cs = 3654; goto _test_eof + _test_eof3655: cs = 3655; goto _test_eof + _test_eof3656: cs = 3656; goto _test_eof + _test_eof3657: cs = 3657; goto _test_eof + _test_eof3658: cs = 3658; goto _test_eof + _test_eof3659: cs = 3659; goto _test_eof + _test_eof3660: cs = 3660; goto _test_eof + _test_eof3661: cs = 3661; goto _test_eof + _test_eof3662: cs = 3662; goto _test_eof + _test_eof3663: cs = 3663; goto _test_eof + _test_eof3664: cs = 3664; goto _test_eof + _test_eof3665: cs = 3665; goto _test_eof + _test_eof3666: cs = 3666; goto _test_eof + _test_eof3667: cs = 3667; goto _test_eof + _test_eof3668: cs = 3668; goto _test_eof + _test_eof3669: cs = 3669; goto _test_eof + _test_eof3670: cs = 3670; goto _test_eof + _test_eof3671: cs = 3671; goto _test_eof + _test_eof3672: cs = 3672; goto _test_eof + _test_eof3673: cs = 3673; goto _test_eof + _test_eof3674: cs = 3674; goto _test_eof + _test_eof3675: cs = 3675; goto _test_eof + _test_eof3676: cs = 3676; goto _test_eof + _test_eof3677: cs = 3677; goto _test_eof + _test_eof3678: cs = 3678; goto _test_eof + _test_eof3679: cs = 3679; goto _test_eof + _test_eof3680: cs = 3680; goto _test_eof + _test_eof3681: cs = 3681; goto _test_eof + _test_eof3682: cs = 3682; goto _test_eof + _test_eof3683: cs = 3683; goto _test_eof + _test_eof3684: cs = 3684; goto _test_eof + _test_eof3685: cs = 3685; goto _test_eof + _test_eof3686: cs = 3686; goto _test_eof + _test_eof3687: cs = 3687; goto _test_eof + _test_eof3688: cs = 3688; goto _test_eof + _test_eof3689: cs = 3689; goto _test_eof + _test_eof3690: cs = 3690; goto _test_eof + _test_eof3691: cs = 3691; goto _test_eof + _test_eof3692: cs = 3692; goto _test_eof + _test_eof3693: cs = 3693; goto _test_eof + _test_eof3694: cs = 3694; goto _test_eof + _test_eof3695: cs = 3695; goto _test_eof + _test_eof3696: cs = 3696; goto _test_eof + _test_eof3697: cs = 3697; goto _test_eof + _test_eof3698: cs = 3698; goto _test_eof + _test_eof3699: cs = 3699; goto _test_eof + _test_eof3700: cs = 3700; goto _test_eof + _test_eof3701: cs = 3701; goto _test_eof + _test_eof3702: cs = 3702; goto _test_eof + _test_eof3703: cs = 3703; goto _test_eof + _test_eof3704: cs = 3704; goto _test_eof + _test_eof3705: cs = 3705; goto _test_eof + _test_eof3706: cs = 3706; goto _test_eof + _test_eof3707: cs = 3707; goto _test_eof + _test_eof3708: cs = 3708; goto _test_eof + _test_eof3709: cs = 3709; goto _test_eof + _test_eof3710: cs = 3710; goto _test_eof + _test_eof3711: cs = 3711; goto _test_eof + _test_eof3712: cs = 3712; goto _test_eof + _test_eof3713: cs = 3713; goto _test_eof + _test_eof3714: cs = 3714; goto _test_eof + _test_eof3715: cs = 3715; goto _test_eof + _test_eof3716: cs = 3716; goto _test_eof + _test_eof3717: cs = 3717; goto _test_eof + _test_eof3718: cs = 3718; goto _test_eof + _test_eof3719: cs = 3719; goto _test_eof + _test_eof3720: cs = 3720; goto _test_eof + _test_eof3721: cs = 3721; goto _test_eof + _test_eof3722: cs = 3722; goto _test_eof + _test_eof3723: cs = 3723; goto _test_eof + _test_eof3724: cs = 3724; goto _test_eof + _test_eof3725: cs = 3725; goto _test_eof + _test_eof3726: cs = 3726; goto _test_eof + _test_eof3727: cs = 3727; goto _test_eof + _test_eof3728: cs = 3728; goto _test_eof + _test_eof3729: cs = 3729; goto _test_eof + _test_eof3730: cs = 3730; goto _test_eof + _test_eof3731: cs = 3731; goto _test_eof + _test_eof3732: cs = 3732; goto _test_eof + _test_eof3733: cs = 3733; goto _test_eof + _test_eof3734: cs = 3734; goto _test_eof + _test_eof3735: cs = 3735; goto _test_eof + _test_eof3736: cs = 3736; goto _test_eof + _test_eof5077: cs = 5077; goto _test_eof + _test_eof3737: cs = 3737; goto _test_eof + _test_eof5078: cs = 5078; goto _test_eof + _test_eof3738: cs = 3738; goto _test_eof + _test_eof3739: cs = 3739; goto _test_eof + _test_eof3740: cs = 3740; goto _test_eof + _test_eof3741: cs = 3741; goto _test_eof + _test_eof3742: cs = 3742; goto _test_eof + _test_eof3743: cs = 3743; goto _test_eof + _test_eof3744: cs = 3744; goto _test_eof + _test_eof3745: cs = 3745; goto _test_eof + _test_eof3746: cs = 3746; goto _test_eof + _test_eof3747: cs = 3747; goto _test_eof + _test_eof3748: cs = 3748; goto _test_eof + _test_eof3749: cs = 3749; goto _test_eof + _test_eof3750: cs = 3750; goto _test_eof + _test_eof3751: cs = 3751; goto _test_eof + _test_eof3752: cs = 3752; goto _test_eof + _test_eof3753: cs = 3753; goto _test_eof + _test_eof3754: cs = 3754; goto _test_eof + _test_eof3755: cs = 3755; goto _test_eof + _test_eof3756: cs = 3756; goto _test_eof + _test_eof3757: cs = 3757; goto _test_eof + _test_eof3758: cs = 3758; goto _test_eof + _test_eof3759: cs = 3759; goto _test_eof + _test_eof3760: cs = 3760; goto _test_eof + _test_eof3761: cs = 3761; goto _test_eof + _test_eof3762: cs = 3762; goto _test_eof + _test_eof3763: cs = 3763; goto _test_eof + _test_eof3764: cs = 3764; goto _test_eof + _test_eof3765: cs = 3765; goto _test_eof + _test_eof3766: cs = 3766; goto _test_eof + _test_eof3767: cs = 3767; goto _test_eof + _test_eof3768: cs = 3768; goto _test_eof + _test_eof3769: cs = 3769; goto _test_eof + _test_eof3770: cs = 3770; goto _test_eof + _test_eof3771: cs = 3771; goto _test_eof + _test_eof3772: cs = 3772; goto _test_eof + _test_eof3773: cs = 3773; goto _test_eof + _test_eof3774: cs = 3774; goto _test_eof + _test_eof3775: cs = 3775; goto _test_eof + _test_eof3776: cs = 3776; goto _test_eof + _test_eof3777: cs = 3777; goto _test_eof + _test_eof3778: cs = 3778; goto _test_eof + _test_eof3779: cs = 3779; goto _test_eof + _test_eof3780: cs = 3780; goto _test_eof + _test_eof3781: cs = 3781; goto _test_eof + _test_eof3782: cs = 3782; goto _test_eof + _test_eof3783: cs = 3783; goto _test_eof + _test_eof3784: cs = 3784; goto _test_eof + _test_eof3785: cs = 3785; goto _test_eof + _test_eof3786: cs = 3786; goto _test_eof + _test_eof3787: cs = 3787; goto _test_eof + _test_eof3788: cs = 3788; goto _test_eof + _test_eof3789: cs = 3789; goto _test_eof + _test_eof3790: cs = 3790; goto _test_eof + _test_eof3791: cs = 3791; goto _test_eof + _test_eof3792: cs = 3792; goto _test_eof + _test_eof3793: cs = 3793; goto _test_eof + _test_eof3794: cs = 3794; goto _test_eof + _test_eof3795: cs = 3795; goto _test_eof + _test_eof3796: cs = 3796; goto _test_eof + _test_eof3797: cs = 3797; goto _test_eof + _test_eof3798: cs = 3798; goto _test_eof + _test_eof3799: cs = 3799; goto _test_eof + _test_eof3800: cs = 3800; goto _test_eof + _test_eof3801: cs = 3801; goto _test_eof + _test_eof3802: cs = 3802; goto _test_eof + _test_eof3803: cs = 3803; goto _test_eof + _test_eof3804: cs = 3804; goto _test_eof + _test_eof3805: cs = 3805; goto _test_eof + _test_eof3806: cs = 3806; goto _test_eof + _test_eof3807: cs = 3807; goto _test_eof + _test_eof3808: cs = 3808; goto _test_eof + _test_eof3809: cs = 3809; goto _test_eof + _test_eof3810: cs = 3810; goto _test_eof + _test_eof3811: cs = 3811; goto _test_eof + _test_eof3812: cs = 3812; goto _test_eof + _test_eof3813: cs = 3813; goto _test_eof + _test_eof3814: cs = 3814; goto _test_eof + _test_eof3815: cs = 3815; goto _test_eof + _test_eof3816: cs = 3816; goto _test_eof + _test_eof3817: cs = 3817; goto _test_eof + _test_eof3818: cs = 3818; goto _test_eof + _test_eof3819: cs = 3819; goto _test_eof + _test_eof3820: cs = 3820; goto _test_eof + _test_eof3821: cs = 3821; goto _test_eof + _test_eof3822: cs = 3822; goto _test_eof + _test_eof3823: cs = 3823; goto _test_eof + _test_eof3824: cs = 3824; goto _test_eof + _test_eof3825: cs = 3825; goto _test_eof + _test_eof3826: cs = 3826; goto _test_eof + _test_eof3827: cs = 3827; goto _test_eof + _test_eof3828: cs = 3828; goto _test_eof + _test_eof3829: cs = 3829; goto _test_eof + _test_eof3830: cs = 3830; goto _test_eof + _test_eof3831: cs = 3831; goto _test_eof + _test_eof3832: cs = 3832; goto _test_eof + _test_eof3833: cs = 3833; goto _test_eof + _test_eof3834: cs = 3834; goto _test_eof + _test_eof3835: cs = 3835; goto _test_eof + _test_eof3836: cs = 3836; goto _test_eof + _test_eof3837: cs = 3837; goto _test_eof + _test_eof3838: cs = 3838; goto _test_eof + _test_eof3839: cs = 3839; goto _test_eof + _test_eof3840: cs = 3840; goto _test_eof + _test_eof3841: cs = 3841; goto _test_eof + _test_eof3842: cs = 3842; goto _test_eof + _test_eof3843: cs = 3843; goto _test_eof + _test_eof3844: cs = 3844; goto _test_eof + _test_eof3845: cs = 3845; goto _test_eof + _test_eof3846: cs = 3846; goto _test_eof + _test_eof3847: cs = 3847; goto _test_eof + _test_eof3848: cs = 3848; goto _test_eof + _test_eof3849: cs = 3849; goto _test_eof + _test_eof3850: cs = 3850; goto _test_eof + _test_eof3851: cs = 3851; goto _test_eof + _test_eof3852: cs = 3852; goto _test_eof + _test_eof3853: cs = 3853; goto _test_eof + _test_eof3854: cs = 3854; goto _test_eof + _test_eof3855: cs = 3855; goto _test_eof + _test_eof3856: cs = 3856; goto _test_eof + _test_eof3857: cs = 3857; goto _test_eof + _test_eof3858: cs = 3858; goto _test_eof + _test_eof3859: cs = 3859; goto _test_eof + _test_eof3860: cs = 3860; goto _test_eof + _test_eof3861: cs = 3861; goto _test_eof + _test_eof3862: cs = 3862; goto _test_eof + _test_eof3863: cs = 3863; goto _test_eof + _test_eof3864: cs = 3864; goto _test_eof + _test_eof3865: cs = 3865; goto _test_eof + _test_eof3866: cs = 3866; goto _test_eof + _test_eof3867: cs = 3867; goto _test_eof + _test_eof3868: cs = 3868; goto _test_eof + _test_eof3869: cs = 3869; goto _test_eof + _test_eof3870: cs = 3870; goto _test_eof + _test_eof3871: cs = 3871; goto _test_eof + _test_eof3872: cs = 3872; goto _test_eof + _test_eof3873: cs = 3873; goto _test_eof + _test_eof3874: cs = 3874; goto _test_eof + _test_eof3875: cs = 3875; goto _test_eof + _test_eof3876: cs = 3876; goto _test_eof + _test_eof3877: cs = 3877; goto _test_eof + _test_eof3878: cs = 3878; goto _test_eof + _test_eof3879: cs = 3879; goto _test_eof + _test_eof3880: cs = 3880; goto _test_eof + _test_eof3881: cs = 3881; goto _test_eof + _test_eof3882: cs = 3882; goto _test_eof + _test_eof3883: cs = 3883; goto _test_eof + _test_eof3884: cs = 3884; goto _test_eof + _test_eof5079: cs = 5079; goto _test_eof + _test_eof3885: cs = 3885; goto _test_eof + _test_eof3886: cs = 3886; goto _test_eof + _test_eof3887: cs = 3887; goto _test_eof + _test_eof3888: cs = 3888; goto _test_eof + _test_eof3889: cs = 3889; goto _test_eof + _test_eof3890: cs = 3890; goto _test_eof + _test_eof3891: cs = 3891; goto _test_eof + _test_eof3892: cs = 3892; goto _test_eof + _test_eof3893: cs = 3893; goto _test_eof + _test_eof3894: cs = 3894; goto _test_eof + _test_eof3895: cs = 3895; goto _test_eof + _test_eof3896: cs = 3896; goto _test_eof + _test_eof3897: cs = 3897; goto _test_eof + _test_eof3898: cs = 3898; goto _test_eof + _test_eof3899: cs = 3899; goto _test_eof + _test_eof3900: cs = 3900; goto _test_eof + _test_eof3901: cs = 3901; goto _test_eof + _test_eof3902: cs = 3902; goto _test_eof + _test_eof3903: cs = 3903; goto _test_eof + _test_eof3904: cs = 3904; goto _test_eof + _test_eof3905: cs = 3905; goto _test_eof + _test_eof3906: cs = 3906; goto _test_eof + _test_eof3907: cs = 3907; goto _test_eof + _test_eof3908: cs = 3908; goto _test_eof + _test_eof3909: cs = 3909; goto _test_eof + _test_eof3910: cs = 3910; goto _test_eof + _test_eof3911: cs = 3911; goto _test_eof + _test_eof3912: cs = 3912; goto _test_eof + _test_eof3913: cs = 3913; goto _test_eof + _test_eof3914: cs = 3914; goto _test_eof + _test_eof3915: cs = 3915; goto _test_eof + _test_eof3916: cs = 3916; goto _test_eof + _test_eof3917: cs = 3917; goto _test_eof + _test_eof3918: cs = 3918; goto _test_eof + _test_eof3919: cs = 3919; goto _test_eof + _test_eof3920: cs = 3920; goto _test_eof + _test_eof3921: cs = 3921; goto _test_eof + _test_eof3922: cs = 3922; goto _test_eof + _test_eof3923: cs = 3923; goto _test_eof + _test_eof3924: cs = 3924; goto _test_eof + _test_eof3925: cs = 3925; goto _test_eof + _test_eof3926: cs = 3926; goto _test_eof + _test_eof3927: cs = 3927; goto _test_eof + _test_eof3928: cs = 3928; goto _test_eof + _test_eof3929: cs = 3929; goto _test_eof + _test_eof3930: cs = 3930; goto _test_eof + _test_eof3931: cs = 3931; goto _test_eof + _test_eof3932: cs = 3932; goto _test_eof + _test_eof3933: cs = 3933; goto _test_eof + _test_eof3934: cs = 3934; goto _test_eof + _test_eof3935: cs = 3935; goto _test_eof + _test_eof3936: cs = 3936; goto _test_eof + _test_eof3937: cs = 3937; goto _test_eof + _test_eof3938: cs = 3938; goto _test_eof + _test_eof3939: cs = 3939; goto _test_eof + _test_eof3940: cs = 3940; goto _test_eof + _test_eof3941: cs = 3941; goto _test_eof + _test_eof3942: cs = 3942; goto _test_eof + _test_eof3943: cs = 3943; goto _test_eof + _test_eof3944: cs = 3944; goto _test_eof + _test_eof3945: cs = 3945; goto _test_eof + _test_eof3946: cs = 3946; goto _test_eof + _test_eof3947: cs = 3947; goto _test_eof + _test_eof3948: cs = 3948; goto _test_eof + _test_eof3949: cs = 3949; goto _test_eof + _test_eof3950: cs = 3950; goto _test_eof + _test_eof3951: cs = 3951; goto _test_eof + _test_eof3952: cs = 3952; goto _test_eof + _test_eof3953: cs = 3953; goto _test_eof + _test_eof3954: cs = 3954; goto _test_eof + _test_eof3955: cs = 3955; goto _test_eof + _test_eof3956: cs = 3956; goto _test_eof + _test_eof3957: cs = 3957; goto _test_eof + _test_eof3958: cs = 3958; goto _test_eof + _test_eof3959: cs = 3959; goto _test_eof + _test_eof3960: cs = 3960; goto _test_eof + _test_eof3961: cs = 3961; goto _test_eof + _test_eof3962: cs = 3962; goto _test_eof + _test_eof3963: cs = 3963; goto _test_eof + _test_eof3964: cs = 3964; goto _test_eof + _test_eof3965: cs = 3965; goto _test_eof + _test_eof3966: cs = 3966; goto _test_eof + _test_eof3967: cs = 3967; goto _test_eof + _test_eof3968: cs = 3968; goto _test_eof + _test_eof3969: cs = 3969; goto _test_eof + _test_eof3970: cs = 3970; goto _test_eof + _test_eof3971: cs = 3971; goto _test_eof + _test_eof3972: cs = 3972; goto _test_eof + _test_eof3973: cs = 3973; goto _test_eof + _test_eof3974: cs = 3974; goto _test_eof + _test_eof3975: cs = 3975; goto _test_eof + _test_eof3976: cs = 3976; goto _test_eof + _test_eof3977: cs = 3977; goto _test_eof + _test_eof3978: cs = 3978; goto _test_eof + _test_eof3979: cs = 3979; goto _test_eof + _test_eof3980: cs = 3980; goto _test_eof + _test_eof3981: cs = 3981; goto _test_eof + _test_eof3982: cs = 3982; goto _test_eof + _test_eof3983: cs = 3983; goto _test_eof + _test_eof3984: cs = 3984; goto _test_eof + _test_eof3985: cs = 3985; goto _test_eof + _test_eof3986: cs = 3986; goto _test_eof + _test_eof3987: cs = 3987; goto _test_eof + _test_eof3988: cs = 3988; goto _test_eof + _test_eof3989: cs = 3989; goto _test_eof + _test_eof3990: cs = 3990; goto _test_eof + _test_eof3991: cs = 3991; goto _test_eof + _test_eof3992: cs = 3992; goto _test_eof + _test_eof3993: cs = 3993; goto _test_eof + _test_eof3994: cs = 3994; goto _test_eof + _test_eof3995: cs = 3995; goto _test_eof + _test_eof3996: cs = 3996; goto _test_eof + _test_eof3997: cs = 3997; goto _test_eof + _test_eof3998: cs = 3998; goto _test_eof + _test_eof3999: cs = 3999; goto _test_eof + _test_eof4000: cs = 4000; goto _test_eof + _test_eof4001: cs = 4001; goto _test_eof + _test_eof4002: cs = 4002; goto _test_eof + _test_eof4003: cs = 4003; goto _test_eof + _test_eof4004: cs = 4004; goto _test_eof + _test_eof4005: cs = 4005; goto _test_eof + _test_eof4006: cs = 4006; goto _test_eof + _test_eof4007: cs = 4007; goto _test_eof + _test_eof4008: cs = 4008; goto _test_eof + _test_eof4009: cs = 4009; goto _test_eof + _test_eof4010: cs = 4010; goto _test_eof + _test_eof4011: cs = 4011; goto _test_eof + _test_eof4012: cs = 4012; goto _test_eof + _test_eof4013: cs = 4013; goto _test_eof + _test_eof4014: cs = 4014; goto _test_eof + _test_eof4015: cs = 4015; goto _test_eof + _test_eof4016: cs = 4016; goto _test_eof + _test_eof4017: cs = 4017; goto _test_eof + _test_eof4018: cs = 4018; goto _test_eof + _test_eof4019: cs = 4019; goto _test_eof + _test_eof4020: cs = 4020; goto _test_eof + _test_eof4021: cs = 4021; goto _test_eof + _test_eof4022: cs = 4022; goto _test_eof + _test_eof4023: cs = 4023; goto _test_eof + _test_eof4024: cs = 4024; goto _test_eof + _test_eof4025: cs = 4025; goto _test_eof + _test_eof4026: cs = 4026; goto _test_eof + _test_eof5080: cs = 5080; goto _test_eof + _test_eof4027: cs = 4027; goto _test_eof + _test_eof4028: cs = 4028; goto _test_eof + _test_eof4029: cs = 4029; goto _test_eof + _test_eof4030: cs = 4030; goto _test_eof + _test_eof4031: cs = 4031; goto _test_eof + _test_eof4032: cs = 4032; goto _test_eof + _test_eof4033: cs = 4033; goto _test_eof + _test_eof4034: cs = 4034; goto _test_eof + _test_eof4035: cs = 4035; goto _test_eof + _test_eof4036: cs = 4036; goto _test_eof + _test_eof4037: cs = 4037; goto _test_eof + _test_eof4038: cs = 4038; goto _test_eof + _test_eof4039: cs = 4039; goto _test_eof + _test_eof4040: cs = 4040; goto _test_eof + _test_eof4041: cs = 4041; goto _test_eof + _test_eof4042: cs = 4042; goto _test_eof + _test_eof4043: cs = 4043; goto _test_eof + _test_eof4044: cs = 4044; goto _test_eof + _test_eof4045: cs = 4045; goto _test_eof + _test_eof4046: cs = 4046; goto _test_eof + _test_eof4047: cs = 4047; goto _test_eof + _test_eof4048: cs = 4048; goto _test_eof + _test_eof4049: cs = 4049; goto _test_eof + _test_eof4050: cs = 4050; goto _test_eof + _test_eof4051: cs = 4051; goto _test_eof + _test_eof4052: cs = 4052; goto _test_eof + _test_eof4053: cs = 4053; goto _test_eof + _test_eof4054: cs = 4054; goto _test_eof + _test_eof4055: cs = 4055; goto _test_eof + _test_eof4056: cs = 4056; goto _test_eof + _test_eof4057: cs = 4057; goto _test_eof + _test_eof4058: cs = 4058; goto _test_eof + _test_eof4059: cs = 4059; goto _test_eof + _test_eof4060: cs = 4060; goto _test_eof + _test_eof4061: cs = 4061; goto _test_eof + _test_eof4062: cs = 4062; goto _test_eof + _test_eof4063: cs = 4063; goto _test_eof + _test_eof4064: cs = 4064; goto _test_eof + _test_eof4065: cs = 4065; goto _test_eof + _test_eof4066: cs = 4066; goto _test_eof + _test_eof4067: cs = 4067; goto _test_eof + _test_eof4068: cs = 4068; goto _test_eof + _test_eof4069: cs = 4069; goto _test_eof + _test_eof4070: cs = 4070; goto _test_eof + _test_eof4071: cs = 4071; goto _test_eof + _test_eof4072: cs = 4072; goto _test_eof + _test_eof4073: cs = 4073; goto _test_eof + _test_eof4074: cs = 4074; goto _test_eof + _test_eof4075: cs = 4075; goto _test_eof + _test_eof4076: cs = 4076; goto _test_eof + _test_eof4077: cs = 4077; goto _test_eof + _test_eof4078: cs = 4078; goto _test_eof + _test_eof4079: cs = 4079; goto _test_eof + _test_eof4080: cs = 4080; goto _test_eof + _test_eof4081: cs = 4081; goto _test_eof + _test_eof4082: cs = 4082; goto _test_eof + _test_eof4083: cs = 4083; goto _test_eof + _test_eof4084: cs = 4084; goto _test_eof + _test_eof4085: cs = 4085; goto _test_eof + _test_eof4086: cs = 4086; goto _test_eof + _test_eof4087: cs = 4087; goto _test_eof + _test_eof4088: cs = 4088; goto _test_eof + _test_eof4089: cs = 4089; goto _test_eof + _test_eof4090: cs = 4090; goto _test_eof + _test_eof4091: cs = 4091; goto _test_eof + _test_eof4092: cs = 4092; goto _test_eof + _test_eof4093: cs = 4093; goto _test_eof + _test_eof4094: cs = 4094; goto _test_eof + _test_eof4095: cs = 4095; goto _test_eof + _test_eof4096: cs = 4096; goto _test_eof + _test_eof4097: cs = 4097; goto _test_eof + _test_eof4098: cs = 4098; goto _test_eof + _test_eof4099: cs = 4099; goto _test_eof + _test_eof4100: cs = 4100; goto _test_eof + _test_eof4101: cs = 4101; goto _test_eof + _test_eof4102: cs = 4102; goto _test_eof + _test_eof4103: cs = 4103; goto _test_eof + _test_eof4104: cs = 4104; goto _test_eof + _test_eof4105: cs = 4105; goto _test_eof + _test_eof4106: cs = 4106; goto _test_eof + _test_eof4107: cs = 4107; goto _test_eof + _test_eof4108: cs = 4108; goto _test_eof + _test_eof4109: cs = 4109; goto _test_eof + _test_eof4110: cs = 4110; goto _test_eof + _test_eof4111: cs = 4111; goto _test_eof + _test_eof4112: cs = 4112; goto _test_eof + _test_eof4113: cs = 4113; goto _test_eof + _test_eof4114: cs = 4114; goto _test_eof + _test_eof4115: cs = 4115; goto _test_eof + _test_eof4116: cs = 4116; goto _test_eof + _test_eof4117: cs = 4117; goto _test_eof + _test_eof4118: cs = 4118; goto _test_eof + _test_eof4119: cs = 4119; goto _test_eof + _test_eof4120: cs = 4120; goto _test_eof + _test_eof4121: cs = 4121; goto _test_eof + _test_eof4122: cs = 4122; goto _test_eof + _test_eof4123: cs = 4123; goto _test_eof + _test_eof4124: cs = 4124; goto _test_eof + _test_eof4125: cs = 4125; goto _test_eof + _test_eof4126: cs = 4126; goto _test_eof + _test_eof4127: cs = 4127; goto _test_eof + _test_eof4128: cs = 4128; goto _test_eof + _test_eof4129: cs = 4129; goto _test_eof + _test_eof4130: cs = 4130; goto _test_eof + _test_eof4131: cs = 4131; goto _test_eof + _test_eof4132: cs = 4132; goto _test_eof + _test_eof4133: cs = 4133; goto _test_eof + _test_eof4134: cs = 4134; goto _test_eof + _test_eof4135: cs = 4135; goto _test_eof + _test_eof4136: cs = 4136; goto _test_eof + _test_eof4137: cs = 4137; goto _test_eof + _test_eof4138: cs = 4138; goto _test_eof + _test_eof4139: cs = 4139; goto _test_eof + _test_eof4140: cs = 4140; goto _test_eof + _test_eof4141: cs = 4141; goto _test_eof + _test_eof4142: cs = 4142; goto _test_eof + _test_eof4143: cs = 4143; goto _test_eof + _test_eof4144: cs = 4144; goto _test_eof + _test_eof4145: cs = 4145; goto _test_eof + _test_eof4146: cs = 4146; goto _test_eof + _test_eof4147: cs = 4147; goto _test_eof + _test_eof4148: cs = 4148; goto _test_eof + _test_eof4149: cs = 4149; goto _test_eof + _test_eof4150: cs = 4150; goto _test_eof + _test_eof4151: cs = 4151; goto _test_eof + _test_eof4152: cs = 4152; goto _test_eof + _test_eof4153: cs = 4153; goto _test_eof + _test_eof4154: cs = 4154; goto _test_eof + _test_eof4155: cs = 4155; goto _test_eof + _test_eof4156: cs = 4156; goto _test_eof + _test_eof4157: cs = 4157; goto _test_eof + _test_eof4158: cs = 4158; goto _test_eof + _test_eof4159: cs = 4159; goto _test_eof + _test_eof4160: cs = 4160; goto _test_eof + _test_eof4161: cs = 4161; goto _test_eof + _test_eof4162: cs = 4162; goto _test_eof + _test_eof4163: cs = 4163; goto _test_eof + _test_eof4164: cs = 4164; goto _test_eof + _test_eof4165: cs = 4165; goto _test_eof + _test_eof4166: cs = 4166; goto _test_eof + _test_eof4167: cs = 4167; goto _test_eof + _test_eof4168: cs = 4168; goto _test_eof + _test_eof4169: cs = 4169; goto _test_eof + _test_eof4170: cs = 4170; goto _test_eof + _test_eof4171: cs = 4171; goto _test_eof + _test_eof4172: cs = 4172; goto _test_eof + _test_eof4173: cs = 4173; goto _test_eof + _test_eof4174: cs = 4174; goto _test_eof + _test_eof4175: cs = 4175; goto _test_eof + _test_eof5081: cs = 5081; goto _test_eof + _test_eof4176: cs = 4176; goto _test_eof + _test_eof4177: cs = 4177; goto _test_eof + _test_eof4178: cs = 4178; goto _test_eof + _test_eof4179: cs = 4179; goto _test_eof + _test_eof4180: cs = 4180; goto _test_eof + _test_eof4181: cs = 4181; goto _test_eof + _test_eof4182: cs = 4182; goto _test_eof + _test_eof4183: cs = 4183; goto _test_eof + _test_eof4184: cs = 4184; goto _test_eof + _test_eof4185: cs = 4185; goto _test_eof + _test_eof4186: cs = 4186; goto _test_eof + _test_eof4187: cs = 4187; goto _test_eof + _test_eof4188: cs = 4188; goto _test_eof + _test_eof4189: cs = 4189; goto _test_eof + _test_eof4190: cs = 4190; goto _test_eof + _test_eof4191: cs = 4191; goto _test_eof + _test_eof4192: cs = 4192; goto _test_eof + _test_eof4193: cs = 4193; goto _test_eof + _test_eof4194: cs = 4194; goto _test_eof + _test_eof4195: cs = 4195; goto _test_eof + _test_eof4196: cs = 4196; goto _test_eof + _test_eof4197: cs = 4197; goto _test_eof + _test_eof4198: cs = 4198; goto _test_eof + _test_eof4199: cs = 4199; goto _test_eof + _test_eof4200: cs = 4200; goto _test_eof + _test_eof4201: cs = 4201; goto _test_eof + _test_eof4202: cs = 4202; goto _test_eof + _test_eof4203: cs = 4203; goto _test_eof + _test_eof4204: cs = 4204; goto _test_eof + _test_eof4205: cs = 4205; goto _test_eof + _test_eof4206: cs = 4206; goto _test_eof + _test_eof4207: cs = 4207; goto _test_eof + _test_eof4208: cs = 4208; goto _test_eof + _test_eof4209: cs = 4209; goto _test_eof + _test_eof4210: cs = 4210; goto _test_eof + _test_eof4211: cs = 4211; goto _test_eof + _test_eof4212: cs = 4212; goto _test_eof + _test_eof4213: cs = 4213; goto _test_eof + _test_eof4214: cs = 4214; goto _test_eof + _test_eof4215: cs = 4215; goto _test_eof + _test_eof4216: cs = 4216; goto _test_eof + _test_eof4217: cs = 4217; goto _test_eof + _test_eof4218: cs = 4218; goto _test_eof + _test_eof4219: cs = 4219; goto _test_eof + _test_eof4220: cs = 4220; goto _test_eof + _test_eof4221: cs = 4221; goto _test_eof + _test_eof4222: cs = 4222; goto _test_eof + _test_eof4223: cs = 4223; goto _test_eof + _test_eof4224: cs = 4224; goto _test_eof + _test_eof4225: cs = 4225; goto _test_eof + _test_eof4226: cs = 4226; goto _test_eof + _test_eof4227: cs = 4227; goto _test_eof + _test_eof4228: cs = 4228; goto _test_eof + _test_eof4229: cs = 4229; goto _test_eof + _test_eof4230: cs = 4230; goto _test_eof + _test_eof4231: cs = 4231; goto _test_eof + _test_eof4232: cs = 4232; goto _test_eof + _test_eof4233: cs = 4233; goto _test_eof + _test_eof4234: cs = 4234; goto _test_eof + _test_eof4235: cs = 4235; goto _test_eof + _test_eof4236: cs = 4236; goto _test_eof + _test_eof4237: cs = 4237; goto _test_eof + _test_eof4238: cs = 4238; goto _test_eof + _test_eof4239: cs = 4239; goto _test_eof + _test_eof4240: cs = 4240; goto _test_eof + _test_eof4241: cs = 4241; goto _test_eof + _test_eof4242: cs = 4242; goto _test_eof + _test_eof4243: cs = 4243; goto _test_eof + _test_eof4244: cs = 4244; goto _test_eof + _test_eof4245: cs = 4245; goto _test_eof + _test_eof4246: cs = 4246; goto _test_eof + _test_eof4247: cs = 4247; goto _test_eof + _test_eof4248: cs = 4248; goto _test_eof + _test_eof4249: cs = 4249; goto _test_eof + _test_eof4250: cs = 4250; goto _test_eof + _test_eof4251: cs = 4251; goto _test_eof + _test_eof4252: cs = 4252; goto _test_eof + _test_eof4253: cs = 4253; goto _test_eof + _test_eof4254: cs = 4254; goto _test_eof + _test_eof4255: cs = 4255; goto _test_eof + _test_eof4256: cs = 4256; goto _test_eof + _test_eof4257: cs = 4257; goto _test_eof + _test_eof4258: cs = 4258; goto _test_eof + _test_eof4259: cs = 4259; goto _test_eof + _test_eof4260: cs = 4260; goto _test_eof + _test_eof4261: cs = 4261; goto _test_eof + _test_eof4262: cs = 4262; goto _test_eof + _test_eof4263: cs = 4263; goto _test_eof + _test_eof4264: cs = 4264; goto _test_eof + _test_eof4265: cs = 4265; goto _test_eof + _test_eof4266: cs = 4266; goto _test_eof + _test_eof4267: cs = 4267; goto _test_eof + _test_eof4268: cs = 4268; goto _test_eof + _test_eof4269: cs = 4269; goto _test_eof + _test_eof4270: cs = 4270; goto _test_eof + _test_eof4271: cs = 4271; goto _test_eof + _test_eof4272: cs = 4272; goto _test_eof + _test_eof4273: cs = 4273; goto _test_eof + _test_eof4274: cs = 4274; goto _test_eof + _test_eof4275: cs = 4275; goto _test_eof + _test_eof4276: cs = 4276; goto _test_eof + _test_eof4277: cs = 4277; goto _test_eof + _test_eof4278: cs = 4278; goto _test_eof + _test_eof4279: cs = 4279; goto _test_eof + _test_eof4280: cs = 4280; goto _test_eof + _test_eof4281: cs = 4281; goto _test_eof + _test_eof4282: cs = 4282; goto _test_eof + _test_eof4283: cs = 4283; goto _test_eof + _test_eof4284: cs = 4284; goto _test_eof + _test_eof4285: cs = 4285; goto _test_eof + _test_eof4286: cs = 4286; goto _test_eof + _test_eof4287: cs = 4287; goto _test_eof + _test_eof4288: cs = 4288; goto _test_eof + _test_eof4289: cs = 4289; goto _test_eof + _test_eof4290: cs = 4290; goto _test_eof + _test_eof4291: cs = 4291; goto _test_eof + _test_eof4292: cs = 4292; goto _test_eof + _test_eof4293: cs = 4293; goto _test_eof + _test_eof4294: cs = 4294; goto _test_eof + _test_eof4295: cs = 4295; goto _test_eof + _test_eof4296: cs = 4296; goto _test_eof + _test_eof4297: cs = 4297; goto _test_eof + _test_eof4298: cs = 4298; goto _test_eof + _test_eof4299: cs = 4299; goto _test_eof + _test_eof4300: cs = 4300; goto _test_eof + _test_eof4301: cs = 4301; goto _test_eof + _test_eof4302: cs = 4302; goto _test_eof + _test_eof4303: cs = 4303; goto _test_eof + _test_eof4304: cs = 4304; goto _test_eof + _test_eof4305: cs = 4305; goto _test_eof + _test_eof4306: cs = 4306; goto _test_eof + _test_eof4307: cs = 4307; goto _test_eof + _test_eof4308: cs = 4308; goto _test_eof + _test_eof4309: cs = 4309; goto _test_eof + _test_eof4310: cs = 4310; goto _test_eof + _test_eof4311: cs = 4311; goto _test_eof + _test_eof4312: cs = 4312; goto _test_eof + _test_eof4313: cs = 4313; goto _test_eof + _test_eof4314: cs = 4314; goto _test_eof + _test_eof4315: cs = 4315; goto _test_eof + _test_eof4316: cs = 4316; goto _test_eof + _test_eof4317: cs = 4317; goto _test_eof + _test_eof4318: cs = 4318; goto _test_eof + _test_eof5082: cs = 5082; goto _test_eof + _test_eof4319: cs = 4319; goto _test_eof + _test_eof4320: cs = 4320; goto _test_eof + _test_eof4321: cs = 4321; goto _test_eof + _test_eof4322: cs = 4322; goto _test_eof + _test_eof4323: cs = 4323; goto _test_eof + _test_eof4324: cs = 4324; goto _test_eof + _test_eof4325: cs = 4325; goto _test_eof + _test_eof4326: cs = 4326; goto _test_eof + _test_eof4327: cs = 4327; goto _test_eof + _test_eof4328: cs = 4328; goto _test_eof + _test_eof4329: cs = 4329; goto _test_eof + _test_eof4330: cs = 4330; goto _test_eof + _test_eof4331: cs = 4331; goto _test_eof + _test_eof4332: cs = 4332; goto _test_eof + _test_eof4333: cs = 4333; goto _test_eof + _test_eof4334: cs = 4334; goto _test_eof + _test_eof4335: cs = 4335; goto _test_eof + _test_eof4336: cs = 4336; goto _test_eof + _test_eof4337: cs = 4337; goto _test_eof + _test_eof4338: cs = 4338; goto _test_eof + _test_eof4339: cs = 4339; goto _test_eof + _test_eof4340: cs = 4340; goto _test_eof + _test_eof4341: cs = 4341; goto _test_eof + _test_eof4342: cs = 4342; goto _test_eof + _test_eof4343: cs = 4343; goto _test_eof + _test_eof4344: cs = 4344; goto _test_eof + _test_eof4345: cs = 4345; goto _test_eof + _test_eof4346: cs = 4346; goto _test_eof + _test_eof4347: cs = 4347; goto _test_eof + _test_eof4348: cs = 4348; goto _test_eof + _test_eof4349: cs = 4349; goto _test_eof + _test_eof4350: cs = 4350; goto _test_eof + _test_eof4351: cs = 4351; goto _test_eof + _test_eof4352: cs = 4352; goto _test_eof + _test_eof4353: cs = 4353; goto _test_eof + _test_eof4354: cs = 4354; goto _test_eof + _test_eof4355: cs = 4355; goto _test_eof + _test_eof4356: cs = 4356; goto _test_eof + _test_eof4357: cs = 4357; goto _test_eof + _test_eof4358: cs = 4358; goto _test_eof + _test_eof4359: cs = 4359; goto _test_eof + _test_eof4360: cs = 4360; goto _test_eof + _test_eof4361: cs = 4361; goto _test_eof + _test_eof4362: cs = 4362; goto _test_eof + _test_eof4363: cs = 4363; goto _test_eof + _test_eof4364: cs = 4364; goto _test_eof + _test_eof4365: cs = 4365; goto _test_eof + _test_eof4366: cs = 4366; goto _test_eof + _test_eof4367: cs = 4367; goto _test_eof + _test_eof4368: cs = 4368; goto _test_eof + _test_eof4369: cs = 4369; goto _test_eof + _test_eof4370: cs = 4370; goto _test_eof + _test_eof4371: cs = 4371; goto _test_eof + _test_eof4372: cs = 4372; goto _test_eof + _test_eof4373: cs = 4373; goto _test_eof + _test_eof4374: cs = 4374; goto _test_eof + _test_eof4375: cs = 4375; goto _test_eof + _test_eof4376: cs = 4376; goto _test_eof + _test_eof4377: cs = 4377; goto _test_eof + _test_eof4378: cs = 4378; goto _test_eof + _test_eof4379: cs = 4379; goto _test_eof + _test_eof4380: cs = 4380; goto _test_eof + _test_eof4381: cs = 4381; goto _test_eof + _test_eof4382: cs = 4382; goto _test_eof + _test_eof4383: cs = 4383; goto _test_eof + _test_eof4384: cs = 4384; goto _test_eof + _test_eof4385: cs = 4385; goto _test_eof + _test_eof4386: cs = 4386; goto _test_eof + _test_eof4387: cs = 4387; goto _test_eof + _test_eof4388: cs = 4388; goto _test_eof + _test_eof4389: cs = 4389; goto _test_eof + _test_eof4390: cs = 4390; goto _test_eof + _test_eof4391: cs = 4391; goto _test_eof + _test_eof4392: cs = 4392; goto _test_eof + _test_eof4393: cs = 4393; goto _test_eof + _test_eof4394: cs = 4394; goto _test_eof + _test_eof4395: cs = 4395; goto _test_eof + _test_eof4396: cs = 4396; goto _test_eof + _test_eof4397: cs = 4397; goto _test_eof + _test_eof4398: cs = 4398; goto _test_eof + _test_eof4399: cs = 4399; goto _test_eof + _test_eof4400: cs = 4400; goto _test_eof + _test_eof4401: cs = 4401; goto _test_eof + _test_eof4402: cs = 4402; goto _test_eof + _test_eof4403: cs = 4403; goto _test_eof + _test_eof4404: cs = 4404; goto _test_eof + _test_eof4405: cs = 4405; goto _test_eof + _test_eof4406: cs = 4406; goto _test_eof + _test_eof4407: cs = 4407; goto _test_eof + _test_eof4408: cs = 4408; goto _test_eof + _test_eof4409: cs = 4409; goto _test_eof + _test_eof4410: cs = 4410; goto _test_eof + _test_eof4411: cs = 4411; goto _test_eof + _test_eof4412: cs = 4412; goto _test_eof + _test_eof4413: cs = 4413; goto _test_eof + _test_eof4414: cs = 4414; goto _test_eof + _test_eof4415: cs = 4415; goto _test_eof + _test_eof4416: cs = 4416; goto _test_eof + _test_eof4417: cs = 4417; goto _test_eof + _test_eof4418: cs = 4418; goto _test_eof + _test_eof4419: cs = 4419; goto _test_eof + _test_eof4420: cs = 4420; goto _test_eof + _test_eof4421: cs = 4421; goto _test_eof + _test_eof4422: cs = 4422; goto _test_eof + _test_eof4423: cs = 4423; goto _test_eof + _test_eof4424: cs = 4424; goto _test_eof + _test_eof4425: cs = 4425; goto _test_eof + _test_eof4426: cs = 4426; goto _test_eof + _test_eof4427: cs = 4427; goto _test_eof + _test_eof4428: cs = 4428; goto _test_eof + _test_eof4429: cs = 4429; goto _test_eof + _test_eof4430: cs = 4430; goto _test_eof + _test_eof4431: cs = 4431; goto _test_eof + _test_eof4432: cs = 4432; goto _test_eof + _test_eof4433: cs = 4433; goto _test_eof + _test_eof4434: cs = 4434; goto _test_eof + _test_eof4435: cs = 4435; goto _test_eof + _test_eof4436: cs = 4436; goto _test_eof + _test_eof4437: cs = 4437; goto _test_eof + _test_eof4438: cs = 4438; goto _test_eof + _test_eof4439: cs = 4439; goto _test_eof + _test_eof4440: cs = 4440; goto _test_eof + _test_eof4441: cs = 4441; goto _test_eof + _test_eof4442: cs = 4442; goto _test_eof + _test_eof4443: cs = 4443; goto _test_eof + _test_eof4444: cs = 4444; goto _test_eof + _test_eof4445: cs = 4445; goto _test_eof + _test_eof4446: cs = 4446; goto _test_eof + _test_eof4447: cs = 4447; goto _test_eof + _test_eof4448: cs = 4448; goto _test_eof + _test_eof4449: cs = 4449; goto _test_eof + _test_eof4450: cs = 4450; goto _test_eof + _test_eof4451: cs = 4451; goto _test_eof + _test_eof4452: cs = 4452; goto _test_eof + _test_eof4453: cs = 4453; goto _test_eof + _test_eof4454: cs = 4454; goto _test_eof + _test_eof4455: cs = 4455; goto _test_eof + _test_eof4456: cs = 4456; goto _test_eof + _test_eof4457: cs = 4457; goto _test_eof + _test_eof4458: cs = 4458; goto _test_eof + _test_eof4459: cs = 4459; goto _test_eof + _test_eof4460: cs = 4460; goto _test_eof + _test_eof4461: cs = 4461; goto _test_eof + _test_eof4462: cs = 4462; goto _test_eof + _test_eof4463: cs = 4463; goto _test_eof + _test_eof4464: cs = 4464; goto _test_eof + _test_eof4465: cs = 4465; goto _test_eof + _test_eof4466: cs = 4466; goto _test_eof + _test_eof4467: cs = 4467; goto _test_eof + _test_eof4468: cs = 4468; goto _test_eof + _test_eof4469: cs = 4469; goto _test_eof + _test_eof4470: cs = 4470; goto _test_eof + _test_eof4471: cs = 4471; goto _test_eof + _test_eof4472: cs = 4472; goto _test_eof + _test_eof5083: cs = 5083; goto _test_eof + _test_eof5084: cs = 5084; goto _test_eof + _test_eof5085: cs = 5085; goto _test_eof + _test_eof5086: cs = 5086; goto _test_eof + _test_eof5087: cs = 5087; goto _test_eof + _test_eof5088: cs = 5088; goto _test_eof + _test_eof5089: cs = 5089; goto _test_eof + _test_eof5090: cs = 5090; goto _test_eof + _test_eof5091: cs = 5091; goto _test_eof + _test_eof5092: cs = 5092; goto _test_eof + _test_eof5093: cs = 5093; goto _test_eof + _test_eof5094: cs = 5094; goto _test_eof + _test_eof5095: cs = 5095; goto _test_eof + _test_eof5096: cs = 5096; goto _test_eof + _test_eof5097: cs = 5097; goto _test_eof + _test_eof5098: cs = 5098; goto _test_eof + _test_eof5099: cs = 5099; goto _test_eof + _test_eof5100: cs = 5100; goto _test_eof + _test_eof5101: cs = 5101; goto _test_eof + _test_eof5102: cs = 5102; goto _test_eof + _test_eof5103: cs = 5103; goto _test_eof + _test_eof5104: cs = 5104; goto _test_eof + _test_eof5105: cs = 5105; goto _test_eof + _test_eof5106: cs = 5106; goto _test_eof + _test_eof5107: cs = 5107; goto _test_eof + _test_eof5108: cs = 5108; goto _test_eof + _test_eof5109: cs = 5109; goto _test_eof + _test_eof5110: cs = 5110; goto _test_eof + _test_eof5111: cs = 5111; goto _test_eof + _test_eof5112: cs = 5112; goto _test_eof + _test_eof5113: cs = 5113; goto _test_eof + _test_eof5114: cs = 5114; goto _test_eof + _test_eof5115: cs = 5115; goto _test_eof + _test_eof5116: cs = 5116; goto _test_eof + _test_eof5117: cs = 5117; goto _test_eof + _test_eof5118: cs = 5118; goto _test_eof + _test_eof5119: cs = 5119; goto _test_eof + _test_eof5120: cs = 5120; goto _test_eof + _test_eof5121: cs = 5121; goto _test_eof + _test_eof5122: cs = 5122; goto _test_eof + _test_eof5123: cs = 5123; goto _test_eof + _test_eof5124: cs = 5124; goto _test_eof + _test_eof5125: cs = 5125; goto _test_eof + _test_eof5126: cs = 5126; goto _test_eof + _test_eof5127: cs = 5127; goto _test_eof + _test_eof5128: cs = 5128; goto _test_eof + _test_eof5129: cs = 5129; goto _test_eof + _test_eof5130: cs = 5130; goto _test_eof + _test_eof5131: cs = 5131; goto _test_eof + _test_eof5132: cs = 5132; goto _test_eof + _test_eof5133: cs = 5133; goto _test_eof + _test_eof5134: cs = 5134; goto _test_eof + _test_eof5135: cs = 5135; goto _test_eof + _test_eof5136: cs = 5136; goto _test_eof + _test_eof5137: cs = 5137; goto _test_eof + _test_eof5138: cs = 5138; goto _test_eof + _test_eof5139: cs = 5139; goto _test_eof + _test_eof5140: cs = 5140; goto _test_eof + _test_eof5141: cs = 5141; goto _test_eof + _test_eof5142: cs = 5142; goto _test_eof + _test_eof5143: cs = 5143; goto _test_eof + _test_eof5144: cs = 5144; goto _test_eof + _test_eof5145: cs = 5145; goto _test_eof + _test_eof5146: cs = 5146; goto _test_eof + _test_eof5147: cs = 5147; goto _test_eof + _test_eof5148: cs = 5148; goto _test_eof + _test_eof5149: cs = 5149; goto _test_eof + _test_eof5150: cs = 5150; goto _test_eof + _test_eof5151: cs = 5151; goto _test_eof + _test_eof5152: cs = 5152; goto _test_eof + _test_eof4473: cs = 4473; goto _test_eof + _test_eof5153: cs = 5153; goto _test_eof + _test_eof5154: cs = 5154; goto _test_eof + _test_eof5155: cs = 5155; goto _test_eof + _test_eof5156: cs = 5156; goto _test_eof + _test_eof5157: cs = 5157; goto _test_eof + _test_eof5158: cs = 5158; goto _test_eof + _test_eof5159: cs = 5159; goto _test_eof + _test_eof5160: cs = 5160; goto _test_eof + _test_eof5161: cs = 5161; goto _test_eof + _test_eof5162: cs = 5162; goto _test_eof + _test_eof5163: cs = 5163; goto _test_eof + _test_eof5164: cs = 5164; goto _test_eof + _test_eof5165: cs = 5165; goto _test_eof + _test_eof5166: cs = 5166; goto _test_eof + _test_eof5167: cs = 5167; goto _test_eof + _test_eof5168: cs = 5168; goto _test_eof + _test_eof5169: cs = 5169; goto _test_eof + _test_eof5170: cs = 5170; goto _test_eof + _test_eof5171: cs = 5171; goto _test_eof + _test_eof5172: cs = 5172; goto _test_eof + _test_eof5173: cs = 5173; goto _test_eof + _test_eof4474: cs = 4474; goto _test_eof + _test_eof5174: cs = 5174; goto _test_eof + _test_eof5175: cs = 5175; goto _test_eof + _test_eof5176: cs = 5176; goto _test_eof + _test_eof5177: cs = 5177; goto _test_eof + _test_eof5178: cs = 5178; goto _test_eof + _test_eof5179: cs = 5179; goto _test_eof + _test_eof4475: cs = 4475; goto _test_eof + _test_eof5180: cs = 5180; goto _test_eof + _test_eof5181: cs = 5181; goto _test_eof + _test_eof4476: cs = 4476; goto _test_eof + _test_eof5182: cs = 5182; goto _test_eof + _test_eof5183: cs = 5183; goto _test_eof + _test_eof5184: cs = 5184; goto _test_eof + _test_eof5185: cs = 5185; goto _test_eof + _test_eof5186: cs = 5186; goto _test_eof + _test_eof5187: cs = 5187; goto _test_eof + _test_eof5188: cs = 5188; goto _test_eof + _test_eof5189: cs = 5189; goto _test_eof + _test_eof5190: cs = 5190; goto _test_eof + _test_eof5191: cs = 5191; goto _test_eof + _test_eof5192: cs = 5192; goto _test_eof + _test_eof5193: cs = 5193; goto _test_eof + _test_eof5194: cs = 5194; goto _test_eof + _test_eof5195: cs = 5195; goto _test_eof + _test_eof5196: cs = 5196; goto _test_eof + _test_eof4477: cs = 4477; goto _test_eof + _test_eof5197: cs = 5197; goto _test_eof + _test_eof5198: cs = 5198; goto _test_eof + _test_eof5199: cs = 5199; goto _test_eof + _test_eof4478: cs = 4478; goto _test_eof + _test_eof5200: cs = 5200; goto _test_eof + _test_eof5201: cs = 5201; goto _test_eof + _test_eof5202: cs = 5202; goto _test_eof + _test_eof5203: cs = 5203; goto _test_eof + _test_eof5204: cs = 5204; goto _test_eof + _test_eof5205: cs = 5205; goto _test_eof + _test_eof4479: cs = 4479; goto _test_eof + _test_eof5206: cs = 5206; goto _test_eof + _test_eof5207: cs = 5207; goto _test_eof + _test_eof4480: cs = 4480; goto _test_eof + _test_eof5208: cs = 5208; goto _test_eof + _test_eof5209: cs = 5209; goto _test_eof + _test_eof5210: cs = 5210; goto _test_eof + _test_eof4481: cs = 4481; goto _test_eof + _test_eof4482: cs = 4482; goto _test_eof + _test_eof4483: cs = 4483; goto _test_eof + _test_eof4484: cs = 4484; goto _test_eof + _test_eof4485: cs = 4485; goto _test_eof + _test_eof4486: cs = 4486; goto _test_eof + _test_eof4487: cs = 4487; goto _test_eof + _test_eof4488: cs = 4488; goto _test_eof + _test_eof4489: cs = 4489; goto _test_eof + _test_eof4490: cs = 4490; goto _test_eof + _test_eof4491: cs = 4491; goto _test_eof + _test_eof4492: cs = 4492; goto _test_eof + _test_eof4493: cs = 4493; goto _test_eof + _test_eof4494: cs = 4494; goto _test_eof + _test_eof4495: cs = 4495; goto _test_eof + _test_eof5211: cs = 5211; goto _test_eof + _test_eof4496: cs = 4496; goto _test_eof + _test_eof4497: cs = 4497; goto _test_eof + _test_eof4498: cs = 4498; goto _test_eof + _test_eof4499: cs = 4499; goto _test_eof + _test_eof4500: cs = 4500; goto _test_eof + _test_eof4501: cs = 4501; goto _test_eof + _test_eof4502: cs = 4502; goto _test_eof + _test_eof4503: cs = 4503; goto _test_eof + _test_eof4504: cs = 4504; goto _test_eof + _test_eof4505: cs = 4505; goto _test_eof + _test_eof4506: cs = 4506; goto _test_eof + _test_eof4507: cs = 4507; goto _test_eof + _test_eof4508: cs = 4508; goto _test_eof + _test_eof4509: cs = 4509; goto _test_eof + _test_eof4510: cs = 4510; goto _test_eof + _test_eof4511: cs = 4511; goto _test_eof + _test_eof4512: cs = 4512; goto _test_eof + _test_eof4513: cs = 4513; goto _test_eof + _test_eof4514: cs = 4514; goto _test_eof + _test_eof4515: cs = 4515; goto _test_eof + _test_eof4516: cs = 4516; goto _test_eof + _test_eof4517: cs = 4517; goto _test_eof + _test_eof4518: cs = 4518; goto _test_eof + _test_eof4519: cs = 4519; goto _test_eof + _test_eof4520: cs = 4520; goto _test_eof + _test_eof4521: cs = 4521; goto _test_eof + _test_eof4522: cs = 4522; goto _test_eof + _test_eof4523: cs = 4523; goto _test_eof + _test_eof4524: cs = 4524; goto _test_eof + _test_eof4525: cs = 4525; goto _test_eof + _test_eof4526: cs = 4526; goto _test_eof + _test_eof4527: cs = 4527; goto _test_eof + _test_eof4528: cs = 4528; goto _test_eof + _test_eof4529: cs = 4529; goto _test_eof + _test_eof4530: cs = 4530; goto _test_eof + _test_eof4531: cs = 4531; goto _test_eof + _test_eof4532: cs = 4532; goto _test_eof + _test_eof4533: cs = 4533; goto _test_eof + _test_eof4534: cs = 4534; goto _test_eof + _test_eof4535: cs = 4535; goto _test_eof + _test_eof4536: cs = 4536; goto _test_eof + _test_eof4537: cs = 4537; goto _test_eof + _test_eof4538: cs = 4538; goto _test_eof + _test_eof4539: cs = 4539; goto _test_eof + _test_eof4540: cs = 4540; goto _test_eof + _test_eof4541: cs = 4541; goto _test_eof + _test_eof4542: cs = 4542; goto _test_eof + _test_eof4543: cs = 4543; goto _test_eof + _test_eof4544: cs = 4544; goto _test_eof + _test_eof4545: cs = 4545; goto _test_eof + _test_eof4546: cs = 4546; goto _test_eof + _test_eof4547: cs = 4547; goto _test_eof + _test_eof4548: cs = 4548; goto _test_eof + _test_eof4549: cs = 4549; goto _test_eof + _test_eof4550: cs = 4550; goto _test_eof + _test_eof4551: cs = 4551; goto _test_eof + _test_eof4552: cs = 4552; goto _test_eof + _test_eof4553: cs = 4553; goto _test_eof + _test_eof4554: cs = 4554; goto _test_eof + _test_eof4555: cs = 4555; goto _test_eof + _test_eof4556: cs = 4556; goto _test_eof + _test_eof4557: cs = 4557; goto _test_eof + _test_eof4558: cs = 4558; goto _test_eof + _test_eof4559: cs = 4559; goto _test_eof + _test_eof4560: cs = 4560; goto _test_eof + _test_eof4561: cs = 4561; goto _test_eof + _test_eof4562: cs = 4562; goto _test_eof + _test_eof4563: cs = 4563; goto _test_eof + _test_eof4564: cs = 4564; goto _test_eof + _test_eof4565: cs = 4565; goto _test_eof + _test_eof4566: cs = 4566; goto _test_eof + _test_eof4567: cs = 4567; goto _test_eof + _test_eof4568: cs = 4568; goto _test_eof + _test_eof4569: cs = 4569; goto _test_eof + _test_eof4570: cs = 4570; goto _test_eof + _test_eof4571: cs = 4571; goto _test_eof + _test_eof4572: cs = 4572; goto _test_eof + _test_eof4573: cs = 4573; goto _test_eof + _test_eof4574: cs = 4574; goto _test_eof + _test_eof4575: cs = 4575; goto _test_eof + _test_eof4576: cs = 4576; goto _test_eof + _test_eof4577: cs = 4577; goto _test_eof + _test_eof4578: cs = 4578; goto _test_eof + _test_eof4579: cs = 4579; goto _test_eof + _test_eof4580: cs = 4580; goto _test_eof + _test_eof4581: cs = 4581; goto _test_eof + _test_eof4582: cs = 4582; goto _test_eof + _test_eof4583: cs = 4583; goto _test_eof + _test_eof4584: cs = 4584; goto _test_eof + _test_eof4585: cs = 4585; goto _test_eof + _test_eof4586: cs = 4586; goto _test_eof + _test_eof4587: cs = 4587; goto _test_eof + _test_eof4588: cs = 4588; goto _test_eof + _test_eof4589: cs = 4589; goto _test_eof + _test_eof4590: cs = 4590; goto _test_eof + _test_eof4591: cs = 4591; goto _test_eof + _test_eof4592: cs = 4592; goto _test_eof + _test_eof4593: cs = 4593; goto _test_eof + _test_eof4594: cs = 4594; goto _test_eof + _test_eof4595: cs = 4595; goto _test_eof + _test_eof4596: cs = 4596; goto _test_eof + _test_eof4597: cs = 4597; goto _test_eof + _test_eof4598: cs = 4598; goto _test_eof + _test_eof4599: cs = 4599; goto _test_eof + _test_eof4600: cs = 4600; goto _test_eof + _test_eof4601: cs = 4601; goto _test_eof + _test_eof4602: cs = 4602; goto _test_eof + _test_eof4603: cs = 4603; goto _test_eof + _test_eof4604: cs = 4604; goto _test_eof + _test_eof4605: cs = 4605; goto _test_eof + _test_eof4606: cs = 4606; goto _test_eof + _test_eof4607: cs = 4607; goto _test_eof + _test_eof4608: cs = 4608; goto _test_eof + _test_eof4609: cs = 4609; goto _test_eof + _test_eof4610: cs = 4610; goto _test_eof + _test_eof4611: cs = 4611; goto _test_eof + _test_eof4612: cs = 4612; goto _test_eof + _test_eof4613: cs = 4613; goto _test_eof + _test_eof4614: cs = 4614; goto _test_eof + _test_eof4615: cs = 4615; goto _test_eof + _test_eof4616: cs = 4616; goto _test_eof + _test_eof4617: cs = 4617; goto _test_eof + _test_eof4618: cs = 4618; goto _test_eof + _test_eof4619: cs = 4619; goto _test_eof + _test_eof4620: cs = 4620; goto _test_eof + _test_eof4621: cs = 4621; goto _test_eof + _test_eof4622: cs = 4622; goto _test_eof + _test_eof4623: cs = 4623; goto _test_eof + _test_eof4624: cs = 4624; goto _test_eof + _test_eof4625: cs = 4625; goto _test_eof + _test_eof4626: cs = 4626; goto _test_eof + _test_eof4627: cs = 4627; goto _test_eof + _test_eof4628: cs = 4628; goto _test_eof + _test_eof4629: cs = 4629; goto _test_eof + _test_eof4630: cs = 4630; goto _test_eof + _test_eof4631: cs = 4631; goto _test_eof + _test_eof4632: cs = 4632; goto _test_eof + _test_eof4633: cs = 4633; goto _test_eof + _test_eof4634: cs = 4634; goto _test_eof + _test_eof4635: cs = 4635; goto _test_eof + _test_eof4636: cs = 4636; goto _test_eof + _test_eof4637: cs = 4637; goto _test_eof + _test_eof4638: cs = 4638; goto _test_eof + _test_eof4639: cs = 4639; goto _test_eof + _test_eof4640: cs = 4640; goto _test_eof + _test_eof4641: cs = 4641; goto _test_eof + _test_eof4642: cs = 4642; goto _test_eof + _test_eof4643: cs = 4643; goto _test_eof + _test_eof4644: cs = 4644; goto _test_eof + _test_eof4645: cs = 4645; goto _test_eof + _test_eof4646: cs = 4646; goto _test_eof + _test_eof4647: cs = 4647; goto _test_eof + _test_eof4648: cs = 4648; goto _test_eof + _test_eof4649: cs = 4649; goto _test_eof + _test_eof4650: cs = 4650; goto _test_eof + _test_eof4651: cs = 4651; goto _test_eof + _test_eof4652: cs = 4652; goto _test_eof + _test_eof4653: cs = 4653; goto _test_eof + _test_eof4654: cs = 4654; goto _test_eof + _test_eof4655: cs = 4655; goto _test_eof + _test_eof5212: cs = 5212; goto _test_eof + _test_eof5213: cs = 5213; goto _test_eof + _test_eof5214: cs = 5214; goto _test_eof + _test_eof5215: cs = 5215; goto _test_eof + _test_eof5216: cs = 5216; goto _test_eof + _test_eof5217: cs = 5217; goto _test_eof + _test_eof5218: cs = 5218; goto _test_eof + _test_eof5219: cs = 5219; goto _test_eof + _test_eof5220: cs = 5220; goto _test_eof + _test_eof5221: cs = 5221; goto _test_eof + _test_eof5222: cs = 5222; goto _test_eof + _test_eof5223: cs = 5223; goto _test_eof + _test_eof5224: cs = 5224; goto _test_eof + _test_eof5225: cs = 5225; goto _test_eof + _test_eof5226: cs = 5226; goto _test_eof + _test_eof5227: cs = 5227; goto _test_eof + _test_eof5228: cs = 5228; goto _test_eof + _test_eof5229: cs = 5229; goto _test_eof + _test_eof5230: cs = 5230; goto _test_eof + _test_eof5231: cs = 5231; goto _test_eof + _test_eof5232: cs = 5232; goto _test_eof + _test_eof5233: cs = 5233; goto _test_eof + _test_eof5234: cs = 5234; goto _test_eof + _test_eof5235: cs = 5235; goto _test_eof + _test_eof5236: cs = 5236; goto _test_eof + _test_eof5237: cs = 5237; goto _test_eof + _test_eof5238: cs = 5238; goto _test_eof + _test_eof5239: cs = 5239; goto _test_eof + _test_eof5240: cs = 5240; goto _test_eof + _test_eof5241: cs = 5241; goto _test_eof + _test_eof5242: cs = 5242; goto _test_eof + _test_eof4656: cs = 4656; goto _test_eof + _test_eof5243: cs = 5243; goto _test_eof + _test_eof5244: cs = 5244; goto _test_eof + _test_eof5245: cs = 5245; goto _test_eof + _test_eof5246: cs = 5246; goto _test_eof + _test_eof5247: cs = 5247; goto _test_eof + _test_eof5248: cs = 5248; goto _test_eof + _test_eof5249: cs = 5249; goto _test_eof + _test_eof5250: cs = 5250; goto _test_eof + _test_eof4657: cs = 4657; goto _test_eof + _test_eof5251: cs = 5251; goto _test_eof + _test_eof5252: cs = 5252; goto _test_eof + _test_eof5253: cs = 5253; goto _test_eof + _test_eof5254: cs = 5254; goto _test_eof + _test_eof5255: cs = 5255; goto _test_eof + _test_eof5256: cs = 5256; goto _test_eof + _test_eof4658: cs = 4658; goto _test_eof + _test_eof5257: cs = 5257; goto _test_eof + _test_eof5258: cs = 5258; goto _test_eof + _test_eof4659: cs = 4659; goto _test_eof + _test_eof5259: cs = 5259; goto _test_eof + _test_eof5260: cs = 5260; goto _test_eof + _test_eof5261: cs = 5261; goto _test_eof + _test_eof5262: cs = 5262; goto _test_eof + _test_eof5263: cs = 5263; goto _test_eof + _test_eof5264: cs = 5264; goto _test_eof + _test_eof5265: cs = 5265; goto _test_eof + _test_eof5266: cs = 5266; goto _test_eof + _test_eof5267: cs = 5267; goto _test_eof + _test_eof5268: cs = 5268; goto _test_eof + _test_eof5269: cs = 5269; goto _test_eof + _test_eof5270: cs = 5270; goto _test_eof + _test_eof5271: cs = 5271; goto _test_eof + _test_eof5272: cs = 5272; goto _test_eof + _test_eof5273: cs = 5273; goto _test_eof + _test_eof5274: cs = 5274; goto _test_eof + _test_eof5275: cs = 5275; goto _test_eof + _test_eof5276: cs = 5276; goto _test_eof + _test_eof5277: cs = 5277; goto _test_eof + _test_eof4660: cs = 4660; goto _test_eof + _test_eof5278: cs = 5278; goto _test_eof + _test_eof5279: cs = 5279; goto _test_eof + _test_eof5280: cs = 5280; goto _test_eof + _test_eof4661: cs = 4661; goto _test_eof + _test_eof5281: cs = 5281; goto _test_eof + _test_eof5282: cs = 5282; goto _test_eof + _test_eof5283: cs = 5283; goto _test_eof + _test_eof5284: cs = 5284; goto _test_eof + _test_eof5285: cs = 5285; goto _test_eof + _test_eof5286: cs = 5286; goto _test_eof + _test_eof4662: cs = 4662; goto _test_eof + _test_eof5287: cs = 5287; goto _test_eof + _test_eof5288: cs = 5288; goto _test_eof + _test_eof5289: cs = 5289; goto _test_eof + _test_eof5290: cs = 5290; goto _test_eof + _test_eof5291: cs = 5291; goto _test_eof + _test_eof5292: cs = 5292; goto _test_eof + _test_eof5293: cs = 5293; goto _test_eof + _test_eof5294: cs = 5294; goto _test_eof + _test_eof5295: cs = 5295; goto _test_eof + _test_eof5296: cs = 5296; goto _test_eof + _test_eof5297: cs = 5297; goto _test_eof + _test_eof5298: cs = 5298; goto _test_eof + _test_eof5299: cs = 5299; goto _test_eof + _test_eof5300: cs = 5300; goto _test_eof + _test_eof5301: cs = 5301; goto _test_eof + _test_eof5302: cs = 5302; goto _test_eof + _test_eof5303: cs = 5303; goto _test_eof + _test_eof5304: cs = 5304; goto _test_eof + _test_eof5305: cs = 5305; goto _test_eof + _test_eof5306: cs = 5306; goto _test_eof + _test_eof5307: cs = 5307; goto _test_eof + _test_eof5308: cs = 5308; goto _test_eof + _test_eof5309: cs = 5309; goto _test_eof + _test_eof5310: cs = 5310; goto _test_eof + _test_eof5311: cs = 5311; goto _test_eof + _test_eof5312: cs = 5312; goto _test_eof + _test_eof5313: cs = 5313; goto _test_eof + _test_eof5314: cs = 5314; goto _test_eof + _test_eof5315: cs = 5315; goto _test_eof + _test_eof5316: cs = 5316; goto _test_eof + _test_eof5317: cs = 5317; goto _test_eof + _test_eof5318: cs = 5318; goto _test_eof + _test_eof5319: cs = 5319; goto _test_eof + _test_eof5320: cs = 5320; goto _test_eof + _test_eof5321: cs = 5321; goto _test_eof + _test_eof5322: cs = 5322; goto _test_eof + _test_eof5323: cs = 5323; goto _test_eof + _test_eof5324: cs = 5324; goto _test_eof + _test_eof5325: cs = 5325; goto _test_eof + _test_eof5326: cs = 5326; goto _test_eof + _test_eof5327: cs = 5327; goto _test_eof + _test_eof5328: cs = 5328; goto _test_eof + _test_eof5329: cs = 5329; goto _test_eof + _test_eof5330: cs = 5330; goto _test_eof + _test_eof5331: cs = 5331; goto _test_eof + _test_eof5332: cs = 5332; goto _test_eof + _test_eof5333: cs = 5333; goto _test_eof + _test_eof5334: cs = 5334; goto _test_eof + _test_eof5335: cs = 5335; goto _test_eof + _test_eof5336: cs = 5336; goto _test_eof + _test_eof5337: cs = 5337; goto _test_eof + _test_eof5338: cs = 5338; goto _test_eof + _test_eof4663: cs = 4663; goto _test_eof + _test_eof4664: cs = 4664; goto _test_eof + _test_eof4665: cs = 4665; goto _test_eof + _test_eof4666: cs = 4666; goto _test_eof + _test_eof4667: cs = 4667; goto _test_eof + _test_eof4668: cs = 4668; goto _test_eof + _test_eof4669: cs = 4669; goto _test_eof + _test_eof4670: cs = 4670; goto _test_eof + _test_eof5339: cs = 5339; goto _test_eof + _test_eof4671: cs = 4671; goto _test_eof + _test_eof4672: cs = 4672; goto _test_eof + _test_eof4673: cs = 4673; goto _test_eof + _test_eof4674: cs = 4674; goto _test_eof + _test_eof4675: cs = 4675; goto _test_eof + _test_eof4676: cs = 4676; goto _test_eof + _test_eof4677: cs = 4677; goto _test_eof + _test_eof4678: cs = 4678; goto _test_eof + _test_eof4679: cs = 4679; goto _test_eof + _test_eof4680: cs = 4680; goto _test_eof + _test_eof4681: cs = 4681; goto _test_eof + _test_eof4682: cs = 4682; goto _test_eof + _test_eof4683: cs = 4683; goto _test_eof + _test_eof4684: cs = 4684; goto _test_eof + _test_eof4685: cs = 4685; goto _test_eof + _test_eof4686: cs = 4686; goto _test_eof + _test_eof4687: cs = 4687; goto _test_eof + _test_eof4688: cs = 4688; goto _test_eof + _test_eof4689: cs = 4689; goto _test_eof + _test_eof4690: cs = 4690; goto _test_eof + _test_eof4691: cs = 4691; goto _test_eof + _test_eof4692: cs = 4692; goto _test_eof + _test_eof4693: cs = 4693; goto _test_eof + _test_eof4694: cs = 4694; goto _test_eof + _test_eof4695: cs = 4695; goto _test_eof + _test_eof4696: cs = 4696; goto _test_eof + _test_eof4697: cs = 4697; goto _test_eof + _test_eof4698: cs = 4698; goto _test_eof + _test_eof4699: cs = 4699; goto _test_eof + _test_eof4700: cs = 4700; goto _test_eof + _test_eof4701: cs = 4701; goto _test_eof + _test_eof4702: cs = 4702; goto _test_eof + _test_eof4703: cs = 4703; goto _test_eof + _test_eof4704: cs = 4704; goto _test_eof + _test_eof4705: cs = 4705; goto _test_eof + _test_eof4706: cs = 4706; goto _test_eof + _test_eof4707: cs = 4707; goto _test_eof + _test_eof5340: cs = 5340; goto _test_eof + _test_eof4708: cs = 4708; goto _test_eof + _test_eof4709: cs = 4709; goto _test_eof + _test_eof4710: cs = 4710; goto _test_eof + _test_eof4711: cs = 4711; goto _test_eof + _test_eof4712: cs = 4712; goto _test_eof + _test_eof4713: cs = 4713; goto _test_eof + _test_eof4714: cs = 4714; goto _test_eof + _test_eof4715: cs = 4715; goto _test_eof + _test_eof4716: cs = 4716; goto _test_eof + _test_eof4717: cs = 4717; goto _test_eof + _test_eof4718: cs = 4718; goto _test_eof + _test_eof4719: cs = 4719; goto _test_eof + _test_eof4720: cs = 4720; goto _test_eof + _test_eof4721: cs = 4721; goto _test_eof + _test_eof4722: cs = 4722; goto _test_eof + _test_eof4723: cs = 4723; goto _test_eof + _test_eof4724: cs = 4724; goto _test_eof + _test_eof4725: cs = 4725; goto _test_eof + _test_eof4726: cs = 4726; goto _test_eof + _test_eof4727: cs = 4727; goto _test_eof + _test_eof4728: cs = 4728; goto _test_eof + _test_eof4729: cs = 4729; goto _test_eof + _test_eof4730: cs = 4730; goto _test_eof + _test_eof4731: cs = 4731; goto _test_eof + _test_eof4732: cs = 4732; goto _test_eof + _test_eof4733: cs = 4733; goto _test_eof + _test_eof4734: cs = 4734; goto _test_eof + _test_eof4735: cs = 4735; goto _test_eof + _test_eof4736: cs = 4736; goto _test_eof + _test_eof4737: cs = 4737; goto _test_eof + _test_eof4738: cs = 4738; goto _test_eof + _test_eof4739: cs = 4739; goto _test_eof + _test_eof4740: cs = 4740; goto _test_eof + _test_eof4741: cs = 4741; goto _test_eof + _test_eof4742: cs = 4742; goto _test_eof + _test_eof4743: cs = 4743; goto _test_eof + _test_eof4744: cs = 4744; goto _test_eof + _test_eof4745: cs = 4745; goto _test_eof + _test_eof4746: cs = 4746; goto _test_eof + _test_eof4747: cs = 4747; goto _test_eof + _test_eof4748: cs = 4748; goto _test_eof + _test_eof4749: cs = 4749; goto _test_eof + _test_eof4750: cs = 4750; goto _test_eof + _test_eof4751: cs = 4751; goto _test_eof + _test_eof4752: cs = 4752; goto _test_eof + _test_eof4753: cs = 4753; goto _test_eof + _test_eof4754: cs = 4754; goto _test_eof + _test_eof4755: cs = 4755; goto _test_eof + _test_eof4756: cs = 4756; goto _test_eof + _test_eof4757: cs = 4757; goto _test_eof + _test_eof4758: cs = 4758; goto _test_eof + _test_eof4759: cs = 4759; goto _test_eof + _test_eof4760: cs = 4760; goto _test_eof + _test_eof4761: cs = 4761; goto _test_eof + _test_eof4762: cs = 4762; goto _test_eof + _test_eof4763: cs = 4763; goto _test_eof + _test_eof4764: cs = 4764; goto _test_eof + _test_eof4765: cs = 4765; goto _test_eof + _test_eof4766: cs = 4766; goto _test_eof + _test_eof4767: cs = 4767; goto _test_eof + _test_eof4768: cs = 4768; goto _test_eof + _test_eof4769: cs = 4769; goto _test_eof + _test_eof4770: cs = 4770; goto _test_eof + _test_eof4771: cs = 4771; goto _test_eof + _test_eof4772: cs = 4772; goto _test_eof + _test_eof4773: cs = 4773; goto _test_eof + _test_eof4774: cs = 4774; goto _test_eof + _test_eof4775: cs = 4775; goto _test_eof + _test_eof4776: cs = 4776; goto _test_eof + _test_eof4777: cs = 4777; goto _test_eof + _test_eof4778: cs = 4778; goto _test_eof + _test_eof4779: cs = 4779; goto _test_eof + _test_eof4780: cs = 4780; goto _test_eof + _test_eof4781: cs = 4781; goto _test_eof + _test_eof4782: cs = 4782; goto _test_eof + _test_eof4783: cs = 4783; goto _test_eof + _test_eof4784: cs = 4784; goto _test_eof + _test_eof4785: cs = 4785; goto _test_eof + _test_eof4786: cs = 4786; goto _test_eof + _test_eof4787: cs = 4787; goto _test_eof + _test_eof4788: cs = 4788; goto _test_eof + _test_eof4789: cs = 4789; goto _test_eof + _test_eof4790: cs = 4790; goto _test_eof + _test_eof4791: cs = 4791; goto _test_eof + _test_eof4792: cs = 4792; goto _test_eof + _test_eof4793: cs = 4793; goto _test_eof + _test_eof4794: cs = 4794; goto _test_eof + _test_eof4795: cs = 4795; goto _test_eof + _test_eof4796: cs = 4796; goto _test_eof + _test_eof4797: cs = 4797; goto _test_eof + _test_eof4798: cs = 4798; goto _test_eof + _test_eof4799: cs = 4799; goto _test_eof + _test_eof4800: cs = 4800; goto _test_eof + _test_eof4801: cs = 4801; goto _test_eof + _test_eof4802: cs = 4802; goto _test_eof + _test_eof4803: cs = 4803; goto _test_eof + _test_eof4804: cs = 4804; goto _test_eof + _test_eof4805: cs = 4805; goto _test_eof + _test_eof4806: cs = 4806; goto _test_eof + _test_eof4807: cs = 4807; goto _test_eof + _test_eof4808: cs = 4808; goto _test_eof + _test_eof4809: cs = 4809; goto _test_eof + _test_eof4810: cs = 4810; goto _test_eof + _test_eof4811: cs = 4811; goto _test_eof + _test_eof4812: cs = 4812; goto _test_eof + _test_eof4813: cs = 4813; goto _test_eof + _test_eof4814: cs = 4814; goto _test_eof + _test_eof4815: cs = 4815; goto _test_eof + _test_eof4816: cs = 4816; goto _test_eof + _test_eof4817: cs = 4817; goto _test_eof + _test_eof4818: cs = 4818; goto _test_eof + _test_eof4819: cs = 4819; goto _test_eof + _test_eof4820: cs = 4820; goto _test_eof + _test_eof4821: cs = 4821; goto _test_eof + _test_eof4822: cs = 4822; goto _test_eof + _test_eof4823: cs = 4823; goto _test_eof + _test_eof4824: cs = 4824; goto _test_eof + _test_eof4825: cs = 4825; goto _test_eof + _test_eof4826: cs = 4826; goto _test_eof + _test_eof4827: cs = 4827; goto _test_eof + _test_eof4828: cs = 4828; goto _test_eof + _test_eof4829: cs = 4829; goto _test_eof + _test_eof4830: cs = 4830; goto _test_eof + _test_eof4831: cs = 4831; goto _test_eof + _test_eof4832: cs = 4832; goto _test_eof + _test_eof4833: cs = 4833; goto _test_eof + _test_eof4834: cs = 4834; goto _test_eof + _test_eof4835: cs = 4835; goto _test_eof + _test_eof4836: cs = 4836; goto _test_eof + _test_eof4837: cs = 4837; goto _test_eof + _test_eof4838: cs = 4838; goto _test_eof + _test_eof4839: cs = 4839; goto _test_eof + _test_eof4840: cs = 4840; goto _test_eof + _test_eof4841: cs = 4841; goto _test_eof + _test_eof4842: cs = 4842; goto _test_eof + _test_eof4843: cs = 4843; goto _test_eof + _test_eof4844: cs = 4844; goto _test_eof + _test_eof4845: cs = 4845; goto _test_eof + _test_eof4846: cs = 4846; goto _test_eof + _test_eof4847: cs = 4847; goto _test_eof + _test_eof4848: cs = 4848; goto _test_eof + _test_eof4849: cs = 4849; goto _test_eof + _test_eof4850: cs = 4850; goto _test_eof + _test_eof4851: cs = 4851; goto _test_eof + _test_eof4852: cs = 4852; goto _test_eof + _test_eof4853: cs = 4853; goto _test_eof + _test_eof4854: cs = 4854; goto _test_eof + _test_eof4855: cs = 4855; goto _test_eof + _test_eof4856: cs = 4856; goto _test_eof + _test_eof4857: cs = 4857; goto _test_eof + _test_eof4858: cs = 4858; goto _test_eof + _test_eof4859: cs = 4859; goto _test_eof + _test_eof4860: cs = 4860; goto _test_eof + _test_eof4861: cs = 4861; goto _test_eof + + _test_eof: {} + if p == eof { + switch cs { + case 4863: + goto tr4499 + case 0: + goto tr0 + case 1: + goto tr2 + case 2: + goto tr2 + case 3: + goto tr0 + case 4: + goto tr0 + case 5: + goto tr0 + case 6: + goto tr0 + case 7: + goto tr0 + case 8: + goto tr0 + case 9: + goto tr0 + case 10: + goto tr0 + case 11: + goto tr0 + case 12: + goto tr0 + case 13: + goto tr0 + case 14: + goto tr2 + case 15: + goto tr2 + case 16: + goto tr2 + case 17: + goto tr2 + case 18: + goto tr2 + case 19: + goto tr2 + case 20: + goto tr2 + case 21: + goto tr2 + case 22: + goto tr2 + case 23: + goto tr2 + case 24: + goto tr2 + case 25: + goto tr2 + case 26: + goto tr2 + case 27: + goto tr2 + case 28: + goto tr2 + case 29: + goto tr2 + case 30: + goto tr2 + case 31: + goto tr2 + case 32: + goto tr2 + case 33: + goto tr2 + case 34: + goto tr2 + case 35: + goto tr2 + case 36: + goto tr2 + case 37: + goto tr2 + case 38: + goto tr2 + case 39: + goto tr2 + case 40: + goto tr2 + case 41: + goto tr2 + case 42: + goto tr0 + case 43: + goto tr2 + case 44: + goto tr2 + case 45: + goto tr2 + case 46: + goto tr2 + case 47: + goto tr2 + case 48: + goto tr2 + case 49: + goto tr2 + case 50: + goto tr2 + case 51: + goto tr2 + case 52: + goto tr2 + case 53: + goto tr2 + case 54: + goto tr2 + case 55: + goto tr2 + case 56: + goto tr2 + case 57: + goto tr2 + case 58: + goto tr2 + case 59: + goto tr2 + case 60: + goto tr2 + case 61: + goto tr2 + case 62: + goto tr2 + case 63: + goto tr2 + case 64: + goto tr0 + case 65: + goto tr2 + case 66: + goto tr2 + case 67: + goto tr2 + case 68: + goto tr2 + case 69: + goto tr2 + case 70: + goto tr2 + case 71: + goto tr0 + case 72: + goto tr2 + case 73: + goto tr2 + case 74: + goto tr0 + case 75: + goto tr2 + case 76: + goto tr2 + case 77: + goto tr2 + case 78: + goto tr2 + case 79: + goto tr2 + case 80: + goto tr2 + case 81: + goto tr2 + case 82: + goto tr2 + case 83: + goto tr2 + case 84: + goto tr2 + case 85: + goto tr2 + case 86: + goto tr2 + case 87: + goto tr2 + case 88: + goto tr2 + case 89: + goto tr2 + case 90: + goto tr0 + case 91: + goto tr2 + case 92: + goto tr2 + case 93: + goto tr2 + case 94: + goto tr0 + case 95: + goto tr2 + case 96: + goto tr2 + case 97: + goto tr2 + case 98: + goto tr2 + case 99: + goto tr2 + case 100: + goto tr2 + case 101: + goto tr2 + case 102: + goto tr2 + case 103: + goto tr2 + case 104: + goto tr2 + case 105: + goto tr2 + case 106: + goto tr2 + case 107: + goto tr2 + case 108: + goto tr2 + case 109: + goto tr2 + case 110: + goto tr2 + case 111: + goto tr2 + case 112: + goto tr2 + case 113: + goto tr2 + case 114: + goto tr2 + case 115: + goto tr2 + case 116: + goto tr2 + case 117: + goto tr2 + case 118: + goto tr2 + case 119: + goto tr2 + case 120: + goto tr2 + case 121: + goto tr2 + case 122: + goto tr2 + case 123: + goto tr2 + case 124: + goto tr2 + case 125: + goto tr2 + case 126: + goto tr2 + case 127: + goto tr2 + case 128: + goto tr2 + case 129: + goto tr2 + case 130: + goto tr2 + case 131: + goto tr2 + case 132: + goto tr2 + case 133: + goto tr2 + case 134: + goto tr2 + case 135: + goto tr2 + case 136: + goto tr0 + case 137: + goto tr2 + case 138: + goto tr2 + case 139: + goto tr2 + case 140: + goto tr2 + case 4864: + goto tr4519 + case 4865: + goto tr4521 + case 141: + goto tr125 + case 4866: + goto tr4521 + case 4867: + goto tr4562 + case 142: + goto tr2 + case 143: + goto tr2 + case 144: + goto tr2 + case 145: + goto tr2 + case 146: + goto tr2 + case 147: + goto tr2 + case 148: + goto tr2 + case 149: + goto tr2 + case 150: + goto tr2 + case 151: + goto tr2 + case 152: + goto tr2 + case 153: + goto tr2 + case 154: + goto tr2 + case 155: + goto tr2 + case 156: + goto tr2 + case 157: + goto tr2 + case 158: + goto tr2 + case 159: + goto tr2 + case 160: + goto tr2 + case 161: + goto tr2 + case 162: + goto tr2 + case 163: + goto tr2 + case 164: + goto tr2 + case 165: + goto tr2 + case 166: + goto tr2 + case 167: + goto tr2 + case 168: + goto tr2 + case 169: + goto tr2 + case 170: + goto tr2 + case 171: + goto tr2 + case 172: + goto tr2 + case 173: + goto tr2 + case 174: + goto tr2 + case 175: + goto tr2 + case 176: + goto tr2 + case 177: + goto tr2 + case 178: + goto tr2 + case 179: + goto tr2 + case 180: + goto tr2 + case 181: + goto tr2 + case 182: + goto tr2 + case 183: + goto tr2 + case 184: + goto tr2 + case 185: + goto tr2 + case 186: + goto tr2 + case 187: + goto tr2 + case 188: + goto tr2 + case 189: + goto tr2 + case 190: + goto tr2 + case 191: + goto tr2 + case 192: + goto tr2 + case 193: + goto tr2 + case 194: + goto tr2 + case 195: + goto tr2 + case 196: + goto tr2 + case 197: + goto tr2 + case 198: + goto tr2 + case 199: + goto tr2 + case 200: + goto tr2 + case 201: + goto tr2 + case 202: + goto tr2 + case 203: + goto tr2 + case 204: + goto tr2 + case 205: + goto tr2 + case 206: + goto tr2 + case 207: + goto tr2 + case 208: + goto tr2 + case 209: + goto tr2 + case 210: + goto tr2 + case 211: + goto tr2 + case 212: + goto tr2 + case 213: + goto tr2 + case 214: + goto tr2 + case 215: + goto tr2 + case 216: + goto tr2 + case 217: + goto tr2 + case 218: + goto tr2 + case 219: + goto tr2 + case 220: + goto tr2 + case 221: + goto tr2 + case 222: + goto tr2 + case 223: + goto tr2 + case 224: + goto tr2 + case 225: + goto tr2 + case 226: + goto tr2 + case 227: + goto tr2 + case 228: + goto tr2 + case 229: + goto tr2 + case 230: + goto tr2 + case 231: + goto tr2 + case 232: + goto tr2 + case 233: + goto tr2 + case 234: + goto tr2 + case 235: + goto tr2 + case 236: + goto tr2 + case 237: + goto tr2 + case 238: + goto tr2 + case 239: + goto tr2 + case 240: + goto tr2 + case 241: + goto tr2 + case 242: + goto tr2 + case 243: + goto tr2 + case 244: + goto tr2 + case 245: + goto tr2 + case 246: + goto tr2 + case 247: + goto tr2 + case 248: + goto tr2 + case 249: + goto tr2 + case 250: + goto tr2 + case 251: + goto tr2 + case 252: + goto tr2 + case 253: + goto tr2 + case 254: + goto tr2 + case 255: + goto tr2 + case 256: + goto tr2 + case 257: + goto tr2 + case 258: + goto tr2 + case 259: + goto tr2 + case 260: + goto tr2 + case 261: + goto tr2 + case 262: + goto tr2 + case 263: + goto tr2 + case 264: + goto tr2 + case 265: + goto tr2 + case 266: + goto tr2 + case 267: + goto tr2 + case 268: + goto tr2 + case 269: + goto tr2 + case 270: + goto tr2 + case 271: + goto tr2 + case 272: + goto tr2 + case 273: + goto tr2 + case 274: + goto tr2 + case 275: + goto tr2 + case 276: + goto tr2 + case 277: + goto tr2 + case 278: + goto tr2 + case 279: + goto tr2 + case 280: + goto tr2 + case 281: + goto tr2 + case 282: + goto tr2 + case 283: + goto tr2 + case 284: + goto tr2 + case 285: + goto tr2 + case 286: + goto tr2 + case 287: + goto tr2 + case 288: + goto tr2 + case 289: + goto tr2 + case 290: + goto tr2 + case 291: + goto tr2 + case 292: + goto tr2 + case 293: + goto tr2 + case 294: + goto tr2 + case 295: + goto tr2 + case 296: + goto tr2 + case 297: + goto tr2 + case 298: + goto tr2 + case 299: + goto tr2 + case 300: + goto tr2 + case 301: + goto tr2 + case 302: + goto tr2 + case 303: + goto tr2 + case 304: + goto tr2 + case 305: + goto tr2 + case 306: + goto tr2 + case 307: + goto tr2 + case 308: + goto tr2 + case 309: + goto tr2 + case 310: + goto tr2 + case 311: + goto tr2 + case 312: + goto tr2 + case 313: + goto tr2 + case 314: + goto tr2 + case 315: + goto tr2 + case 316: + goto tr2 + case 317: + goto tr2 + case 318: + goto tr2 + case 319: + goto tr2 + case 320: + goto tr2 + case 321: + goto tr2 + case 322: + goto tr2 + case 323: + goto tr2 + case 324: + goto tr2 + case 325: + goto tr2 + case 326: + goto tr2 + case 327: + goto tr2 + case 328: + goto tr2 + case 329: + goto tr2 + case 330: + goto tr2 + case 331: + goto tr2 + case 332: + goto tr2 + case 333: + goto tr2 + case 334: + goto tr2 + case 335: + goto tr2 + case 336: + goto tr2 + case 337: + goto tr2 + case 338: + goto tr2 + case 339: + goto tr2 + case 340: + goto tr2 + case 341: + goto tr2 + case 342: + goto tr2 + case 343: + goto tr2 + case 344: + goto tr2 + case 345: + goto tr2 + case 346: + goto tr2 + case 347: + goto tr2 + case 348: + goto tr2 + case 349: + goto tr2 + case 350: + goto tr2 + case 351: + goto tr2 + case 352: + goto tr2 + case 353: + goto tr2 + case 354: + goto tr2 + case 355: + goto tr2 + case 356: + goto tr2 + case 357: + goto tr2 + case 358: + goto tr2 + case 359: + goto tr2 + case 360: + goto tr2 + case 361: + goto tr2 + case 362: + goto tr2 + case 363: + goto tr2 + case 364: + goto tr2 + case 365: + goto tr2 + case 366: + goto tr2 + case 367: + goto tr2 + case 368: + goto tr2 + case 369: + goto tr2 + case 370: + goto tr2 + case 371: + goto tr2 + case 372: + goto tr2 + case 373: + goto tr2 + case 374: + goto tr2 + case 375: + goto tr2 + case 376: + goto tr2 + case 377: + goto tr2 + case 378: + goto tr2 + case 379: + goto tr2 + case 380: + goto tr2 + case 381: + goto tr2 + case 382: + goto tr2 + case 383: + goto tr2 + case 384: + goto tr2 + case 385: + goto tr2 + case 386: + goto tr2 + case 387: + goto tr2 + case 388: + goto tr2 + case 389: + goto tr2 + case 390: + goto tr2 + case 391: + goto tr2 + case 392: + goto tr2 + case 393: + goto tr2 + case 394: + goto tr2 + case 395: + goto tr2 + case 396: + goto tr2 + case 397: + goto tr2 + case 398: + goto tr2 + case 399: + goto tr2 + case 400: + goto tr2 + case 401: + goto tr2 + case 402: + goto tr2 + case 403: + goto tr2 + case 404: + goto tr2 + case 405: + goto tr2 + case 406: + goto tr2 + case 407: + goto tr2 + case 408: + goto tr2 + case 409: + goto tr2 + case 410: + goto tr2 + case 411: + goto tr2 + case 412: + goto tr2 + case 4868: + goto tr4562 + case 413: + goto tr420 + case 414: + goto tr420 + case 415: + goto tr420 + case 416: + goto tr420 + case 417: + goto tr420 + case 418: + goto tr420 + case 419: + goto tr420 + case 420: + goto tr420 + case 421: + goto tr420 + case 422: + goto tr420 + case 423: + goto tr420 + case 424: + goto tr420 + case 425: + goto tr420 + case 426: + goto tr420 + case 427: + goto tr420 + case 428: + goto tr420 + case 429: + goto tr420 + case 430: + goto tr420 + case 431: + goto tr420 + case 432: + goto tr420 + case 433: + goto tr420 + case 434: + goto tr420 + case 435: + goto tr420 + case 436: + goto tr420 + case 437: + goto tr420 + case 438: + goto tr420 + case 439: + goto tr420 + case 440: + goto tr420 + case 441: + goto tr420 + case 442: + goto tr420 + case 443: + goto tr420 + case 444: + goto tr420 + case 445: + goto tr420 + case 446: + goto tr420 + case 447: + goto tr420 + case 448: + goto tr420 + case 449: + goto tr420 + case 450: + goto tr420 + case 451: + goto tr420 + case 452: + goto tr420 + case 453: + goto tr420 + case 454: + goto tr420 + case 455: + goto tr420 + case 456: + goto tr420 + case 457: + goto tr420 + case 458: + goto tr420 + case 459: + goto tr420 + case 460: + goto tr420 + case 461: + goto tr420 + case 462: + goto tr420 + case 463: + goto tr420 + case 464: + goto tr420 + case 465: + goto tr420 + case 466: + goto tr420 + case 467: + goto tr420 + case 468: + goto tr2 + case 469: + goto tr2 + case 470: + goto tr420 + case 471: + goto tr420 + case 472: + goto tr420 + case 473: + goto tr420 + case 474: + goto tr420 + case 475: + goto tr420 + case 476: + goto tr420 + case 477: + goto tr420 + case 478: + goto tr420 + case 479: + goto tr420 + case 480: + goto tr420 + case 481: + goto tr420 + case 482: + goto tr420 + case 483: + goto tr420 + case 484: + goto tr420 + case 485: + goto tr420 + case 486: + goto tr420 + case 487: + goto tr420 + case 488: + goto tr420 + case 489: + goto tr420 + case 490: + goto tr420 + case 491: + goto tr420 + case 492: + goto tr420 + case 493: + goto tr420 + case 494: + goto tr420 + case 495: + goto tr420 + case 496: + goto tr420 + case 497: + goto tr420 + case 498: + goto tr420 + case 499: + goto tr420 + case 500: + goto tr420 + case 501: + goto tr420 + case 502: + goto tr420 + case 503: + goto tr420 + case 504: + goto tr420 + case 505: + goto tr420 + case 506: + goto tr420 + case 507: + goto tr420 + case 508: + goto tr420 + case 509: + goto tr420 + case 510: + goto tr420 + case 511: + goto tr420 + case 512: + goto tr420 + case 513: + goto tr420 + case 514: + goto tr420 + case 515: + goto tr420 + case 516: + goto tr420 + case 517: + goto tr420 + case 518: + goto tr420 + case 519: + goto tr420 + case 520: + goto tr420 + case 521: + goto tr420 + case 522: + goto tr420 + case 523: + goto tr420 + case 524: + goto tr420 + case 525: + goto tr420 + case 526: + goto tr420 + case 527: + goto tr420 + case 528: + goto tr420 + case 529: + goto tr420 + case 530: + goto tr420 + case 531: + goto tr420 + case 532: + goto tr420 + case 533: + goto tr420 + case 534: + goto tr420 + case 535: + goto tr420 + case 536: + goto tr420 + case 537: + goto tr420 + case 538: + goto tr2 + case 539: + goto tr420 + case 540: + goto tr420 + case 541: + goto tr420 + case 542: + goto tr420 + case 543: + goto tr420 + case 544: + goto tr420 + case 545: + goto tr420 + case 546: + goto tr420 + case 547: + goto tr420 + case 548: + goto tr420 + case 549: + goto tr420 + case 550: + goto tr420 + case 551: + goto tr420 + case 552: + goto tr420 + case 553: + goto tr420 + case 554: + goto tr420 + case 555: + goto tr420 + case 556: + goto tr420 + case 557: + goto tr420 + case 558: + goto tr420 + case 559: + goto tr420 + case 560: + goto tr420 + case 561: + goto tr420 + case 4869: + goto tr4562 + case 562: + goto tr420 + case 563: + goto tr420 + case 564: + goto tr420 + case 565: + goto tr420 + case 566: + goto tr420 + case 567: + goto tr420 + case 4870: + goto tr4562 + case 568: + goto tr420 + case 569: + goto tr420 + case 570: + goto tr420 + case 571: + goto tr420 + case 572: + goto tr420 + case 573: + goto tr420 + case 574: + goto tr420 + case 4871: + goto tr4562 + case 575: + goto tr420 + case 576: + goto tr420 + case 577: + goto tr420 + case 578: + goto tr420 + case 579: + goto tr420 + case 580: + goto tr420 + case 581: + goto tr420 + case 582: + goto tr420 + case 583: + goto tr420 + case 584: + goto tr420 + case 585: + goto tr420 + case 586: + goto tr420 + case 587: + goto tr420 + case 588: + goto tr420 + case 589: + goto tr420 + case 590: + goto tr420 + case 591: + goto tr420 + case 592: + goto tr420 + case 593: + goto tr420 + case 594: + goto tr420 + case 595: + goto tr420 + case 596: + goto tr420 + case 597: + goto tr420 + case 598: + goto tr420 + case 599: + goto tr420 + case 600: + goto tr420 + case 601: + goto tr420 + case 602: + goto tr420 + case 603: + goto tr420 + case 604: + goto tr420 + case 605: + goto tr420 + case 606: + goto tr420 + case 607: + goto tr420 + case 608: + goto tr420 + case 609: + goto tr420 + case 610: + goto tr420 + case 611: + goto tr420 + case 612: + goto tr420 + case 613: + goto tr420 + case 614: + goto tr420 + case 615: + goto tr420 + case 616: + goto tr420 + case 617: + goto tr420 + case 618: + goto tr420 + case 619: + goto tr420 + case 620: + goto tr420 + case 621: + goto tr420 + case 622: + goto tr420 + case 623: + goto tr420 + case 624: + goto tr420 + case 625: + goto tr420 + case 626: + goto tr420 + case 627: + goto tr420 + case 628: + goto tr420 + case 629: + goto tr420 + case 630: + goto tr420 + case 631: + goto tr420 + case 632: + goto tr420 + case 633: + goto tr420 + case 634: + goto tr420 + case 635: + goto tr420 + case 636: + goto tr420 + case 637: + goto tr420 + case 638: + goto tr420 + case 639: + goto tr420 + case 640: + goto tr2 + case 641: + goto tr420 + case 642: + goto tr420 + case 643: + goto tr420 + case 644: + goto tr420 + case 645: + goto tr420 + case 646: + goto tr420 + case 647: + goto tr420 + case 648: + goto tr420 + case 649: + goto tr420 + case 650: + goto tr420 + case 651: + goto tr420 + case 652: + goto tr420 + case 653: + goto tr420 + case 654: + goto tr2 + case 655: + goto tr420 + case 656: + goto tr420 + case 657: + goto tr420 + case 658: + goto tr420 + case 659: + goto tr420 + case 660: + goto tr420 + case 661: + goto tr420 + case 662: + goto tr420 + case 663: + goto tr420 + case 664: + goto tr420 + case 665: + goto tr420 + case 666: + goto tr420 + case 667: + goto tr420 + case 668: + goto tr420 + case 669: + goto tr420 + case 670: + goto tr420 + case 671: + goto tr420 + case 672: + goto tr2 + case 673: + goto tr420 + case 674: + goto tr420 + case 675: + goto tr420 + case 676: + goto tr420 + case 677: + goto tr420 + case 678: + goto tr420 + case 679: + goto tr420 + case 680: + goto tr420 + case 681: + goto tr420 + case 682: + goto tr420 + case 683: + goto tr420 + case 684: + goto tr2 + case 685: + goto tr420 + case 686: + goto tr420 + case 687: + goto tr420 + case 688: + goto tr420 + case 689: + goto tr420 + case 690: + goto tr420 + case 691: + goto tr2 + case 692: + goto tr420 + case 693: + goto tr420 + case 694: + goto tr420 + case 695: + goto tr420 + case 696: + goto tr420 + case 697: + goto tr420 + case 698: + goto tr420 + case 699: + goto tr420 + case 700: + goto tr420 + case 701: + goto tr420 + case 702: + goto tr420 + case 703: + goto tr420 + case 704: + goto tr420 + case 705: + goto tr420 + case 706: + goto tr420 + case 707: + goto tr2 + case 708: + goto tr420 + case 709: + goto tr2 + case 710: + goto tr420 + case 711: + goto tr420 + case 712: + goto tr2 + case 713: + goto tr420 + case 714: + goto tr420 + case 715: + goto tr420 + case 716: + goto tr420 + case 717: + goto tr420 + case 718: + goto tr420 + case 719: + goto tr420 + case 720: + goto tr420 + case 721: + goto tr2 + case 722: + goto tr420 + case 723: + goto tr420 + case 724: + goto tr420 + case 725: + goto tr420 + case 726: + goto tr420 + case 727: + goto tr420 + case 728: + goto tr420 + case 729: + goto tr420 + case 730: + goto tr420 + case 731: + goto tr420 + case 732: + goto tr420 + case 733: + goto tr420 + case 734: + goto tr420 + case 735: + goto tr420 + case 736: + goto tr420 + case 737: + goto tr420 + case 738: + goto tr420 + case 739: + goto tr420 + case 740: + goto tr420 + case 741: + goto tr420 + case 742: + goto tr420 + case 743: + goto tr420 + case 744: + goto tr420 + case 745: + goto tr420 + case 746: + goto tr420 + case 747: + goto tr420 + case 748: + goto tr420 + case 749: + goto tr420 + case 750: + goto tr420 + case 751: + goto tr420 + case 752: + goto tr420 + case 753: + goto tr420 + case 754: + goto tr420 + case 755: + goto tr420 + case 756: + goto tr420 + case 757: + goto tr420 + case 758: + goto tr420 + case 759: + goto tr420 + case 760: + goto tr420 + case 761: + goto tr420 + case 762: + goto tr420 + case 763: + goto tr420 + case 764: + goto tr420 + case 765: + goto tr420 + case 766: + goto tr420 + case 767: + goto tr420 + case 768: + goto tr420 + case 769: + goto tr420 + case 770: + goto tr420 + case 771: + goto tr420 + case 772: + goto tr420 + case 773: + goto tr420 + case 774: + goto tr420 + case 775: + goto tr420 + case 776: + goto tr420 + case 777: + goto tr420 + case 778: + goto tr420 + case 779: + goto tr420 + case 780: + goto tr420 + case 781: + goto tr420 + case 782: + goto tr420 + case 783: + goto tr420 + case 784: + goto tr420 + case 785: + goto tr420 + case 786: + goto tr420 + case 787: + goto tr420 + case 788: + goto tr420 + case 789: + goto tr420 + case 790: + goto tr420 + case 791: + goto tr420 + case 792: + goto tr420 + case 793: + goto tr420 + case 794: + goto tr420 + case 795: + goto tr420 + case 796: + goto tr420 + case 797: + goto tr420 + case 798: + goto tr420 + case 799: + goto tr420 + case 800: + goto tr420 + case 801: + goto tr420 + case 802: + goto tr420 + case 803: + goto tr420 + case 804: + goto tr420 + case 805: + goto tr420 + case 806: + goto tr420 + case 807: + goto tr420 + case 808: + goto tr420 + case 809: + goto tr420 + case 810: + goto tr420 + case 811: + goto tr420 + case 812: + goto tr420 + case 813: + goto tr420 + case 814: + goto tr420 + case 815: + goto tr420 + case 816: + goto tr420 + case 817: + goto tr420 + case 818: + goto tr420 + case 819: + goto tr420 + case 820: + goto tr420 + case 821: + goto tr420 + case 822: + goto tr420 + case 823: + goto tr420 + case 824: + goto tr420 + case 825: + goto tr420 + case 826: + goto tr420 + case 827: + goto tr420 + case 828: + goto tr420 + case 829: + goto tr420 + case 830: + goto tr420 + case 831: + goto tr420 + case 832: + goto tr420 + case 833: + goto tr420 + case 834: + goto tr420 + case 835: + goto tr420 + case 836: + goto tr420 + case 837: + goto tr420 + case 838: + goto tr420 + case 839: + goto tr420 + case 840: + goto tr420 + case 841: + goto tr420 + case 842: + goto tr420 + case 843: + goto tr420 + case 844: + goto tr420 + case 845: + goto tr420 + case 846: + goto tr420 + case 847: + goto tr420 + case 848: + goto tr420 + case 849: + goto tr420 + case 850: + goto tr420 + case 851: + goto tr420 + case 852: + goto tr420 + case 853: + goto tr420 + case 854: + goto tr420 + case 855: + goto tr420 + case 856: + goto tr420 + case 857: + goto tr420 + case 858: + goto tr420 + case 859: + goto tr420 + case 860: + goto tr420 + case 861: + goto tr420 + case 862: + goto tr420 + case 863: + goto tr420 + case 864: + goto tr420 + case 865: + goto tr420 + case 866: + goto tr420 + case 867: + goto tr420 + case 868: + goto tr420 + case 869: + goto tr420 + case 870: + goto tr2 + case 871: + goto tr420 + case 872: + goto tr420 + case 873: + goto tr2 + case 874: + goto tr420 + case 875: + goto tr420 + case 876: + goto tr420 + case 877: + goto tr420 + case 878: + goto tr420 + case 879: + goto tr420 + case 880: + goto tr420 + case 881: + goto tr420 + case 882: + goto tr420 + case 883: + goto tr420 + case 884: + goto tr420 + case 885: + goto tr420 + case 886: + goto tr420 + case 887: + goto tr420 + case 888: + goto tr420 + case 889: + goto tr420 + case 890: + goto tr420 + case 891: + goto tr420 + case 892: + goto tr420 + case 893: + goto tr420 + case 894: + goto tr420 + case 895: + goto tr420 + case 896: + goto tr420 + case 897: + goto tr420 + case 898: + goto tr420 + case 899: + goto tr420 + case 900: + goto tr420 + case 901: + goto tr420 + case 902: + goto tr420 + case 903: + goto tr420 + case 904: + goto tr420 + case 905: + goto tr420 + case 906: + goto tr420 + case 907: + goto tr420 + case 908: + goto tr420 + case 909: + goto tr420 + case 910: + goto tr420 + case 911: + goto tr420 + case 912: + goto tr420 + case 913: + goto tr420 + case 914: + goto tr420 + case 915: + goto tr420 + case 916: + goto tr420 + case 917: + goto tr420 + case 918: + goto tr420 + case 919: + goto tr420 + case 920: + goto tr420 + case 921: + goto tr420 + case 922: + goto tr420 + case 923: + goto tr420 + case 924: + goto tr420 + case 925: + goto tr420 + case 926: + goto tr420 + case 927: + goto tr420 + case 928: + goto tr420 + case 929: + goto tr420 + case 930: + goto tr420 + case 931: + goto tr420 + case 932: + goto tr420 + case 933: + goto tr420 + case 934: + goto tr420 + case 935: + goto tr420 + case 936: + goto tr420 + case 937: + goto tr420 + case 938: + goto tr420 + case 939: + goto tr420 + case 940: + goto tr420 + case 941: + goto tr420 + case 942: + goto tr420 + case 943: + goto tr420 + case 944: + goto tr420 + case 945: + goto tr420 + case 946: + goto tr420 + case 947: + goto tr420 + case 948: + goto tr420 + case 949: + goto tr420 + case 950: + goto tr420 + case 951: + goto tr420 + case 952: + goto tr420 + case 953: + goto tr420 + case 954: + goto tr420 + case 955: + goto tr420 + case 956: + goto tr420 + case 957: + goto tr420 + case 958: + goto tr420 + case 959: + goto tr420 + case 960: + goto tr420 + case 961: + goto tr420 + case 962: + goto tr420 + case 963: + goto tr420 + case 964: + goto tr420 + case 965: + goto tr420 + case 966: + goto tr420 + case 967: + goto tr2 + case 968: + goto tr420 + case 969: + goto tr2 + case 970: + goto tr420 + case 971: + goto tr420 + case 972: + goto tr420 + case 973: + goto tr420 + case 974: + goto tr420 + case 975: + goto tr420 + case 976: + goto tr420 + case 977: + goto tr420 + case 978: + goto tr420 + case 979: + goto tr420 + case 980: + goto tr420 + case 981: + goto tr420 + case 982: + goto tr420 + case 983: + goto tr420 + case 984: + goto tr420 + case 985: + goto tr420 + case 986: + goto tr420 + case 987: + goto tr420 + case 988: + goto tr420 + case 989: + goto tr420 + case 990: + goto tr420 + case 991: + goto tr420 + case 992: + goto tr420 + case 993: + goto tr420 + case 994: + goto tr420 + case 995: + goto tr420 + case 996: + goto tr420 + case 997: + goto tr420 + case 998: + goto tr420 + case 999: + goto tr420 + case 1000: + goto tr420 + case 1001: + goto tr420 + case 1002: + goto tr420 + case 1003: + goto tr420 + case 1004: + goto tr420 + case 1005: + goto tr420 + case 1006: + goto tr420 + case 1007: + goto tr420 + case 1008: + goto tr420 + case 1009: + goto tr420 + case 1010: + goto tr420 + case 1011: + goto tr420 + case 1012: + goto tr420 + case 1013: + goto tr420 + case 1014: + goto tr420 + case 1015: + goto tr420 + case 1016: + goto tr420 + case 1017: + goto tr420 + case 1018: + goto tr420 + case 1019: + goto tr420 + case 1020: + goto tr420 + case 1021: + goto tr420 + case 1022: + goto tr420 + case 1023: + goto tr420 + case 1024: + goto tr420 + case 1025: + goto tr420 + case 1026: + goto tr420 + case 1027: + goto tr420 + case 1028: + goto tr420 + case 1029: + goto tr420 + case 1030: + goto tr420 + case 1031: + goto tr420 + case 1032: + goto tr420 + case 1033: + goto tr420 + case 1034: + goto tr420 + case 1035: + goto tr420 + case 1036: + goto tr420 + case 1037: + goto tr420 + case 1038: + goto tr420 + case 1039: + goto tr420 + case 1040: + goto tr420 + case 1041: + goto tr420 + case 1042: + goto tr420 + case 1043: + goto tr420 + case 1044: + goto tr420 + case 1045: + goto tr420 + case 1046: + goto tr420 + case 1047: + goto tr420 + case 1048: + goto tr420 + case 1049: + goto tr420 + case 1050: + goto tr420 + case 1051: + goto tr420 + case 1052: + goto tr420 + case 1053: + goto tr420 + case 1054: + goto tr420 + case 1055: + goto tr420 + case 1056: + goto tr420 + case 1057: + goto tr420 + case 1058: + goto tr420 + case 1059: + goto tr420 + case 1060: + goto tr420 + case 1061: + goto tr420 + case 1062: + goto tr420 + case 1063: + goto tr420 + case 1064: + goto tr420 + case 1065: + goto tr420 + case 1066: + goto tr420 + case 1067: + goto tr420 + case 1068: + goto tr420 + case 1069: + goto tr420 + case 1070: + goto tr420 + case 1071: + goto tr420 + case 1072: + goto tr420 + case 1073: + goto tr420 + case 1074: + goto tr420 + case 1075: + goto tr420 + case 1076: + goto tr420 + case 1077: + goto tr420 + case 1078: + goto tr420 + case 1079: + goto tr420 + case 1080: + goto tr420 + case 1081: + goto tr420 + case 1082: + goto tr420 + case 1083: + goto tr420 + case 1084: + goto tr420 + case 1085: + goto tr420 + case 1086: + goto tr420 + case 1087: + goto tr420 + case 1088: + goto tr420 + case 1089: + goto tr420 + case 4872: + goto tr4562 + case 1090: + goto tr420 + case 1091: + goto tr2 + case 1092: + goto tr420 + case 1093: + goto tr420 + case 1094: + goto tr420 + case 1095: + goto tr420 + case 1096: + goto tr420 + case 1097: + goto tr420 + case 1098: + goto tr420 + case 1099: + goto tr420 + case 1100: + goto tr420 + case 1101: + goto tr420 + case 1102: + goto tr420 + case 1103: + goto tr420 + case 1104: + goto tr420 + case 1105: + goto tr420 + case 1106: + goto tr420 + case 1107: + goto tr420 + case 1108: + goto tr420 + case 1109: + goto tr420 + case 1110: + goto tr420 + case 1111: + goto tr420 + case 1112: + goto tr420 + case 1113: + goto tr420 + case 1114: + goto tr420 + case 1115: + goto tr420 + case 1116: + goto tr420 + case 1117: + goto tr420 + case 1118: + goto tr420 + case 1119: + goto tr420 + case 1120: + goto tr420 + case 1121: + goto tr420 + case 1122: + goto tr420 + case 1123: + goto tr420 + case 1124: + goto tr420 + case 1125: + goto tr420 + case 1126: + goto tr420 + case 1127: + goto tr420 + case 1128: + goto tr420 + case 1129: + goto tr420 + case 1130: + goto tr420 + case 1131: + goto tr420 + case 1132: + goto tr420 + case 1133: + goto tr420 + case 1134: + goto tr420 + case 1135: + goto tr420 + case 1136: + goto tr420 + case 1137: + goto tr420 + case 1138: + goto tr420 + case 1139: + goto tr420 + case 1140: + goto tr420 + case 1141: + goto tr420 + case 1142: + goto tr420 + case 1143: + goto tr420 + case 1144: + goto tr420 + case 1145: + goto tr420 + case 1146: + goto tr420 + case 1147: + goto tr420 + case 1148: + goto tr420 + case 1149: + goto tr420 + case 1150: + goto tr420 + case 1151: + goto tr420 + case 1152: + goto tr420 + case 1153: + goto tr420 + case 1154: + goto tr420 + case 1155: + goto tr420 + case 1156: + goto tr420 + case 1157: + goto tr420 + case 1158: + goto tr420 + case 1159: + goto tr420 + case 1160: + goto tr420 + case 1161: + goto tr420 + case 1162: + goto tr420 + case 1163: + goto tr420 + case 1164: + goto tr2 + case 1165: + goto tr2 + case 1166: + goto tr2 + case 1167: + goto tr2 + case 1168: + goto tr420 + case 1169: + goto tr420 + case 1170: + goto tr420 + case 1171: + goto tr420 + case 1172: + goto tr420 + case 1173: + goto tr420 + case 1174: + goto tr420 + case 1175: + goto tr420 + case 1176: + goto tr420 + case 1177: + goto tr420 + case 1178: + goto tr420 + case 1179: + goto tr420 + case 1180: + goto tr420 + case 1181: + goto tr420 + case 1182: + goto tr420 + case 1183: + goto tr420 + case 1184: + goto tr420 + case 1185: + goto tr420 + case 1186: + goto tr420 + case 1187: + goto tr2 + case 1188: + goto tr2 + case 1189: + goto tr420 + case 1190: + goto tr420 + case 1191: + goto tr420 + case 1192: + goto tr420 + case 1193: + goto tr420 + case 1194: + goto tr420 + case 1195: + goto tr420 + case 1196: + goto tr420 + case 1197: + goto tr420 + case 1198: + goto tr420 + case 1199: + goto tr420 + case 1200: + goto tr420 + case 1201: + goto tr420 + case 1202: + goto tr420 + case 1203: + goto tr420 + case 1204: + goto tr420 + case 1205: + goto tr420 + case 1206: + goto tr420 + case 1207: + goto tr420 + case 1208: + goto tr420 + case 1209: + goto tr420 + case 1210: + goto tr420 + case 1211: + goto tr420 + case 1212: + goto tr420 + case 1213: + goto tr420 + case 1214: + goto tr420 + case 1215: + goto tr420 + case 1216: + goto tr420 + case 1217: + goto tr420 + case 1218: + goto tr420 + case 1219: + goto tr420 + case 1220: + goto tr420 + case 1221: + goto tr420 + case 1222: + goto tr420 + case 1223: + goto tr420 + case 1224: + goto tr2 + case 1225: + goto tr420 + case 1226: + goto tr420 + case 1227: + goto tr420 + case 1228: + goto tr420 + case 1229: + goto tr420 + case 1230: + goto tr420 + case 1231: + goto tr420 + case 1232: + goto tr420 + case 1233: + goto tr420 + case 1234: + goto tr420 + case 1235: + goto tr420 + case 1236: + goto tr420 + case 1237: + goto tr420 + case 1238: + goto tr420 + case 1239: + goto tr420 + case 1240: + goto tr420 + case 1241: + goto tr420 + case 1242: + goto tr420 + case 1243: + goto tr420 + case 1244: + goto tr420 + case 1245: + goto tr420 + case 1246: + goto tr420 + case 1247: + goto tr420 + case 1248: + goto tr420 + case 1249: + goto tr420 + case 1250: + goto tr420 + case 1251: + goto tr420 + case 1252: + goto tr420 + case 1253: + goto tr420 + case 1254: + goto tr420 + case 1255: + goto tr420 + case 1256: + goto tr420 + case 1257: + goto tr420 + case 1258: + goto tr420 + case 1259: + goto tr420 + case 1260: + goto tr420 + case 1261: + goto tr2 + case 1262: + goto tr420 + case 1263: + goto tr420 + case 1264: + goto tr420 + case 1265: + goto tr420 + case 1266: + goto tr420 + case 1267: + goto tr420 + case 1268: + goto tr420 + case 1269: + goto tr420 + case 1270: + goto tr420 + case 1271: + goto tr420 + case 1272: + goto tr420 + case 1273: + goto tr420 + case 1274: + goto tr420 + case 1275: + goto tr420 + case 1276: + goto tr420 + case 1277: + goto tr420 + case 1278: + goto tr420 + case 1279: + goto tr420 + case 1280: + goto tr420 + case 1281: + goto tr420 + case 1282: + goto tr420 + case 1283: + goto tr420 + case 1284: + goto tr420 + case 1285: + goto tr420 + case 1286: + goto tr420 + case 1287: + goto tr420 + case 1288: + goto tr420 + case 1289: + goto tr420 + case 1290: + goto tr420 + case 1291: + goto tr420 + case 1292: + goto tr420 + case 1293: + goto tr420 + case 1294: + goto tr420 + case 1295: + goto tr420 + case 1296: + goto tr420 + case 1297: + goto tr420 + case 1298: + goto tr420 + case 1299: + goto tr420 + case 1300: + goto tr420 + case 1301: + goto tr420 + case 1302: + goto tr420 + case 1303: + goto tr420 + case 1304: + goto tr420 + case 1305: + goto tr420 + case 1306: + goto tr420 + case 1307: + goto tr420 + case 1308: + goto tr420 + case 1309: + goto tr420 + case 1310: + goto tr420 + case 1311: + goto tr420 + case 1312: + goto tr420 + case 1313: + goto tr420 + case 1314: + goto tr420 + case 1315: + goto tr420 + case 1316: + goto tr420 + case 1317: + goto tr420 + case 1318: + goto tr420 + case 1319: + goto tr420 + case 1320: + goto tr420 + case 1321: + goto tr420 + case 1322: + goto tr420 + case 1323: + goto tr420 + case 1324: + goto tr420 + case 1325: + goto tr420 + case 1326: + goto tr420 + case 1327: + goto tr420 + case 1328: + goto tr420 + case 1329: + goto tr420 + case 1330: + goto tr420 + case 1331: + goto tr420 + case 1332: + goto tr420 + case 1333: + goto tr420 + case 1334: + goto tr420 + case 1335: + goto tr420 + case 1336: + goto tr420 + case 1337: + goto tr420 + case 1338: + goto tr420 + case 1339: + goto tr420 + case 1340: + goto tr420 + case 1341: + goto tr420 + case 1342: + goto tr420 + case 1343: + goto tr420 + case 1344: + goto tr420 + case 1345: + goto tr420 + case 1346: + goto tr420 + case 1347: + goto tr420 + case 1348: + goto tr420 + case 1349: + goto tr420 + case 1350: + goto tr420 + case 1351: + goto tr420 + case 1352: + goto tr420 + case 1353: + goto tr420 + case 1354: + goto tr420 + case 1355: + goto tr420 + case 1356: + goto tr420 + case 1357: + goto tr420 + case 1358: + goto tr420 + case 1359: + goto tr420 + case 1360: + goto tr420 + case 1361: + goto tr420 + case 1362: + goto tr420 + case 1363: + goto tr420 + case 1364: + goto tr420 + case 1365: + goto tr420 + case 1366: + goto tr420 + case 1367: + goto tr420 + case 1368: + goto tr420 + case 1369: + goto tr420 + case 1370: + goto tr420 + case 1371: + goto tr420 + case 1372: + goto tr420 + case 1373: + goto tr420 + case 1374: + goto tr420 + case 1375: + goto tr420 + case 1376: + goto tr420 + case 1377: + goto tr420 + case 1378: + goto tr420 + case 1379: + goto tr420 + case 1380: + goto tr420 + case 1381: + goto tr420 + case 1382: + goto tr420 + case 1383: + goto tr420 + case 1384: + goto tr420 + case 1385: + goto tr420 + case 1386: + goto tr420 + case 1387: + goto tr420 + case 1388: + goto tr420 + case 1389: + goto tr420 + case 1390: + goto tr420 + case 1391: + goto tr420 + case 1392: + goto tr420 + case 1393: + goto tr420 + case 1394: + goto tr420 + case 1395: + goto tr420 + case 1396: + goto tr420 + case 1397: + goto tr420 + case 1398: + goto tr420 + case 1399: + goto tr420 + case 1400: + goto tr420 + case 1401: + goto tr420 + case 1402: + goto tr420 + case 1403: + goto tr420 + case 1404: + goto tr420 + case 1405: + goto tr420 + case 1406: + goto tr420 + case 1407: + goto tr420 + case 1408: + goto tr420 + case 1409: + goto tr420 + case 1410: + goto tr420 + case 1411: + goto tr420 + case 1412: + goto tr420 + case 1413: + goto tr420 + case 1414: + goto tr420 + case 1415: + goto tr420 + case 1416: + goto tr420 + case 1417: + goto tr420 + case 1418: + goto tr420 + case 1419: + goto tr420 + case 1420: + goto tr420 + case 1421: + goto tr420 + case 1422: + goto tr420 + case 1423: + goto tr420 + case 1424: + goto tr420 + case 1425: + goto tr420 + case 1426: + goto tr420 + case 1427: + goto tr420 + case 1428: + goto tr420 + case 1429: + goto tr420 + case 1430: + goto tr420 + case 1431: + goto tr420 + case 1432: + goto tr420 + case 1433: + goto tr420 + case 1434: + goto tr420 + case 1435: + goto tr420 + case 1436: + goto tr420 + case 1437: + goto tr420 + case 1438: + goto tr420 + case 1439: + goto tr420 + case 1440: + goto tr420 + case 1441: + goto tr420 + case 1442: + goto tr420 + case 1443: + goto tr420 + case 1444: + goto tr420 + case 1445: + goto tr420 + case 1446: + goto tr420 + case 1447: + goto tr420 + case 1448: + goto tr420 + case 1449: + goto tr420 + case 1450: + goto tr420 + case 1451: + goto tr420 + case 1452: + goto tr420 + case 1453: + goto tr420 + case 1454: + goto tr420 + case 1455: + goto tr420 + case 1456: + goto tr420 + case 1457: + goto tr420 + case 1458: + goto tr420 + case 1459: + goto tr420 + case 1460: + goto tr420 + case 1461: + goto tr420 + case 1462: + goto tr420 + case 1463: + goto tr420 + case 1464: + goto tr420 + case 1465: + goto tr420 + case 1466: + goto tr420 + case 1467: + goto tr420 + case 1468: + goto tr420 + case 1469: + goto tr420 + case 1470: + goto tr420 + case 1471: + goto tr420 + case 1472: + goto tr420 + case 1473: + goto tr2 + case 1474: + goto tr2 + case 1475: + goto tr2 + case 1476: + goto tr2 + case 1477: + goto tr2 + case 1478: + goto tr2 + case 1479: + goto tr2 + case 1480: + goto tr2 + case 1481: + goto tr2 + case 1482: + goto tr2 + case 1483: + goto tr2 + case 1484: + goto tr2 + case 1485: + goto tr2 + case 1486: + goto tr2 + case 1487: + goto tr2 + case 1488: + goto tr2 + case 1489: + goto tr2 + case 1490: + goto tr2 + case 1491: + goto tr2 + case 1492: + goto tr2 + case 1493: + goto tr2 + case 1494: + goto tr2 + case 1495: + goto tr2 + case 1496: + goto tr2 + case 1497: + goto tr2 + case 1498: + goto tr2 + case 1499: + goto tr2 + case 1500: + goto tr2 + case 1501: + goto tr2 + case 1502: + goto tr2 + case 1503: + goto tr420 + case 1504: + goto tr2 + case 1505: + goto tr2 + case 1506: + goto tr2 + case 1507: + goto tr2 + case 1508: + goto tr2 + case 1509: + goto tr2 + case 1510: + goto tr2 + case 1511: + goto tr2 + case 1512: + goto tr2 + case 1513: + goto tr2 + case 1514: + goto tr2 + case 1515: + goto tr2 + case 1516: + goto tr2 + case 1517: + goto tr2 + case 1518: + goto tr2 + case 1519: + goto tr2 + case 1520: + goto tr2 + case 1521: + goto tr2 + case 1522: + goto tr2 + case 1523: + goto tr420 + case 1524: + goto tr2 + case 1525: + goto tr2 + case 1526: + goto tr2 + case 1527: + goto tr2 + case 1528: + goto tr2 + case 1529: + goto tr2 + case 1530: + goto tr420 + case 1531: + goto tr2 + case 1532: + goto tr2 + case 1533: + goto tr420 + case 1534: + goto tr2 + case 1535: + goto tr2 + case 1536: + goto tr2 + case 1537: + goto tr2 + case 1538: + goto tr2 + case 1539: + goto tr2 + case 1540: + goto tr2 + case 1541: + goto tr2 + case 1542: + goto tr2 + case 1543: + goto tr2 + case 1544: + goto tr2 + case 1545: + goto tr420 + case 1546: + goto tr2 + case 1547: + goto tr2 + case 1548: + goto tr2 + case 1549: + goto tr2 + case 1550: + goto tr2 + case 1551: + goto tr420 + case 1552: + goto tr2 + case 1553: + goto tr2 + case 1554: + goto tr2 + case 1555: + goto tr2 + case 1556: + goto tr2 + case 1557: + goto tr2 + case 1558: + goto tr2 + case 1559: + goto tr2 + case 1560: + goto tr2 + case 1561: + goto tr2 + case 1562: + goto tr2 + case 1563: + goto tr2 + case 1564: + goto tr2 + case 1565: + goto tr2 + case 1566: + goto tr2 + case 1567: + goto tr2 + case 1568: + goto tr2 + case 1569: + goto tr2 + case 1570: + goto tr2 + case 1571: + goto tr2 + case 1572: + goto tr2 + case 1573: + goto tr2 + case 1574: + goto tr2 + case 1575: + goto tr2 + case 1576: + goto tr2 + case 1577: + goto tr2 + case 1578: + goto tr2 + case 1579: + goto tr2 + case 1580: + goto tr2 + case 1581: + goto tr2 + case 1582: + goto tr2 + case 1583: + goto tr2 + case 1584: + goto tr2 + case 1585: + goto tr2 + case 1586: + goto tr2 + case 1587: + goto tr2 + case 1588: + goto tr420 + case 1589: + goto tr2 + case 1590: + goto tr2 + case 1591: + goto tr2 + case 4873: + goto tr4521 + case 1592: + goto tr125 + case 1593: + goto tr125 + case 1594: + goto tr125 + case 1595: + goto tr125 + case 1596: + goto tr125 + case 1597: + goto tr125 + case 1598: + goto tr125 + case 1599: + goto tr125 + case 1600: + goto tr125 + case 1601: + goto tr125 + case 1602: + goto tr125 + case 1603: + goto tr125 + case 1604: + goto tr125 + case 1605: + goto tr125 + case 1606: + goto tr125 + case 1607: + goto tr125 + case 1608: + goto tr125 + case 1609: + goto tr125 + case 1610: + goto tr125 + case 1611: + goto tr125 + case 1612: + goto tr125 + case 1613: + goto tr125 + case 1614: + goto tr125 + case 1615: + goto tr125 + case 1616: + goto tr125 + case 1617: + goto tr125 + case 1618: + goto tr125 + case 1619: + goto tr125 + case 1620: + goto tr125 + case 1621: + goto tr125 + case 1622: + goto tr125 + case 1623: + goto tr125 + case 1624: + goto tr125 + case 1625: + goto tr125 + case 1626: + goto tr125 + case 1627: + goto tr125 + case 1628: + goto tr125 + case 1629: + goto tr125 + case 1630: + goto tr125 + case 1631: + goto tr125 + case 1632: + goto tr125 + case 1633: + goto tr125 + case 1634: + goto tr125 + case 1635: + goto tr125 + case 1636: + goto tr125 + case 1637: + goto tr125 + case 1638: + goto tr125 + case 1639: + goto tr125 + case 1640: + goto tr125 + case 1641: + goto tr125 + case 1642: + goto tr125 + case 1643: + goto tr125 + case 1644: + goto tr125 + case 1645: + goto tr125 + case 1646: + goto tr125 + case 1647: + goto tr125 + case 1648: + goto tr125 + case 1649: + goto tr2 + case 1650: + goto tr2 + case 1651: + goto tr125 + case 1652: + goto tr125 + case 1653: + goto tr125 + case 1654: + goto tr125 + case 1655: + goto tr125 + case 1656: + goto tr125 + case 1657: + goto tr125 + case 1658: + goto tr125 + case 1659: + goto tr2 + case 1660: + goto tr125 + case 1661: + goto tr125 + case 1662: + goto tr125 + case 1663: + goto tr125 + case 1664: + goto tr125 + case 1665: + goto tr125 + case 1666: + goto tr125 + case 1667: + goto tr125 + case 1668: + goto tr125 + case 1669: + goto tr125 + case 1670: + goto tr125 + case 1671: + goto tr125 + case 1672: + goto tr125 + case 1673: + goto tr2 + case 1674: + goto tr125 + case 1675: + goto tr125 + case 1676: + goto tr125 + case 1677: + goto tr125 + case 1678: + goto tr125 + case 1679: + goto tr125 + case 1680: + goto tr125 + case 1681: + goto tr125 + case 1682: + goto tr125 + case 1683: + goto tr125 + case 1684: + goto tr125 + case 1685: + goto tr125 + case 1686: + goto tr125 + case 1687: + goto tr125 + case 1688: + goto tr125 + case 1689: + goto tr125 + case 1690: + goto tr125 + case 1691: + goto tr125 + case 1692: + goto tr125 + case 1693: + goto tr125 + case 1694: + goto tr125 + case 1695: + goto tr125 + case 1696: + goto tr125 + case 1697: + goto tr125 + case 1698: + goto tr125 + case 1699: + goto tr125 + case 1700: + goto tr125 + case 1701: + goto tr125 + case 1702: + goto tr2 + case 1703: + goto tr125 + case 1704: + goto tr125 + case 1705: + goto tr125 + case 1706: + goto tr125 + case 1707: + goto tr125 + case 1708: + goto tr125 + case 1709: + goto tr2 + case 1710: + goto tr125 + case 1711: + goto tr125 + case 1712: + goto tr125 + case 1713: + goto tr125 + case 1714: + goto tr125 + case 1715: + goto tr125 + case 1716: + goto tr125 + case 1717: + goto tr125 + case 1718: + goto tr125 + case 1719: + goto tr125 + case 1720: + goto tr125 + case 1721: + goto tr125 + case 1722: + goto tr125 + case 1723: + goto tr125 + case 1724: + goto tr2 + case 1725: + goto tr125 + case 1726: + goto tr2 + case 1727: + goto tr125 + case 1728: + goto tr2 + case 1729: + goto tr125 + case 1730: + goto tr125 + case 1731: + goto tr2 + case 1732: + goto tr125 + case 1733: + goto tr125 + case 1734: + goto tr125 + case 1735: + goto tr125 + case 1736: + goto tr125 + case 1737: + goto tr125 + case 1738: + goto tr125 + case 1739: + goto tr125 + case 1740: + goto tr2 + case 1741: + goto tr125 + case 1742: + goto tr125 + case 1743: + goto tr125 + case 1744: + goto tr125 + case 1745: + goto tr125 + case 1746: + goto tr125 + case 1747: + goto tr125 + case 1748: + goto tr125 + case 1749: + goto tr125 + case 1750: + goto tr125 + case 1751: + goto tr125 + case 1752: + goto tr125 + case 1753: + goto tr125 + case 1754: + goto tr125 + case 1755: + goto tr125 + case 1756: + goto tr125 + case 1757: + goto tr125 + case 1758: + goto tr125 + case 1759: + goto tr125 + case 1760: + goto tr125 + case 1761: + goto tr125 + case 1762: + goto tr125 + case 1763: + goto tr125 + case 1764: + goto tr125 + case 1765: + goto tr125 + case 1766: + goto tr125 + case 1767: + goto tr125 + case 1768: + goto tr125 + case 1769: + goto tr125 + case 1770: + goto tr125 + case 1771: + goto tr125 + case 1772: + goto tr125 + case 1773: + goto tr125 + case 1774: + goto tr125 + case 1775: + goto tr125 + case 1776: + goto tr125 + case 1777: + goto tr125 + case 1778: + goto tr125 + case 1779: + goto tr125 + case 1780: + goto tr125 + case 1781: + goto tr125 + case 1782: + goto tr125 + case 1783: + goto tr125 + case 1784: + goto tr125 + case 1785: + goto tr125 + case 1786: + goto tr125 + case 1787: + goto tr125 + case 1788: + goto tr125 + case 1789: + goto tr125 + case 1790: + goto tr125 + case 1791: + goto tr125 + case 1792: + goto tr125 + case 1793: + goto tr125 + case 1794: + goto tr125 + case 1795: + goto tr125 + case 1796: + goto tr125 + case 1797: + goto tr125 + case 1798: + goto tr125 + case 1799: + goto tr125 + case 1800: + goto tr125 + case 1801: + goto tr125 + case 1802: + goto tr125 + case 1803: + goto tr125 + case 1804: + goto tr125 + case 1805: + goto tr125 + case 1806: + goto tr125 + case 1807: + goto tr125 + case 1808: + goto tr125 + case 1809: + goto tr125 + case 1810: + goto tr125 + case 1811: + goto tr125 + case 1812: + goto tr125 + case 1813: + goto tr125 + case 1814: + goto tr125 + case 1815: + goto tr125 + case 1816: + goto tr125 + case 1817: + goto tr125 + case 1818: + goto tr125 + case 1819: + goto tr125 + case 1820: + goto tr125 + case 1821: + goto tr125 + case 1822: + goto tr125 + case 1823: + goto tr125 + case 1824: + goto tr125 + case 1825: + goto tr125 + case 1826: + goto tr125 + case 1827: + goto tr125 + case 1828: + goto tr125 + case 1829: + goto tr125 + case 1830: + goto tr125 + case 1831: + goto tr125 + case 1832: + goto tr125 + case 1833: + goto tr125 + case 1834: + goto tr125 + case 1835: + goto tr125 + case 1836: + goto tr125 + case 1837: + goto tr125 + case 1838: + goto tr125 + case 1839: + goto tr125 + case 1840: + goto tr125 + case 1841: + goto tr125 + case 1842: + goto tr125 + case 1843: + goto tr125 + case 1844: + goto tr125 + case 1845: + goto tr125 + case 1846: + goto tr125 + case 1847: + goto tr125 + case 1848: + goto tr125 + case 1849: + goto tr125 + case 1850: + goto tr125 + case 1851: + goto tr125 + case 1852: + goto tr125 + case 1853: + goto tr125 + case 1854: + goto tr125 + case 1855: + goto tr125 + case 1856: + goto tr125 + case 1857: + goto tr125 + case 1858: + goto tr125 + case 1859: + goto tr125 + case 1860: + goto tr125 + case 1861: + goto tr125 + case 1862: + goto tr125 + case 1863: + goto tr125 + case 1864: + goto tr125 + case 1865: + goto tr125 + case 1866: + goto tr125 + case 1867: + goto tr125 + case 1868: + goto tr125 + case 1869: + goto tr125 + case 1870: + goto tr125 + case 1871: + goto tr125 + case 1872: + goto tr125 + case 1873: + goto tr125 + case 1874: + goto tr125 + case 1875: + goto tr125 + case 1876: + goto tr125 + case 1877: + goto tr125 + case 1878: + goto tr125 + case 1879: + goto tr125 + case 1880: + goto tr125 + case 1881: + goto tr125 + case 1882: + goto tr125 + case 1883: + goto tr125 + case 1884: + goto tr125 + case 1885: + goto tr125 + case 1886: + goto tr125 + case 1887: + goto tr125 + case 1888: + goto tr125 + case 1889: + goto tr125 + case 1890: + goto tr125 + case 1891: + goto tr125 + case 1892: + goto tr125 + case 1893: + goto tr125 + case 1894: + goto tr125 + case 1895: + goto tr125 + case 1896: + goto tr125 + case 1897: + goto tr125 + case 1898: + goto tr125 + case 1899: + goto tr125 + case 1900: + goto tr125 + case 1901: + goto tr125 + case 1902: + goto tr125 + case 1903: + goto tr125 + case 1904: + goto tr125 + case 1905: + goto tr125 + case 1906: + goto tr125 + case 1907: + goto tr125 + case 1908: + goto tr125 + case 1909: + goto tr125 + case 1910: + goto tr125 + case 1911: + goto tr125 + case 1912: + goto tr125 + case 1913: + goto tr125 + case 1914: + goto tr125 + case 1915: + goto tr125 + case 1916: + goto tr125 + case 1917: + goto tr125 + case 1918: + goto tr125 + case 1919: + goto tr125 + case 1920: + goto tr125 + case 1921: + goto tr125 + case 1922: + goto tr125 + case 1923: + goto tr125 + case 1924: + goto tr125 + case 1925: + goto tr125 + case 1926: + goto tr125 + case 1927: + goto tr125 + case 1928: + goto tr125 + case 1929: + goto tr125 + case 1930: + goto tr125 + case 1931: + goto tr125 + case 1932: + goto tr125 + case 1933: + goto tr125 + case 1934: + goto tr125 + case 1935: + goto tr125 + case 1936: + goto tr125 + case 1937: + goto tr125 + case 1938: + goto tr125 + case 1939: + goto tr125 + case 1940: + goto tr125 + case 1941: + goto tr125 + case 1942: + goto tr125 + case 1943: + goto tr125 + case 1944: + goto tr125 + case 1945: + goto tr125 + case 1946: + goto tr125 + case 1947: + goto tr125 + case 1948: + goto tr125 + case 1949: + goto tr125 + case 1950: + goto tr125 + case 1951: + goto tr125 + case 1952: + goto tr125 + case 1953: + goto tr125 + case 1954: + goto tr125 + case 1955: + goto tr125 + case 1956: + goto tr125 + case 1957: + goto tr125 + case 1958: + goto tr125 + case 1959: + goto tr125 + case 1960: + goto tr125 + case 1961: + goto tr125 + case 1962: + goto tr125 + case 1963: + goto tr125 + case 1964: + goto tr125 + case 1965: + goto tr125 + case 1966: + goto tr125 + case 1967: + goto tr125 + case 1968: + goto tr125 + case 1969: + goto tr125 + case 1970: + goto tr125 + case 1971: + goto tr125 + case 1972: + goto tr125 + case 1973: + goto tr125 + case 1974: + goto tr125 + case 1975: + goto tr125 + case 1976: + goto tr125 + case 1977: + goto tr125 + case 1978: + goto tr125 + case 1979: + goto tr125 + case 1980: + goto tr125 + case 1981: + goto tr125 + case 1982: + goto tr125 + case 1983: + goto tr125 + case 1984: + goto tr125 + case 1985: + goto tr125 + case 1986: + goto tr125 + case 1987: + goto tr125 + case 1988: + goto tr125 + case 1989: + goto tr125 + case 1990: + goto tr125 + case 1991: + goto tr125 + case 1992: + goto tr125 + case 1993: + goto tr125 + case 1994: + goto tr125 + case 1995: + goto tr125 + case 1996: + goto tr125 + case 1997: + goto tr125 + case 1998: + goto tr125 + case 1999: + goto tr125 + case 2000: + goto tr125 + case 2001: + goto tr125 + case 2002: + goto tr125 + case 2003: + goto tr125 + case 2004: + goto tr125 + case 2005: + goto tr125 + case 2006: + goto tr125 + case 2007: + goto tr125 + case 2008: + goto tr125 + case 2009: + goto tr125 + case 2010: + goto tr125 + case 2011: + goto tr125 + case 2012: + goto tr125 + case 2013: + goto tr125 + case 2014: + goto tr125 + case 2015: + goto tr125 + case 2016: + goto tr125 + case 2017: + goto tr125 + case 2018: + goto tr125 + case 2019: + goto tr125 + case 2020: + goto tr125 + case 2021: + goto tr125 + case 2022: + goto tr125 + case 2023: + goto tr125 + case 2024: + goto tr125 + case 2025: + goto tr125 + case 2026: + goto tr125 + case 2027: + goto tr125 + case 2028: + goto tr125 + case 2029: + goto tr125 + case 2030: + goto tr125 + case 2031: + goto tr125 + case 2032: + goto tr125 + case 2033: + goto tr125 + case 2034: + goto tr125 + case 2035: + goto tr125 + case 2036: + goto tr125 + case 2037: + goto tr125 + case 2038: + goto tr125 + case 2039: + goto tr125 + case 2040: + goto tr125 + case 2041: + goto tr125 + case 2042: + goto tr125 + case 2043: + goto tr125 + case 2044: + goto tr125 + case 2045: + goto tr125 + case 2046: + goto tr125 + case 2047: + goto tr125 + case 2048: + goto tr125 + case 2049: + goto tr125 + case 2050: + goto tr125 + case 2051: + goto tr125 + case 2052: + goto tr125 + case 2053: + goto tr125 + case 2054: + goto tr125 + case 2055: + goto tr125 + case 2056: + goto tr125 + case 2057: + goto tr125 + case 2058: + goto tr125 + case 2059: + goto tr125 + case 2060: + goto tr125 + case 2061: + goto tr125 + case 2062: + goto tr125 + case 2063: + goto tr125 + case 2064: + goto tr125 + case 2065: + goto tr125 + case 2066: + goto tr125 + case 2067: + goto tr125 + case 2068: + goto tr125 + case 2069: + goto tr125 + case 2070: + goto tr125 + case 2071: + goto tr125 + case 2072: + goto tr125 + case 2073: + goto tr125 + case 2074: + goto tr125 + case 2075: + goto tr125 + case 2076: + goto tr125 + case 2077: + goto tr125 + case 2078: + goto tr125 + case 2079: + goto tr125 + case 2080: + goto tr125 + case 2081: + goto tr125 + case 2082: + goto tr125 + case 2083: + goto tr125 + case 2084: + goto tr125 + case 2085: + goto tr125 + case 2086: + goto tr125 + case 2087: + goto tr125 + case 2088: + goto tr125 + case 2089: + goto tr125 + case 2090: + goto tr125 + case 2091: + goto tr125 + case 2092: + goto tr125 + case 2093: + goto tr125 + case 2094: + goto tr125 + case 2095: + goto tr125 + case 2096: + goto tr125 + case 2097: + goto tr125 + case 2098: + goto tr125 + case 2099: + goto tr125 + case 2100: + goto tr125 + case 2101: + goto tr125 + case 2102: + goto tr125 + case 2103: + goto tr125 + case 2104: + goto tr125 + case 2105: + goto tr125 + case 2106: + goto tr125 + case 2107: + goto tr125 + case 2108: + goto tr125 + case 2109: + goto tr125 + case 2110: + goto tr125 + case 2111: + goto tr125 + case 2112: + goto tr125 + case 2113: + goto tr125 + case 2114: + goto tr125 + case 2115: + goto tr125 + case 2116: + goto tr125 + case 2117: + goto tr125 + case 2118: + goto tr125 + case 2119: + goto tr125 + case 2120: + goto tr125 + case 2121: + goto tr125 + case 2122: + goto tr125 + case 2123: + goto tr125 + case 2124: + goto tr125 + case 2125: + goto tr125 + case 2126: + goto tr125 + case 2127: + goto tr125 + case 2128: + goto tr125 + case 2129: + goto tr125 + case 2130: + goto tr125 + case 2131: + goto tr125 + case 2132: + goto tr125 + case 2133: + goto tr125 + case 2134: + goto tr125 + case 2135: + goto tr125 + case 2136: + goto tr125 + case 2137: + goto tr125 + case 2138: + goto tr125 + case 2139: + goto tr125 + case 2140: + goto tr125 + case 2141: + goto tr125 + case 2142: + goto tr125 + case 2143: + goto tr125 + case 2144: + goto tr125 + case 2145: + goto tr125 + case 2146: + goto tr125 + case 2147: + goto tr125 + case 2148: + goto tr125 + case 2149: + goto tr125 + case 2150: + goto tr125 + case 2151: + goto tr125 + case 2152: + goto tr125 + case 2153: + goto tr125 + case 2154: + goto tr125 + case 2155: + goto tr125 + case 2156: + goto tr125 + case 2157: + goto tr125 + case 2158: + goto tr125 + case 2159: + goto tr125 + case 2160: + goto tr125 + case 2161: + goto tr125 + case 2162: + goto tr125 + case 2163: + goto tr125 + case 2164: + goto tr125 + case 2165: + goto tr125 + case 2166: + goto tr125 + case 2167: + goto tr125 + case 2168: + goto tr125 + case 2169: + goto tr125 + case 2170: + goto tr125 + case 2171: + goto tr125 + case 2172: + goto tr125 + case 2173: + goto tr125 + case 2174: + goto tr125 + case 2175: + goto tr125 + case 2176: + goto tr125 + case 2177: + goto tr125 + case 2178: + goto tr125 + case 2179: + goto tr125 + case 2180: + goto tr125 + case 2181: + goto tr125 + case 2182: + goto tr125 + case 2183: + goto tr125 + case 2184: + goto tr125 + case 2185: + goto tr125 + case 2186: + goto tr125 + case 2187: + goto tr125 + case 2188: + goto tr125 + case 2189: + goto tr125 + case 2190: + goto tr125 + case 2191: + goto tr125 + case 2192: + goto tr125 + case 4874: + goto tr4562 + case 2193: + goto tr420 + case 2194: + goto tr420 + case 2195: + goto tr420 + case 2196: + goto tr420 + case 2197: + goto tr420 + case 2198: + goto tr420 + case 2199: + goto tr420 + case 2200: + goto tr420 + case 2201: + goto tr420 + case 2202: + goto tr420 + case 2203: + goto tr420 + case 2204: + goto tr420 + case 2205: + goto tr420 + case 2206: + goto tr420 + case 2207: + goto tr420 + case 2208: + goto tr420 + case 2209: + goto tr420 + case 2210: + goto tr420 + case 2211: + goto tr420 + case 2212: + goto tr420 + case 2213: + goto tr420 + case 2214: + goto tr420 + case 2215: + goto tr420 + case 2216: + goto tr420 + case 2217: + goto tr420 + case 2218: + goto tr420 + case 2219: + goto tr420 + case 2220: + goto tr420 + case 2221: + goto tr420 + case 2222: + goto tr420 + case 2223: + goto tr420 + case 2224: + goto tr420 + case 2225: + goto tr420 + case 2226: + goto tr420 + case 2227: + goto tr420 + case 2228: + goto tr420 + case 2229: + goto tr420 + case 2230: + goto tr420 + case 2231: + goto tr420 + case 2232: + goto tr420 + case 2233: + goto tr420 + case 2234: + goto tr420 + case 2235: + goto tr420 + case 2236: + goto tr420 + case 2237: + goto tr420 + case 2238: + goto tr420 + case 2239: + goto tr420 + case 2240: + goto tr420 + case 2241: + goto tr420 + case 2242: + goto tr420 + case 2243: + goto tr420 + case 2244: + goto tr420 + case 2245: + goto tr420 + case 2246: + goto tr420 + case 2247: + goto tr420 + case 2248: + goto tr420 + case 2249: + goto tr420 + case 2250: + goto tr420 + case 2251: + goto tr420 + case 2252: + goto tr420 + case 2253: + goto tr420 + case 2254: + goto tr420 + case 2255: + goto tr420 + case 2256: + goto tr420 + case 2257: + goto tr420 + case 2258: + goto tr420 + case 2259: + goto tr420 + case 2260: + goto tr420 + case 2261: + goto tr420 + case 2262: + goto tr420 + case 2263: + goto tr420 + case 2264: + goto tr420 + case 2265: + goto tr420 + case 2266: + goto tr420 + case 2267: + goto tr420 + case 2268: + goto tr420 + case 2269: + goto tr420 + case 2270: + goto tr420 + case 2271: + goto tr420 + case 2272: + goto tr420 + case 2273: + goto tr420 + case 2274: + goto tr420 + case 2275: + goto tr420 + case 2276: + goto tr420 + case 2277: + goto tr420 + case 2278: + goto tr420 + case 2279: + goto tr420 + case 2280: + goto tr420 + case 2281: + goto tr420 + case 2282: + goto tr420 + case 2283: + goto tr420 + case 2284: + goto tr420 + case 2285: + goto tr420 + case 2286: + goto tr420 + case 2287: + goto tr420 + case 2288: + goto tr420 + case 2289: + goto tr420 + case 2290: + goto tr420 + case 2291: + goto tr420 + case 2292: + goto tr420 + case 2293: + goto tr420 + case 2294: + goto tr420 + case 2295: + goto tr420 + case 2296: + goto tr420 + case 2297: + goto tr420 + case 2298: + goto tr420 + case 2299: + goto tr420 + case 2300: + goto tr420 + case 2301: + goto tr420 + case 2302: + goto tr420 + case 2303: + goto tr420 + case 2304: + goto tr420 + case 2305: + goto tr420 + case 2306: + goto tr420 + case 2307: + goto tr420 + case 2308: + goto tr420 + case 2309: + goto tr420 + case 2310: + goto tr420 + case 2311: + goto tr420 + case 2312: + goto tr420 + case 2313: + goto tr420 + case 2314: + goto tr420 + case 2315: + goto tr420 + case 2316: + goto tr420 + case 2317: + goto tr420 + case 2318: + goto tr420 + case 2319: + goto tr420 + case 2320: + goto tr420 + case 2321: + goto tr420 + case 2322: + goto tr420 + case 2323: + goto tr420 + case 2324: + goto tr420 + case 2325: + goto tr420 + case 2326: + goto tr420 + case 2327: + goto tr420 + case 2328: + goto tr420 + case 2329: + goto tr420 + case 2330: + goto tr420 + case 2331: + goto tr420 + case 2332: + goto tr420 + case 2333: + goto tr420 + case 2334: + goto tr420 + case 2335: + goto tr420 + case 2336: + goto tr420 + case 2337: + goto tr420 + case 2338: + goto tr420 + case 2339: + goto tr420 + case 4875: + goto tr4562 + case 4876: + goto tr4562 + case 2340: + goto tr420 + case 2341: + goto tr420 + case 2342: + goto tr420 + case 2343: + goto tr420 + case 2344: + goto tr420 + case 2345: + goto tr420 + case 2346: + goto tr420 + case 2347: + goto tr420 + case 2348: + goto tr420 + case 2349: + goto tr420 + case 2350: + goto tr420 + case 2351: + goto tr420 + case 2352: + goto tr420 + case 2353: + goto tr420 + case 2354: + goto tr420 + case 2355: + goto tr420 + case 2356: + goto tr420 + case 2357: + goto tr420 + case 2358: + goto tr420 + case 2359: + goto tr420 + case 2360: + goto tr420 + case 2361: + goto tr420 + case 2362: + goto tr420 + case 2363: + goto tr420 + case 2364: + goto tr420 + case 2365: + goto tr420 + case 2366: + goto tr420 + case 2367: + goto tr420 + case 2368: + goto tr420 + case 2369: + goto tr420 + case 2370: + goto tr420 + case 2371: + goto tr420 + case 2372: + goto tr420 + case 2373: + goto tr420 + case 2374: + goto tr420 + case 2375: + goto tr420 + case 2376: + goto tr420 + case 2377: + goto tr420 + case 2378: + goto tr420 + case 2379: + goto tr420 + case 2380: + goto tr420 + case 2381: + goto tr420 + case 2382: + goto tr420 + case 2383: + goto tr420 + case 2384: + goto tr420 + case 2385: + goto tr420 + case 2386: + goto tr420 + case 2387: + goto tr420 + case 2388: + goto tr420 + case 2389: + goto tr420 + case 2390: + goto tr420 + case 2391: + goto tr420 + case 2392: + goto tr420 + case 2393: + goto tr420 + case 2394: + goto tr420 + case 2395: + goto tr420 + case 2396: + goto tr420 + case 2397: + goto tr420 + case 2398: + goto tr420 + case 2399: + goto tr420 + case 2400: + goto tr420 + case 2401: + goto tr420 + case 2402: + goto tr420 + case 2403: + goto tr420 + case 2404: + goto tr420 + case 2405: + goto tr420 + case 2406: + goto tr420 + case 2407: + goto tr420 + case 2408: + goto tr420 + case 2409: + goto tr420 + case 2410: + goto tr420 + case 2411: + goto tr420 + case 2412: + goto tr420 + case 2413: + goto tr420 + case 2414: + goto tr420 + case 2415: + goto tr420 + case 2416: + goto tr420 + case 2417: + goto tr420 + case 2418: + goto tr420 + case 2419: + goto tr420 + case 2420: + goto tr420 + case 2421: + goto tr420 + case 2422: + goto tr420 + case 2423: + goto tr420 + case 2424: + goto tr420 + case 2425: + goto tr420 + case 2426: + goto tr420 + case 2427: + goto tr420 + case 2428: + goto tr420 + case 2429: + goto tr420 + case 2430: + goto tr420 + case 2431: + goto tr420 + case 2432: + goto tr420 + case 2433: + goto tr420 + case 2434: + goto tr420 + case 2435: + goto tr420 + case 2436: + goto tr2 + case 2437: + goto tr420 + case 2438: + goto tr2 + case 2439: + goto tr420 + case 2440: + goto tr420 + case 2441: + goto tr420 + case 2442: + goto tr420 + case 2443: + goto tr420 + case 2444: + goto tr420 + case 2445: + goto tr420 + case 2446: + goto tr420 + case 2447: + goto tr420 + case 2448: + goto tr420 + case 2449: + goto tr420 + case 2450: + goto tr420 + case 2451: + goto tr420 + case 2452: + goto tr420 + case 2453: + goto tr420 + case 2454: + goto tr420 + case 2455: + goto tr420 + case 2456: + goto tr420 + case 2457: + goto tr420 + case 2458: + goto tr420 + case 2459: + goto tr420 + case 2460: + goto tr420 + case 2461: + goto tr420 + case 2462: + goto tr420 + case 2463: + goto tr420 + case 2464: + goto tr420 + case 2465: + goto tr420 + case 2466: + goto tr420 + case 2467: + goto tr420 + case 2468: + goto tr420 + case 2469: + goto tr420 + case 2470: + goto tr420 + case 2471: + goto tr420 + case 2472: + goto tr420 + case 2473: + goto tr420 + case 2474: + goto tr420 + case 2475: + goto tr420 + case 2476: + goto tr420 + case 2477: + goto tr420 + case 2478: + goto tr420 + case 2479: + goto tr420 + case 2480: + goto tr420 + case 2481: + goto tr420 + case 2482: + goto tr420 + case 2483: + goto tr420 + case 2484: + goto tr420 + case 2485: + goto tr420 + case 2486: + goto tr420 + case 2487: + goto tr420 + case 2488: + goto tr420 + case 2489: + goto tr420 + case 2490: + goto tr420 + case 2491: + goto tr420 + case 2492: + goto tr420 + case 2493: + goto tr420 + case 2494: + goto tr420 + case 2495: + goto tr420 + case 2496: + goto tr420 + case 2497: + goto tr420 + case 2498: + goto tr420 + case 2499: + goto tr420 + case 2500: + goto tr420 + case 2501: + goto tr420 + case 2502: + goto tr420 + case 2503: + goto tr420 + case 2504: + goto tr420 + case 2505: + goto tr420 + case 2506: + goto tr420 + case 2507: + goto tr420 + case 2508: + goto tr420 + case 2509: + goto tr420 + case 2510: + goto tr420 + case 2511: + goto tr420 + case 2512: + goto tr420 + case 2513: + goto tr420 + case 2514: + goto tr420 + case 2515: + goto tr420 + case 2516: + goto tr420 + case 2517: + goto tr420 + case 2518: + goto tr420 + case 2519: + goto tr420 + case 2520: + goto tr420 + case 2521: + goto tr420 + case 2522: + goto tr420 + case 2523: + goto tr420 + case 2524: + goto tr420 + case 2525: + goto tr420 + case 2526: + goto tr420 + case 2527: + goto tr420 + case 2528: + goto tr420 + case 2529: + goto tr420 + case 2530: + goto tr420 + case 2531: + goto tr420 + case 2532: + goto tr420 + case 2533: + goto tr420 + case 2534: + goto tr420 + case 2535: + goto tr420 + case 2536: + goto tr420 + case 2537: + goto tr420 + case 2538: + goto tr420 + case 2539: + goto tr420 + case 2540: + goto tr420 + case 2541: + goto tr420 + case 2542: + goto tr420 + case 2543: + goto tr420 + case 2544: + goto tr420 + case 2545: + goto tr420 + case 2546: + goto tr420 + case 2547: + goto tr420 + case 2548: + goto tr420 + case 2549: + goto tr420 + case 2550: + goto tr420 + case 2551: + goto tr420 + case 2552: + goto tr420 + case 2553: + goto tr420 + case 2554: + goto tr420 + case 2555: + goto tr420 + case 2556: + goto tr420 + case 2557: + goto tr420 + case 2558: + goto tr420 + case 2559: + goto tr420 + case 2560: + goto tr420 + case 2561: + goto tr420 + case 2562: + goto tr420 + case 2563: + goto tr420 + case 2564: + goto tr420 + case 2565: + goto tr420 + case 2566: + goto tr420 + case 2567: + goto tr420 + case 2568: + goto tr420 + case 2569: + goto tr420 + case 2570: + goto tr420 + case 2571: + goto tr420 + case 2572: + goto tr420 + case 2573: + goto tr420 + case 2574: + goto tr420 + case 2575: + goto tr420 + case 2576: + goto tr420 + case 2577: + goto tr420 + case 2578: + goto tr420 + case 2579: + goto tr420 + case 2580: + goto tr420 + case 2581: + goto tr420 + case 2582: + goto tr420 + case 2583: + goto tr420 + case 2584: + goto tr420 + case 2585: + goto tr420 + case 2586: + goto tr420 + case 2587: + goto tr420 + case 2588: + goto tr420 + case 2589: + goto tr420 + case 2590: + goto tr420 + case 2591: + goto tr420 + case 2592: + goto tr420 + case 2593: + goto tr420 + case 2594: + goto tr420 + case 2595: + goto tr420 + case 2596: + goto tr420 + case 2597: + goto tr420 + case 2598: + goto tr420 + case 2599: + goto tr420 + case 2600: + goto tr420 + case 2601: + goto tr420 + case 2602: + goto tr420 + case 2603: + goto tr420 + case 2604: + goto tr420 + case 2605: + goto tr420 + case 2606: + goto tr420 + case 2607: + goto tr420 + case 2608: + goto tr420 + case 2609: + goto tr420 + case 2610: + goto tr420 + case 2611: + goto tr420 + case 2612: + goto tr420 + case 2613: + goto tr420 + case 2614: + goto tr420 + case 2615: + goto tr420 + case 2616: + goto tr420 + case 2617: + goto tr420 + case 2618: + goto tr420 + case 2619: + goto tr420 + case 2620: + goto tr420 + case 2621: + goto tr420 + case 2622: + goto tr420 + case 2623: + goto tr420 + case 2624: + goto tr420 + case 2625: + goto tr420 + case 2626: + goto tr420 + case 2627: + goto tr420 + case 2628: + goto tr420 + case 2629: + goto tr420 + case 2630: + goto tr420 + case 2631: + goto tr420 + case 2632: + goto tr420 + case 2633: + goto tr420 + case 2634: + goto tr420 + case 2635: + goto tr420 + case 4877: + goto tr4499 + case 4878: + goto tr4763 + case 2636: + goto tr2394 + case 2637: + goto tr2 + case 2638: + goto tr2 + case 2639: + goto tr2394 + case 2640: + goto tr2394 + case 2641: + goto tr2394 + case 2642: + goto tr2394 + case 2643: + goto tr2394 + case 2644: + goto tr2394 + case 2645: + goto tr2394 + case 2646: + goto tr2394 + case 2647: + goto tr2394 + case 2648: + goto tr2394 + case 2649: + goto tr2394 + case 2650: + goto tr2 + case 2651: + goto tr2 + case 2652: + goto tr2 + case 2653: + goto tr2 + case 2654: + goto tr2 + case 2655: + goto tr2 + case 2656: + goto tr2 + case 2657: + goto tr2 + case 2658: + goto tr2 + case 2659: + goto tr2 + case 2660: + goto tr2 + case 2661: + goto tr2 + case 2662: + goto tr2 + case 2663: + goto tr2 + case 2664: + goto tr2 + case 2665: + goto tr2 + case 2666: + goto tr2 + case 2667: + goto tr2 + case 2668: + goto tr2 + case 2669: + goto tr2 + case 2670: + goto tr2 + case 2671: + goto tr2 + case 2672: + goto tr2 + case 2673: + goto tr2 + case 2674: + goto tr2 + case 2675: + goto tr2 + case 2676: + goto tr2 + case 2677: + goto tr2 + case 2678: + goto tr2394 + case 2679: + goto tr2 + case 2680: + goto tr2 + case 2681: + goto tr2 + case 2682: + goto tr2 + case 2683: + goto tr2 + case 2684: + goto tr2 + case 2685: + goto tr2 + case 2686: + goto tr2 + case 2687: + goto tr2 + case 2688: + goto tr2 + case 2689: + goto tr2 + case 2690: + goto tr2 + case 2691: + goto tr2 + case 2692: + goto tr2 + case 2693: + goto tr2 + case 2694: + goto tr2 + case 2695: + goto tr2 + case 2696: + goto tr2 + case 2697: + goto tr2 + case 2698: + goto tr2 + case 2699: + goto tr2 + case 2700: + goto tr2394 + case 2701: + goto tr2 + case 2702: + goto tr2 + case 2703: + goto tr2 + case 2704: + goto tr2 + case 2705: + goto tr2 + case 2706: + goto tr2 + case 2707: + goto tr2394 + case 2708: + goto tr2 + case 2709: + goto tr2 + case 2710: + goto tr2394 + case 2711: + goto tr2 + case 2712: + goto tr2 + case 2713: + goto tr2 + case 2714: + goto tr2 + case 2715: + goto tr2 + case 2716: + goto tr2 + case 2717: + goto tr2 + case 2718: + goto tr2 + case 2719: + goto tr2 + case 2720: + goto tr2 + case 2721: + goto tr2 + case 2722: + goto tr2 + case 2723: + goto tr2 + case 2724: + goto tr2 + case 2725: + goto tr2 + case 2726: + goto tr2394 + case 2727: + goto tr2 + case 2728: + goto tr2 + case 2729: + goto tr2 + case 2730: + goto tr2394 + case 2731: + goto tr2 + case 2732: + goto tr2 + case 2733: + goto tr2 + case 2734: + goto tr2 + case 2735: + goto tr2 + case 2736: + goto tr2 + case 2737: + goto tr2 + case 2738: + goto tr2 + case 2739: + goto tr2 + case 2740: + goto tr2 + case 2741: + goto tr2 + case 2742: + goto tr2 + case 2743: + goto tr2 + case 2744: + goto tr2 + case 2745: + goto tr2 + case 2746: + goto tr2 + case 2747: + goto tr2 + case 2748: + goto tr2 + case 2749: + goto tr2 + case 2750: + goto tr2 + case 2751: + goto tr2 + case 2752: + goto tr2 + case 2753: + goto tr2 + case 2754: + goto tr2 + case 2755: + goto tr2 + case 2756: + goto tr2 + case 2757: + goto tr2 + case 2758: + goto tr2 + case 2759: + goto tr2 + case 2760: + goto tr2 + case 2761: + goto tr2 + case 2762: + goto tr2 + case 2763: + goto tr2 + case 2764: + goto tr2 + case 2765: + goto tr2 + case 2766: + goto tr2 + case 2767: + goto tr2 + case 2768: + goto tr2 + case 2769: + goto tr2 + case 2770: + goto tr2 + case 2771: + goto tr2 + case 2772: + goto tr2394 + case 2773: + goto tr2 + case 2774: + goto tr2 + case 2775: + goto tr2 + case 2776: + goto tr2 + case 4879: + goto tr4499 + case 4880: + goto tr4562 + case 4881: + goto tr4562 + case 4882: + goto tr4499 + case 4883: + goto tr4499 + case 4884: + goto tr4562 + case 4885: + goto tr4499 + case 2777: + goto tr0 + case 2778: + goto tr0 + case 2779: + goto tr0 + case 2780: + goto tr0 + case 2781: + goto tr0 + case 2782: + goto tr0 + case 2783: + goto tr0 + case 2784: + goto tr0 + case 2785: + goto tr0 + case 2786: + goto tr0 + case 2787: + goto tr0 + case 2788: + goto tr0 + case 2789: + goto tr0 + case 2790: + goto tr0 + case 2791: + goto tr0 + case 2792: + goto tr0 + case 2793: + goto tr0 + case 2794: + goto tr0 + case 2795: + goto tr0 + case 2796: + goto tr0 + case 2797: + goto tr0 + case 2798: + goto tr0 + case 2799: + goto tr0 + case 2800: + goto tr0 + case 2801: + goto tr0 + case 2802: + goto tr0 + case 2803: + goto tr0 + case 2804: + goto tr0 + case 2805: + goto tr0 + case 2806: + goto tr0 + case 2807: + goto tr0 + case 2808: + goto tr0 + case 2809: + goto tr0 + case 2810: + goto tr0 + case 2811: + goto tr0 + case 2812: + goto tr0 + case 2813: + goto tr0 + case 2814: + goto tr0 + case 2815: + goto tr0 + case 2816: + goto tr0 + case 2817: + goto tr0 + case 2818: + goto tr0 + case 2819: + goto tr0 + case 2820: + goto tr0 + case 2821: + goto tr0 + case 2822: + goto tr0 + case 2823: + goto tr0 + case 2824: + goto tr0 + case 2825: + goto tr0 + case 2826: + goto tr0 + case 2827: + goto tr0 + case 2828: + goto tr0 + case 2829: + goto tr0 + case 2830: + goto tr0 + case 2831: + goto tr0 + case 2832: + goto tr0 + case 2833: + goto tr0 + case 2834: + goto tr0 + case 2835: + goto tr0 + case 2836: + goto tr0 + case 2837: + goto tr0 + case 2838: + goto tr0 + case 2839: + goto tr0 + case 2840: + goto tr0 + case 2841: + goto tr0 + case 2842: + goto tr0 + case 2843: + goto tr0 + case 2844: + goto tr0 + case 2845: + goto tr0 + case 2846: + goto tr0 + case 2847: + goto tr0 + case 2848: + goto tr0 + case 2849: + goto tr0 + case 2850: + goto tr0 + case 2851: + goto tr0 + case 2852: + goto tr0 + case 2853: + goto tr0 + case 2854: + goto tr0 + case 2855: + goto tr0 + case 2856: + goto tr0 + case 2857: + goto tr0 + case 2858: + goto tr0 + case 2859: + goto tr0 + case 2860: + goto tr0 + case 2861: + goto tr0 + case 2862: + goto tr0 + case 2863: + goto tr0 + case 2864: + goto tr0 + case 2865: + goto tr0 + case 2866: + goto tr0 + case 2867: + goto tr0 + case 2868: + goto tr0 + case 2869: + goto tr0 + case 2870: + goto tr0 + case 2871: + goto tr0 + case 2872: + goto tr0 + case 2873: + goto tr0 + case 2874: + goto tr0 + case 2875: + goto tr0 + case 2876: + goto tr0 + case 2877: + goto tr0 + case 2878: + goto tr0 + case 2879: + goto tr0 + case 2880: + goto tr0 + case 2881: + goto tr0 + case 2882: + goto tr0 + case 2883: + goto tr0 + case 2884: + goto tr0 + case 2885: + goto tr0 + case 2886: + goto tr0 + case 2887: + goto tr0 + case 2888: + goto tr0 + case 2889: + goto tr0 + case 2890: + goto tr0 + case 2891: + goto tr0 + case 2892: + goto tr0 + case 2893: + goto tr0 + case 2894: + goto tr0 + case 2895: + goto tr0 + case 2896: + goto tr0 + case 2897: + goto tr0 + case 2898: + goto tr0 + case 2899: + goto tr0 + case 2900: + goto tr0 + case 2901: + goto tr0 + case 2902: + goto tr0 + case 2903: + goto tr0 + case 2904: + goto tr0 + case 2905: + goto tr0 + case 2906: + goto tr0 + case 2907: + goto tr0 + case 2908: + goto tr0 + case 2909: + goto tr0 + case 2910: + goto tr0 + case 2911: + goto tr0 + case 2912: + goto tr0 + case 2913: + goto tr0 + case 2914: + goto tr0 + case 2915: + goto tr0 + case 2916: + goto tr0 + case 2917: + goto tr0 + case 2918: + goto tr0 + case 2919: + goto tr0 + case 2920: + goto tr0 + case 2921: + goto tr0 + case 2922: + goto tr0 + case 2923: + goto tr0 + case 4886: + goto tr4562 + case 2924: + goto tr420 + case 2925: + goto tr420 + case 2926: + goto tr420 + case 2927: + goto tr420 + case 2928: + goto tr420 + case 2929: + goto tr420 + case 2930: + goto tr420 + case 2931: + goto tr420 + case 2932: + goto tr420 + case 2933: + goto tr420 + case 2934: + goto tr420 + case 2935: + goto tr420 + case 2936: + goto tr420 + case 2937: + goto tr420 + case 2938: + goto tr420 + case 2939: + goto tr420 + case 2940: + goto tr420 + case 2941: + goto tr420 + case 2942: + goto tr420 + case 2943: + goto tr420 + case 2944: + goto tr420 + case 2945: + goto tr420 + case 2946: + goto tr420 + case 2947: + goto tr420 + case 2948: + goto tr420 + case 2949: + goto tr420 + case 2950: + goto tr420 + case 2951: + goto tr420 + case 2952: + goto tr420 + case 2953: + goto tr420 + case 2954: + goto tr420 + case 2955: + goto tr420 + case 2956: + goto tr420 + case 2957: + goto tr420 + case 2958: + goto tr420 + case 2959: + goto tr420 + case 2960: + goto tr420 + case 2961: + goto tr420 + case 2962: + goto tr420 + case 2963: + goto tr420 + case 2964: + goto tr420 + case 2965: + goto tr420 + case 2966: + goto tr420 + case 2967: + goto tr420 + case 2968: + goto tr420 + case 2969: + goto tr420 + case 2970: + goto tr420 + case 2971: + goto tr420 + case 2972: + goto tr420 + case 2973: + goto tr420 + case 2974: + goto tr420 + case 2975: + goto tr420 + case 2976: + goto tr420 + case 2977: + goto tr420 + case 2978: + goto tr420 + case 2979: + goto tr420 + case 2980: + goto tr420 + case 2981: + goto tr420 + case 2982: + goto tr420 + case 2983: + goto tr420 + case 2984: + goto tr420 + case 2985: + goto tr420 + case 2986: + goto tr420 + case 2987: + goto tr420 + case 2988: + goto tr420 + case 2989: + goto tr420 + case 2990: + goto tr420 + case 2991: + goto tr420 + case 2992: + goto tr420 + case 2993: + goto tr420 + case 2994: + goto tr420 + case 2995: + goto tr420 + case 2996: + goto tr420 + case 2997: + goto tr420 + case 2998: + goto tr420 + case 2999: + goto tr420 + case 3000: + goto tr420 + case 3001: + goto tr420 + case 3002: + goto tr420 + case 3003: + goto tr420 + case 3004: + goto tr420 + case 3005: + goto tr420 + case 3006: + goto tr420 + case 3007: + goto tr420 + case 3008: + goto tr420 + case 3009: + goto tr420 + case 3010: + goto tr420 + case 3011: + goto tr420 + case 3012: + goto tr420 + case 3013: + goto tr420 + case 3014: + goto tr420 + case 3015: + goto tr420 + case 3016: + goto tr420 + case 3017: + goto tr420 + case 3018: + goto tr420 + case 3019: + goto tr420 + case 3020: + goto tr420 + case 3021: + goto tr420 + case 3022: + goto tr420 + case 3023: + goto tr420 + case 3024: + goto tr420 + case 3025: + goto tr420 + case 3026: + goto tr420 + case 3027: + goto tr420 + case 3028: + goto tr420 + case 3029: + goto tr420 + case 3030: + goto tr420 + case 3031: + goto tr420 + case 3032: + goto tr420 + case 3033: + goto tr420 + case 3034: + goto tr420 + case 3035: + goto tr420 + case 3036: + goto tr420 + case 3037: + goto tr420 + case 3038: + goto tr420 + case 3039: + goto tr420 + case 3040: + goto tr420 + case 3041: + goto tr420 + case 3042: + goto tr420 + case 3043: + goto tr420 + case 3044: + goto tr420 + case 3045: + goto tr420 + case 3046: + goto tr420 + case 3047: + goto tr420 + case 3048: + goto tr420 + case 3049: + goto tr420 + case 3050: + goto tr420 + case 3051: + goto tr420 + case 3052: + goto tr420 + case 3053: + goto tr420 + case 3054: + goto tr420 + case 3055: + goto tr420 + case 3056: + goto tr420 + case 3057: + goto tr420 + case 3058: + goto tr420 + case 3059: + goto tr420 + case 3060: + goto tr420 + case 3061: + goto tr420 + case 3062: + goto tr420 + case 3063: + goto tr420 + case 3064: + goto tr420 + case 3065: + goto tr420 + case 3066: + goto tr420 + case 3067: + goto tr420 + case 3068: + goto tr420 + case 3069: + goto tr420 + case 3070: + goto tr420 + case 4887: + goto tr4562 + case 3071: + goto tr420 + case 3072: + goto tr420 + case 3073: + goto tr420 + case 3074: + goto tr420 + case 3075: + goto tr420 + case 3076: + goto tr420 + case 3077: + goto tr420 + case 3078: + goto tr420 + case 3079: + goto tr420 + case 3080: + goto tr420 + case 3081: + goto tr420 + case 3082: + goto tr420 + case 3083: + goto tr420 + case 3084: + goto tr420 + case 3085: + goto tr420 + case 3086: + goto tr420 + case 3087: + goto tr420 + case 3088: + goto tr420 + case 3089: + goto tr420 + case 3090: + goto tr420 + case 3091: + goto tr420 + case 3092: + goto tr420 + case 3093: + goto tr420 + case 3094: + goto tr420 + case 3095: + goto tr420 + case 3096: + goto tr420 + case 3097: + goto tr420 + case 3098: + goto tr420 + case 3099: + goto tr420 + case 3100: + goto tr420 + case 3101: + goto tr420 + case 3102: + goto tr420 + case 3103: + goto tr420 + case 3104: + goto tr420 + case 3105: + goto tr420 + case 3106: + goto tr420 + case 3107: + goto tr420 + case 3108: + goto tr420 + case 3109: + goto tr420 + case 3110: + goto tr420 + case 3111: + goto tr420 + case 3112: + goto tr420 + case 3113: + goto tr420 + case 3114: + goto tr420 + case 3115: + goto tr420 + case 3116: + goto tr420 + case 3117: + goto tr420 + case 3118: + goto tr420 + case 3119: + goto tr420 + case 3120: + goto tr420 + case 3121: + goto tr420 + case 3122: + goto tr420 + case 3123: + goto tr420 + case 3124: + goto tr420 + case 3125: + goto tr420 + case 3126: + goto tr420 + case 3127: + goto tr420 + case 3128: + goto tr420 + case 3129: + goto tr420 + case 3130: + goto tr420 + case 3131: + goto tr420 + case 3132: + goto tr420 + case 3133: + goto tr420 + case 3134: + goto tr420 + case 3135: + goto tr420 + case 3136: + goto tr420 + case 3137: + goto tr420 + case 3138: + goto tr420 + case 3139: + goto tr420 + case 3140: + goto tr420 + case 3141: + goto tr420 + case 3142: + goto tr420 + case 3143: + goto tr420 + case 3144: + goto tr420 + case 3145: + goto tr420 + case 3146: + goto tr420 + case 3147: + goto tr420 + case 3148: + goto tr420 + case 3149: + goto tr420 + case 3150: + goto tr420 + case 3151: + goto tr420 + case 3152: + goto tr420 + case 3153: + goto tr420 + case 3154: + goto tr420 + case 3155: + goto tr420 + case 3156: + goto tr420 + case 3157: + goto tr420 + case 3158: + goto tr420 + case 3159: + goto tr420 + case 3160: + goto tr420 + case 3161: + goto tr420 + case 3162: + goto tr420 + case 3163: + goto tr420 + case 3164: + goto tr420 + case 3165: + goto tr420 + case 3166: + goto tr420 + case 3167: + goto tr420 + case 3168: + goto tr420 + case 3169: + goto tr420 + case 3170: + goto tr420 + case 3171: + goto tr420 + case 3172: + goto tr420 + case 3173: + goto tr420 + case 3174: + goto tr420 + case 3175: + goto tr420 + case 3176: + goto tr420 + case 3177: + goto tr420 + case 3178: + goto tr420 + case 3179: + goto tr420 + case 3180: + goto tr420 + case 3181: + goto tr420 + case 3182: + goto tr420 + case 3183: + goto tr420 + case 3184: + goto tr420 + case 3185: + goto tr420 + case 3186: + goto tr420 + case 3187: + goto tr420 + case 3188: + goto tr420 + case 3189: + goto tr420 + case 3190: + goto tr420 + case 3191: + goto tr420 + case 3192: + goto tr420 + case 3193: + goto tr420 + case 3194: + goto tr420 + case 3195: + goto tr420 + case 3196: + goto tr420 + case 3197: + goto tr420 + case 3198: + goto tr420 + case 3199: + goto tr420 + case 3200: + goto tr420 + case 3201: + goto tr420 + case 3202: + goto tr420 + case 3203: + goto tr420 + case 3204: + goto tr420 + case 3205: + goto tr420 + case 3206: + goto tr420 + case 3207: + goto tr420 + case 3208: + goto tr420 + case 3209: + goto tr420 + case 3210: + goto tr420 + case 3211: + goto tr420 + case 3212: + goto tr420 + case 3213: + goto tr420 + case 3214: + goto tr420 + case 3215: + goto tr420 + case 3216: + goto tr420 + case 3217: + goto tr420 + case 4888: + goto tr4562 + case 4889: + goto tr4562 + case 4890: + goto tr4562 + case 4891: + goto tr4562 + case 4892: + goto tr4562 + case 4893: + goto tr4562 + case 4894: + goto tr4562 + case 4895: + goto tr4499 + case 4896: + goto tr4499 + case 4897: + goto tr4562 + case 4898: + goto tr4562 + case 4899: + goto tr4562 + case 4900: + goto tr4562 + case 4901: + goto tr4562 + case 4902: + goto tr4562 + case 4903: + goto tr4562 + case 4904: + goto tr4562 + case 4905: + goto tr4562 + case 4906: + goto tr4562 + case 4907: + goto tr4562 + case 4908: + goto tr4499 + case 4909: + goto tr4499 + case 4910: + goto tr4499 + case 4911: + goto tr4499 + case 4912: + goto tr4499 + case 4913: + goto tr4499 + case 4914: + goto tr4499 + case 4915: + goto tr4499 + case 4916: + goto tr4499 + case 4917: + goto tr4499 + case 4918: + goto tr4499 + case 4919: + goto tr4499 + case 4920: + goto tr4499 + case 4921: + goto tr4499 + case 4922: + goto tr4499 + case 4923: + goto tr4499 + case 4924: + goto tr4499 + case 4925: + goto tr4499 + case 4926: + goto tr4499 + case 4927: + goto tr4499 + case 4928: + goto tr4499 + case 3218: + goto tr0 + case 3219: + goto tr0 + case 3220: + goto tr0 + case 3221: + goto tr0 + case 3222: + goto tr0 + case 3223: + goto tr0 + case 3224: + goto tr0 + case 3225: + goto tr0 + case 3226: + goto tr0 + case 3227: + goto tr0 + case 3228: + goto tr0 + case 3229: + goto tr0 + case 3230: + goto tr0 + case 3231: + goto tr0 + case 4929: + goto tr4562 + case 4930: + goto tr4562 + case 4931: + goto tr4562 + case 4932: + goto tr4499 + case 3232: + goto tr0 + case 4933: + goto tr4562 + case 4934: + goto tr4562 + case 4935: + goto tr4562 + case 4936: + goto tr4562 + case 4937: + goto tr4562 + case 4938: + goto tr4562 + case 4939: + goto tr4562 + case 4940: + goto tr4499 + case 4941: + goto tr4499 + case 4942: + goto tr4499 + case 4943: + goto tr4499 + case 4944: + goto tr4562 + case 4945: + goto tr4562 + case 4946: + goto tr4562 + case 4947: + goto tr4562 + case 4948: + goto tr4562 + case 4949: + goto tr4562 + case 4950: + goto tr4562 + case 4951: + goto tr4562 + case 4952: + goto tr4562 + case 4953: + goto tr4562 + case 4954: + goto tr4562 + case 4955: + goto tr4562 + case 4956: + goto tr4562 + case 4957: + goto tr4562 + case 3233: + goto tr0 + case 4958: + goto tr4562 + case 4959: + goto tr4562 + case 4960: + goto tr4562 + case 4961: + goto tr4562 + case 4962: + goto tr4562 + case 4963: + goto tr4562 + case 3234: + goto tr0 + case 4964: + goto tr4562 + case 4965: + goto tr4562 + case 3235: + goto tr0 + case 4966: + goto tr4562 + case 4967: + goto tr4562 + case 4968: + goto tr4562 + case 4969: + goto tr4562 + case 4970: + goto tr4562 + case 4971: + goto tr4562 + case 4972: + goto tr4562 + case 4973: + goto tr4562 + case 4974: + goto tr4562 + case 4975: + goto tr4562 + case 4976: + goto tr4562 + case 4977: + goto tr4562 + case 4978: + goto tr4562 + case 4979: + goto tr4562 + case 4980: + goto tr4562 + case 3236: + goto tr0 + case 4981: + goto tr4562 + case 4982: + goto tr4562 + case 4983: + goto tr4562 + case 3237: + goto tr0 + case 4984: + goto tr4562 + case 4985: + goto tr4562 + case 4986: + goto tr4562 + case 4987: + goto tr4562 + case 4988: + goto tr4562 + case 4989: + goto tr4562 + case 3238: + goto tr0 + case 4990: + goto tr4562 + case 4991: + goto tr4562 + case 4992: + goto tr4562 + case 4993: + goto tr4562 + case 4994: + goto tr4562 + case 4995: + goto tr4562 + case 4996: + goto tr4562 + case 4997: + goto tr4562 + case 4998: + goto tr4562 + case 4999: + goto tr4562 + case 5000: + goto tr4562 + case 5001: + goto tr4562 + case 5002: + goto tr4562 + case 5003: + goto tr4562 + case 5004: + goto tr4562 + case 5005: + goto tr4562 + case 5006: + goto tr4562 + case 5007: + goto tr4562 + case 5008: + goto tr4562 + case 5009: + goto tr4562 + case 5010: + goto tr4562 + case 5011: + goto tr4562 + case 5012: + goto tr4562 + case 5013: + goto tr4562 + case 5014: + goto tr4562 + case 5015: + goto tr4562 + case 5016: + goto tr4499 + case 5017: + goto tr4499 + case 5018: + goto tr4763 + case 5019: + goto tr4763 + case 5020: + goto tr4499 + case 5021: + goto tr4499 + case 5022: + goto tr4499 + case 5023: + goto tr4499 + case 5024: + goto tr4499 + case 5025: + goto tr4499 + case 5026: + goto tr4499 + case 5027: + goto tr4499 + case 5028: + goto tr4499 + case 5029: + goto tr4763 + case 5030: + goto tr4763 + case 5031: + goto tr4763 + case 5032: + goto tr4763 + case 5033: + goto tr4763 + case 5034: + goto tr4763 + case 5035: + goto tr4763 + case 5036: + goto tr4763 + case 5037: + goto tr4499 + case 5038: + goto tr4499 + case 5039: + goto tr4499 + case 5040: + goto tr4499 + case 5041: + goto tr4499 + case 5042: + goto tr4499 + case 5043: + goto tr4499 + case 5044: + goto tr4499 + case 5045: + goto tr4499 + case 5046: + goto tr4499 + case 5047: + goto tr4499 + case 5048: + goto tr4763 + case 5049: + goto tr4763 + case 5050: + goto tr4763 + case 5051: + goto tr4763 + case 5052: + goto tr4763 + case 5053: + goto tr4763 + case 5054: + goto tr4763 + case 5055: + goto tr4763 + case 5056: + goto tr4763 + case 5057: + goto tr4763 + case 5058: + goto tr4763 + case 5059: + goto tr4499 + case 5060: + goto tr4499 + case 5061: + goto tr4499 + case 5062: + goto tr4499 + case 5063: + goto tr4499 + case 5064: + goto tr4499 + case 5065: + goto tr4499 + case 5066: + goto tr4499 + case 5067: + goto tr4499 + case 5068: + goto tr4499 + case 5069: + goto tr4499 + case 5070: + goto tr4499 + case 5071: + goto tr4499 + case 3239: + goto tr0 + case 3240: + goto tr0 + case 3241: + goto tr0 + case 3242: + goto tr0 + case 3243: + goto tr0 + case 3244: + goto tr0 + case 3245: + goto tr0 + case 3246: + goto tr0 + case 3247: + goto tr0 + case 3248: + goto tr0 + case 3249: + goto tr0 + case 3250: + goto tr0 + case 3251: + goto tr0 + case 3252: + goto tr0 + case 3253: + goto tr0 + case 3254: + goto tr0 + case 3255: + goto tr0 + case 3256: + goto tr0 + case 3257: + goto tr0 + case 3258: + goto tr0 + case 3259: + goto tr0 + case 3260: + goto tr0 + case 3261: + goto tr0 + case 3262: + goto tr0 + case 3263: + goto tr0 + case 3264: + goto tr0 + case 3265: + goto tr0 + case 5072: + goto tr4499 + case 3266: + goto tr0 + case 3267: + goto tr0 + case 3268: + goto tr2 + case 5073: + goto tr5002 + case 3269: + goto tr2985 + case 3270: + goto tr2 + case 3271: + goto tr2985 + case 3272: + goto tr2985 + case 3273: + goto tr2985 + case 3274: + goto tr2985 + case 3275: + goto tr2985 + case 3276: + goto tr2985 + case 3277: + goto tr2985 + case 3278: + goto tr2985 + case 3279: + goto tr2985 + case 3280: + goto tr2985 + case 3281: + goto tr2985 + case 3282: + goto tr2985 + case 3283: + goto tr2 + case 3284: + goto tr2 + case 3285: + goto tr2 + case 3286: + goto tr2 + case 3287: + goto tr2 + case 3288: + goto tr2 + case 3289: + goto tr2 + case 3290: + goto tr2 + case 3291: + goto tr2 + case 3292: + goto tr2 + case 3293: + goto tr2 + case 3294: + goto tr2 + case 3295: + goto tr2 + case 3296: + goto tr2 + case 3297: + goto tr2 + case 3298: + goto tr2 + case 3299: + goto tr2 + case 3300: + goto tr2 + case 3301: + goto tr2 + case 3302: + goto tr2 + case 3303: + goto tr2 + case 3304: + goto tr2 + case 3305: + goto tr2 + case 3306: + goto tr2 + case 3307: + goto tr2 + case 3308: + goto tr2 + case 3309: + goto tr2 + case 3310: + goto tr2 + case 3311: + goto tr2 + case 3312: + goto tr2 + case 3313: + goto tr2 + case 3314: + goto tr2985 + case 3315: + goto tr2 + case 3316: + goto tr2 + case 3317: + goto tr2 + case 3318: + goto tr2 + case 3319: + goto tr2 + case 3320: + goto tr2 + case 3321: + goto tr2 + case 3322: + goto tr2 + case 3323: + goto tr2 + case 3324: + goto tr2 + case 3325: + goto tr2 + case 3326: + goto tr2 + case 3327: + goto tr2 + case 3328: + goto tr2 + case 3329: + goto tr2 + case 3330: + goto tr2 + case 3331: + goto tr2 + case 3332: + goto tr2 + case 3333: + goto tr2 + case 3334: + goto tr2 + case 3335: + goto tr2 + case 3336: + goto tr2 + case 3337: + goto tr2 + case 3338: + goto tr2985 + case 3339: + goto tr2 + case 3340: + goto tr2 + case 3341: + goto tr2 + case 3342: + goto tr2 + case 3343: + goto tr2 + case 3344: + goto tr2 + case 3345: + goto tr2985 + case 3346: + goto tr2 + case 3347: + goto tr2 + case 3348: + goto tr2 + case 3349: + goto tr2 + case 3350: + goto tr2 + case 5074: + goto tr5002 + case 3351: + goto tr2985 + case 3352: + goto tr2985 + case 3353: + goto tr2985 + case 3354: + goto tr2985 + case 3355: + goto tr2985 + case 3356: + goto tr2985 + case 3357: + goto tr2985 + case 3358: + goto tr2985 + case 3359: + goto tr2985 + case 3360: + goto tr2985 + case 3361: + goto tr2985 + case 3362: + goto tr2985 + case 3363: + goto tr2985 + case 3364: + goto tr2985 + case 3365: + goto tr2985 + case 3366: + goto tr2985 + case 3367: + goto tr2985 + case 3368: + goto tr2985 + case 3369: + goto tr2985 + case 3370: + goto tr2985 + case 3371: + goto tr2985 + case 3372: + goto tr2985 + case 3373: + goto tr2985 + case 3374: + goto tr2985 + case 3375: + goto tr2985 + case 3376: + goto tr2985 + case 3377: + goto tr2985 + case 3378: + goto tr2985 + case 3379: + goto tr2985 + case 3380: + goto tr2985 + case 3381: + goto tr2985 + case 3382: + goto tr2985 + case 3383: + goto tr2985 + case 3384: + goto tr2985 + case 3385: + goto tr2985 + case 3386: + goto tr2985 + case 3387: + goto tr2985 + case 3388: + goto tr2985 + case 3389: + goto tr2985 + case 3390: + goto tr2985 + case 3391: + goto tr2985 + case 3392: + goto tr2985 + case 3393: + goto tr2985 + case 3394: + goto tr2985 + case 3395: + goto tr2985 + case 3396: + goto tr2985 + case 3397: + goto tr2985 + case 3398: + goto tr2985 + case 3399: + goto tr2985 + case 3400: + goto tr2985 + case 3401: + goto tr2985 + case 3402: + goto tr2985 + case 3403: + goto tr2985 + case 3404: + goto tr2985 + case 3405: + goto tr2985 + case 3406: + goto tr2985 + case 3407: + goto tr2985 + case 3408: + goto tr2985 + case 3409: + goto tr2985 + case 3410: + goto tr2985 + case 3411: + goto tr2985 + case 3412: + goto tr2985 + case 3413: + goto tr2985 + case 3414: + goto tr2985 + case 3415: + goto tr2985 + case 3416: + goto tr2985 + case 3417: + goto tr2985 + case 3418: + goto tr2985 + case 3419: + goto tr2985 + case 3420: + goto tr2985 + case 3421: + goto tr2985 + case 3422: + goto tr2985 + case 3423: + goto tr2985 + case 3424: + goto tr2985 + case 3425: + goto tr2985 + case 3426: + goto tr2985 + case 3427: + goto tr2985 + case 3428: + goto tr2985 + case 3429: + goto tr2 + case 3430: + goto tr2985 + case 3431: + goto tr2985 + case 3432: + goto tr2985 + case 3433: + goto tr2985 + case 3434: + goto tr2985 + case 3435: + goto tr2985 + case 3436: + goto tr2985 + case 3437: + goto tr2985 + case 3438: + goto tr2985 + case 3439: + goto tr2985 + case 3440: + goto tr2985 + case 3441: + goto tr2985 + case 3442: + goto tr2985 + case 3443: + goto tr2985 + case 3444: + goto tr2985 + case 3445: + goto tr2985 + case 3446: + goto tr2985 + case 3447: + goto tr2985 + case 3448: + goto tr2985 + case 3449: + goto tr2985 + case 3450: + goto tr2985 + case 3451: + goto tr2985 + case 3452: + goto tr2985 + case 3453: + goto tr2985 + case 3454: + goto tr2985 + case 3455: + goto tr2985 + case 3456: + goto tr2985 + case 3457: + goto tr2985 + case 3458: + goto tr2985 + case 3459: + goto tr2985 + case 3460: + goto tr2985 + case 3461: + goto tr2985 + case 3462: + goto tr2985 + case 3463: + goto tr2985 + case 3464: + goto tr2985 + case 3465: + goto tr2985 + case 3466: + goto tr2985 + case 3467: + goto tr2985 + case 3468: + goto tr2985 + case 3469: + goto tr2985 + case 3470: + goto tr2985 + case 3471: + goto tr2985 + case 3472: + goto tr2985 + case 3473: + goto tr2985 + case 3474: + goto tr2985 + case 3475: + goto tr2985 + case 3476: + goto tr2985 + case 3477: + goto tr2985 + case 3478: + goto tr2985 + case 3479: + goto tr2985 + case 3480: + goto tr2985 + case 3481: + goto tr2985 + case 3482: + goto tr2985 + case 3483: + goto tr2985 + case 3484: + goto tr2985 + case 3485: + goto tr2985 + case 3486: + goto tr2985 + case 3487: + goto tr2985 + case 3488: + goto tr2985 + case 3489: + goto tr2985 + case 3490: + goto tr2985 + case 3491: + goto tr2985 + case 3492: + goto tr2985 + case 3493: + goto tr2985 + case 3494: + goto tr2985 + case 3495: + goto tr2985 + case 3496: + goto tr2985 + case 3497: + goto tr2985 + case 3498: + goto tr2985 + case 3499: + goto tr2985 + case 3500: + goto tr2985 + case 3501: + goto tr2 + case 3502: + goto tr2 + case 3503: + goto tr2 + case 3504: + goto tr2 + case 3505: + goto tr2 + case 3506: + goto tr2 + case 3507: + goto tr2 + case 3508: + goto tr2 + case 3509: + goto tr2 + case 3510: + goto tr2 + case 3511: + goto tr2 + case 3512: + goto tr2 + case 3513: + goto tr2 + case 3514: + goto tr2 + case 3515: + goto tr2 + case 3516: + goto tr2985 + case 3517: + goto tr2985 + case 3518: + goto tr2 + case 3519: + goto tr2 + case 3520: + goto tr2985 + case 3521: + goto tr2 + case 3522: + goto tr2 + case 3523: + goto tr2 + case 3524: + goto tr2 + case 3525: + goto tr2 + case 3526: + goto tr2985 + case 3527: + goto tr2 + case 3528: + goto tr2 + case 3529: + goto tr2 + case 3530: + goto tr2 + case 3531: + goto tr2 + case 3532: + goto tr2 + case 3533: + goto tr2 + case 3534: + goto tr2 + case 3535: + goto tr2 + case 3536: + goto tr2 + case 3537: + goto tr2 + case 3538: + goto tr2 + case 3539: + goto tr2 + case 3540: + goto tr2 + case 3541: + goto tr2 + case 3542: + goto tr2 + case 3543: + goto tr2 + case 3544: + goto tr2 + case 3545: + goto tr2 + case 3546: + goto tr2 + case 3547: + goto tr2 + case 3548: + goto tr2 + case 3549: + goto tr2 + case 3550: + goto tr2 + case 3551: + goto tr2 + case 3552: + goto tr2 + case 3553: + goto tr2 + case 3554: + goto tr2 + case 3555: + goto tr2 + case 3556: + goto tr2 + case 3557: + goto tr2 + case 3558: + goto tr2 + case 3559: + goto tr2 + case 3560: + goto tr2 + case 3561: + goto tr2 + case 3562: + goto tr2 + case 3563: + goto tr2 + case 3564: + goto tr2 + case 3565: + goto tr2 + case 3566: + goto tr2 + case 3567: + goto tr2 + case 3568: + goto tr2985 + case 3569: + goto tr2 + case 3570: + goto tr2 + case 3571: + goto tr2 + case 3572: + goto tr2 + case 3573: + goto tr0 + case 3574: + goto tr0 + case 3575: + goto tr0 + case 3576: + goto tr0 + case 3577: + goto tr0 + case 3578: + goto tr0 + case 3579: + goto tr0 + case 3580: + goto tr0 + case 3581: + goto tr0 + case 3582: + goto tr0 + case 3583: + goto tr0 + case 3584: + goto tr0 + case 3585: + goto tr0 + case 3586: + goto tr0 + case 3587: + goto tr0 + case 5075: + goto tr4499 + case 3588: + goto tr0 + case 3589: + goto tr0 + case 3590: + goto tr0 + case 3591: + goto tr0 + case 3592: + goto tr0 + case 3593: + goto tr0 + case 5076: + goto tr5054 + case 3594: + goto tr3251 + case 3595: + goto tr2 + case 3596: + goto tr2 + case 3597: + goto tr3251 + case 3598: + goto tr3251 + case 3599: + goto tr3251 + case 3600: + goto tr3251 + case 3601: + goto tr3251 + case 3602: + goto tr3251 + case 3603: + goto tr3251 + case 3604: + goto tr3251 + case 3605: + goto tr3251 + case 3606: + goto tr3251 + case 3607: + goto tr3251 + case 3608: + goto tr2 + case 3609: + goto tr2 + case 3610: + goto tr2 + case 3611: + goto tr2 + case 3612: + goto tr2 + case 3613: + goto tr2 + case 3614: + goto tr2 + case 3615: + goto tr2 + case 3616: + goto tr2 + case 3617: + goto tr2 + case 3618: + goto tr2 + case 3619: + goto tr2 + case 3620: + goto tr2 + case 3621: + goto tr2 + case 3622: + goto tr2 + case 3623: + goto tr2 + case 3624: + goto tr2 + case 3625: + goto tr2 + case 3626: + goto tr2 + case 3627: + goto tr2 + case 3628: + goto tr2 + case 3629: + goto tr2 + case 3630: + goto tr2 + case 3631: + goto tr2 + case 3632: + goto tr2 + case 3633: + goto tr2 + case 3634: + goto tr2 + case 3635: + goto tr2 + case 3636: + goto tr3251 + case 3637: + goto tr2 + case 3638: + goto tr2 + case 3639: + goto tr2 + case 3640: + goto tr2 + case 3641: + goto tr2 + case 3642: + goto tr2 + case 3643: + goto tr2 + case 3644: + goto tr2 + case 3645: + goto tr2 + case 3646: + goto tr2 + case 3647: + goto tr2 + case 3648: + goto tr2 + case 3649: + goto tr2 + case 3650: + goto tr2 + case 3651: + goto tr2 + case 3652: + goto tr2 + case 3653: + goto tr2 + case 3654: + goto tr2 + case 3655: + goto tr2 + case 3656: + goto tr2 + case 3657: + goto tr2 + case 3658: + goto tr3251 + case 3659: + goto tr2 + case 3660: + goto tr2 + case 3661: + goto tr2 + case 3662: + goto tr2 + case 3663: + goto tr2 + case 3664: + goto tr2 + case 3665: + goto tr3251 + case 3666: + goto tr2 + case 3667: + goto tr2 + case 3668: + goto tr3251 + case 3669: + goto tr2 + case 3670: + goto tr2 + case 3671: + goto tr2 + case 3672: + goto tr2 + case 3673: + goto tr2 + case 3674: + goto tr2 + case 3675: + goto tr2 + case 3676: + goto tr2 + case 3677: + goto tr2 + case 3678: + goto tr2 + case 3679: + goto tr2 + case 3680: + goto tr2 + case 3681: + goto tr2 + case 3682: + goto tr2 + case 3683: + goto tr2 + case 3684: + goto tr3251 + case 3685: + goto tr2 + case 3686: + goto tr2 + case 3687: + goto tr2 + case 3688: + goto tr3251 + case 3689: + goto tr2 + case 3690: + goto tr2 + case 3691: + goto tr2 + case 3692: + goto tr2 + case 3693: + goto tr2 + case 3694: + goto tr2 + case 3695: + goto tr2 + case 3696: + goto tr2 + case 3697: + goto tr2 + case 3698: + goto tr2 + case 3699: + goto tr2 + case 3700: + goto tr2 + case 3701: + goto tr2 + case 3702: + goto tr2 + case 3703: + goto tr2 + case 3704: + goto tr2 + case 3705: + goto tr2 + case 3706: + goto tr2 + case 3707: + goto tr2 + case 3708: + goto tr2 + case 3709: + goto tr2 + case 3710: + goto tr2 + case 3711: + goto tr2 + case 3712: + goto tr2 + case 3713: + goto tr2 + case 3714: + goto tr2 + case 3715: + goto tr2 + case 3716: + goto tr2 + case 3717: + goto tr2 + case 3718: + goto tr2 + case 3719: + goto tr2 + case 3720: + goto tr2 + case 3721: + goto tr2 + case 3722: + goto tr2 + case 3723: + goto tr2 + case 3724: + goto tr2 + case 3725: + goto tr2 + case 3726: + goto tr2 + case 3727: + goto tr2 + case 3728: + goto tr2 + case 3729: + goto tr2 + case 3730: + goto tr3251 + case 3731: + goto tr2 + case 3732: + goto tr2 + case 3733: + goto tr2 + case 3734: + goto tr2 + case 3735: + goto tr0 + case 3736: + goto tr0 + case 5077: + goto tr4499 + case 3737: + goto tr0 + case 5078: + goto tr4562 + case 3738: + goto tr420 + case 3739: + goto tr420 + case 3740: + goto tr420 + case 3741: + goto tr420 + case 3742: + goto tr420 + case 3743: + goto tr420 + case 3744: + goto tr420 + case 3745: + goto tr420 + case 3746: + goto tr420 + case 3747: + goto tr420 + case 3748: + goto tr420 + case 3749: + goto tr420 + case 3750: + goto tr420 + case 3751: + goto tr420 + case 3752: + goto tr420 + case 3753: + goto tr420 + case 3754: + goto tr420 + case 3755: + goto tr420 + case 3756: + goto tr420 + case 3757: + goto tr420 + case 3758: + goto tr420 + case 3759: + goto tr420 + case 3760: + goto tr420 + case 3761: + goto tr420 + case 3762: + goto tr420 + case 3763: + goto tr420 + case 3764: + goto tr420 + case 3765: + goto tr420 + case 3766: + goto tr420 + case 3767: + goto tr420 + case 3768: + goto tr420 + case 3769: + goto tr420 + case 3770: + goto tr420 + case 3771: + goto tr420 + case 3772: + goto tr420 + case 3773: + goto tr420 + case 3774: + goto tr420 + case 3775: + goto tr420 + case 3776: + goto tr420 + case 3777: + goto tr420 + case 3778: + goto tr420 + case 3779: + goto tr420 + case 3780: + goto tr420 + case 3781: + goto tr420 + case 3782: + goto tr420 + case 3783: + goto tr420 + case 3784: + goto tr420 + case 3785: + goto tr420 + case 3786: + goto tr420 + case 3787: + goto tr420 + case 3788: + goto tr420 + case 3789: + goto tr420 + case 3790: + goto tr420 + case 3791: + goto tr420 + case 3792: + goto tr420 + case 3793: + goto tr420 + case 3794: + goto tr420 + case 3795: + goto tr420 + case 3796: + goto tr420 + case 3797: + goto tr420 + case 3798: + goto tr420 + case 3799: + goto tr420 + case 3800: + goto tr420 + case 3801: + goto tr420 + case 3802: + goto tr420 + case 3803: + goto tr420 + case 3804: + goto tr420 + case 3805: + goto tr420 + case 3806: + goto tr420 + case 3807: + goto tr420 + case 3808: + goto tr420 + case 3809: + goto tr420 + case 3810: + goto tr420 + case 3811: + goto tr420 + case 3812: + goto tr420 + case 3813: + goto tr420 + case 3814: + goto tr420 + case 3815: + goto tr420 + case 3816: + goto tr420 + case 3817: + goto tr420 + case 3818: + goto tr420 + case 3819: + goto tr420 + case 3820: + goto tr420 + case 3821: + goto tr420 + case 3822: + goto tr420 + case 3823: + goto tr420 + case 3824: + goto tr420 + case 3825: + goto tr420 + case 3826: + goto tr420 + case 3827: + goto tr420 + case 3828: + goto tr420 + case 3829: + goto tr420 + case 3830: + goto tr420 + case 3831: + goto tr420 + case 3832: + goto tr420 + case 3833: + goto tr420 + case 3834: + goto tr420 + case 3835: + goto tr420 + case 3836: + goto tr420 + case 3837: + goto tr420 + case 3838: + goto tr420 + case 3839: + goto tr420 + case 3840: + goto tr420 + case 3841: + goto tr420 + case 3842: + goto tr420 + case 3843: + goto tr420 + case 3844: + goto tr420 + case 3845: + goto tr420 + case 3846: + goto tr420 + case 3847: + goto tr420 + case 3848: + goto tr420 + case 3849: + goto tr420 + case 3850: + goto tr420 + case 3851: + goto tr420 + case 3852: + goto tr420 + case 3853: + goto tr420 + case 3854: + goto tr420 + case 3855: + goto tr420 + case 3856: + goto tr420 + case 3857: + goto tr420 + case 3858: + goto tr420 + case 3859: + goto tr420 + case 3860: + goto tr420 + case 3861: + goto tr420 + case 3862: + goto tr420 + case 3863: + goto tr420 + case 3864: + goto tr420 + case 3865: + goto tr420 + case 3866: + goto tr420 + case 3867: + goto tr420 + case 3868: + goto tr420 + case 3869: + goto tr420 + case 3870: + goto tr420 + case 3871: + goto tr420 + case 3872: + goto tr420 + case 3873: + goto tr420 + case 3874: + goto tr420 + case 3875: + goto tr420 + case 3876: + goto tr420 + case 3877: + goto tr420 + case 3878: + goto tr420 + case 3879: + goto tr420 + case 3880: + goto tr420 + case 3881: + goto tr420 + case 3882: + goto tr420 + case 3883: + goto tr420 + case 3884: + goto tr420 + case 5079: + goto tr5002 + case 3885: + goto tr2985 + case 3886: + goto tr2985 + case 3887: + goto tr2985 + case 3888: + goto tr2985 + case 3889: + goto tr2985 + case 3890: + goto tr2985 + case 3891: + goto tr2985 + case 3892: + goto tr2985 + case 3893: + goto tr2985 + case 3894: + goto tr2985 + case 3895: + goto tr2985 + case 3896: + goto tr2985 + case 3897: + goto tr2985 + case 3898: + goto tr2985 + case 3899: + goto tr2985 + case 3900: + goto tr2985 + case 3901: + goto tr2985 + case 3902: + goto tr2985 + case 3903: + goto tr2985 + case 3904: + goto tr2985 + case 3905: + goto tr2985 + case 3906: + goto tr2985 + case 3907: + goto tr2985 + case 3908: + goto tr2985 + case 3909: + goto tr2985 + case 3910: + goto tr2985 + case 3911: + goto tr2985 + case 3912: + goto tr2985 + case 3913: + goto tr2985 + case 3914: + goto tr2985 + case 3915: + goto tr2985 + case 3916: + goto tr2985 + case 3917: + goto tr2985 + case 3918: + goto tr2985 + case 3919: + goto tr2985 + case 3920: + goto tr2985 + case 3921: + goto tr2985 + case 3922: + goto tr2985 + case 3923: + goto tr2985 + case 3924: + goto tr2985 + case 3925: + goto tr2985 + case 3926: + goto tr2985 + case 3927: + goto tr2985 + case 3928: + goto tr2985 + case 3929: + goto tr2985 + case 3930: + goto tr2985 + case 3931: + goto tr2985 + case 3932: + goto tr2985 + case 3933: + goto tr2985 + case 3934: + goto tr2985 + case 3935: + goto tr2985 + case 3936: + goto tr2985 + case 3937: + goto tr2985 + case 3938: + goto tr2985 + case 3939: + goto tr2985 + case 3940: + goto tr2985 + case 3941: + goto tr2985 + case 3942: + goto tr2985 + case 3943: + goto tr2985 + case 3944: + goto tr2985 + case 3945: + goto tr2985 + case 3946: + goto tr2985 + case 3947: + goto tr2985 + case 3948: + goto tr2985 + case 3949: + goto tr2985 + case 3950: + goto tr2985 + case 3951: + goto tr2985 + case 3952: + goto tr2985 + case 3953: + goto tr2985 + case 3954: + goto tr2985 + case 3955: + goto tr2985 + case 3956: + goto tr2985 + case 3957: + goto tr2985 + case 3958: + goto tr2985 + case 3959: + goto tr2985 + case 3960: + goto tr2985 + case 3961: + goto tr2985 + case 3962: + goto tr2985 + case 3963: + goto tr2985 + case 3964: + goto tr2985 + case 3965: + goto tr2985 + case 3966: + goto tr2985 + case 3967: + goto tr2985 + case 3968: + goto tr2985 + case 3969: + goto tr2985 + case 3970: + goto tr2985 + case 3971: + goto tr2985 + case 3972: + goto tr2985 + case 3973: + goto tr2985 + case 3974: + goto tr2985 + case 3975: + goto tr2985 + case 3976: + goto tr2985 + case 3977: + goto tr2985 + case 3978: + goto tr2985 + case 3979: + goto tr2985 + case 3980: + goto tr2985 + case 3981: + goto tr2985 + case 3982: + goto tr2985 + case 3983: + goto tr2985 + case 3984: + goto tr2985 + case 3985: + goto tr2985 + case 3986: + goto tr2985 + case 3987: + goto tr2985 + case 3988: + goto tr2985 + case 3989: + goto tr2985 + case 3990: + goto tr2985 + case 3991: + goto tr2985 + case 3992: + goto tr2985 + case 3993: + goto tr2985 + case 3994: + goto tr2985 + case 3995: + goto tr2985 + case 3996: + goto tr2985 + case 3997: + goto tr2985 + case 3998: + goto tr2985 + case 3999: + goto tr2985 + case 4000: + goto tr2985 + case 4001: + goto tr2985 + case 4002: + goto tr2985 + case 4003: + goto tr2985 + case 4004: + goto tr2985 + case 4005: + goto tr2985 + case 4006: + goto tr2985 + case 4007: + goto tr2985 + case 4008: + goto tr2985 + case 4009: + goto tr2985 + case 4010: + goto tr2985 + case 4011: + goto tr2985 + case 4012: + goto tr2985 + case 4013: + goto tr2985 + case 4014: + goto tr2985 + case 4015: + goto tr2985 + case 4016: + goto tr2985 + case 4017: + goto tr2985 + case 4018: + goto tr2985 + case 4019: + goto tr2985 + case 4020: + goto tr2985 + case 4021: + goto tr2985 + case 4022: + goto tr2985 + case 4023: + goto tr2985 + case 4024: + goto tr2985 + case 4025: + goto tr2985 + case 4026: + goto tr2985 + case 5080: + goto tr5137 + case 4027: + goto tr3627 + case 4028: + goto tr2 + case 4029: + goto tr3627 + case 4030: + goto tr3627 + case 4031: + goto tr3627 + case 4032: + goto tr3627 + case 4033: + goto tr3627 + case 4034: + goto tr3627 + case 4035: + goto tr3627 + case 4036: + goto tr3627 + case 4037: + goto tr3627 + case 4038: + goto tr3627 + case 4039: + goto tr3627 + case 4040: + goto tr3627 + case 4041: + goto tr3627 + case 4042: + goto tr3627 + case 4043: + goto tr3627 + case 4044: + goto tr3627 + case 4045: + goto tr3627 + case 4046: + goto tr3627 + case 4047: + goto tr3627 + case 4048: + goto tr3627 + case 4049: + goto tr3627 + case 4050: + goto tr3627 + case 4051: + goto tr3627 + case 4052: + goto tr3627 + case 4053: + goto tr3627 + case 4054: + goto tr3627 + case 4055: + goto tr3627 + case 4056: + goto tr3627 + case 4057: + goto tr3627 + case 4058: + goto tr3627 + case 4059: + goto tr3627 + case 4060: + goto tr3627 + case 4061: + goto tr3627 + case 4062: + goto tr3627 + case 4063: + goto tr3627 + case 4064: + goto tr3627 + case 4065: + goto tr3627 + case 4066: + goto tr3627 + case 4067: + goto tr3627 + case 4068: + goto tr3627 + case 4069: + goto tr3627 + case 4070: + goto tr3627 + case 4071: + goto tr3627 + case 4072: + goto tr3627 + case 4073: + goto tr3627 + case 4074: + goto tr3627 + case 4075: + goto tr3627 + case 4076: + goto tr3627 + case 4077: + goto tr3627 + case 4078: + goto tr3627 + case 4079: + goto tr3627 + case 4080: + goto tr3627 + case 4081: + goto tr3627 + case 4082: + goto tr3627 + case 4083: + goto tr3627 + case 4084: + goto tr3627 + case 4085: + goto tr3627 + case 4086: + goto tr3627 + case 4087: + goto tr3627 + case 4088: + goto tr3627 + case 4089: + goto tr3627 + case 4090: + goto tr3627 + case 4091: + goto tr3627 + case 4092: + goto tr3627 + case 4093: + goto tr3627 + case 4094: + goto tr3627 + case 4095: + goto tr3627 + case 4096: + goto tr3627 + case 4097: + goto tr3627 + case 4098: + goto tr3627 + case 4099: + goto tr3627 + case 4100: + goto tr3627 + case 4101: + goto tr2 + case 4102: + goto tr2 + case 4103: + goto tr2 + case 4104: + goto tr2 + case 4105: + goto tr3627 + case 4106: + goto tr3627 + case 4107: + goto tr3627 + case 4108: + goto tr3627 + case 4109: + goto tr3627 + case 4110: + goto tr3627 + case 4111: + goto tr3627 + case 4112: + goto tr3627 + case 4113: + goto tr3627 + case 4114: + goto tr3627 + case 4115: + goto tr3627 + case 4116: + goto tr3627 + case 4117: + goto tr3627 + case 4118: + goto tr3627 + case 4119: + goto tr3627 + case 4120: + goto tr3627 + case 4121: + goto tr3627 + case 4122: + goto tr3627 + case 4123: + goto tr3627 + case 4124: + goto tr3627 + case 4125: + goto tr3627 + case 4126: + goto tr3627 + case 4127: + goto tr3627 + case 4128: + goto tr3627 + case 4129: + goto tr3627 + case 4130: + goto tr3627 + case 4131: + goto tr3627 + case 4132: + goto tr3627 + case 4133: + goto tr3627 + case 4134: + goto tr3627 + case 4135: + goto tr3627 + case 4136: + goto tr3627 + case 4137: + goto tr3627 + case 4138: + goto tr3627 + case 4139: + goto tr3627 + case 4140: + goto tr3627 + case 4141: + goto tr3627 + case 4142: + goto tr3627 + case 4143: + goto tr3627 + case 4144: + goto tr3627 + case 4145: + goto tr3627 + case 4146: + goto tr3627 + case 4147: + goto tr3627 + case 4148: + goto tr3627 + case 4149: + goto tr3627 + case 4150: + goto tr3627 + case 4151: + goto tr3627 + case 4152: + goto tr3627 + case 4153: + goto tr3627 + case 4154: + goto tr3627 + case 4155: + goto tr3627 + case 4156: + goto tr3627 + case 4157: + goto tr3627 + case 4158: + goto tr3627 + case 4159: + goto tr3627 + case 4160: + goto tr3627 + case 4161: + goto tr3627 + case 4162: + goto tr3627 + case 4163: + goto tr3627 + case 4164: + goto tr3627 + case 4165: + goto tr3627 + case 4166: + goto tr3627 + case 4167: + goto tr3627 + case 4168: + goto tr3627 + case 4169: + goto tr3627 + case 4170: + goto tr3627 + case 4171: + goto tr3627 + case 4172: + goto tr3627 + case 4173: + goto tr3627 + case 4174: + goto tr3627 + case 4175: + goto tr0 + case 5081: + goto tr5157 + case 4176: + goto tr3758 + case 4177: + goto tr3758 + case 4178: + goto tr3758 + case 4179: + goto tr3758 + case 4180: + goto tr3758 + case 4181: + goto tr3758 + case 4182: + goto tr3758 + case 4183: + goto tr3758 + case 4184: + goto tr3758 + case 4185: + goto tr3758 + case 4186: + goto tr3758 + case 4187: + goto tr3758 + case 4188: + goto tr3758 + case 4189: + goto tr3758 + case 4190: + goto tr3758 + case 4191: + goto tr3758 + case 4192: + goto tr3758 + case 4193: + goto tr3758 + case 4194: + goto tr3758 + case 4195: + goto tr3758 + case 4196: + goto tr3758 + case 4197: + goto tr3758 + case 4198: + goto tr3758 + case 4199: + goto tr3758 + case 4200: + goto tr3758 + case 4201: + goto tr3758 + case 4202: + goto tr3758 + case 4203: + goto tr3758 + case 4204: + goto tr3758 + case 4205: + goto tr3758 + case 4206: + goto tr3758 + case 4207: + goto tr3758 + case 4208: + goto tr3758 + case 4209: + goto tr3758 + case 4210: + goto tr3758 + case 4211: + goto tr3758 + case 4212: + goto tr3758 + case 4213: + goto tr3758 + case 4214: + goto tr3758 + case 4215: + goto tr3758 + case 4216: + goto tr3758 + case 4217: + goto tr3758 + case 4218: + goto tr3758 + case 4219: + goto tr3758 + case 4220: + goto tr3758 + case 4221: + goto tr3758 + case 4222: + goto tr3758 + case 4223: + goto tr3758 + case 4224: + goto tr3758 + case 4225: + goto tr3758 + case 4226: + goto tr3758 + case 4227: + goto tr3758 + case 4228: + goto tr3758 + case 4229: + goto tr3758 + case 4230: + goto tr3758 + case 4231: + goto tr3758 + case 4232: + goto tr3758 + case 4233: + goto tr3758 + case 4234: + goto tr3758 + case 4235: + goto tr3758 + case 4236: + goto tr3758 + case 4237: + goto tr3758 + case 4238: + goto tr3758 + case 4239: + goto tr3758 + case 4240: + goto tr3758 + case 4241: + goto tr3758 + case 4242: + goto tr3758 + case 4243: + goto tr3758 + case 4244: + goto tr3758 + case 4245: + goto tr3758 + case 4246: + goto tr3758 + case 4247: + goto tr3758 + case 4248: + goto tr3758 + case 4249: + goto tr3758 + case 4250: + goto tr3758 + case 4251: + goto tr3758 + case 4252: + goto tr3758 + case 4253: + goto tr3758 + case 4254: + goto tr3758 + case 4255: + goto tr3758 + case 4256: + goto tr3758 + case 4257: + goto tr3758 + case 4258: + goto tr3758 + case 4259: + goto tr3758 + case 4260: + goto tr3758 + case 4261: + goto tr3758 + case 4262: + goto tr3758 + case 4263: + goto tr3758 + case 4264: + goto tr3758 + case 4265: + goto tr3758 + case 4266: + goto tr3758 + case 4267: + goto tr3758 + case 4268: + goto tr3758 + case 4269: + goto tr3758 + case 4270: + goto tr3758 + case 4271: + goto tr3758 + case 4272: + goto tr3758 + case 4273: + goto tr3758 + case 4274: + goto tr3758 + case 4275: + goto tr3758 + case 4276: + goto tr3758 + case 4277: + goto tr3758 + case 4278: + goto tr3758 + case 4279: + goto tr3758 + case 4280: + goto tr3758 + case 4281: + goto tr3758 + case 4282: + goto tr3758 + case 4283: + goto tr3758 + case 4284: + goto tr3758 + case 4285: + goto tr3758 + case 4286: + goto tr3758 + case 4287: + goto tr3758 + case 4288: + goto tr3758 + case 4289: + goto tr3758 + case 4290: + goto tr3758 + case 4291: + goto tr3758 + case 4292: + goto tr3758 + case 4293: + goto tr3758 + case 4294: + goto tr3758 + case 4295: + goto tr3758 + case 4296: + goto tr3758 + case 4297: + goto tr3758 + case 4298: + goto tr3758 + case 4299: + goto tr3758 + case 4300: + goto tr3758 + case 4301: + goto tr3758 + case 4302: + goto tr3758 + case 4303: + goto tr3758 + case 4304: + goto tr3758 + case 4305: + goto tr3758 + case 4306: + goto tr3758 + case 4307: + goto tr3758 + case 4308: + goto tr3758 + case 4309: + goto tr3758 + case 4310: + goto tr3758 + case 4311: + goto tr3758 + case 4312: + goto tr3758 + case 4313: + goto tr3758 + case 4314: + goto tr3758 + case 4315: + goto tr3758 + case 4316: + goto tr3758 + case 4317: + goto tr0 + case 4318: + goto tr0 + case 5082: + goto tr5054 + case 4319: + goto tr3251 + case 4320: + goto tr3251 + case 4321: + goto tr3251 + case 4322: + goto tr3251 + case 4323: + goto tr3251 + case 4324: + goto tr3251 + case 4325: + goto tr3251 + case 4326: + goto tr3251 + case 4327: + goto tr3251 + case 4328: + goto tr3251 + case 4329: + goto tr3251 + case 4330: + goto tr3251 + case 4331: + goto tr3251 + case 4332: + goto tr3251 + case 4333: + goto tr3251 + case 4334: + goto tr3251 + case 4335: + goto tr3251 + case 4336: + goto tr3251 + case 4337: + goto tr3251 + case 4338: + goto tr3251 + case 4339: + goto tr3251 + case 4340: + goto tr3251 + case 4341: + goto tr3251 + case 4342: + goto tr3251 + case 4343: + goto tr3251 + case 4344: + goto tr3251 + case 4345: + goto tr3251 + case 4346: + goto tr3251 + case 4347: + goto tr3251 + case 4348: + goto tr3251 + case 4349: + goto tr3251 + case 4350: + goto tr3251 + case 4351: + goto tr3251 + case 4352: + goto tr3251 + case 4353: + goto tr3251 + case 4354: + goto tr3251 + case 4355: + goto tr3251 + case 4356: + goto tr3251 + case 4357: + goto tr3251 + case 4358: + goto tr3251 + case 4359: + goto tr3251 + case 4360: + goto tr3251 + case 4361: + goto tr3251 + case 4362: + goto tr3251 + case 4363: + goto tr3251 + case 4364: + goto tr3251 + case 4365: + goto tr3251 + case 4366: + goto tr3251 + case 4367: + goto tr3251 + case 4368: + goto tr3251 + case 4369: + goto tr3251 + case 4370: + goto tr3251 + case 4371: + goto tr3251 + case 4372: + goto tr3251 + case 4373: + goto tr3251 + case 4374: + goto tr3251 + case 4375: + goto tr3251 + case 4376: + goto tr3251 + case 4377: + goto tr3251 + case 4378: + goto tr3251 + case 4379: + goto tr3251 + case 4380: + goto tr3251 + case 4381: + goto tr3251 + case 4382: + goto tr3251 + case 4383: + goto tr3251 + case 4384: + goto tr3251 + case 4385: + goto tr3251 + case 4386: + goto tr3251 + case 4387: + goto tr3251 + case 4388: + goto tr3251 + case 4389: + goto tr3251 + case 4390: + goto tr3251 + case 4391: + goto tr3251 + case 4392: + goto tr3251 + case 4393: + goto tr3251 + case 4394: + goto tr3251 + case 4395: + goto tr3251 + case 4396: + goto tr3251 + case 4397: + goto tr3251 + case 4398: + goto tr3251 + case 4399: + goto tr3251 + case 4400: + goto tr3251 + case 4401: + goto tr3251 + case 4402: + goto tr3251 + case 4403: + goto tr3251 + case 4404: + goto tr3251 + case 4405: + goto tr3251 + case 4406: + goto tr3251 + case 4407: + goto tr3251 + case 4408: + goto tr3251 + case 4409: + goto tr3251 + case 4410: + goto tr3251 + case 4411: + goto tr3251 + case 4412: + goto tr3251 + case 4413: + goto tr3251 + case 4414: + goto tr3251 + case 4415: + goto tr3251 + case 4416: + goto tr3251 + case 4417: + goto tr3251 + case 4418: + goto tr3251 + case 4419: + goto tr3251 + case 4420: + goto tr3251 + case 4421: + goto tr3251 + case 4422: + goto tr3251 + case 4423: + goto tr3251 + case 4424: + goto tr3251 + case 4425: + goto tr3251 + case 4426: + goto tr3251 + case 4427: + goto tr3251 + case 4428: + goto tr3251 + case 4429: + goto tr3251 + case 4430: + goto tr3251 + case 4431: + goto tr3251 + case 4432: + goto tr3251 + case 4433: + goto tr3251 + case 4434: + goto tr3251 + case 4435: + goto tr3251 + case 4436: + goto tr3251 + case 4437: + goto tr3251 + case 4438: + goto tr3251 + case 4439: + goto tr3251 + case 4440: + goto tr3251 + case 4441: + goto tr3251 + case 4442: + goto tr3251 + case 4443: + goto tr3251 + case 4444: + goto tr3251 + case 4445: + goto tr3251 + case 4446: + goto tr3251 + case 4447: + goto tr3251 + case 4448: + goto tr3251 + case 4449: + goto tr3251 + case 4450: + goto tr3251 + case 4451: + goto tr3251 + case 4452: + goto tr3251 + case 4453: + goto tr3251 + case 4454: + goto tr3251 + case 4455: + goto tr3251 + case 4456: + goto tr3251 + case 4457: + goto tr3251 + case 4458: + goto tr3251 + case 4459: + goto tr3251 + case 4460: + goto tr0 + case 4461: + goto tr0 + case 4462: + goto tr0 + case 4463: + goto tr0 + case 4464: + goto tr0 + case 4465: + goto tr0 + case 4466: + goto tr0 + case 4467: + goto tr0 + case 4468: + goto tr0 + case 4469: + goto tr0 + case 4470: + goto tr0 + case 4471: + goto tr0 + case 4472: + goto tr0 + case 5083: + goto tr5054 + case 5084: + goto tr5054 + case 5085: + goto tr5054 + case 5086: + goto tr4499 + case 5087: + goto tr4499 + case 5088: + goto tr5054 + case 5089: + goto tr5054 + case 5090: + goto tr4499 + case 5091: + goto tr4499 + case 5092: + goto tr4499 + case 5093: + goto tr4499 + case 5094: + goto tr4499 + case 5095: + goto tr4499 + case 5096: + goto tr4499 + case 5097: + goto tr4499 + case 5098: + goto tr5054 + case 5099: + goto tr5054 + case 5100: + goto tr5054 + case 5101: + goto tr5054 + case 5102: + goto tr5054 + case 5103: + goto tr5054 + case 5104: + goto tr5054 + case 5105: + goto tr5054 + case 5106: + goto tr4499 + case 5107: + goto tr4499 + case 5108: + goto tr4499 + case 5109: + goto tr4499 + case 5110: + goto tr4499 + case 5111: + goto tr4499 + case 5112: + goto tr4499 + case 5113: + goto tr4499 + case 5114: + goto tr4499 + case 5115: + goto tr4499 + case 5116: + goto tr4499 + case 5117: + goto tr5054 + case 5118: + goto tr5054 + case 5119: + goto tr5054 + case 5120: + goto tr5054 + case 5121: + goto tr5054 + case 5122: + goto tr5054 + case 5123: + goto tr5054 + case 5124: + goto tr5054 + case 5125: + goto tr5054 + case 5126: + goto tr5054 + case 5127: + goto tr5054 + case 5128: + goto tr5054 + case 5129: + goto tr5054 + case 5130: + goto tr5054 + case 5131: + goto tr5054 + case 5132: + goto tr5054 + case 5133: + goto tr5054 + case 5134: + goto tr5054 + case 5135: + goto tr5054 + case 5136: + goto tr5054 + case 5137: + goto tr5054 + case 5138: + goto tr5054 + case 5139: + goto tr5054 + case 5140: + goto tr5054 + case 5141: + goto tr5054 + case 5142: + goto tr5054 + case 5143: + goto tr5054 + case 5144: + goto tr5054 + case 5145: + goto tr5054 + case 5146: + goto tr5054 + case 5147: + goto tr5054 + case 5148: + goto tr5054 + case 5149: + goto tr5054 + case 5150: + goto tr5054 + case 5151: + goto tr5054 + case 5152: + goto tr5054 + case 4473: + goto tr0 + case 5153: + goto tr5054 + case 5154: + goto tr5054 + case 5155: + goto tr5054 + case 5156: + goto tr5054 + case 5157: + goto tr5054 + case 5158: + goto tr5054 + case 5159: + goto tr5054 + case 5160: + goto tr5054 + case 5161: + goto tr5054 + case 5162: + goto tr5054 + case 5163: + goto tr5054 + case 5164: + goto tr5054 + case 5165: + goto tr5054 + case 5166: + goto tr5054 + case 5167: + goto tr5054 + case 5168: + goto tr5054 + case 5169: + goto tr5054 + case 5170: + goto tr5054 + case 5171: + goto tr5054 + case 5172: + goto tr5054 + case 5173: + goto tr5054 + case 4474: + goto tr0 + case 5174: + goto tr5054 + case 5175: + goto tr5054 + case 5176: + goto tr5054 + case 5177: + goto tr5054 + case 5178: + goto tr5054 + case 5179: + goto tr5054 + case 4475: + goto tr0 + case 5180: + goto tr5054 + case 5181: + goto tr5054 + case 4476: + goto tr0 + case 5182: + goto tr5054 + case 5183: + goto tr5054 + case 5184: + goto tr5054 + case 5185: + goto tr5054 + case 5186: + goto tr5054 + case 5187: + goto tr5054 + case 5188: + goto tr5054 + case 5189: + goto tr5054 + case 5190: + goto tr5054 + case 5191: + goto tr5054 + case 5192: + goto tr5054 + case 5193: + goto tr5054 + case 5194: + goto tr5054 + case 5195: + goto tr5054 + case 5196: + goto tr5054 + case 4477: + goto tr0 + case 5197: + goto tr5054 + case 5198: + goto tr5054 + case 5199: + goto tr5054 + case 4478: + goto tr0 + case 5200: + goto tr5054 + case 5201: + goto tr5054 + case 5202: + goto tr5054 + case 5203: + goto tr5054 + case 5204: + goto tr5054 + case 5205: + goto tr5054 + case 4479: + goto tr0 + case 5206: + goto tr5054 + case 5207: + goto tr4499 + case 4480: + goto tr0 + case 5208: + goto tr4499 + case 5209: + goto tr4499 + case 5210: + goto tr4499 + case 4481: + goto tr0 + case 4482: + goto tr0 + case 4483: + goto tr0 + case 4484: + goto tr0 + case 4485: + goto tr0 + case 4486: + goto tr0 + case 4487: + goto tr0 + case 4488: + goto tr0 + case 4489: + goto tr0 + case 4490: + goto tr0 + case 4491: + goto tr0 + case 4492: + goto tr0 + case 4493: + goto tr0 + case 4494: + goto tr0 + case 4495: + goto tr0 + case 5211: + goto tr5002 + case 4496: + goto tr2985 + case 4497: + goto tr2985 + case 4498: + goto tr2985 + case 4499: + goto tr2985 + case 4500: + goto tr2985 + case 4501: + goto tr2985 + case 4502: + goto tr2985 + case 4503: + goto tr2985 + case 4504: + goto tr2985 + case 4505: + goto tr2985 + case 4506: + goto tr2985 + case 4507: + goto tr2985 + case 4508: + goto tr2985 + case 4509: + goto tr2985 + case 4510: + goto tr2985 + case 4511: + goto tr2985 + case 4512: + goto tr2985 + case 4513: + goto tr2985 + case 4514: + goto tr2985 + case 4515: + goto tr2985 + case 4516: + goto tr2985 + case 4517: + goto tr2985 + case 4518: + goto tr2985 + case 4519: + goto tr2985 + case 4520: + goto tr2985 + case 4521: + goto tr2985 + case 4522: + goto tr2985 + case 4523: + goto tr2985 + case 4524: + goto tr2985 + case 4525: + goto tr2985 + case 4526: + goto tr2985 + case 4527: + goto tr2985 + case 4528: + goto tr2985 + case 4529: + goto tr2985 + case 4530: + goto tr2985 + case 4531: + goto tr2985 + case 4532: + goto tr2985 + case 4533: + goto tr2985 + case 4534: + goto tr2985 + case 4535: + goto tr2985 + case 4536: + goto tr2985 + case 4537: + goto tr2985 + case 4538: + goto tr2985 + case 4539: + goto tr2985 + case 4540: + goto tr2985 + case 4541: + goto tr2985 + case 4542: + goto tr2985 + case 4543: + goto tr2985 + case 4544: + goto tr2985 + case 4545: + goto tr2985 + case 4546: + goto tr2985 + case 4547: + goto tr2985 + case 4548: + goto tr2985 + case 4549: + goto tr2985 + case 4550: + goto tr2985 + case 4551: + goto tr2985 + case 4552: + goto tr2985 + case 4553: + goto tr2985 + case 4554: + goto tr2985 + case 4555: + goto tr2985 + case 4556: + goto tr2985 + case 4557: + goto tr2985 + case 4558: + goto tr2985 + case 4559: + goto tr2985 + case 4560: + goto tr2985 + case 4561: + goto tr2985 + case 4562: + goto tr2985 + case 4563: + goto tr2985 + case 4564: + goto tr2985 + case 4565: + goto tr2985 + case 4566: + goto tr2985 + case 4567: + goto tr2985 + case 4568: + goto tr2985 + case 4569: + goto tr2985 + case 4570: + goto tr2985 + case 4571: + goto tr2985 + case 4572: + goto tr2985 + case 4573: + goto tr2985 + case 4574: + goto tr2985 + case 4575: + goto tr2985 + case 4576: + goto tr2985 + case 4577: + goto tr2985 + case 4578: + goto tr2985 + case 4579: + goto tr2985 + case 4580: + goto tr2985 + case 4581: + goto tr2985 + case 4582: + goto tr2985 + case 4583: + goto tr2985 + case 4584: + goto tr2985 + case 4585: + goto tr2985 + case 4586: + goto tr2985 + case 4587: + goto tr2985 + case 4588: + goto tr2985 + case 4589: + goto tr2985 + case 4590: + goto tr2985 + case 4591: + goto tr2985 + case 4592: + goto tr2985 + case 4593: + goto tr2985 + case 4594: + goto tr2985 + case 4595: + goto tr2985 + case 4596: + goto tr2985 + case 4597: + goto tr2985 + case 4598: + goto tr2985 + case 4599: + goto tr2985 + case 4600: + goto tr2985 + case 4601: + goto tr2985 + case 4602: + goto tr2985 + case 4603: + goto tr2985 + case 4604: + goto tr2985 + case 4605: + goto tr2985 + case 4606: + goto tr2985 + case 4607: + goto tr2985 + case 4608: + goto tr2985 + case 4609: + goto tr2985 + case 4610: + goto tr2985 + case 4611: + goto tr2985 + case 4612: + goto tr2985 + case 4613: + goto tr2985 + case 4614: + goto tr2985 + case 4615: + goto tr2985 + case 4616: + goto tr2985 + case 4617: + goto tr2985 + case 4618: + goto tr2985 + case 4619: + goto tr2985 + case 4620: + goto tr2985 + case 4621: + goto tr2985 + case 4622: + goto tr2985 + case 4623: + goto tr2985 + case 4624: + goto tr2985 + case 4625: + goto tr2985 + case 4626: + goto tr2985 + case 4627: + goto tr2985 + case 4628: + goto tr2985 + case 4629: + goto tr2985 + case 4630: + goto tr2985 + case 4631: + goto tr2985 + case 4632: + goto tr2985 + case 4633: + goto tr2985 + case 4634: + goto tr2985 + case 4635: + goto tr2985 + case 4636: + goto tr2985 + case 4637: + goto tr2985 + case 4638: + goto tr2985 + case 4639: + goto tr2985 + case 4640: + goto tr2985 + case 4641: + goto tr2985 + case 4642: + goto tr2985 + case 4643: + goto tr0 + case 4644: + goto tr0 + case 4645: + goto tr0 + case 4646: + goto tr0 + case 4647: + goto tr0 + case 4648: + goto tr0 + case 4649: + goto tr0 + case 4650: + goto tr0 + case 4651: + goto tr0 + case 4652: + goto tr0 + case 4653: + goto tr0 + case 4654: + goto tr0 + case 4655: + goto tr0 + case 5212: + goto tr5002 + case 5213: + goto tr5002 + case 5214: + goto tr5002 + case 5215: + goto tr4499 + case 5216: + goto tr4499 + case 5217: + goto tr5002 + case 5218: + goto tr5002 + case 5219: + goto tr4499 + case 5220: + goto tr4499 + case 5221: + goto tr4499 + case 5222: + goto tr4499 + case 5223: + goto tr4499 + case 5224: + goto tr4499 + case 5225: + goto tr4499 + case 5226: + goto tr4499 + case 5227: + goto tr5002 + case 5228: + goto tr5002 + case 5229: + goto tr5002 + case 5230: + goto tr5002 + case 5231: + goto tr5002 + case 5232: + goto tr5002 + case 5233: + goto tr5002 + case 5234: + goto tr5002 + case 5235: + goto tr4499 + case 5236: + goto tr4499 + case 5237: + goto tr4499 + case 5238: + goto tr4499 + case 5239: + goto tr4499 + case 5240: + goto tr4499 + case 5241: + goto tr4499 + case 5242: + goto tr4499 + case 4656: + goto tr0 + case 5243: + goto tr5002 + case 5244: + goto tr5002 + case 5245: + goto tr5002 + case 5246: + goto tr5002 + case 5247: + goto tr5002 + case 5248: + goto tr5002 + case 5249: + goto tr5002 + case 5250: + goto tr4499 + case 4657: + goto tr0 + case 5251: + goto tr5002 + case 5252: + goto tr5002 + case 5253: + goto tr5002 + case 5254: + goto tr5002 + case 5255: + goto tr5002 + case 5256: + goto tr5002 + case 4658: + goto tr0 + case 5257: + goto tr5002 + case 5258: + goto tr5002 + case 4659: + goto tr0 + case 5259: + goto tr5002 + case 5260: + goto tr5002 + case 5261: + goto tr5002 + case 5262: + goto tr5002 + case 5263: + goto tr5002 + case 5264: + goto tr4499 + case 5265: + goto tr4499 + case 5266: + goto tr4499 + case 5267: + goto tr4499 + case 5268: + goto tr5002 + case 5269: + goto tr5002 + case 5270: + goto tr5002 + case 5271: + goto tr5002 + case 5272: + goto tr5002 + case 5273: + goto tr5002 + case 5274: + goto tr5002 + case 5275: + goto tr5002 + case 5276: + goto tr5002 + case 5277: + goto tr5002 + case 4660: + goto tr0 + case 5278: + goto tr5002 + case 5279: + goto tr5002 + case 5280: + goto tr5002 + case 4661: + goto tr0 + case 5281: + goto tr5002 + case 5282: + goto tr5002 + case 5283: + goto tr5002 + case 5284: + goto tr5002 + case 5285: + goto tr5002 + case 5286: + goto tr5002 + case 4662: + goto tr0 + case 5287: + goto tr5002 + case 5288: + goto tr5002 + case 5289: + goto tr5002 + case 5290: + goto tr5002 + case 5291: + goto tr5002 + case 5292: + goto tr5002 + case 5293: + goto tr5002 + case 5294: + goto tr5002 + case 5295: + goto tr5002 + case 5296: + goto tr5002 + case 5297: + goto tr5002 + case 5298: + goto tr5002 + case 5299: + goto tr5002 + case 5300: + goto tr5002 + case 5301: + goto tr5002 + case 5302: + goto tr5002 + case 5303: + goto tr5002 + case 5304: + goto tr5002 + case 5305: + goto tr5002 + case 5306: + goto tr5002 + case 5307: + goto tr5002 + case 5308: + goto tr5002 + case 5309: + goto tr5002 + case 5310: + goto tr5002 + case 5311: + goto tr5002 + case 5312: + goto tr5002 + case 5313: + goto tr5002 + case 5314: + goto tr5002 + case 5315: + goto tr5002 + case 5316: + goto tr5002 + case 5317: + goto tr5002 + case 5318: + goto tr5002 + case 5319: + goto tr5002 + case 5320: + goto tr5002 + case 5321: + goto tr5002 + case 5322: + goto tr5002 + case 5323: + goto tr5002 + case 5324: + goto tr5002 + case 5325: + goto tr5002 + case 5326: + goto tr5002 + case 5327: + goto tr5002 + case 5328: + goto tr5002 + case 5329: + goto tr5002 + case 5330: + goto tr5002 + case 5331: + goto tr5002 + case 5332: + goto tr5002 + case 5333: + goto tr5002 + case 5334: + goto tr5002 + case 5335: + goto tr5002 + case 5336: + goto tr5002 + case 5337: + goto tr5002 + case 5338: + goto tr4499 + case 4663: + goto tr0 + case 4664: + goto tr0 + case 4665: + goto tr0 + case 4666: + goto tr0 + case 4667: + goto tr0 + case 4668: + goto tr0 + case 4669: + goto tr0 + case 4670: + goto tr0 + case 5339: + goto tr4499 + case 4671: + goto tr0 + case 4672: + goto tr0 + case 4673: + goto tr0 + case 4674: + goto tr0 + case 4675: + goto tr0 + case 4676: + goto tr0 + case 4677: + goto tr0 + case 4678: + goto tr0 + case 4679: + goto tr0 + case 4680: + goto tr0 + case 4681: + goto tr0 + case 4682: + goto tr0 + case 4683: + goto tr0 + case 4684: + goto tr0 + case 4685: + goto tr0 + case 4686: + goto tr0 + case 4687: + goto tr0 + case 4688: + goto tr0 + case 4689: + goto tr0 + case 4690: + goto tr0 + case 4691: + goto tr0 + case 4692: + goto tr0 + case 4693: + goto tr0 + case 4694: + goto tr0 + case 4695: + goto tr0 + case 4696: + goto tr0 + case 4697: + goto tr0 + case 4698: + goto tr0 + case 4699: + goto tr0 + case 4700: + goto tr0 + case 4701: + goto tr0 + case 4702: + goto tr0 + case 4703: + goto tr0 + case 4704: + goto tr0 + case 4705: + goto tr0 + case 4706: + goto tr0 + case 4707: + goto tr2 + case 5340: + goto tr5359 + case 4708: + goto tr4328 + case 4709: + goto tr4328 + case 4710: + goto tr4328 + case 4711: + goto tr4328 + case 4712: + goto tr4328 + case 4713: + goto tr4328 + case 4714: + goto tr4328 + case 4715: + goto tr4328 + case 4716: + goto tr4328 + case 4717: + goto tr4328 + case 4718: + goto tr4328 + case 4719: + goto tr4328 + case 4720: + goto tr4328 + case 4721: + goto tr4328 + case 4722: + goto tr4328 + case 4723: + goto tr4328 + case 4724: + goto tr4328 + case 4725: + goto tr4328 + case 4726: + goto tr4328 + case 4727: + goto tr4328 + case 4728: + goto tr4328 + case 4729: + goto tr4328 + case 4730: + goto tr4328 + case 4731: + goto tr4328 + case 4732: + goto tr4328 + case 4733: + goto tr4328 + case 4734: + goto tr4328 + case 4735: + goto tr4328 + case 4736: + goto tr4328 + case 4737: + goto tr4328 + case 4738: + goto tr4328 + case 4739: + goto tr4328 + case 4740: + goto tr4328 + case 4741: + goto tr4328 + case 4742: + goto tr4328 + case 4743: + goto tr4328 + case 4744: + goto tr4328 + case 4745: + goto tr4328 + case 4746: + goto tr4328 + case 4747: + goto tr4328 + case 4748: + goto tr4328 + case 4749: + goto tr4328 + case 4750: + goto tr4328 + case 4751: + goto tr4328 + case 4752: + goto tr4328 + case 4753: + goto tr4328 + case 4754: + goto tr4328 + case 4755: + goto tr4328 + case 4756: + goto tr4328 + case 4757: + goto tr4328 + case 4758: + goto tr4328 + case 4759: + goto tr4328 + case 4760: + goto tr4328 + case 4761: + goto tr4328 + case 4762: + goto tr4328 + case 4763: + goto tr4328 + case 4764: + goto tr4328 + case 4765: + goto tr4328 + case 4766: + goto tr4328 + case 4767: + goto tr4328 + case 4768: + goto tr4328 + case 4769: + goto tr4328 + case 4770: + goto tr4328 + case 4771: + goto tr4328 + case 4772: + goto tr4328 + case 4773: + goto tr4328 + case 4774: + goto tr4328 + case 4775: + goto tr4328 + case 4776: + goto tr4328 + case 4777: + goto tr4328 + case 4778: + goto tr4328 + case 4779: + goto tr4328 + case 4780: + goto tr4328 + case 4781: + goto tr4328 + case 4782: + goto tr4328 + case 4783: + goto tr4328 + case 4784: + goto tr4328 + case 4785: + goto tr4328 + case 4786: + goto tr4328 + case 4787: + goto tr4328 + case 4788: + goto tr4328 + case 4789: + goto tr4328 + case 4790: + goto tr4328 + case 4791: + goto tr4328 + case 4792: + goto tr4328 + case 4793: + goto tr4328 + case 4794: + goto tr4328 + case 4795: + goto tr4328 + case 4796: + goto tr4328 + case 4797: + goto tr4328 + case 4798: + goto tr4328 + case 4799: + goto tr4328 + case 4800: + goto tr4328 + case 4801: + goto tr4328 + case 4802: + goto tr4328 + case 4803: + goto tr4328 + case 4804: + goto tr4328 + case 4805: + goto tr4328 + case 4806: + goto tr4328 + case 4807: + goto tr4328 + case 4808: + goto tr4328 + case 4809: + goto tr4328 + case 4810: + goto tr4328 + case 4811: + goto tr4328 + case 4812: + goto tr4328 + case 4813: + goto tr4328 + case 4814: + goto tr4328 + case 4815: + goto tr4328 + case 4816: + goto tr4328 + case 4817: + goto tr4328 + case 4818: + goto tr4328 + case 4819: + goto tr4328 + case 4820: + goto tr4328 + case 4821: + goto tr4328 + case 4822: + goto tr4328 + case 4823: + goto tr4328 + case 4824: + goto tr4328 + case 4825: + goto tr4328 + case 4826: + goto tr4328 + case 4827: + goto tr4328 + case 4828: + goto tr4328 + case 4829: + goto tr4328 + case 4830: + goto tr4328 + case 4831: + goto tr4328 + case 4832: + goto tr4328 + case 4833: + goto tr4328 + case 4834: + goto tr4328 + case 4835: + goto tr4328 + case 4836: + goto tr4328 + case 4837: + goto tr4328 + case 4838: + goto tr4328 + case 4839: + goto tr4328 + case 4840: + goto tr4328 + case 4841: + goto tr4328 + case 4842: + goto tr4328 + case 4843: + goto tr4328 + case 4844: + goto tr4328 + case 4845: + goto tr4328 + case 4846: + goto tr4328 + case 4847: + goto tr4328 + case 4848: + goto tr4328 + case 4849: + goto tr4328 + case 4850: + goto tr0 + case 4851: + goto tr0 + case 4852: + goto tr0 + case 4853: + goto tr0 + case 4854: + goto tr0 + case 4855: + goto tr0 + case 4856: + goto tr0 + case 4857: + goto tr0 + case 4858: + goto tr0 + case 4859: + goto tr0 + case 4860: + goto tr0 + case 4861: + goto tr0 + case 4862: +//line segment_words.rl:68 + + startPos = p + +//line segment_words_prod.go:173630 + } + } + + } + +//line segment_words.rl:278 + + + if cs < s_first_final { + return val, types, totalConsumed, ParseError + } + + return val, types, totalConsumed, nil +} diff --git a/backend/vendor/github.com/blevesearch/snowballstem/COPYING b/backend/vendor/github.com/blevesearch/snowballstem/COPYING new file mode 100644 index 0000000000..f36607f9e9 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/snowballstem/COPYING @@ -0,0 +1,29 @@ +Copyright (c) 2001, Dr Martin Porter +Copyright (c) 2004,2005, Richard Boulton +Copyright (c) 2013, Yoshiki Shibukawa +Copyright (c) 2006,2007,2009,2010,2011,2014-2019, Olly Betts +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the Snowball project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/backend/vendor/github.com/blevesearch/snowballstem/README.md b/backend/vendor/github.com/blevesearch/snowballstem/README.md new file mode 100644 index 0000000000..bb4ff8ab96 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/snowballstem/README.md @@ -0,0 +1,66 @@ +# snowballstem + +This repository contains the Go stemmers generated by the [Snowball](https://github.com/snowballstem/snowball) project. They are maintained outside of the core bleve package so that they may be more easily be reused in other contexts. + +## Usage + +All these stemmers export a single `Stem()` method which operates on a snowball `Env` structure. The `Env` structure maintains all state for the stemmer. A new `Env` is created to point at an initial string. After stemming, the results of the `Stem()` operation can be retrieved using the `Current()` method. The `Env` structure can be reused for subsequent calls by using the `SetCurrent()` method. + +## Example + +``` +package main + +import ( + "fmt" + + "github.com/blevesearch/snowballstem" + "github.com/blevesearch/snowballstem/english" +) + +func main() { + + // words to stem + words := []string{ + "running", + "jumping", + } + + // build new environment + env := snowballstem.NewEnv("") + + for _, word := range words { + // set up environment for word + env.SetCurrent(word) + // invoke stemmer + english.Stem(env) + // print results + fmt.Printf("%s stemmed to %s\n", word, env.Current()) + } +} +``` +Produces Output: +``` +$ ./snowtest +running stemmed to run +jumping stemmed to jump +``` + +## Testing + +The test harness for these stemmers is hosted in the main [Snowball](https://github.com/snowballstem/snowball) repository. There are functional tests built around the separate [snowballstem-data](https://github.com/snowballstem/snowball-data) repository, and there is support for fuzz-testing the stemmers there as well. + +## Generating the Stemmers + +``` +$ export SNOWBALL=/path/to/github.com/snowballstem/snowball/after/snowball/built +$ go generate +``` + +## Updated the Go Generate Commands + +A simple tool is provided to automate these from the snowball algorithms directory: + +``` +$ go run gengen.go /path/to/github.com/snowballstem/snowball/algorithms +``` diff --git a/backend/vendor/github.com/blevesearch/snowballstem/among.go b/backend/vendor/github.com/blevesearch/snowballstem/among.go new file mode 100644 index 0000000000..1a0c70257f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/snowballstem/among.go @@ -0,0 +1,16 @@ +package snowballstem + +import "fmt" + +type AmongF func(env *Env, ctx interface{}) bool + +type Among struct { + Str string + A int32 + B int32 + F AmongF +} + +func (a *Among) String() string { + return fmt.Sprintf("str: `%s`, a: %d, b: %d, f: %p", a.Str, a.A, a.B, a.F) +} diff --git a/backend/vendor/github.com/blevesearch/snowballstem/english/english_stemmer.go b/backend/vendor/github.com/blevesearch/snowballstem/english/english_stemmer.go new file mode 100644 index 0000000000..87e1d48e7d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/snowballstem/english/english_stemmer.go @@ -0,0 +1,1341 @@ +//! This file was generated automatically by the Snowball to Go compiler +//! http://snowballstem.org/ + +package english + +import ( + snowballRuntime "github.com/blevesearch/snowballstem" +) + +var A_0 = []*snowballRuntime.Among{ + {Str: "arsen", A: -1, B: -1, F: nil}, + {Str: "commun", A: -1, B: -1, F: nil}, + {Str: "gener", A: -1, B: -1, F: nil}, +} + +var A_1 = []*snowballRuntime.Among{ + {Str: "'", A: -1, B: 1, F: nil}, + {Str: "'s'", A: 0, B: 1, F: nil}, + {Str: "'s", A: -1, B: 1, F: nil}, +} + +var A_2 = []*snowballRuntime.Among{ + {Str: "ied", A: -1, B: 2, F: nil}, + {Str: "s", A: -1, B: 3, F: nil}, + {Str: "ies", A: 1, B: 2, F: nil}, + {Str: "sses", A: 1, B: 1, F: nil}, + {Str: "ss", A: 1, B: -1, F: nil}, + {Str: "us", A: 1, B: -1, F: nil}, +} + +var A_3 = []*snowballRuntime.Among{ + {Str: "", A: -1, B: 3, F: nil}, + {Str: "bb", A: 0, B: 2, F: nil}, + {Str: "dd", A: 0, B: 2, F: nil}, + {Str: "ff", A: 0, B: 2, F: nil}, + {Str: "gg", A: 0, B: 2, F: nil}, + {Str: "bl", A: 0, B: 1, F: nil}, + {Str: "mm", A: 0, B: 2, F: nil}, + {Str: "nn", A: 0, B: 2, F: nil}, + {Str: "pp", A: 0, B: 2, F: nil}, + {Str: "rr", A: 0, B: 2, F: nil}, + {Str: "at", A: 0, B: 1, F: nil}, + {Str: "tt", A: 0, B: 2, F: nil}, + {Str: "iz", A: 0, B: 1, F: nil}, +} + +var A_4 = []*snowballRuntime.Among{ + {Str: "ed", A: -1, B: 2, F: nil}, + {Str: "eed", A: 0, B: 1, F: nil}, + {Str: "ing", A: -1, B: 2, F: nil}, + {Str: "edly", A: -1, B: 2, F: nil}, + {Str: "eedly", A: 3, B: 1, F: nil}, + {Str: "ingly", A: -1, B: 2, F: nil}, +} + +var A_5 = []*snowballRuntime.Among{ + {Str: "anci", A: -1, B: 3, F: nil}, + {Str: "enci", A: -1, B: 2, F: nil}, + {Str: "ogi", A: -1, B: 13, F: nil}, + {Str: "li", A: -1, B: 16, F: nil}, + {Str: "bli", A: 3, B: 12, F: nil}, + {Str: "abli", A: 4, B: 4, F: nil}, + {Str: "alli", A: 3, B: 8, F: nil}, + {Str: "fulli", A: 3, B: 14, F: nil}, + {Str: "lessli", A: 3, B: 15, F: nil}, + {Str: "ousli", A: 3, B: 10, F: nil}, + {Str: "entli", A: 3, B: 5, F: nil}, + {Str: "aliti", A: -1, B: 8, F: nil}, + {Str: "biliti", A: -1, B: 12, F: nil}, + {Str: "iviti", A: -1, B: 11, F: nil}, + {Str: "tional", A: -1, B: 1, F: nil}, + {Str: "ational", A: 14, B: 7, F: nil}, + {Str: "alism", A: -1, B: 8, F: nil}, + {Str: "ation", A: -1, B: 7, F: nil}, + {Str: "ization", A: 17, B: 6, F: nil}, + {Str: "izer", A: -1, B: 6, F: nil}, + {Str: "ator", A: -1, B: 7, F: nil}, + {Str: "iveness", A: -1, B: 11, F: nil}, + {Str: "fulness", A: -1, B: 9, F: nil}, + {Str: "ousness", A: -1, B: 10, F: nil}, +} + +var A_6 = []*snowballRuntime.Among{ + {Str: "icate", A: -1, B: 4, F: nil}, + {Str: "ative", A: -1, B: 6, F: nil}, + {Str: "alize", A: -1, B: 3, F: nil}, + {Str: "iciti", A: -1, B: 4, F: nil}, + {Str: "ical", A: -1, B: 4, F: nil}, + {Str: "tional", A: -1, B: 1, F: nil}, + {Str: "ational", A: 5, B: 2, F: nil}, + {Str: "ful", A: -1, B: 5, F: nil}, + {Str: "ness", A: -1, B: 5, F: nil}, +} + +var A_7 = []*snowballRuntime.Among{ + {Str: "ic", A: -1, B: 1, F: nil}, + {Str: "ance", A: -1, B: 1, F: nil}, + {Str: "ence", A: -1, B: 1, F: nil}, + {Str: "able", A: -1, B: 1, F: nil}, + {Str: "ible", A: -1, B: 1, F: nil}, + {Str: "ate", A: -1, B: 1, F: nil}, + {Str: "ive", A: -1, B: 1, F: nil}, + {Str: "ize", A: -1, B: 1, F: nil}, + {Str: "iti", A: -1, B: 1, F: nil}, + {Str: "al", A: -1, B: 1, F: nil}, + {Str: "ism", A: -1, B: 1, F: nil}, + {Str: "ion", A: -1, B: 2, F: nil}, + {Str: "er", A: -1, B: 1, F: nil}, + {Str: "ous", A: -1, B: 1, F: nil}, + {Str: "ant", A: -1, B: 1, F: nil}, + {Str: "ent", A: -1, B: 1, F: nil}, + {Str: "ment", A: 15, B: 1, F: nil}, + {Str: "ement", A: 16, B: 1, F: nil}, +} + +var A_8 = []*snowballRuntime.Among{ + {Str: "e", A: -1, B: 1, F: nil}, + {Str: "l", A: -1, B: 2, F: nil}, +} + +var A_9 = []*snowballRuntime.Among{ + {Str: "succeed", A: -1, B: -1, F: nil}, + {Str: "proceed", A: -1, B: -1, F: nil}, + {Str: "exceed", A: -1, B: -1, F: nil}, + {Str: "canning", A: -1, B: -1, F: nil}, + {Str: "inning", A: -1, B: -1, F: nil}, + {Str: "earring", A: -1, B: -1, F: nil}, + {Str: "herring", A: -1, B: -1, F: nil}, + {Str: "outing", A: -1, B: -1, F: nil}, +} + +var A_10 = []*snowballRuntime.Among{ + {Str: "andes", A: -1, B: -1, F: nil}, + {Str: "atlas", A: -1, B: -1, F: nil}, + {Str: "bias", A: -1, B: -1, F: nil}, + {Str: "cosmos", A: -1, B: -1, F: nil}, + {Str: "dying", A: -1, B: 3, F: nil}, + {Str: "early", A: -1, B: 9, F: nil}, + {Str: "gently", A: -1, B: 7, F: nil}, + {Str: "howe", A: -1, B: -1, F: nil}, + {Str: "idly", A: -1, B: 6, F: nil}, + {Str: "lying", A: -1, B: 4, F: nil}, + {Str: "news", A: -1, B: -1, F: nil}, + {Str: "only", A: -1, B: 10, F: nil}, + {Str: "singly", A: -1, B: 11, F: nil}, + {Str: "skies", A: -1, B: 2, F: nil}, + {Str: "skis", A: -1, B: 1, F: nil}, + {Str: "sky", A: -1, B: -1, F: nil}, + {Str: "tying", A: -1, B: 5, F: nil}, + {Str: "ugly", A: -1, B: 8, F: nil}, +} + +var G_v = []byte{17, 65, 16, 1} + +var G_v_WXY = []byte{1, 17, 65, 208, 1} + +var G_valid_LI = []byte{55, 141, 2} + +type Context struct { + b_Y_found bool + i_p2 int + i_p1 int +} + +func r_prelude(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 25 + // unset Y_found, line 26 + context.b_Y_found = false + // do, line 27 + var v_1 = env.Cursor +lab0: + for { + // (, line 27 + // [, line 27 + env.Bra = env.Cursor + // literal, line 27 + if !env.EqS("'") { + break lab0 + } + // ], line 27 + env.Ket = env.Cursor + // delete, line 27 + if !env.SliceDel() { + return false + } + break lab0 + } + env.Cursor = v_1 + // do, line 28 + var v_2 = env.Cursor +lab1: + for { + // (, line 28 + // [, line 28 + env.Bra = env.Cursor + // literal, line 28 + if !env.EqS("y") { + break lab1 + } + // ], line 28 + env.Ket = env.Cursor + // <-, line 28 + if !env.SliceFrom("Y") { + return false + } + // set Y_found, line 28 + context.b_Y_found = true + break lab1 + } + env.Cursor = v_2 + // do, line 29 + var v_3 = env.Cursor +lab2: + for { + // repeat, line 29 + replab3: + for { + var v_4 = env.Cursor + lab4: + for range [2]struct{}{} { + // (, line 29 + // goto, line 29 + golab5: + for { + var v_5 = env.Cursor + lab6: + for { + // (, line 29 + if !env.InGrouping(G_v, 97, 121) { + break lab6 + } + // [, line 29 + env.Bra = env.Cursor + // literal, line 29 + if !env.EqS("y") { + break lab6 + } + // ], line 29 + env.Ket = env.Cursor + env.Cursor = v_5 + break golab5 + } + env.Cursor = v_5 + if env.Cursor >= env.Limit { + break lab4 + } + env.NextChar() + } + // <-, line 29 + if !env.SliceFrom("Y") { + return false + } + // set Y_found, line 29 + context.b_Y_found = true + continue replab3 + } + env.Cursor = v_4 + break replab3 + } + break lab2 + } + env.Cursor = v_3 + return true +} + +func r_mark_regions(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 32 + context.i_p1 = env.Limit + context.i_p2 = env.Limit + // do, line 35 + var v_1 = env.Cursor +lab0: + for { + // (, line 35 + // or, line 41 + lab1: + for { + var v_2 = env.Cursor + lab2: + for { + // among, line 36 + if env.FindAmong(A_0, context) == 0 { + break lab2 + } + break lab1 + } + env.Cursor = v_2 + // (, line 41 + // gopast, line 41 + golab3: + for { + lab4: + for { + if !env.InGrouping(G_v, 97, 121) { + break lab4 + } + break golab3 + } + if env.Cursor >= env.Limit { + break lab0 + } + env.NextChar() + } + // gopast, line 41 + golab5: + for { + lab6: + for { + if !env.OutGrouping(G_v, 97, 121) { + break lab6 + } + break golab5 + } + if env.Cursor >= env.Limit { + break lab0 + } + env.NextChar() + } + break lab1 + } + // setmark p1, line 42 + context.i_p1 = env.Cursor + // gopast, line 43 + golab7: + for { + lab8: + for { + if !env.InGrouping(G_v, 97, 121) { + break lab8 + } + break golab7 + } + if env.Cursor >= env.Limit { + break lab0 + } + env.NextChar() + } + // gopast, line 43 + golab9: + for { + lab10: + for { + if !env.OutGrouping(G_v, 97, 121) { + break lab10 + } + break golab9 + } + if env.Cursor >= env.Limit { + break lab0 + } + env.NextChar() + } + // setmark p2, line 43 + context.i_p2 = env.Cursor + break lab0 + } + env.Cursor = v_1 + return true +} + +func r_shortv(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 49 + // or, line 51 +lab0: + for { + var v_1 = env.Limit - env.Cursor + lab1: + for { + // (, line 50 + if !env.OutGroupingB(G_v_WXY, 89, 121) { + break lab1 + } + if !env.InGroupingB(G_v, 97, 121) { + break lab1 + } + if !env.OutGroupingB(G_v, 97, 121) { + break lab1 + } + break lab0 + } + env.Cursor = env.Limit - v_1 + // (, line 52 + if !env.OutGroupingB(G_v, 97, 121) { + return false + } + if !env.InGroupingB(G_v, 97, 121) { + return false + } + // atlimit, line 52 + if env.Cursor > env.LimitBackward { + return false + } + break lab0 + } + return true +} + +func r_R1(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + if !(context.i_p1 <= env.Cursor) { + return false + } + return true +} + +func r_R2(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + if !(context.i_p2 <= env.Cursor) { + return false + } + return true +} + +func r_Step_1a(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 58 + // try, line 59 + var v_1 = env.Limit - env.Cursor +lab0: + for { + // (, line 59 + // [, line 60 + env.Ket = env.Cursor + // substring, line 60 + among_var = env.FindAmongB(A_1, context) + if among_var == 0 { + env.Cursor = env.Limit - v_1 + break lab0 + } + // ], line 60 + env.Bra = env.Cursor + if among_var == 0 { + env.Cursor = env.Limit - v_1 + break lab0 + } else if among_var == 1 { + // (, line 62 + // delete, line 62 + if !env.SliceDel() { + return false + } + } + break lab0 + } + // [, line 65 + env.Ket = env.Cursor + // substring, line 65 + among_var = env.FindAmongB(A_2, context) + if among_var == 0 { + return false + } + // ], line 65 + env.Bra = env.Cursor + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 66 + // <-, line 66 + if !env.SliceFrom("ss") { + return false + } + } else if among_var == 2 { + // (, line 68 + // or, line 68 + lab1: + for { + var v_2 = env.Limit - env.Cursor + lab2: + for { + // (, line 68 + { + // hop, line 68 + var c = env.ByteIndexForHop(-(2)) + if int32(env.LimitBackward) > c || c > int32(env.Limit) { + break lab2 + } + env.Cursor = int(c) + } + // <-, line 68 + if !env.SliceFrom("i") { + return false + } + break lab1 + } + env.Cursor = env.Limit - v_2 + // <-, line 68 + if !env.SliceFrom("ie") { + return false + } + break lab1 + } + } else if among_var == 3 { + // (, line 69 + // next, line 69 + if env.Cursor <= env.LimitBackward { + return false + } + env.PrevChar() + // gopast, line 69 + golab3: + for { + lab4: + for { + if !env.InGroupingB(G_v, 97, 121) { + break lab4 + } + break golab3 + } + if env.Cursor <= env.LimitBackward { + return false + } + env.PrevChar() + } + // delete, line 69 + if !env.SliceDel() { + return false + } + } + return true +} + +func r_Step_1b(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 74 + // [, line 75 + env.Ket = env.Cursor + // substring, line 75 + among_var = env.FindAmongB(A_4, context) + if among_var == 0 { + return false + } + // ], line 75 + env.Bra = env.Cursor + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 77 + // call R1, line 77 + if !r_R1(env, context) { + return false + } + // <-, line 77 + if !env.SliceFrom("ee") { + return false + } + } else if among_var == 2 { + // (, line 79 + // test, line 80 + var v_1 = env.Limit - env.Cursor + // gopast, line 80 + golab0: + for { + lab1: + for { + if !env.InGroupingB(G_v, 97, 121) { + break lab1 + } + break golab0 + } + if env.Cursor <= env.LimitBackward { + return false + } + env.PrevChar() + } + env.Cursor = env.Limit - v_1 + // delete, line 80 + if !env.SliceDel() { + return false + } + // test, line 81 + var v_3 = env.Limit - env.Cursor + // substring, line 81 + among_var = env.FindAmongB(A_3, context) + if among_var == 0 { + return false + } + env.Cursor = env.Limit - v_3 + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 83 + { + // <+, line 83 + var c = env.Cursor + bra, ket := env.Cursor, env.Cursor + env.Insert(bra, ket, "e") + env.Cursor = c + } + } else if among_var == 2 { + // (, line 86 + // [, line 86 + env.Ket = env.Cursor + // next, line 86 + if env.Cursor <= env.LimitBackward { + return false + } + env.PrevChar() + // ], line 86 + env.Bra = env.Cursor + // delete, line 86 + if !env.SliceDel() { + return false + } + } else if among_var == 3 { + // (, line 87 + // atmark, line 87 + if env.Cursor != context.i_p1 { + return false + } + // test, line 87 + var v_4 = env.Limit - env.Cursor + // call shortv, line 87 + if !r_shortv(env, context) { + return false + } + env.Cursor = env.Limit - v_4 + { + // <+, line 87 + var c = env.Cursor + bra, ket := env.Cursor, env.Cursor + env.Insert(bra, ket, "e") + env.Cursor = c + } + } + } + return true +} + +func r_Step_1c(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 93 + // [, line 94 + env.Ket = env.Cursor + // or, line 94 +lab0: + for { + var v_1 = env.Limit - env.Cursor + lab1: + for { + // literal, line 94 + if !env.EqSB("y") { + break lab1 + } + break lab0 + } + env.Cursor = env.Limit - v_1 + // literal, line 94 + if !env.EqSB("Y") { + return false + } + break lab0 + } + // ], line 94 + env.Bra = env.Cursor + if !env.OutGroupingB(G_v, 97, 121) { + return false + } + // not, line 95 + var v_2 = env.Limit - env.Cursor +lab2: + for { + // atlimit, line 95 + if env.Cursor > env.LimitBackward { + break lab2 + } + return false + } + env.Cursor = env.Limit - v_2 + // <-, line 96 + if !env.SliceFrom("i") { + return false + } + return true +} + +func r_Step_2(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 99 + // [, line 100 + env.Ket = env.Cursor + // substring, line 100 + among_var = env.FindAmongB(A_5, context) + if among_var == 0 { + return false + } + // ], line 100 + env.Bra = env.Cursor + // call R1, line 100 + if !r_R1(env, context) { + return false + } + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 101 + // <-, line 101 + if !env.SliceFrom("tion") { + return false + } + } else if among_var == 2 { + // (, line 102 + // <-, line 102 + if !env.SliceFrom("ence") { + return false + } + } else if among_var == 3 { + // (, line 103 + // <-, line 103 + if !env.SliceFrom("ance") { + return false + } + } else if among_var == 4 { + // (, line 104 + // <-, line 104 + if !env.SliceFrom("able") { + return false + } + } else if among_var == 5 { + // (, line 105 + // <-, line 105 + if !env.SliceFrom("ent") { + return false + } + } else if among_var == 6 { + // (, line 107 + // <-, line 107 + if !env.SliceFrom("ize") { + return false + } + } else if among_var == 7 { + // (, line 109 + // <-, line 109 + if !env.SliceFrom("ate") { + return false + } + } else if among_var == 8 { + // (, line 111 + // <-, line 111 + if !env.SliceFrom("al") { + return false + } + } else if among_var == 9 { + // (, line 112 + // <-, line 112 + if !env.SliceFrom("ful") { + return false + } + } else if among_var == 10 { + // (, line 114 + // <-, line 114 + if !env.SliceFrom("ous") { + return false + } + } else if among_var == 11 { + // (, line 116 + // <-, line 116 + if !env.SliceFrom("ive") { + return false + } + } else if among_var == 12 { + // (, line 118 + // <-, line 118 + if !env.SliceFrom("ble") { + return false + } + } else if among_var == 13 { + // (, line 119 + // literal, line 119 + if !env.EqSB("l") { + return false + } + // <-, line 119 + if !env.SliceFrom("og") { + return false + } + } else if among_var == 14 { + // (, line 120 + // <-, line 120 + if !env.SliceFrom("ful") { + return false + } + } else if among_var == 15 { + // (, line 121 + // <-, line 121 + if !env.SliceFrom("less") { + return false + } + } else if among_var == 16 { + // (, line 122 + if !env.InGroupingB(G_valid_LI, 99, 116) { + return false + } + // delete, line 122 + if !env.SliceDel() { + return false + } + } + return true +} + +func r_Step_3(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 126 + // [, line 127 + env.Ket = env.Cursor + // substring, line 127 + among_var = env.FindAmongB(A_6, context) + if among_var == 0 { + return false + } + // ], line 127 + env.Bra = env.Cursor + // call R1, line 127 + if !r_R1(env, context) { + return false + } + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 128 + // <-, line 128 + if !env.SliceFrom("tion") { + return false + } + } else if among_var == 2 { + // (, line 129 + // <-, line 129 + if !env.SliceFrom("ate") { + return false + } + } else if among_var == 3 { + // (, line 130 + // <-, line 130 + if !env.SliceFrom("al") { + return false + } + } else if among_var == 4 { + // (, line 132 + // <-, line 132 + if !env.SliceFrom("ic") { + return false + } + } else if among_var == 5 { + // (, line 134 + // delete, line 134 + if !env.SliceDel() { + return false + } + } else if among_var == 6 { + // (, line 136 + // call R2, line 136 + if !r_R2(env, context) { + return false + } + // delete, line 136 + if !env.SliceDel() { + return false + } + } + return true +} + +func r_Step_4(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 140 + // [, line 141 + env.Ket = env.Cursor + // substring, line 141 + among_var = env.FindAmongB(A_7, context) + if among_var == 0 { + return false + } + // ], line 141 + env.Bra = env.Cursor + // call R2, line 141 + if !r_R2(env, context) { + return false + } + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 144 + // delete, line 144 + if !env.SliceDel() { + return false + } + } else if among_var == 2 { + // (, line 145 + // or, line 145 + lab0: + for { + var v_1 = env.Limit - env.Cursor + lab1: + for { + // literal, line 145 + if !env.EqSB("s") { + break lab1 + } + break lab0 + } + env.Cursor = env.Limit - v_1 + // literal, line 145 + if !env.EqSB("t") { + return false + } + break lab0 + } + // delete, line 145 + if !env.SliceDel() { + return false + } + } + return true +} + +func r_Step_5(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 149 + // [, line 150 + env.Ket = env.Cursor + // substring, line 150 + among_var = env.FindAmongB(A_8, context) + if among_var == 0 { + return false + } + // ], line 150 + env.Bra = env.Cursor + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 151 + // or, line 151 + lab0: + for { + var v_1 = env.Limit - env.Cursor + lab1: + for { + // call R2, line 151 + if !r_R2(env, context) { + break lab1 + } + break lab0 + } + env.Cursor = env.Limit - v_1 + // (, line 151 + // call R1, line 151 + if !r_R1(env, context) { + return false + } + // not, line 151 + var v_2 = env.Limit - env.Cursor + lab2: + for { + // call shortv, line 151 + if !r_shortv(env, context) { + break lab2 + } + return false + } + env.Cursor = env.Limit - v_2 + break lab0 + } + // delete, line 151 + if !env.SliceDel() { + return false + } + } else if among_var == 2 { + // (, line 152 + // call R2, line 152 + if !r_R2(env, context) { + return false + } + // literal, line 152 + if !env.EqSB("l") { + return false + } + // delete, line 152 + if !env.SliceDel() { + return false + } + } + return true +} + +func r_exception2(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 156 + // [, line 158 + env.Ket = env.Cursor + // substring, line 158 + if env.FindAmongB(A_9, context) == 0 { + return false + } + // ], line 158 + env.Bra = env.Cursor + // atlimit, line 158 + if env.Cursor > env.LimitBackward { + return false + } + return true +} + +func r_exception1(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 168 + // [, line 170 + env.Bra = env.Cursor + // substring, line 170 + among_var = env.FindAmong(A_10, context) + if among_var == 0 { + return false + } + // ], line 170 + env.Ket = env.Cursor + // atlimit, line 170 + if env.Cursor < env.Limit { + return false + } + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 174 + // <-, line 174 + if !env.SliceFrom("ski") { + return false + } + } else if among_var == 2 { + // (, line 175 + // <-, line 175 + if !env.SliceFrom("sky") { + return false + } + } else if among_var == 3 { + // (, line 176 + // <-, line 176 + if !env.SliceFrom("die") { + return false + } + } else if among_var == 4 { + // (, line 177 + // <-, line 177 + if !env.SliceFrom("lie") { + return false + } + } else if among_var == 5 { + // (, line 178 + // <-, line 178 + if !env.SliceFrom("tie") { + return false + } + } else if among_var == 6 { + // (, line 182 + // <-, line 182 + if !env.SliceFrom("idl") { + return false + } + } else if among_var == 7 { + // (, line 183 + // <-, line 183 + if !env.SliceFrom("gentl") { + return false + } + } else if among_var == 8 { + // (, line 184 + // <-, line 184 + if !env.SliceFrom("ugli") { + return false + } + } else if among_var == 9 { + // (, line 185 + // <-, line 185 + if !env.SliceFrom("earli") { + return false + } + } else if among_var == 10 { + // (, line 186 + // <-, line 186 + if !env.SliceFrom("onli") { + return false + } + } else if among_var == 11 { + // (, line 187 + // <-, line 187 + if !env.SliceFrom("singl") { + return false + } + } + return true +} + +func r_postlude(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 203 + // Boolean test Y_found, line 203 + if !context.b_Y_found { + return false + } + // repeat, line 203 +replab0: + for { + var v_1 = env.Cursor + lab1: + for range [2]struct{}{} { + // (, line 203 + // goto, line 203 + golab2: + for { + var v_2 = env.Cursor + lab3: + for { + // (, line 203 + // [, line 203 + env.Bra = env.Cursor + // literal, line 203 + if !env.EqS("Y") { + break lab3 + } + // ], line 203 + env.Ket = env.Cursor + env.Cursor = v_2 + break golab2 + } + env.Cursor = v_2 + if env.Cursor >= env.Limit { + break lab1 + } + env.NextChar() + } + // <-, line 203 + if !env.SliceFrom("y") { + return false + } + continue replab0 + } + env.Cursor = v_1 + break replab0 + } + return true +} + +func Stem(env *snowballRuntime.Env) bool { + var context = &Context{ + b_Y_found: false, + i_p2: 0, + i_p1: 0, + } + _ = context + // (, line 205 + // or, line 207 +lab0: + for { + var v_1 = env.Cursor + lab1: + for { + // call exception1, line 207 + if !r_exception1(env, context) { + break lab1 + } + break lab0 + } + env.Cursor = v_1 + lab2: + for { + // not, line 208 + var v_2 = env.Cursor + lab3: + for { + { + // hop, line 208 + var c = env.ByteIndexForHop((3)) + if int32(0) > c || c > int32(env.Limit) { + break lab3 + } + env.Cursor = int(c) + } + break lab2 + } + env.Cursor = v_2 + break lab0 + } + env.Cursor = v_1 + // (, line 208 + // do, line 209 + var v_3 = env.Cursor + lab4: + for { + // call prelude, line 209 + if !r_prelude(env, context) { + break lab4 + } + break lab4 + } + env.Cursor = v_3 + // do, line 210 + var v_4 = env.Cursor + lab5: + for { + // call mark_regions, line 210 + if !r_mark_regions(env, context) { + break lab5 + } + break lab5 + } + env.Cursor = v_4 + // backwards, line 211 + env.LimitBackward = env.Cursor + env.Cursor = env.Limit + // (, line 211 + // do, line 213 + var v_5 = env.Limit - env.Cursor + lab6: + for { + // call Step_1a, line 213 + if !r_Step_1a(env, context) { + break lab6 + } + break lab6 + } + env.Cursor = env.Limit - v_5 + // or, line 215 + lab7: + for { + var v_6 = env.Limit - env.Cursor + lab8: + for { + // call exception2, line 215 + if !r_exception2(env, context) { + break lab8 + } + break lab7 + } + env.Cursor = env.Limit - v_6 + // (, line 215 + // do, line 217 + var v_7 = env.Limit - env.Cursor + lab9: + for { + // call Step_1b, line 217 + if !r_Step_1b(env, context) { + break lab9 + } + break lab9 + } + env.Cursor = env.Limit - v_7 + // do, line 218 + var v_8 = env.Limit - env.Cursor + lab10: + for { + // call Step_1c, line 218 + if !r_Step_1c(env, context) { + break lab10 + } + break lab10 + } + env.Cursor = env.Limit - v_8 + // do, line 220 + var v_9 = env.Limit - env.Cursor + lab11: + for { + // call Step_2, line 220 + if !r_Step_2(env, context) { + break lab11 + } + break lab11 + } + env.Cursor = env.Limit - v_9 + // do, line 221 + var v_10 = env.Limit - env.Cursor + lab12: + for { + // call Step_3, line 221 + if !r_Step_3(env, context) { + break lab12 + } + break lab12 + } + env.Cursor = env.Limit - v_10 + // do, line 222 + var v_11 = env.Limit - env.Cursor + lab13: + for { + // call Step_4, line 222 + if !r_Step_4(env, context) { + break lab13 + } + break lab13 + } + env.Cursor = env.Limit - v_11 + // do, line 224 + var v_12 = env.Limit - env.Cursor + lab14: + for { + // call Step_5, line 224 + if !r_Step_5(env, context) { + break lab14 + } + break lab14 + } + env.Cursor = env.Limit - v_12 + break lab7 + } + env.Cursor = env.LimitBackward + // do, line 227 + var v_13 = env.Cursor + lab15: + for { + // call postlude, line 227 + if !r_postlude(env, context) { + break lab15 + } + break lab15 + } + env.Cursor = v_13 + break lab0 + } + return true +} diff --git a/backend/vendor/github.com/blevesearch/snowballstem/env.go b/backend/vendor/github.com/blevesearch/snowballstem/env.go new file mode 100644 index 0000000000..6636994ac7 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/snowballstem/env.go @@ -0,0 +1,389 @@ +package snowballstem + +import ( + "log" + "strings" + "unicode/utf8" +) + +// Env represents the Snowball execution environment +type Env struct { + current string + Cursor int + Limit int + LimitBackward int + Bra int + Ket int +} + +// NewEnv creates a new Snowball execution environment on the provided string +func NewEnv(val string) *Env { + return &Env{ + current: val, + Cursor: 0, + Limit: len(val), + LimitBackward: 0, + Bra: 0, + Ket: len(val), + } +} + +func (env *Env) Current() string { + return env.current +} + +func (env *Env) SetCurrent(s string) { + env.current = s + env.Cursor = 0 + env.Limit = len(s) + env.LimitBackward = 0 + env.Bra = 0 + env.Ket = len(s) +} + +func (env *Env) ReplaceS(bra, ket int, s string) int32 { + adjustment := int32(len(s)) - (int32(ket) - int32(bra)) + result, _ := splitAt(env.current, bra) + rsplit := ket + if ket < bra { + rsplit = bra + } + _, rhs := splitAt(env.current, rsplit) + result += s + result += rhs + + newLim := int32(env.Limit) + adjustment + env.Limit = int(newLim) + + if env.Cursor >= ket { + newCur := int32(env.Cursor) + adjustment + env.Cursor = int(newCur) + } else if env.Cursor > bra { + env.Cursor = bra + } + + env.current = result + return adjustment +} + +func (env *Env) EqS(s string) bool { + if env.Cursor >= env.Limit { + return false + } + + if strings.HasPrefix(env.current[env.Cursor:], s) { + env.Cursor += len(s) + for !onCharBoundary(env.current, env.Cursor) { + env.Cursor++ + } + return true + } + return false +} + +func (env *Env) EqSB(s string) bool { + if int32(env.Cursor)-int32(env.LimitBackward) < int32(len(s)) { + return false + } else if !onCharBoundary(env.current, env.Cursor-len(s)) || + !strings.HasPrefix(env.current[env.Cursor-len(s):], s) { + return false + } else { + env.Cursor -= len(s) + return true + } +} + +func (env *Env) SliceFrom(s string) bool { + bra, ket := env.Bra, env.Ket + env.ReplaceS(bra, ket, s) + return true +} + +func (env *Env) NextChar() { + env.Cursor++ + for !onCharBoundary(env.current, env.Cursor) { + env.Cursor++ + } +} + +func (env *Env) PrevChar() { + env.Cursor-- + for !onCharBoundary(env.current, env.Cursor) { + env.Cursor-- + } +} + +func (env *Env) ByteIndexForHop(delta int32) int32 { + if delta > 0 { + res := env.Cursor + for delta > 0 { + res++ + delta-- + for res <= len(env.current) && !onCharBoundary(env.current, res) { + res++ + } + } + return int32(res) + } else if delta < 0 { + res := env.Cursor + for delta < 0 { + res-- + delta++ + for res >= 0 && !onCharBoundary(env.current, res) { + res-- + } + } + return int32(res) + } else { + return int32(env.Cursor) + } +} + +func (env *Env) InGrouping(chars []byte, min, max int32) bool { + if env.Cursor >= env.Limit { + return false + } + + r, _ := utf8.DecodeRuneInString(env.current[env.Cursor:]) + if r != utf8.RuneError { + if r > max || r < min { + return false + } + r -= min + if (chars[uint(r>>3)] & (0x1 << uint(r&0x7))) == 0 { + return false + } + env.NextChar() + return true + } + return false +} + +func (env *Env) InGroupingB(chars []byte, min, max int32) bool { + if env.Cursor <= env.LimitBackward { + return false + } + env.PrevChar() + r, _ := utf8.DecodeRuneInString(env.current[env.Cursor:]) + if r != utf8.RuneError { + env.NextChar() + if r > max || r < min { + return false + } + r -= min + if (chars[uint(r>>3)] & (0x1 << uint(r&0x7))) == 0 { + return false + } + env.PrevChar() + return true + } + return false +} + +func (env *Env) OutGrouping(chars []byte, min, max int32) bool { + if env.Cursor >= env.Limit { + return false + } + r, _ := utf8.DecodeRuneInString(env.current[env.Cursor:]) + if r != utf8.RuneError { + if r > max || r < min { + env.NextChar() + return true + } + r -= min + if (chars[uint(r>>3)] & (0x1 << uint(r&0x7))) == 0 { + env.NextChar() + return true + } + } + return false +} + +func (env *Env) OutGroupingB(chars []byte, min, max int32) bool { + if env.Cursor <= env.LimitBackward { + return false + } + env.PrevChar() + r, _ := utf8.DecodeRuneInString(env.current[env.Cursor:]) + if r != utf8.RuneError { + env.NextChar() + if r > max || r < min { + env.PrevChar() + return true + } + r -= min + if (chars[uint(r>>3)] & (0x1 << uint(r&0x7))) == 0 { + env.PrevChar() + return true + } + } + return false +} + +func (env *Env) SliceDel() bool { + return env.SliceFrom("") +} + +func (env *Env) Insert(bra, ket int, s string) { + adjustment := env.ReplaceS(bra, ket, s) + if bra <= env.Bra { + env.Bra = int(int32(env.Bra) + adjustment) + } + if bra <= env.Ket { + env.Ket = int(int32(env.Ket) + adjustment) + } +} + +func (env *Env) SliceTo() string { + return env.current[env.Bra:env.Ket] +} + +func (env *Env) FindAmong(amongs []*Among, ctx interface{}) int32 { + var i int32 + j := int32(len(amongs)) + + c := env.Cursor + l := env.Limit + + var commonI, commonJ int + + firstKeyInspected := false + for { + k := i + ((j - i) >> 1) + var diff int32 + common := min(commonI, commonJ) + w := amongs[k] + for lvar := common; lvar < len(w.Str); lvar++ { + if c+common == l { + diff-- + break + } + diff = int32(env.current[c+common]) - int32(w.Str[lvar]) + if diff != 0 { + break + } + common++ + } + if diff < 0 { + j = k + commonJ = common + } else { + i = k + commonI = common + } + if j-i <= 1 { + if i > 0 { + break + } + if j == i { + break + } + if firstKeyInspected { + break + } + firstKeyInspected = true + } + } + + for { + w := amongs[i] + if commonI >= len(w.Str) { + env.Cursor = c + len(w.Str) + if w.F != nil { + res := w.F(env, ctx) + env.Cursor = c + len(w.Str) + if res { + return w.B + } + } else { + return w.B + } + } + i = w.A + if i < 0 { + return 0 + } + } +} + +func (env *Env) FindAmongB(amongs []*Among, ctx interface{}) int32 { + var i int32 + j := int32(len(amongs)) + + c := env.Cursor + lb := env.LimitBackward + + var commonI, commonJ int + + firstKeyInspected := false + + for { + k := i + ((j - i) >> 1) + diff := int32(0) + common := min(commonI, commonJ) + w := amongs[k] + for lvar := len(w.Str) - int(common) - 1; lvar >= 0; lvar-- { + if c-common == lb { + diff-- + break + } + diff = int32(env.current[c-common-1]) - int32(w.Str[lvar]) + if diff != 0 { + break + } + // Count up commons. But not one character but the byte width of that char + common++ + } + if diff < 0 { + j = k + commonJ = common + } else { + i = k + commonI = common + } + if j-i <= 1 { + if i > 0 { + break + } + if j == i { + break + } + if firstKeyInspected { + break + } + firstKeyInspected = true + } + } + for { + w := amongs[i] + if commonI >= len(w.Str) { + env.Cursor = c - len(w.Str) + if w.F != nil { + res := w.F(env, ctx) + env.Cursor = c - len(w.Str) + if res { + return w.B + } + } else { + return w.B + } + } + i = w.A + if i < 0 { + return 0 + } + } +} + +func (env *Env) Debug(count, lineNumber int) { + log.Printf("snowball debug, count: %d, line: %d", count, lineNumber) +} + +func (env *Env) Clone() *Env { + clone := *env + return &clone +} + +func (env *Env) AssignTo() string { + return env.Current() +} diff --git a/backend/vendor/github.com/blevesearch/snowballstem/finnish/finnish_stemmer.go b/backend/vendor/github.com/blevesearch/snowballstem/finnish/finnish_stemmer.go new file mode 100644 index 0000000000..e1db5befd2 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/snowballstem/finnish/finnish_stemmer.go @@ -0,0 +1,994 @@ +//! This file was generated automatically by the Snowball to Go compiler +//! http://snowballstem.org/ + +package finnish + +import ( + snowballRuntime "github.com/blevesearch/snowballstem" +) + +var A_0 = []*snowballRuntime.Among{ + {Str: "pa", A: -1, B: 1, F: nil}, + {Str: "sti", A: -1, B: 2, F: nil}, + {Str: "kaan", A: -1, B: 1, F: nil}, + {Str: "han", A: -1, B: 1, F: nil}, + {Str: "kin", A: -1, B: 1, F: nil}, + {Str: "h\u00E4n", A: -1, B: 1, F: nil}, + {Str: "k\u00E4\u00E4n", A: -1, B: 1, F: nil}, + {Str: "ko", A: -1, B: 1, F: nil}, + {Str: "p\u00E4", A: -1, B: 1, F: nil}, + {Str: "k\u00F6", A: -1, B: 1, F: nil}, +} + +var A_1 = []*snowballRuntime.Among{ + {Str: "lla", A: -1, B: -1, F: nil}, + {Str: "na", A: -1, B: -1, F: nil}, + {Str: "ssa", A: -1, B: -1, F: nil}, + {Str: "ta", A: -1, B: -1, F: nil}, + {Str: "lta", A: 3, B: -1, F: nil}, + {Str: "sta", A: 3, B: -1, F: nil}, +} + +var A_2 = []*snowballRuntime.Among{ + {Str: "ll\u00E4", A: -1, B: -1, F: nil}, + {Str: "n\u00E4", A: -1, B: -1, F: nil}, + {Str: "ss\u00E4", A: -1, B: -1, F: nil}, + {Str: "t\u00E4", A: -1, B: -1, F: nil}, + {Str: "lt\u00E4", A: 3, B: -1, F: nil}, + {Str: "st\u00E4", A: 3, B: -1, F: nil}, +} + +var A_3 = []*snowballRuntime.Among{ + {Str: "lle", A: -1, B: -1, F: nil}, + {Str: "ine", A: -1, B: -1, F: nil}, +} + +var A_4 = []*snowballRuntime.Among{ + {Str: "nsa", A: -1, B: 3, F: nil}, + {Str: "mme", A: -1, B: 3, F: nil}, + {Str: "nne", A: -1, B: 3, F: nil}, + {Str: "ni", A: -1, B: 2, F: nil}, + {Str: "si", A: -1, B: 1, F: nil}, + {Str: "an", A: -1, B: 4, F: nil}, + {Str: "en", A: -1, B: 6, F: nil}, + {Str: "\u00E4n", A: -1, B: 5, F: nil}, + {Str: "ns\u00E4", A: -1, B: 3, F: nil}, +} + +var A_5 = []*snowballRuntime.Among{ + {Str: "aa", A: -1, B: -1, F: nil}, + {Str: "ee", A: -1, B: -1, F: nil}, + {Str: "ii", A: -1, B: -1, F: nil}, + {Str: "oo", A: -1, B: -1, F: nil}, + {Str: "uu", A: -1, B: -1, F: nil}, + {Str: "\u00E4\u00E4", A: -1, B: -1, F: nil}, + {Str: "\u00F6\u00F6", A: -1, B: -1, F: nil}, +} + +var A_6 = []*snowballRuntime.Among{ + {Str: "a", A: -1, B: 8, F: nil}, + {Str: "lla", A: 0, B: -1, F: nil}, + {Str: "na", A: 0, B: -1, F: nil}, + {Str: "ssa", A: 0, B: -1, F: nil}, + {Str: "ta", A: 0, B: -1, F: nil}, + {Str: "lta", A: 4, B: -1, F: nil}, + {Str: "sta", A: 4, B: -1, F: nil}, + {Str: "tta", A: 4, B: 9, F: nil}, + {Str: "lle", A: -1, B: -1, F: nil}, + {Str: "ine", A: -1, B: -1, F: nil}, + {Str: "ksi", A: -1, B: -1, F: nil}, + {Str: "n", A: -1, B: 7, F: nil}, + {Str: "han", A: 11, B: 1, F: nil}, + {Str: "den", A: 11, B: -1, F: r_VI}, + {Str: "seen", A: 11, B: -1, F: r_LONG}, + {Str: "hen", A: 11, B: 2, F: nil}, + {Str: "tten", A: 11, B: -1, F: r_VI}, + {Str: "hin", A: 11, B: 3, F: nil}, + {Str: "siin", A: 11, B: -1, F: r_VI}, + {Str: "hon", A: 11, B: 4, F: nil}, + {Str: "h\u00E4n", A: 11, B: 5, F: nil}, + {Str: "h\u00F6n", A: 11, B: 6, F: nil}, + {Str: "\u00E4", A: -1, B: 8, F: nil}, + {Str: "ll\u00E4", A: 22, B: -1, F: nil}, + {Str: "n\u00E4", A: 22, B: -1, F: nil}, + {Str: "ss\u00E4", A: 22, B: -1, F: nil}, + {Str: "t\u00E4", A: 22, B: -1, F: nil}, + {Str: "lt\u00E4", A: 26, B: -1, F: nil}, + {Str: "st\u00E4", A: 26, B: -1, F: nil}, + {Str: "tt\u00E4", A: 26, B: 9, F: nil}, +} + +var A_7 = []*snowballRuntime.Among{ + {Str: "eja", A: -1, B: -1, F: nil}, + {Str: "mma", A: -1, B: 1, F: nil}, + {Str: "imma", A: 1, B: -1, F: nil}, + {Str: "mpa", A: -1, B: 1, F: nil}, + {Str: "impa", A: 3, B: -1, F: nil}, + {Str: "mmi", A: -1, B: 1, F: nil}, + {Str: "immi", A: 5, B: -1, F: nil}, + {Str: "mpi", A: -1, B: 1, F: nil}, + {Str: "impi", A: 7, B: -1, F: nil}, + {Str: "ej\u00E4", A: -1, B: -1, F: nil}, + {Str: "mm\u00E4", A: -1, B: 1, F: nil}, + {Str: "imm\u00E4", A: 10, B: -1, F: nil}, + {Str: "mp\u00E4", A: -1, B: 1, F: nil}, + {Str: "imp\u00E4", A: 12, B: -1, F: nil}, +} + +var A_8 = []*snowballRuntime.Among{ + {Str: "i", A: -1, B: -1, F: nil}, + {Str: "j", A: -1, B: -1, F: nil}, +} + +var A_9 = []*snowballRuntime.Among{ + {Str: "mma", A: -1, B: 1, F: nil}, + {Str: "imma", A: 0, B: -1, F: nil}, +} + +var G_AEI = []byte{17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8} + +var G_V1 = []byte{17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32} + +var G_V2 = []byte{17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32} + +var G_particle_end = []byte{17, 97, 24, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32} + +type Context struct { + b_ending_removed bool + S_x string + i_p2 int + i_p1 int +} + +func r_mark_regions(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 41 + context.i_p1 = env.Limit + context.i_p2 = env.Limit + // goto, line 46 +golab0: + for { + var v_1 = env.Cursor + lab1: + for { + if !env.InGrouping(G_V1, 97, 246) { + break lab1 + } + env.Cursor = v_1 + break golab0 + } + env.Cursor = v_1 + if env.Cursor >= env.Limit { + return false + } + env.NextChar() + } + // gopast, line 46 +golab2: + for { + lab3: + for { + if !env.OutGrouping(G_V1, 97, 246) { + break lab3 + } + break golab2 + } + if env.Cursor >= env.Limit { + return false + } + env.NextChar() + } + // setmark p1, line 46 + context.i_p1 = env.Cursor + // goto, line 47 +golab4: + for { + var v_3 = env.Cursor + lab5: + for { + if !env.InGrouping(G_V1, 97, 246) { + break lab5 + } + env.Cursor = v_3 + break golab4 + } + env.Cursor = v_3 + if env.Cursor >= env.Limit { + return false + } + env.NextChar() + } + // gopast, line 47 +golab6: + for { + lab7: + for { + if !env.OutGrouping(G_V1, 97, 246) { + break lab7 + } + break golab6 + } + if env.Cursor >= env.Limit { + return false + } + env.NextChar() + } + // setmark p2, line 47 + context.i_p2 = env.Cursor + return true +} + +func r_R2(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + if !(context.i_p2 <= env.Cursor) { + return false + } + return true +} + +func r_particle_etc(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 54 + // setlimit, line 55 + var v_1 = env.Limit - env.Cursor + // tomark, line 55 + if env.Cursor < context.i_p1 { + return false + } + env.Cursor = context.i_p1 + var v_2 = env.LimitBackward + env.LimitBackward = env.Cursor + env.Cursor = env.Limit - v_1 + // (, line 55 + // [, line 55 + env.Ket = env.Cursor + // substring, line 55 + among_var = env.FindAmongB(A_0, context) + if among_var == 0 { + env.LimitBackward = v_2 + return false + } + // ], line 55 + env.Bra = env.Cursor + env.LimitBackward = v_2 + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 62 + if !env.InGroupingB(G_particle_end, 97, 246) { + return false + } + } else if among_var == 2 { + // (, line 64 + // call R2, line 64 + if !r_R2(env, context) { + return false + } + } + // delete, line 66 + if !env.SliceDel() { + return false + } + return true +} + +func r_possessive(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 68 + // setlimit, line 69 + var v_1 = env.Limit - env.Cursor + // tomark, line 69 + if env.Cursor < context.i_p1 { + return false + } + env.Cursor = context.i_p1 + var v_2 = env.LimitBackward + env.LimitBackward = env.Cursor + env.Cursor = env.Limit - v_1 + // (, line 69 + // [, line 69 + env.Ket = env.Cursor + // substring, line 69 + among_var = env.FindAmongB(A_4, context) + if among_var == 0 { + env.LimitBackward = v_2 + return false + } + // ], line 69 + env.Bra = env.Cursor + env.LimitBackward = v_2 + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 72 + // not, line 72 + var v_3 = env.Limit - env.Cursor + lab0: + for { + // literal, line 72 + if !env.EqSB("k") { + break lab0 + } + return false + } + env.Cursor = env.Limit - v_3 + // delete, line 72 + if !env.SliceDel() { + return false + } + } else if among_var == 2 { + // (, line 74 + // delete, line 74 + if !env.SliceDel() { + return false + } + // [, line 74 + env.Ket = env.Cursor + // literal, line 74 + if !env.EqSB("kse") { + return false + } + // ], line 74 + env.Bra = env.Cursor + // <-, line 74 + if !env.SliceFrom("ksi") { + return false + } + } else if among_var == 3 { + // (, line 78 + // delete, line 78 + if !env.SliceDel() { + return false + } + } else if among_var == 4 { + // (, line 81 + // among, line 81 + if env.FindAmongB(A_1, context) == 0 { + return false + } + // delete, line 81 + if !env.SliceDel() { + return false + } + } else if among_var == 5 { + // (, line 83 + // among, line 83 + if env.FindAmongB(A_2, context) == 0 { + return false + } + // delete, line 84 + if !env.SliceDel() { + return false + } + } else if among_var == 6 { + // (, line 86 + // among, line 86 + if env.FindAmongB(A_3, context) == 0 { + return false + } + // delete, line 86 + if !env.SliceDel() { + return false + } + } + return true +} + +func r_LONG(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // among, line 91 + if env.FindAmongB(A_5, context) == 0 { + return false + } + return true +} + +func r_VI(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 93 + // literal, line 93 + if !env.EqSB("i") { + return false + } + if !env.InGroupingB(G_V2, 97, 246) { + return false + } + return true +} + +func r_case_ending(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 95 + // setlimit, line 96 + var v_1 = env.Limit - env.Cursor + // tomark, line 96 + if env.Cursor < context.i_p1 { + return false + } + env.Cursor = context.i_p1 + var v_2 = env.LimitBackward + env.LimitBackward = env.Cursor + env.Cursor = env.Limit - v_1 + // (, line 96 + // [, line 96 + env.Ket = env.Cursor + // substring, line 96 + among_var = env.FindAmongB(A_6, context) + if among_var == 0 { + env.LimitBackward = v_2 + return false + } + // ], line 96 + env.Bra = env.Cursor + env.LimitBackward = v_2 + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 98 + // literal, line 98 + if !env.EqSB("a") { + return false + } + } else if among_var == 2 { + // (, line 99 + // literal, line 99 + if !env.EqSB("e") { + return false + } + } else if among_var == 3 { + // (, line 100 + // literal, line 100 + if !env.EqSB("i") { + return false + } + } else if among_var == 4 { + // (, line 101 + // literal, line 101 + if !env.EqSB("o") { + return false + } + } else if among_var == 5 { + // (, line 102 + // literal, line 102 + if !env.EqSB("\u00E4") { + return false + } + } else if among_var == 6 { + // (, line 103 + // literal, line 103 + if !env.EqSB("\u00F6") { + return false + } + } else if among_var == 7 { + // (, line 111 + // try, line 111 + var v_3 = env.Limit - env.Cursor + lab0: + for { + // (, line 111 + // and, line 113 + var v_4 = env.Limit - env.Cursor + // or, line 112 + lab1: + for { + var v_5 = env.Limit - env.Cursor + lab2: + for { + // call LONG, line 111 + if !r_LONG(env, context) { + break lab2 + } + break lab1 + } + env.Cursor = env.Limit - v_5 + // literal, line 112 + if !env.EqSB("ie") { + env.Cursor = env.Limit - v_3 + break lab0 + } + break lab1 + } + env.Cursor = env.Limit - v_4 + // next, line 113 + if env.Cursor <= env.LimitBackward { + env.Cursor = env.Limit - v_3 + break lab0 + } + env.PrevChar() + // ], line 113 + env.Bra = env.Cursor + break lab0 + } + } else if among_var == 8 { + // (, line 119 + if !env.InGroupingB(G_V1, 97, 246) { + return false + } + if !env.OutGroupingB(G_V1, 97, 246) { + return false + } + } else if among_var == 9 { + // (, line 121 + // literal, line 121 + if !env.EqSB("e") { + return false + } + } + // delete, line 138 + if !env.SliceDel() { + return false + } + // set ending_removed, line 139 + context.b_ending_removed = true + return true +} + +func r_other_endings(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 141 + // setlimit, line 142 + var v_1 = env.Limit - env.Cursor + // tomark, line 142 + if env.Cursor < context.i_p2 { + return false + } + env.Cursor = context.i_p2 + var v_2 = env.LimitBackward + env.LimitBackward = env.Cursor + env.Cursor = env.Limit - v_1 + // (, line 142 + // [, line 142 + env.Ket = env.Cursor + // substring, line 142 + among_var = env.FindAmongB(A_7, context) + if among_var == 0 { + env.LimitBackward = v_2 + return false + } + // ], line 142 + env.Bra = env.Cursor + env.LimitBackward = v_2 + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 146 + // not, line 146 + var v_3 = env.Limit - env.Cursor + lab0: + for { + // literal, line 146 + if !env.EqSB("po") { + break lab0 + } + return false + } + env.Cursor = env.Limit - v_3 + } + // delete, line 151 + if !env.SliceDel() { + return false + } + return true +} + +func r_i_plural(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 153 + // setlimit, line 154 + var v_1 = env.Limit - env.Cursor + // tomark, line 154 + if env.Cursor < context.i_p1 { + return false + } + env.Cursor = context.i_p1 + var v_2 = env.LimitBackward + env.LimitBackward = env.Cursor + env.Cursor = env.Limit - v_1 + // (, line 154 + // [, line 154 + env.Ket = env.Cursor + // substring, line 154 + if env.FindAmongB(A_8, context) == 0 { + env.LimitBackward = v_2 + return false + } + // ], line 154 + env.Bra = env.Cursor + env.LimitBackward = v_2 + // delete, line 158 + if !env.SliceDel() { + return false + } + return true +} + +func r_t_plural(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 160 + // setlimit, line 161 + var v_1 = env.Limit - env.Cursor + // tomark, line 161 + if env.Cursor < context.i_p1 { + return false + } + env.Cursor = context.i_p1 + var v_2 = env.LimitBackward + env.LimitBackward = env.Cursor + env.Cursor = env.Limit - v_1 + // (, line 161 + // [, line 162 + env.Ket = env.Cursor + // literal, line 162 + if !env.EqSB("t") { + env.LimitBackward = v_2 + return false + } + // ], line 162 + env.Bra = env.Cursor + // test, line 162 + var v_3 = env.Limit - env.Cursor + if !env.InGroupingB(G_V1, 97, 246) { + env.LimitBackward = v_2 + return false + } + env.Cursor = env.Limit - v_3 + // delete, line 163 + if !env.SliceDel() { + return false + } + env.LimitBackward = v_2 + // setlimit, line 165 + var v_4 = env.Limit - env.Cursor + // tomark, line 165 + if env.Cursor < context.i_p2 { + return false + } + env.Cursor = context.i_p2 + var v_5 = env.LimitBackward + env.LimitBackward = env.Cursor + env.Cursor = env.Limit - v_4 + // (, line 165 + // [, line 165 + env.Ket = env.Cursor + // substring, line 165 + among_var = env.FindAmongB(A_9, context) + if among_var == 0 { + env.LimitBackward = v_5 + return false + } + // ], line 165 + env.Bra = env.Cursor + env.LimitBackward = v_5 + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 167 + // not, line 167 + var v_6 = env.Limit - env.Cursor + lab0: + for { + // literal, line 167 + if !env.EqSB("po") { + break lab0 + } + return false + } + env.Cursor = env.Limit - v_6 + } + // delete, line 170 + if !env.SliceDel() { + return false + } + return true +} + +func r_tidy(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 172 + // setlimit, line 173 + var v_1 = env.Limit - env.Cursor + // tomark, line 173 + if env.Cursor < context.i_p1 { + return false + } + env.Cursor = context.i_p1 + var v_2 = env.LimitBackward + env.LimitBackward = env.Cursor + env.Cursor = env.Limit - v_1 + // (, line 173 + // do, line 174 + var v_3 = env.Limit - env.Cursor +lab0: + for { + // (, line 174 + // and, line 174 + var v_4 = env.Limit - env.Cursor + // call LONG, line 174 + if !r_LONG(env, context) { + break lab0 + } + env.Cursor = env.Limit - v_4 + // (, line 174 + // [, line 174 + env.Ket = env.Cursor + // next, line 174 + if env.Cursor <= env.LimitBackward { + break lab0 + } + env.PrevChar() + // ], line 174 + env.Bra = env.Cursor + // delete, line 174 + if !env.SliceDel() { + return false + } + break lab0 + } + env.Cursor = env.Limit - v_3 + // do, line 175 + var v_5 = env.Limit - env.Cursor +lab1: + for { + // (, line 175 + // [, line 175 + env.Ket = env.Cursor + if !env.InGroupingB(G_AEI, 97, 228) { + break lab1 + } + // ], line 175 + env.Bra = env.Cursor + if !env.OutGroupingB(G_V1, 97, 246) { + break lab1 + } + // delete, line 175 + if !env.SliceDel() { + return false + } + break lab1 + } + env.Cursor = env.Limit - v_5 + // do, line 176 + var v_6 = env.Limit - env.Cursor +lab2: + for { + // (, line 176 + // [, line 176 + env.Ket = env.Cursor + // literal, line 176 + if !env.EqSB("j") { + break lab2 + } + // ], line 176 + env.Bra = env.Cursor + // or, line 176 + lab3: + for { + var v_7 = env.Limit - env.Cursor + lab4: + for { + // literal, line 176 + if !env.EqSB("o") { + break lab4 + } + break lab3 + } + env.Cursor = env.Limit - v_7 + // literal, line 176 + if !env.EqSB("u") { + break lab2 + } + break lab3 + } + // delete, line 176 + if !env.SliceDel() { + return false + } + break lab2 + } + env.Cursor = env.Limit - v_6 + // do, line 177 + var v_8 = env.Limit - env.Cursor +lab5: + for { + // (, line 177 + // [, line 177 + env.Ket = env.Cursor + // literal, line 177 + if !env.EqSB("o") { + break lab5 + } + // ], line 177 + env.Bra = env.Cursor + // literal, line 177 + if !env.EqSB("j") { + break lab5 + } + // delete, line 177 + if !env.SliceDel() { + return false + } + break lab5 + } + env.Cursor = env.Limit - v_8 + env.LimitBackward = v_2 + // goto, line 179 +golab6: + for { + var v_9 = env.Limit - env.Cursor + lab7: + for { + if !env.OutGroupingB(G_V1, 97, 246) { + break lab7 + } + env.Cursor = env.Limit - v_9 + break golab6 + } + env.Cursor = env.Limit - v_9 + if env.Cursor <= env.LimitBackward { + return false + } + env.PrevChar() + } + // [, line 179 + env.Ket = env.Cursor + // next, line 179 + if env.Cursor <= env.LimitBackward { + return false + } + env.PrevChar() + // ], line 179 + env.Bra = env.Cursor + // -> x, line 179 + context.S_x = env.SliceTo() + if context.S_x == "" { + return false + } + // name x, line 179 + if !env.EqSB(context.S_x) { + return false + } + // delete, line 179 + if !env.SliceDel() { + return false + } + return true +} + +func Stem(env *snowballRuntime.Env) bool { + var context = &Context{ + b_ending_removed: false, + S_x: "", + i_p2: 0, + i_p1: 0, + } + _ = context + // (, line 183 + // do, line 185 + var v_1 = env.Cursor +lab0: + for { + // call mark_regions, line 185 + if !r_mark_regions(env, context) { + break lab0 + } + break lab0 + } + env.Cursor = v_1 + // unset ending_removed, line 186 + context.b_ending_removed = false + // backwards, line 187 + env.LimitBackward = env.Cursor + env.Cursor = env.Limit + // (, line 187 + // do, line 188 + var v_2 = env.Limit - env.Cursor +lab1: + for { + // call particle_etc, line 188 + if !r_particle_etc(env, context) { + break lab1 + } + break lab1 + } + env.Cursor = env.Limit - v_2 + // do, line 189 + var v_3 = env.Limit - env.Cursor +lab2: + for { + // call possessive, line 189 + if !r_possessive(env, context) { + break lab2 + } + break lab2 + } + env.Cursor = env.Limit - v_3 + // do, line 190 + var v_4 = env.Limit - env.Cursor +lab3: + for { + // call case_ending, line 190 + if !r_case_ending(env, context) { + break lab3 + } + break lab3 + } + env.Cursor = env.Limit - v_4 + // do, line 191 + var v_5 = env.Limit - env.Cursor +lab4: + for { + // call other_endings, line 191 + if !r_other_endings(env, context) { + break lab4 + } + break lab4 + } + env.Cursor = env.Limit - v_5 + // or, line 192 +lab5: + for { + var v_6 = env.Limit - env.Cursor + lab6: + for { + // (, line 192 + // Boolean test ending_removed, line 192 + if !context.b_ending_removed { + break lab6 + } + // do, line 192 + var v_7 = env.Limit - env.Cursor + lab7: + for { + // call i_plural, line 192 + if !r_i_plural(env, context) { + break lab7 + } + break lab7 + } + env.Cursor = env.Limit - v_7 + break lab5 + } + env.Cursor = env.Limit - v_6 + // do, line 192 + var v_8 = env.Limit - env.Cursor + lab8: + for { + // call t_plural, line 192 + if !r_t_plural(env, context) { + break lab8 + } + break lab8 + } + env.Cursor = env.Limit - v_8 + break lab5 + } + // do, line 193 + var v_9 = env.Limit - env.Cursor +lab9: + for { + // call tidy, line 193 + if !r_tidy(env, context) { + break lab9 + } + break lab9 + } + env.Cursor = env.Limit - v_9 + env.Cursor = env.LimitBackward + return true +} diff --git a/backend/vendor/github.com/blevesearch/snowballstem/french/french_stemmer.go b/backend/vendor/github.com/blevesearch/snowballstem/french/french_stemmer.go new file mode 100644 index 0000000000..b8cc3546f5 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/snowballstem/french/french_stemmer.go @@ -0,0 +1,1535 @@ +//! This file was generated automatically by the Snowball to Go compiler +//! http://snowballstem.org/ + +package french + +import ( + snowballRuntime "github.com/blevesearch/snowballstem" +) + +var A_0 = []*snowballRuntime.Among{ + {Str: "col", A: -1, B: -1, F: nil}, + {Str: "par", A: -1, B: -1, F: nil}, + {Str: "tap", A: -1, B: -1, F: nil}, +} + +var A_1 = []*snowballRuntime.Among{ + {Str: "", A: -1, B: 4, F: nil}, + {Str: "I", A: 0, B: 1, F: nil}, + {Str: "U", A: 0, B: 2, F: nil}, + {Str: "Y", A: 0, B: 3, F: nil}, +} + +var A_2 = []*snowballRuntime.Among{ + {Str: "iqU", A: -1, B: 3, F: nil}, + {Str: "abl", A: -1, B: 3, F: nil}, + {Str: "I\u00E8r", A: -1, B: 4, F: nil}, + {Str: "i\u00E8r", A: -1, B: 4, F: nil}, + {Str: "eus", A: -1, B: 2, F: nil}, + {Str: "iv", A: -1, B: 1, F: nil}, +} + +var A_3 = []*snowballRuntime.Among{ + {Str: "ic", A: -1, B: 2, F: nil}, + {Str: "abil", A: -1, B: 1, F: nil}, + {Str: "iv", A: -1, B: 3, F: nil}, +} + +var A_4 = []*snowballRuntime.Among{ + {Str: "iqUe", A: -1, B: 1, F: nil}, + {Str: "atrice", A: -1, B: 2, F: nil}, + {Str: "ance", A: -1, B: 1, F: nil}, + {Str: "ence", A: -1, B: 5, F: nil}, + {Str: "logie", A: -1, B: 3, F: nil}, + {Str: "able", A: -1, B: 1, F: nil}, + {Str: "isme", A: -1, B: 1, F: nil}, + {Str: "euse", A: -1, B: 11, F: nil}, + {Str: "iste", A: -1, B: 1, F: nil}, + {Str: "ive", A: -1, B: 8, F: nil}, + {Str: "if", A: -1, B: 8, F: nil}, + {Str: "usion", A: -1, B: 4, F: nil}, + {Str: "ation", A: -1, B: 2, F: nil}, + {Str: "ution", A: -1, B: 4, F: nil}, + {Str: "ateur", A: -1, B: 2, F: nil}, + {Str: "iqUes", A: -1, B: 1, F: nil}, + {Str: "atrices", A: -1, B: 2, F: nil}, + {Str: "ances", A: -1, B: 1, F: nil}, + {Str: "ences", A: -1, B: 5, F: nil}, + {Str: "logies", A: -1, B: 3, F: nil}, + {Str: "ables", A: -1, B: 1, F: nil}, + {Str: "ismes", A: -1, B: 1, F: nil}, + {Str: "euses", A: -1, B: 11, F: nil}, + {Str: "istes", A: -1, B: 1, F: nil}, + {Str: "ives", A: -1, B: 8, F: nil}, + {Str: "ifs", A: -1, B: 8, F: nil}, + {Str: "usions", A: -1, B: 4, F: nil}, + {Str: "ations", A: -1, B: 2, F: nil}, + {Str: "utions", A: -1, B: 4, F: nil}, + {Str: "ateurs", A: -1, B: 2, F: nil}, + {Str: "ments", A: -1, B: 15, F: nil}, + {Str: "ements", A: 30, B: 6, F: nil}, + {Str: "issements", A: 31, B: 12, F: nil}, + {Str: "it\u00E9s", A: -1, B: 7, F: nil}, + {Str: "ment", A: -1, B: 15, F: nil}, + {Str: "ement", A: 34, B: 6, F: nil}, + {Str: "issement", A: 35, B: 12, F: nil}, + {Str: "amment", A: 34, B: 13, F: nil}, + {Str: "emment", A: 34, B: 14, F: nil}, + {Str: "aux", A: -1, B: 10, F: nil}, + {Str: "eaux", A: 39, B: 9, F: nil}, + {Str: "eux", A: -1, B: 1, F: nil}, + {Str: "it\u00E9", A: -1, B: 7, F: nil}, +} + +var A_5 = []*snowballRuntime.Among{ + {Str: "ira", A: -1, B: 1, F: nil}, + {Str: "ie", A: -1, B: 1, F: nil}, + {Str: "isse", A: -1, B: 1, F: nil}, + {Str: "issante", A: -1, B: 1, F: nil}, + {Str: "i", A: -1, B: 1, F: nil}, + {Str: "irai", A: 4, B: 1, F: nil}, + {Str: "ir", A: -1, B: 1, F: nil}, + {Str: "iras", A: -1, B: 1, F: nil}, + {Str: "ies", A: -1, B: 1, F: nil}, + {Str: "\u00EEmes", A: -1, B: 1, F: nil}, + {Str: "isses", A: -1, B: 1, F: nil}, + {Str: "issantes", A: -1, B: 1, F: nil}, + {Str: "\u00EEtes", A: -1, B: 1, F: nil}, + {Str: "is", A: -1, B: 1, F: nil}, + {Str: "irais", A: 13, B: 1, F: nil}, + {Str: "issais", A: 13, B: 1, F: nil}, + {Str: "irions", A: -1, B: 1, F: nil}, + {Str: "issions", A: -1, B: 1, F: nil}, + {Str: "irons", A: -1, B: 1, F: nil}, + {Str: "issons", A: -1, B: 1, F: nil}, + {Str: "issants", A: -1, B: 1, F: nil}, + {Str: "it", A: -1, B: 1, F: nil}, + {Str: "irait", A: 21, B: 1, F: nil}, + {Str: "issait", A: 21, B: 1, F: nil}, + {Str: "issant", A: -1, B: 1, F: nil}, + {Str: "iraIent", A: -1, B: 1, F: nil}, + {Str: "issaIent", A: -1, B: 1, F: nil}, + {Str: "irent", A: -1, B: 1, F: nil}, + {Str: "issent", A: -1, B: 1, F: nil}, + {Str: "iront", A: -1, B: 1, F: nil}, + {Str: "\u00EEt", A: -1, B: 1, F: nil}, + {Str: "iriez", A: -1, B: 1, F: nil}, + {Str: "issiez", A: -1, B: 1, F: nil}, + {Str: "irez", A: -1, B: 1, F: nil}, + {Str: "issez", A: -1, B: 1, F: nil}, +} + +var A_6 = []*snowballRuntime.Among{ + {Str: "a", A: -1, B: 3, F: nil}, + {Str: "era", A: 0, B: 2, F: nil}, + {Str: "asse", A: -1, B: 3, F: nil}, + {Str: "ante", A: -1, B: 3, F: nil}, + {Str: "\u00E9e", A: -1, B: 2, F: nil}, + {Str: "ai", A: -1, B: 3, F: nil}, + {Str: "erai", A: 5, B: 2, F: nil}, + {Str: "er", A: -1, B: 2, F: nil}, + {Str: "as", A: -1, B: 3, F: nil}, + {Str: "eras", A: 8, B: 2, F: nil}, + {Str: "\u00E2mes", A: -1, B: 3, F: nil}, + {Str: "asses", A: -1, B: 3, F: nil}, + {Str: "antes", A: -1, B: 3, F: nil}, + {Str: "\u00E2tes", A: -1, B: 3, F: nil}, + {Str: "\u00E9es", A: -1, B: 2, F: nil}, + {Str: "ais", A: -1, B: 3, F: nil}, + {Str: "erais", A: 15, B: 2, F: nil}, + {Str: "ions", A: -1, B: 1, F: nil}, + {Str: "erions", A: 17, B: 2, F: nil}, + {Str: "assions", A: 17, B: 3, F: nil}, + {Str: "erons", A: -1, B: 2, F: nil}, + {Str: "ants", A: -1, B: 3, F: nil}, + {Str: "\u00E9s", A: -1, B: 2, F: nil}, + {Str: "ait", A: -1, B: 3, F: nil}, + {Str: "erait", A: 23, B: 2, F: nil}, + {Str: "ant", A: -1, B: 3, F: nil}, + {Str: "aIent", A: -1, B: 3, F: nil}, + {Str: "eraIent", A: 26, B: 2, F: nil}, + {Str: "\u00E8rent", A: -1, B: 2, F: nil}, + {Str: "assent", A: -1, B: 3, F: nil}, + {Str: "eront", A: -1, B: 2, F: nil}, + {Str: "\u00E2t", A: -1, B: 3, F: nil}, + {Str: "ez", A: -1, B: 2, F: nil}, + {Str: "iez", A: 32, B: 2, F: nil}, + {Str: "eriez", A: 33, B: 2, F: nil}, + {Str: "assiez", A: 33, B: 3, F: nil}, + {Str: "erez", A: 32, B: 2, F: nil}, + {Str: "\u00E9", A: -1, B: 2, F: nil}, +} + +var A_7 = []*snowballRuntime.Among{ + {Str: "e", A: -1, B: 3, F: nil}, + {Str: "I\u00E8re", A: 0, B: 2, F: nil}, + {Str: "i\u00E8re", A: 0, B: 2, F: nil}, + {Str: "ion", A: -1, B: 1, F: nil}, + {Str: "Ier", A: -1, B: 2, F: nil}, + {Str: "ier", A: -1, B: 2, F: nil}, + {Str: "\u00EB", A: -1, B: 4, F: nil}, +} + +var A_8 = []*snowballRuntime.Among{ + {Str: "ell", A: -1, B: -1, F: nil}, + {Str: "eill", A: -1, B: -1, F: nil}, + {Str: "enn", A: -1, B: -1, F: nil}, + {Str: "onn", A: -1, B: -1, F: nil}, + {Str: "ett", A: -1, B: -1, F: nil}, +} + +var G_v = []byte{17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 130, 103, 8, 5} + +var G_keep_with_s = []byte{1, 65, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128} + +type Context struct { + i_p2 int + i_p1 int + i_pV int +} + +func r_prelude(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // repeat, line 38 +replab0: + for { + var v_1 = env.Cursor + lab1: + for range [2]struct{}{} { + // goto, line 38 + golab2: + for { + var v_2 = env.Cursor + lab3: + for { + // (, line 38 + // or, line 44 + lab4: + for { + var v_3 = env.Cursor + lab5: + for { + // (, line 40 + if !env.InGrouping(G_v, 97, 251) { + break lab5 + } + // [, line 40 + env.Bra = env.Cursor + // or, line 40 + lab6: + for { + var v_4 = env.Cursor + lab7: + for { + // (, line 40 + // literal, line 40 + if !env.EqS("u") { + break lab7 + } + // ], line 40 + env.Ket = env.Cursor + if !env.InGrouping(G_v, 97, 251) { + break lab7 + } + // <-, line 40 + if !env.SliceFrom("U") { + return false + } + break lab6 + } + env.Cursor = v_4 + lab8: + for { + // (, line 41 + // literal, line 41 + if !env.EqS("i") { + break lab8 + } + // ], line 41 + env.Ket = env.Cursor + if !env.InGrouping(G_v, 97, 251) { + break lab8 + } + // <-, line 41 + if !env.SliceFrom("I") { + return false + } + break lab6 + } + env.Cursor = v_4 + // (, line 42 + // literal, line 42 + if !env.EqS("y") { + break lab5 + } + // ], line 42 + env.Ket = env.Cursor + // <-, line 42 + if !env.SliceFrom("Y") { + return false + } + break lab6 + } + break lab4 + } + env.Cursor = v_3 + lab9: + for { + // (, line 45 + // [, line 45 + env.Bra = env.Cursor + // literal, line 45 + if !env.EqS("y") { + break lab9 + } + // ], line 45 + env.Ket = env.Cursor + if !env.InGrouping(G_v, 97, 251) { + break lab9 + } + // <-, line 45 + if !env.SliceFrom("Y") { + return false + } + break lab4 + } + env.Cursor = v_3 + // (, line 47 + // literal, line 47 + if !env.EqS("q") { + break lab3 + } + // [, line 47 + env.Bra = env.Cursor + // literal, line 47 + if !env.EqS("u") { + break lab3 + } + // ], line 47 + env.Ket = env.Cursor + // <-, line 47 + if !env.SliceFrom("U") { + return false + } + break lab4 + } + env.Cursor = v_2 + break golab2 + } + env.Cursor = v_2 + if env.Cursor >= env.Limit { + break lab1 + } + env.NextChar() + } + continue replab0 + } + env.Cursor = v_1 + break replab0 + } + return true +} + +func r_mark_regions(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 50 + context.i_pV = env.Limit + context.i_p1 = env.Limit + context.i_p2 = env.Limit + // do, line 56 + var v_1 = env.Cursor +lab0: + for { + // (, line 56 + // or, line 58 + lab1: + for { + var v_2 = env.Cursor + lab2: + for { + // (, line 57 + if !env.InGrouping(G_v, 97, 251) { + break lab2 + } + if !env.InGrouping(G_v, 97, 251) { + break lab2 + } + // next, line 57 + if env.Cursor >= env.Limit { + break lab2 + } + env.NextChar() + break lab1 + } + env.Cursor = v_2 + lab3: + for { + // among, line 59 + if env.FindAmong(A_0, context) == 0 { + break lab3 + } + break lab1 + } + env.Cursor = v_2 + // (, line 66 + // next, line 66 + if env.Cursor >= env.Limit { + break lab0 + } + env.NextChar() + // gopast, line 66 + golab4: + for { + lab5: + for { + if !env.InGrouping(G_v, 97, 251) { + break lab5 + } + break golab4 + } + if env.Cursor >= env.Limit { + break lab0 + } + env.NextChar() + } + break lab1 + } + // setmark pV, line 67 + context.i_pV = env.Cursor + break lab0 + } + env.Cursor = v_1 + // do, line 69 + var v_4 = env.Cursor +lab6: + for { + // (, line 69 + // gopast, line 70 + golab7: + for { + lab8: + for { + if !env.InGrouping(G_v, 97, 251) { + break lab8 + } + break golab7 + } + if env.Cursor >= env.Limit { + break lab6 + } + env.NextChar() + } + // gopast, line 70 + golab9: + for { + lab10: + for { + if !env.OutGrouping(G_v, 97, 251) { + break lab10 + } + break golab9 + } + if env.Cursor >= env.Limit { + break lab6 + } + env.NextChar() + } + // setmark p1, line 70 + context.i_p1 = env.Cursor + // gopast, line 71 + golab11: + for { + lab12: + for { + if !env.InGrouping(G_v, 97, 251) { + break lab12 + } + break golab11 + } + if env.Cursor >= env.Limit { + break lab6 + } + env.NextChar() + } + // gopast, line 71 + golab13: + for { + lab14: + for { + if !env.OutGrouping(G_v, 97, 251) { + break lab14 + } + break golab13 + } + if env.Cursor >= env.Limit { + break lab6 + } + env.NextChar() + } + // setmark p2, line 71 + context.i_p2 = env.Cursor + break lab6 + } + env.Cursor = v_4 + return true +} + +func r_postlude(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // repeat, line 75 +replab0: + for { + var v_1 = env.Cursor + lab1: + for range [2]struct{}{} { + // (, line 75 + // [, line 77 + env.Bra = env.Cursor + // substring, line 77 + among_var = env.FindAmong(A_1, context) + if among_var == 0 { + break lab1 + } + // ], line 77 + env.Ket = env.Cursor + if among_var == 0 { + break lab1 + } else if among_var == 1 { + // (, line 78 + // <-, line 78 + if !env.SliceFrom("i") { + return false + } + } else if among_var == 2 { + // (, line 79 + // <-, line 79 + if !env.SliceFrom("u") { + return false + } + } else if among_var == 3 { + // (, line 80 + // <-, line 80 + if !env.SliceFrom("y") { + return false + } + } else if among_var == 4 { + // (, line 81 + // next, line 81 + if env.Cursor >= env.Limit { + break lab1 + } + env.NextChar() + } + continue replab0 + } + env.Cursor = v_1 + break replab0 + } + return true +} + +func r_RV(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + if !(context.i_pV <= env.Cursor) { + return false + } + return true +} + +func r_R1(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + if !(context.i_p1 <= env.Cursor) { + return false + } + return true +} + +func r_R2(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + if !(context.i_p2 <= env.Cursor) { + return false + } + return true +} + +func r_standard_suffix(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 91 + // [, line 92 + env.Ket = env.Cursor + // substring, line 92 + among_var = env.FindAmongB(A_4, context) + if among_var == 0 { + return false + } + // ], line 92 + env.Bra = env.Cursor + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 96 + // call R2, line 96 + if !r_R2(env, context) { + return false + } + // delete, line 96 + if !env.SliceDel() { + return false + } + } else if among_var == 2 { + // (, line 99 + // call R2, line 99 + if !r_R2(env, context) { + return false + } + // delete, line 99 + if !env.SliceDel() { + return false + } + // try, line 100 + var v_1 = env.Limit - env.Cursor + lab0: + for { + // (, line 100 + // [, line 100 + env.Ket = env.Cursor + // literal, line 100 + if !env.EqSB("ic") { + env.Cursor = env.Limit - v_1 + break lab0 + } + // ], line 100 + env.Bra = env.Cursor + // or, line 100 + lab1: + for { + var v_2 = env.Limit - env.Cursor + lab2: + for { + // (, line 100 + // call R2, line 100 + if !r_R2(env, context) { + break lab2 + } + // delete, line 100 + if !env.SliceDel() { + return false + } + break lab1 + } + env.Cursor = env.Limit - v_2 + // <-, line 100 + if !env.SliceFrom("iqU") { + return false + } + break lab1 + } + break lab0 + } + } else if among_var == 3 { + // (, line 104 + // call R2, line 104 + if !r_R2(env, context) { + return false + } + // <-, line 104 + if !env.SliceFrom("log") { + return false + } + } else if among_var == 4 { + // (, line 107 + // call R2, line 107 + if !r_R2(env, context) { + return false + } + // <-, line 107 + if !env.SliceFrom("u") { + return false + } + } else if among_var == 5 { + // (, line 110 + // call R2, line 110 + if !r_R2(env, context) { + return false + } + // <-, line 110 + if !env.SliceFrom("ent") { + return false + } + } else if among_var == 6 { + // (, line 113 + // call RV, line 114 + if !r_RV(env, context) { + return false + } + // delete, line 114 + if !env.SliceDel() { + return false + } + // try, line 115 + var v_3 = env.Limit - env.Cursor + lab3: + for { + // (, line 115 + // [, line 116 + env.Ket = env.Cursor + // substring, line 116 + among_var = env.FindAmongB(A_2, context) + if among_var == 0 { + env.Cursor = env.Limit - v_3 + break lab3 + } + // ], line 116 + env.Bra = env.Cursor + if among_var == 0 { + env.Cursor = env.Limit - v_3 + break lab3 + } else if among_var == 1 { + // (, line 117 + // call R2, line 117 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_3 + break lab3 + } + // delete, line 117 + if !env.SliceDel() { + return false + } + // [, line 117 + env.Ket = env.Cursor + // literal, line 117 + if !env.EqSB("at") { + env.Cursor = env.Limit - v_3 + break lab3 + } + // ], line 117 + env.Bra = env.Cursor + // call R2, line 117 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_3 + break lab3 + } + // delete, line 117 + if !env.SliceDel() { + return false + } + } else if among_var == 2 { + // (, line 118 + // or, line 118 + lab4: + for { + var v_4 = env.Limit - env.Cursor + lab5: + for { + // (, line 118 + // call R2, line 118 + if !r_R2(env, context) { + break lab5 + } + // delete, line 118 + if !env.SliceDel() { + return false + } + break lab4 + } + env.Cursor = env.Limit - v_4 + // (, line 118 + // call R1, line 118 + if !r_R1(env, context) { + env.Cursor = env.Limit - v_3 + break lab3 + } + // <-, line 118 + if !env.SliceFrom("eux") { + return false + } + break lab4 + } + } else if among_var == 3 { + // (, line 120 + // call R2, line 120 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_3 + break lab3 + } + // delete, line 120 + if !env.SliceDel() { + return false + } + } else if among_var == 4 { + // (, line 122 + // call RV, line 122 + if !r_RV(env, context) { + env.Cursor = env.Limit - v_3 + break lab3 + } + // <-, line 122 + if !env.SliceFrom("i") { + return false + } + } + break lab3 + } + } else if among_var == 7 { + // (, line 128 + // call R2, line 129 + if !r_R2(env, context) { + return false + } + // delete, line 129 + if !env.SliceDel() { + return false + } + // try, line 130 + var v_5 = env.Limit - env.Cursor + lab6: + for { + // (, line 130 + // [, line 131 + env.Ket = env.Cursor + // substring, line 131 + among_var = env.FindAmongB(A_3, context) + if among_var == 0 { + env.Cursor = env.Limit - v_5 + break lab6 + } + // ], line 131 + env.Bra = env.Cursor + if among_var == 0 { + env.Cursor = env.Limit - v_5 + break lab6 + } else if among_var == 1 { + // (, line 132 + // or, line 132 + lab7: + for { + var v_6 = env.Limit - env.Cursor + lab8: + for { + // (, line 132 + // call R2, line 132 + if !r_R2(env, context) { + break lab8 + } + // delete, line 132 + if !env.SliceDel() { + return false + } + break lab7 + } + env.Cursor = env.Limit - v_6 + // <-, line 132 + if !env.SliceFrom("abl") { + return false + } + break lab7 + } + } else if among_var == 2 { + // (, line 133 + // or, line 133 + lab9: + for { + var v_7 = env.Limit - env.Cursor + lab10: + for { + // (, line 133 + // call R2, line 133 + if !r_R2(env, context) { + break lab10 + } + // delete, line 133 + if !env.SliceDel() { + return false + } + break lab9 + } + env.Cursor = env.Limit - v_7 + // <-, line 133 + if !env.SliceFrom("iqU") { + return false + } + break lab9 + } + } else if among_var == 3 { + // (, line 134 + // call R2, line 134 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_5 + break lab6 + } + // delete, line 134 + if !env.SliceDel() { + return false + } + } + break lab6 + } + } else if among_var == 8 { + // (, line 140 + // call R2, line 141 + if !r_R2(env, context) { + return false + } + // delete, line 141 + if !env.SliceDel() { + return false + } + // try, line 142 + var v_8 = env.Limit - env.Cursor + lab11: + for { + // (, line 142 + // [, line 142 + env.Ket = env.Cursor + // literal, line 142 + if !env.EqSB("at") { + env.Cursor = env.Limit - v_8 + break lab11 + } + // ], line 142 + env.Bra = env.Cursor + // call R2, line 142 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_8 + break lab11 + } + // delete, line 142 + if !env.SliceDel() { + return false + } + // [, line 142 + env.Ket = env.Cursor + // literal, line 142 + if !env.EqSB("ic") { + env.Cursor = env.Limit - v_8 + break lab11 + } + // ], line 142 + env.Bra = env.Cursor + // or, line 142 + lab12: + for { + var v_9 = env.Limit - env.Cursor + lab13: + for { + // (, line 142 + // call R2, line 142 + if !r_R2(env, context) { + break lab13 + } + // delete, line 142 + if !env.SliceDel() { + return false + } + break lab12 + } + env.Cursor = env.Limit - v_9 + // <-, line 142 + if !env.SliceFrom("iqU") { + return false + } + break lab12 + } + break lab11 + } + } else if among_var == 9 { + // (, line 144 + // <-, line 144 + if !env.SliceFrom("eau") { + return false + } + } else if among_var == 10 { + // (, line 145 + // call R1, line 145 + if !r_R1(env, context) { + return false + } + // <-, line 145 + if !env.SliceFrom("al") { + return false + } + } else if among_var == 11 { + // (, line 147 + // or, line 147 + lab14: + for { + var v_10 = env.Limit - env.Cursor + lab15: + for { + // (, line 147 + // call R2, line 147 + if !r_R2(env, context) { + break lab15 + } + // delete, line 147 + if !env.SliceDel() { + return false + } + break lab14 + } + env.Cursor = env.Limit - v_10 + // (, line 147 + // call R1, line 147 + if !r_R1(env, context) { + return false + } + // <-, line 147 + if !env.SliceFrom("eux") { + return false + } + break lab14 + } + } else if among_var == 12 { + // (, line 150 + // call R1, line 150 + if !r_R1(env, context) { + return false + } + if !env.OutGroupingB(G_v, 97, 251) { + return false + } + // delete, line 150 + if !env.SliceDel() { + return false + } + } else if among_var == 13 { + // (, line 155 + // call RV, line 155 + if !r_RV(env, context) { + return false + } + // fail, line 155 + // (, line 155 + // <-, line 155 + if !env.SliceFrom("ant") { + return false + } + return false + } else if among_var == 14 { + // (, line 156 + // call RV, line 156 + if !r_RV(env, context) { + return false + } + // fail, line 156 + // (, line 156 + // <-, line 156 + if !env.SliceFrom("ent") { + return false + } + return false + } else if among_var == 15 { + // (, line 158 + // test, line 158 + var v_11 = env.Limit - env.Cursor + // (, line 158 + if !env.InGroupingB(G_v, 97, 251) { + return false + } + // call RV, line 158 + if !r_RV(env, context) { + return false + } + env.Cursor = env.Limit - v_11 + // fail, line 158 + // (, line 158 + // delete, line 158 + if !env.SliceDel() { + return false + } + return false + } + return true +} + +func r_i_verb_suffix(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // setlimit, line 163 + var v_1 = env.Limit - env.Cursor + // tomark, line 163 + if env.Cursor < context.i_pV { + return false + } + env.Cursor = context.i_pV + var v_2 = env.LimitBackward + env.LimitBackward = env.Cursor + env.Cursor = env.Limit - v_1 + // (, line 163 + // [, line 164 + env.Ket = env.Cursor + // substring, line 164 + among_var = env.FindAmongB(A_5, context) + if among_var == 0 { + env.LimitBackward = v_2 + return false + } + // ], line 164 + env.Bra = env.Cursor + if among_var == 0 { + env.LimitBackward = v_2 + return false + } else if among_var == 1 { + // (, line 170 + if !env.OutGroupingB(G_v, 97, 251) { + env.LimitBackward = v_2 + return false + } + // delete, line 170 + if !env.SliceDel() { + return false + } + } + env.LimitBackward = v_2 + return true +} + +func r_verb_suffix(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // setlimit, line 174 + var v_1 = env.Limit - env.Cursor + // tomark, line 174 + if env.Cursor < context.i_pV { + return false + } + env.Cursor = context.i_pV + var v_2 = env.LimitBackward + env.LimitBackward = env.Cursor + env.Cursor = env.Limit - v_1 + // (, line 174 + // [, line 175 + env.Ket = env.Cursor + // substring, line 175 + among_var = env.FindAmongB(A_6, context) + if among_var == 0 { + env.LimitBackward = v_2 + return false + } + // ], line 175 + env.Bra = env.Cursor + if among_var == 0 { + env.LimitBackward = v_2 + return false + } else if among_var == 1 { + // (, line 177 + // call R2, line 177 + if !r_R2(env, context) { + env.LimitBackward = v_2 + return false + } + // delete, line 177 + if !env.SliceDel() { + return false + } + } else if among_var == 2 { + // (, line 185 + // delete, line 185 + if !env.SliceDel() { + return false + } + } else if among_var == 3 { + // (, line 190 + // delete, line 190 + if !env.SliceDel() { + return false + } + // try, line 191 + var v_3 = env.Limit - env.Cursor + lab0: + for { + // (, line 191 + // [, line 191 + env.Ket = env.Cursor + // literal, line 191 + if !env.EqSB("e") { + env.Cursor = env.Limit - v_3 + break lab0 + } + // ], line 191 + env.Bra = env.Cursor + // delete, line 191 + if !env.SliceDel() { + return false + } + break lab0 + } + } + env.LimitBackward = v_2 + return true +} + +func r_residual_suffix(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 198 + // try, line 199 + var v_1 = env.Limit - env.Cursor +lab0: + for { + // (, line 199 + // [, line 199 + env.Ket = env.Cursor + // literal, line 199 + if !env.EqSB("s") { + env.Cursor = env.Limit - v_1 + break lab0 + } + // ], line 199 + env.Bra = env.Cursor + // test, line 199 + var v_2 = env.Limit - env.Cursor + if !env.OutGroupingB(G_keep_with_s, 97, 232) { + env.Cursor = env.Limit - v_1 + break lab0 + } + env.Cursor = env.Limit - v_2 + // delete, line 199 + if !env.SliceDel() { + return false + } + break lab0 + } + // setlimit, line 200 + var v_3 = env.Limit - env.Cursor + // tomark, line 200 + if env.Cursor < context.i_pV { + return false + } + env.Cursor = context.i_pV + var v_4 = env.LimitBackward + env.LimitBackward = env.Cursor + env.Cursor = env.Limit - v_3 + // (, line 200 + // [, line 201 + env.Ket = env.Cursor + // substring, line 201 + among_var = env.FindAmongB(A_7, context) + if among_var == 0 { + env.LimitBackward = v_4 + return false + } + // ], line 201 + env.Bra = env.Cursor + if among_var == 0 { + env.LimitBackward = v_4 + return false + } else if among_var == 1 { + // (, line 202 + // call R2, line 202 + if !r_R2(env, context) { + env.LimitBackward = v_4 + return false + } + // or, line 202 + lab1: + for { + var v_5 = env.Limit - env.Cursor + lab2: + for { + // literal, line 202 + if !env.EqSB("s") { + break lab2 + } + break lab1 + } + env.Cursor = env.Limit - v_5 + // literal, line 202 + if !env.EqSB("t") { + env.LimitBackward = v_4 + return false + } + break lab1 + } + // delete, line 202 + if !env.SliceDel() { + return false + } + } else if among_var == 2 { + // (, line 204 + // <-, line 204 + if !env.SliceFrom("i") { + return false + } + } else if among_var == 3 { + // (, line 205 + // delete, line 205 + if !env.SliceDel() { + return false + } + } else if among_var == 4 { + // (, line 206 + // literal, line 206 + if !env.EqSB("gu") { + env.LimitBackward = v_4 + return false + } + // delete, line 206 + if !env.SliceDel() { + return false + } + } + env.LimitBackward = v_4 + return true +} + +func r_un_double(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 211 + // test, line 212 + var v_1 = env.Limit - env.Cursor + // among, line 212 + if env.FindAmongB(A_8, context) == 0 { + return false + } + env.Cursor = env.Limit - v_1 + // [, line 212 + env.Ket = env.Cursor + // next, line 212 + if env.Cursor <= env.LimitBackward { + return false + } + env.PrevChar() + // ], line 212 + env.Bra = env.Cursor + // delete, line 212 + if !env.SliceDel() { + return false + } + return true +} + +func r_un_accent(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 215 + // atleast, line 216 + var v_1 = 1 + // atleast, line 216 +replab0: + for { + lab1: + for range [2]struct{}{} { + if !env.OutGroupingB(G_v, 97, 251) { + break lab1 + } + v_1-- + continue replab0 + } + break replab0 + } + if v_1 > 0 { + return false + } + // [, line 217 + env.Ket = env.Cursor + // or, line 217 +lab2: + for { + var v_3 = env.Limit - env.Cursor + lab3: + for { + // literal, line 217 + if !env.EqSB("\u00E9") { + break lab3 + } + break lab2 + } + env.Cursor = env.Limit - v_3 + // literal, line 217 + if !env.EqSB("\u00E8") { + return false + } + break lab2 + } + // ], line 217 + env.Bra = env.Cursor + // <-, line 217 + if !env.SliceFrom("e") { + return false + } + return true +} + +func Stem(env *snowballRuntime.Env) bool { + var context = &Context{ + i_p2: 0, + i_p1: 0, + i_pV: 0, + } + _ = context + // (, line 221 + // do, line 223 + var v_1 = env.Cursor +lab0: + for { + // call prelude, line 223 + if !r_prelude(env, context) { + break lab0 + } + break lab0 + } + env.Cursor = v_1 + // do, line 224 + var v_2 = env.Cursor +lab1: + for { + // call mark_regions, line 224 + if !r_mark_regions(env, context) { + break lab1 + } + break lab1 + } + env.Cursor = v_2 + // backwards, line 225 + env.LimitBackward = env.Cursor + env.Cursor = env.Limit + // (, line 225 + // do, line 227 + var v_3 = env.Limit - env.Cursor +lab2: + for { + // (, line 227 + // or, line 237 + lab3: + for { + var v_4 = env.Limit - env.Cursor + lab4: + for { + // (, line 228 + // and, line 233 + var v_5 = env.Limit - env.Cursor + // (, line 229 + // or, line 229 + lab5: + for { + var v_6 = env.Limit - env.Cursor + lab6: + for { + // call standard_suffix, line 229 + if !r_standard_suffix(env, context) { + break lab6 + } + break lab5 + } + env.Cursor = env.Limit - v_6 + lab7: + for { + // call i_verb_suffix, line 230 + if !r_i_verb_suffix(env, context) { + break lab7 + } + break lab5 + } + env.Cursor = env.Limit - v_6 + // call verb_suffix, line 231 + if !r_verb_suffix(env, context) { + break lab4 + } + break lab5 + } + env.Cursor = env.Limit - v_5 + // try, line 234 + var v_7 = env.Limit - env.Cursor + lab8: + for { + // (, line 234 + // [, line 234 + env.Ket = env.Cursor + // or, line 234 + lab9: + for { + var v_8 = env.Limit - env.Cursor + lab10: + for { + // (, line 234 + // literal, line 234 + if !env.EqSB("Y") { + break lab10 + } + // ], line 234 + env.Bra = env.Cursor + // <-, line 234 + if !env.SliceFrom("i") { + return false + } + break lab9 + } + env.Cursor = env.Limit - v_8 + // (, line 235 + // literal, line 235 + if !env.EqSB("\u00E7") { + env.Cursor = env.Limit - v_7 + break lab8 + } + // ], line 235 + env.Bra = env.Cursor + // <-, line 235 + if !env.SliceFrom("c") { + return false + } + break lab9 + } + break lab8 + } + break lab3 + } + env.Cursor = env.Limit - v_4 + // call residual_suffix, line 238 + if !r_residual_suffix(env, context) { + break lab2 + } + break lab3 + } + break lab2 + } + env.Cursor = env.Limit - v_3 + // do, line 243 + var v_9 = env.Limit - env.Cursor +lab11: + for { + // call un_double, line 243 + if !r_un_double(env, context) { + break lab11 + } + break lab11 + } + env.Cursor = env.Limit - v_9 + // do, line 244 + var v_10 = env.Limit - env.Cursor +lab12: + for { + // call un_accent, line 244 + if !r_un_accent(env, context) { + break lab12 + } + break lab12 + } + env.Cursor = env.Limit - v_10 + env.Cursor = env.LimitBackward + // do, line 246 + var v_11 = env.Cursor +lab13: + for { + // call postlude, line 246 + if !r_postlude(env, context) { + break lab13 + } + break lab13 + } + env.Cursor = v_11 + return true +} diff --git a/backend/vendor/github.com/blevesearch/snowballstem/gen.go b/backend/vendor/github.com/blevesearch/snowballstem/gen.go new file mode 100644 index 0000000000..92548b0010 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/snowballstem/gen.go @@ -0,0 +1,61 @@ +package snowballstem + +// to regenerate these commands, run +// go run gengen.go /path/to/snowball/algorithms/directory + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/arabic/stem_Unicode.sbl -go -o arabic/arabic_stemmer -gop arabic -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w arabic/arabic_stemmer.go + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/danish/stem_ISO_8859_1.sbl -go -o danish/danish_stemmer -gop danish -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w danish/danish_stemmer.go + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/dutch/stem_ISO_8859_1.sbl -go -o dutch/dutch_stemmer -gop dutch -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w dutch/dutch_stemmer.go + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/english/stem_ISO_8859_1.sbl -go -o english/english_stemmer -gop english -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w english/english_stemmer.go + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/finnish/stem_ISO_8859_1.sbl -go -o finnish/finnish_stemmer -gop finnish -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w finnish/finnish_stemmer.go + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/french/stem_ISO_8859_1.sbl -go -o french/french_stemmer -gop french -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w french/french_stemmer.go + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/german/stem_ISO_8859_1.sbl -go -o german/german_stemmer -gop german -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w german/german_stemmer.go + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/hungarian/stem_Unicode.sbl -go -o hungarian/hungarian_stemmer -gop hungarian -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w hungarian/hungarian_stemmer.go + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/irish/stem_ISO_8859_1.sbl -go -o irish/irish_stemmer -gop irish -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w irish/irish_stemmer.go + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/italian/stem_ISO_8859_1.sbl -go -o italian/italian_stemmer -gop italian -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w italian/italian_stemmer.go + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/norwegian/stem_ISO_8859_1.sbl -go -o norwegian/norwegian_stemmer -gop norwegian -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w norwegian/norwegian_stemmer.go + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/porter/stem_ISO_8859_1.sbl -go -o porter/porter_stemmer -gop porter -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w porter/porter_stemmer.go + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/portuguese/stem_ISO_8859_1.sbl -go -o portuguese/portuguese_stemmer -gop portuguese -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w portuguese/portuguese_stemmer.go + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/romanian/stem_Unicode.sbl -go -o romanian/romanian_stemmer -gop romanian -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w romanian/romanian_stemmer.go + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/russian/stem_Unicode.sbl -go -o russian/russian_stemmer -gop russian -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w russian/russian_stemmer.go + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/spanish/stem_ISO_8859_1.sbl -go -o spanish/spanish_stemmer -gop spanish -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w spanish/spanish_stemmer.go + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/swedish/stem_ISO_8859_1.sbl -go -o swedish/swedish_stemmer -gop swedish -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w swedish/swedish_stemmer.go + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/tamil/stem_Unicode.sbl -go -o tamil/tamil_stemmer -gop tamil -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w tamil/tamil_stemmer.go + +//go:generate $SNOWBALL/snowball $SNOWBALL/algorithms/turkish/stem_Unicode.sbl -go -o turkish/turkish_stemmer -gop turkish -gor github.com/blevesearch/snowballstem +//go:generate gofmt -s -w turkish/turkish_stemmer.go diff --git a/backend/vendor/github.com/blevesearch/snowballstem/german/german_stemmer.go b/backend/vendor/github.com/blevesearch/snowballstem/german/german_stemmer.go new file mode 100644 index 0000000000..434ee50887 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/snowballstem/german/german_stemmer.go @@ -0,0 +1,719 @@ +//! This file was generated automatically by the Snowball to Go compiler +//! http://snowballstem.org/ + +package german + +import ( + snowballRuntime "github.com/blevesearch/snowballstem" +) + +var A_0 = []*snowballRuntime.Among{ + {Str: "", A: -1, B: 6, F: nil}, + {Str: "U", A: 0, B: 2, F: nil}, + {Str: "Y", A: 0, B: 1, F: nil}, + {Str: "\u00E4", A: 0, B: 3, F: nil}, + {Str: "\u00F6", A: 0, B: 4, F: nil}, + {Str: "\u00FC", A: 0, B: 5, F: nil}, +} + +var A_1 = []*snowballRuntime.Among{ + {Str: "e", A: -1, B: 2, F: nil}, + {Str: "em", A: -1, B: 1, F: nil}, + {Str: "en", A: -1, B: 2, F: nil}, + {Str: "ern", A: -1, B: 1, F: nil}, + {Str: "er", A: -1, B: 1, F: nil}, + {Str: "s", A: -1, B: 3, F: nil}, + {Str: "es", A: 5, B: 2, F: nil}, +} + +var A_2 = []*snowballRuntime.Among{ + {Str: "en", A: -1, B: 1, F: nil}, + {Str: "er", A: -1, B: 1, F: nil}, + {Str: "st", A: -1, B: 2, F: nil}, + {Str: "est", A: 2, B: 1, F: nil}, +} + +var A_3 = []*snowballRuntime.Among{ + {Str: "ig", A: -1, B: 1, F: nil}, + {Str: "lich", A: -1, B: 1, F: nil}, +} + +var A_4 = []*snowballRuntime.Among{ + {Str: "end", A: -1, B: 1, F: nil}, + {Str: "ig", A: -1, B: 2, F: nil}, + {Str: "ung", A: -1, B: 1, F: nil}, + {Str: "lich", A: -1, B: 3, F: nil}, + {Str: "isch", A: -1, B: 2, F: nil}, + {Str: "ik", A: -1, B: 2, F: nil}, + {Str: "heit", A: -1, B: 3, F: nil}, + {Str: "keit", A: -1, B: 4, F: nil}, +} + +var G_v = []byte{17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32, 8} + +var G_s_ending = []byte{117, 30, 5} + +var G_st_ending = []byte{117, 30, 4} + +type Context struct { + i_x int + i_p2 int + i_p1 int +} + +func r_prelude(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 33 + // test, line 35 + var v_1 = env.Cursor + // repeat, line 35 +replab0: + for { + var v_2 = env.Cursor + lab1: + for range [2]struct{}{} { + // (, line 35 + // or, line 38 + lab2: + for { + var v_3 = env.Cursor + lab3: + for { + // (, line 36 + // [, line 37 + env.Bra = env.Cursor + // literal, line 37 + if !env.EqS("\u00DF") { + break lab3 + } + // ], line 37 + env.Ket = env.Cursor + // <-, line 37 + if !env.SliceFrom("ss") { + return false + } + break lab2 + } + env.Cursor = v_3 + // next, line 38 + if env.Cursor >= env.Limit { + break lab1 + } + env.NextChar() + break lab2 + } + continue replab0 + } + env.Cursor = v_2 + break replab0 + } + env.Cursor = v_1 + // repeat, line 41 +replab4: + for { + var v_4 = env.Cursor + lab5: + for range [2]struct{}{} { + // goto, line 41 + golab6: + for { + var v_5 = env.Cursor + lab7: + for { + // (, line 41 + if !env.InGrouping(G_v, 97, 252) { + break lab7 + } + // [, line 42 + env.Bra = env.Cursor + // or, line 42 + lab8: + for { + var v_6 = env.Cursor + lab9: + for { + // (, line 42 + // literal, line 42 + if !env.EqS("u") { + break lab9 + } + // ], line 42 + env.Ket = env.Cursor + if !env.InGrouping(G_v, 97, 252) { + break lab9 + } + // <-, line 42 + if !env.SliceFrom("U") { + return false + } + break lab8 + } + env.Cursor = v_6 + // (, line 43 + // literal, line 43 + if !env.EqS("y") { + break lab7 + } + // ], line 43 + env.Ket = env.Cursor + if !env.InGrouping(G_v, 97, 252) { + break lab7 + } + // <-, line 43 + if !env.SliceFrom("Y") { + return false + } + break lab8 + } + env.Cursor = v_5 + break golab6 + } + env.Cursor = v_5 + if env.Cursor >= env.Limit { + break lab5 + } + env.NextChar() + } + continue replab4 + } + env.Cursor = v_4 + break replab4 + } + return true +} + +func r_mark_regions(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 47 + context.i_p1 = env.Limit + context.i_p2 = env.Limit + // test, line 52 + var v_1 = env.Cursor + // (, line 52 + { + // hop, line 52 + var c = env.ByteIndexForHop((3)) + if int32(0) > c || c > int32(env.Limit) { + return false + } + env.Cursor = int(c) + } + // setmark x, line 52 + context.i_x = env.Cursor + env.Cursor = v_1 + // gopast, line 54 +golab0: + for { + lab1: + for { + if !env.InGrouping(G_v, 97, 252) { + break lab1 + } + break golab0 + } + if env.Cursor >= env.Limit { + return false + } + env.NextChar() + } + // gopast, line 54 +golab2: + for { + lab3: + for { + if !env.OutGrouping(G_v, 97, 252) { + break lab3 + } + break golab2 + } + if env.Cursor >= env.Limit { + return false + } + env.NextChar() + } + // setmark p1, line 54 + context.i_p1 = env.Cursor + // try, line 55 +lab4: + for { + // (, line 55 + if !(context.i_p1 < context.i_x) { + break lab4 + } + context.i_p1 = context.i_x + break lab4 + } + // gopast, line 56 +golab5: + for { + lab6: + for { + if !env.InGrouping(G_v, 97, 252) { + break lab6 + } + break golab5 + } + if env.Cursor >= env.Limit { + return false + } + env.NextChar() + } + // gopast, line 56 +golab7: + for { + lab8: + for { + if !env.OutGrouping(G_v, 97, 252) { + break lab8 + } + break golab7 + } + if env.Cursor >= env.Limit { + return false + } + env.NextChar() + } + // setmark p2, line 56 + context.i_p2 = env.Cursor + return true +} + +func r_postlude(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // repeat, line 60 +replab0: + for { + var v_1 = env.Cursor + lab1: + for range [2]struct{}{} { + // (, line 60 + // [, line 62 + env.Bra = env.Cursor + // substring, line 62 + among_var = env.FindAmong(A_0, context) + if among_var == 0 { + break lab1 + } + // ], line 62 + env.Ket = env.Cursor + if among_var == 0 { + break lab1 + } else if among_var == 1 { + // (, line 63 + // <-, line 63 + if !env.SliceFrom("y") { + return false + } + } else if among_var == 2 { + // (, line 64 + // <-, line 64 + if !env.SliceFrom("u") { + return false + } + } else if among_var == 3 { + // (, line 65 + // <-, line 65 + if !env.SliceFrom("a") { + return false + } + } else if among_var == 4 { + // (, line 66 + // <-, line 66 + if !env.SliceFrom("o") { + return false + } + } else if among_var == 5 { + // (, line 67 + // <-, line 67 + if !env.SliceFrom("u") { + return false + } + } else if among_var == 6 { + // (, line 68 + // next, line 68 + if env.Cursor >= env.Limit { + break lab1 + } + env.NextChar() + } + continue replab0 + } + env.Cursor = v_1 + break replab0 + } + return true +} + +func r_R1(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + if !(context.i_p1 <= env.Cursor) { + return false + } + return true +} + +func r_R2(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + if !(context.i_p2 <= env.Cursor) { + return false + } + return true +} + +func r_standard_suffix(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 78 + // do, line 79 + var v_1 = env.Limit - env.Cursor +lab0: + for { + // (, line 79 + // [, line 80 + env.Ket = env.Cursor + // substring, line 80 + among_var = env.FindAmongB(A_1, context) + if among_var == 0 { + break lab0 + } + // ], line 80 + env.Bra = env.Cursor + // call R1, line 80 + if !r_R1(env, context) { + break lab0 + } + if among_var == 0 { + break lab0 + } else if among_var == 1 { + // (, line 82 + // delete, line 82 + if !env.SliceDel() { + return false + } + } else if among_var == 2 { + // (, line 85 + // delete, line 85 + if !env.SliceDel() { + return false + } + // try, line 86 + var v_2 = env.Limit - env.Cursor + lab1: + for { + // (, line 86 + // [, line 86 + env.Ket = env.Cursor + // literal, line 86 + if !env.EqSB("s") { + env.Cursor = env.Limit - v_2 + break lab1 + } + // ], line 86 + env.Bra = env.Cursor + // literal, line 86 + if !env.EqSB("nis") { + env.Cursor = env.Limit - v_2 + break lab1 + } + // delete, line 86 + if !env.SliceDel() { + return false + } + break lab1 + } + } else if among_var == 3 { + // (, line 89 + if !env.InGroupingB(G_s_ending, 98, 116) { + break lab0 + } + // delete, line 89 + if !env.SliceDel() { + return false + } + } + break lab0 + } + env.Cursor = env.Limit - v_1 + // do, line 93 + var v_3 = env.Limit - env.Cursor +lab2: + for { + // (, line 93 + // [, line 94 + env.Ket = env.Cursor + // substring, line 94 + among_var = env.FindAmongB(A_2, context) + if among_var == 0 { + break lab2 + } + // ], line 94 + env.Bra = env.Cursor + // call R1, line 94 + if !r_R1(env, context) { + break lab2 + } + if among_var == 0 { + break lab2 + } else if among_var == 1 { + // (, line 96 + // delete, line 96 + if !env.SliceDel() { + return false + } + } else if among_var == 2 { + // (, line 99 + if !env.InGroupingB(G_st_ending, 98, 116) { + break lab2 + } + { + // hop, line 99 + var c = env.ByteIndexForHop(-(3)) + if int32(env.LimitBackward) > c || c > int32(env.Limit) { + break lab2 + } + env.Cursor = int(c) + } + // delete, line 99 + if !env.SliceDel() { + return false + } + } + break lab2 + } + env.Cursor = env.Limit - v_3 + // do, line 103 + var v_4 = env.Limit - env.Cursor +lab3: + for { + // (, line 103 + // [, line 104 + env.Ket = env.Cursor + // substring, line 104 + among_var = env.FindAmongB(A_4, context) + if among_var == 0 { + break lab3 + } + // ], line 104 + env.Bra = env.Cursor + // call R2, line 104 + if !r_R2(env, context) { + break lab3 + } + if among_var == 0 { + break lab3 + } else if among_var == 1 { + // (, line 106 + // delete, line 106 + if !env.SliceDel() { + return false + } + // try, line 107 + var v_5 = env.Limit - env.Cursor + lab4: + for { + // (, line 107 + // [, line 107 + env.Ket = env.Cursor + // literal, line 107 + if !env.EqSB("ig") { + env.Cursor = env.Limit - v_5 + break lab4 + } + // ], line 107 + env.Bra = env.Cursor + // not, line 107 + var v_6 = env.Limit - env.Cursor + lab5: + for { + // literal, line 107 + if !env.EqSB("e") { + break lab5 + } + env.Cursor = env.Limit - v_5 + break lab4 + } + env.Cursor = env.Limit - v_6 + // call R2, line 107 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_5 + break lab4 + } + // delete, line 107 + if !env.SliceDel() { + return false + } + break lab4 + } + } else if among_var == 2 { + // (, line 110 + // not, line 110 + var v_7 = env.Limit - env.Cursor + lab6: + for { + // literal, line 110 + if !env.EqSB("e") { + break lab6 + } + break lab3 + } + env.Cursor = env.Limit - v_7 + // delete, line 110 + if !env.SliceDel() { + return false + } + } else if among_var == 3 { + // (, line 113 + // delete, line 113 + if !env.SliceDel() { + return false + } + // try, line 114 + var v_8 = env.Limit - env.Cursor + lab7: + for { + // (, line 114 + // [, line 115 + env.Ket = env.Cursor + // or, line 115 + lab8: + for { + var v_9 = env.Limit - env.Cursor + lab9: + for { + // literal, line 115 + if !env.EqSB("er") { + break lab9 + } + break lab8 + } + env.Cursor = env.Limit - v_9 + // literal, line 115 + if !env.EqSB("en") { + env.Cursor = env.Limit - v_8 + break lab7 + } + break lab8 + } + // ], line 115 + env.Bra = env.Cursor + // call R1, line 115 + if !r_R1(env, context) { + env.Cursor = env.Limit - v_8 + break lab7 + } + // delete, line 115 + if !env.SliceDel() { + return false + } + break lab7 + } + } else if among_var == 4 { + // (, line 119 + // delete, line 119 + if !env.SliceDel() { + return false + } + // try, line 120 + var v_10 = env.Limit - env.Cursor + lab10: + for { + // (, line 120 + // [, line 121 + env.Ket = env.Cursor + // substring, line 121 + among_var = env.FindAmongB(A_3, context) + if among_var == 0 { + env.Cursor = env.Limit - v_10 + break lab10 + } + // ], line 121 + env.Bra = env.Cursor + // call R2, line 121 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_10 + break lab10 + } + if among_var == 0 { + env.Cursor = env.Limit - v_10 + break lab10 + } else if among_var == 1 { + // (, line 123 + // delete, line 123 + if !env.SliceDel() { + return false + } + } + break lab10 + } + } + break lab3 + } + env.Cursor = env.Limit - v_4 + return true +} + +func Stem(env *snowballRuntime.Env) bool { + var context = &Context{ + i_x: 0, + i_p2: 0, + i_p1: 0, + } + _ = context + // (, line 133 + // do, line 134 + var v_1 = env.Cursor +lab0: + for { + // call prelude, line 134 + if !r_prelude(env, context) { + break lab0 + } + break lab0 + } + env.Cursor = v_1 + // do, line 135 + var v_2 = env.Cursor +lab1: + for { + // call mark_regions, line 135 + if !r_mark_regions(env, context) { + break lab1 + } + break lab1 + } + env.Cursor = v_2 + // backwards, line 136 + env.LimitBackward = env.Cursor + env.Cursor = env.Limit + // do, line 137 + var v_3 = env.Limit - env.Cursor +lab2: + for { + // call standard_suffix, line 137 + if !r_standard_suffix(env, context) { + break lab2 + } + break lab2 + } + env.Cursor = env.Limit - v_3 + env.Cursor = env.LimitBackward + // do, line 138 + var v_4 = env.Cursor +lab3: + for { + // call postlude, line 138 + if !r_postlude(env, context) { + break lab3 + } + break lab3 + } + env.Cursor = v_4 + return true +} diff --git a/backend/vendor/github.com/blevesearch/snowballstem/italian/italian_stemmer.go b/backend/vendor/github.com/blevesearch/snowballstem/italian/italian_stemmer.go new file mode 100644 index 0000000000..66dae809c3 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/snowballstem/italian/italian_stemmer.go @@ -0,0 +1,1182 @@ +//! This file was generated automatically by the Snowball to Go compiler +//! http://snowballstem.org/ + +package italian + +import ( + snowballRuntime "github.com/blevesearch/snowballstem" +) + +var A_0 = []*snowballRuntime.Among{ + {Str: "", A: -1, B: 7, F: nil}, + {Str: "qu", A: 0, B: 6, F: nil}, + {Str: "\u00E1", A: 0, B: 1, F: nil}, + {Str: "\u00E9", A: 0, B: 2, F: nil}, + {Str: "\u00ED", A: 0, B: 3, F: nil}, + {Str: "\u00F3", A: 0, B: 4, F: nil}, + {Str: "\u00FA", A: 0, B: 5, F: nil}, +} + +var A_1 = []*snowballRuntime.Among{ + {Str: "", A: -1, B: 3, F: nil}, + {Str: "I", A: 0, B: 1, F: nil}, + {Str: "U", A: 0, B: 2, F: nil}, +} + +var A_2 = []*snowballRuntime.Among{ + {Str: "la", A: -1, B: -1, F: nil}, + {Str: "cela", A: 0, B: -1, F: nil}, + {Str: "gliela", A: 0, B: -1, F: nil}, + {Str: "mela", A: 0, B: -1, F: nil}, + {Str: "tela", A: 0, B: -1, F: nil}, + {Str: "vela", A: 0, B: -1, F: nil}, + {Str: "le", A: -1, B: -1, F: nil}, + {Str: "cele", A: 6, B: -1, F: nil}, + {Str: "gliele", A: 6, B: -1, F: nil}, + {Str: "mele", A: 6, B: -1, F: nil}, + {Str: "tele", A: 6, B: -1, F: nil}, + {Str: "vele", A: 6, B: -1, F: nil}, + {Str: "ne", A: -1, B: -1, F: nil}, + {Str: "cene", A: 12, B: -1, F: nil}, + {Str: "gliene", A: 12, B: -1, F: nil}, + {Str: "mene", A: 12, B: -1, F: nil}, + {Str: "sene", A: 12, B: -1, F: nil}, + {Str: "tene", A: 12, B: -1, F: nil}, + {Str: "vene", A: 12, B: -1, F: nil}, + {Str: "ci", A: -1, B: -1, F: nil}, + {Str: "li", A: -1, B: -1, F: nil}, + {Str: "celi", A: 20, B: -1, F: nil}, + {Str: "glieli", A: 20, B: -1, F: nil}, + {Str: "meli", A: 20, B: -1, F: nil}, + {Str: "teli", A: 20, B: -1, F: nil}, + {Str: "veli", A: 20, B: -1, F: nil}, + {Str: "gli", A: 20, B: -1, F: nil}, + {Str: "mi", A: -1, B: -1, F: nil}, + {Str: "si", A: -1, B: -1, F: nil}, + {Str: "ti", A: -1, B: -1, F: nil}, + {Str: "vi", A: -1, B: -1, F: nil}, + {Str: "lo", A: -1, B: -1, F: nil}, + {Str: "celo", A: 31, B: -1, F: nil}, + {Str: "glielo", A: 31, B: -1, F: nil}, + {Str: "melo", A: 31, B: -1, F: nil}, + {Str: "telo", A: 31, B: -1, F: nil}, + {Str: "velo", A: 31, B: -1, F: nil}, +} + +var A_3 = []*snowballRuntime.Among{ + {Str: "ando", A: -1, B: 1, F: nil}, + {Str: "endo", A: -1, B: 1, F: nil}, + {Str: "ar", A: -1, B: 2, F: nil}, + {Str: "er", A: -1, B: 2, F: nil}, + {Str: "ir", A: -1, B: 2, F: nil}, +} + +var A_4 = []*snowballRuntime.Among{ + {Str: "ic", A: -1, B: -1, F: nil}, + {Str: "abil", A: -1, B: -1, F: nil}, + {Str: "os", A: -1, B: -1, F: nil}, + {Str: "iv", A: -1, B: 1, F: nil}, +} + +var A_5 = []*snowballRuntime.Among{ + {Str: "ic", A: -1, B: 1, F: nil}, + {Str: "abil", A: -1, B: 1, F: nil}, + {Str: "iv", A: -1, B: 1, F: nil}, +} + +var A_6 = []*snowballRuntime.Among{ + {Str: "ica", A: -1, B: 1, F: nil}, + {Str: "logia", A: -1, B: 3, F: nil}, + {Str: "osa", A: -1, B: 1, F: nil}, + {Str: "ista", A: -1, B: 1, F: nil}, + {Str: "iva", A: -1, B: 9, F: nil}, + {Str: "anza", A: -1, B: 1, F: nil}, + {Str: "enza", A: -1, B: 5, F: nil}, + {Str: "ice", A: -1, B: 1, F: nil}, + {Str: "atrice", A: 7, B: 1, F: nil}, + {Str: "iche", A: -1, B: 1, F: nil}, + {Str: "logie", A: -1, B: 3, F: nil}, + {Str: "abile", A: -1, B: 1, F: nil}, + {Str: "ibile", A: -1, B: 1, F: nil}, + {Str: "usione", A: -1, B: 4, F: nil}, + {Str: "azione", A: -1, B: 2, F: nil}, + {Str: "uzione", A: -1, B: 4, F: nil}, + {Str: "atore", A: -1, B: 2, F: nil}, + {Str: "ose", A: -1, B: 1, F: nil}, + {Str: "ante", A: -1, B: 1, F: nil}, + {Str: "mente", A: -1, B: 1, F: nil}, + {Str: "amente", A: 19, B: 7, F: nil}, + {Str: "iste", A: -1, B: 1, F: nil}, + {Str: "ive", A: -1, B: 9, F: nil}, + {Str: "anze", A: -1, B: 1, F: nil}, + {Str: "enze", A: -1, B: 5, F: nil}, + {Str: "ici", A: -1, B: 1, F: nil}, + {Str: "atrici", A: 25, B: 1, F: nil}, + {Str: "ichi", A: -1, B: 1, F: nil}, + {Str: "abili", A: -1, B: 1, F: nil}, + {Str: "ibili", A: -1, B: 1, F: nil}, + {Str: "ismi", A: -1, B: 1, F: nil}, + {Str: "usioni", A: -1, B: 4, F: nil}, + {Str: "azioni", A: -1, B: 2, F: nil}, + {Str: "uzioni", A: -1, B: 4, F: nil}, + {Str: "atori", A: -1, B: 2, F: nil}, + {Str: "osi", A: -1, B: 1, F: nil}, + {Str: "anti", A: -1, B: 1, F: nil}, + {Str: "amenti", A: -1, B: 6, F: nil}, + {Str: "imenti", A: -1, B: 6, F: nil}, + {Str: "isti", A: -1, B: 1, F: nil}, + {Str: "ivi", A: -1, B: 9, F: nil}, + {Str: "ico", A: -1, B: 1, F: nil}, + {Str: "ismo", A: -1, B: 1, F: nil}, + {Str: "oso", A: -1, B: 1, F: nil}, + {Str: "amento", A: -1, B: 6, F: nil}, + {Str: "imento", A: -1, B: 6, F: nil}, + {Str: "ivo", A: -1, B: 9, F: nil}, + {Str: "it\u00E0", A: -1, B: 8, F: nil}, + {Str: "ist\u00E0", A: -1, B: 1, F: nil}, + {Str: "ist\u00E8", A: -1, B: 1, F: nil}, + {Str: "ist\u00EC", A: -1, B: 1, F: nil}, +} + +var A_7 = []*snowballRuntime.Among{ + {Str: "isca", A: -1, B: 1, F: nil}, + {Str: "enda", A: -1, B: 1, F: nil}, + {Str: "ata", A: -1, B: 1, F: nil}, + {Str: "ita", A: -1, B: 1, F: nil}, + {Str: "uta", A: -1, B: 1, F: nil}, + {Str: "ava", A: -1, B: 1, F: nil}, + {Str: "eva", A: -1, B: 1, F: nil}, + {Str: "iva", A: -1, B: 1, F: nil}, + {Str: "erebbe", A: -1, B: 1, F: nil}, + {Str: "irebbe", A: -1, B: 1, F: nil}, + {Str: "isce", A: -1, B: 1, F: nil}, + {Str: "ende", A: -1, B: 1, F: nil}, + {Str: "are", A: -1, B: 1, F: nil}, + {Str: "ere", A: -1, B: 1, F: nil}, + {Str: "ire", A: -1, B: 1, F: nil}, + {Str: "asse", A: -1, B: 1, F: nil}, + {Str: "ate", A: -1, B: 1, F: nil}, + {Str: "avate", A: 16, B: 1, F: nil}, + {Str: "evate", A: 16, B: 1, F: nil}, + {Str: "ivate", A: 16, B: 1, F: nil}, + {Str: "ete", A: -1, B: 1, F: nil}, + {Str: "erete", A: 20, B: 1, F: nil}, + {Str: "irete", A: 20, B: 1, F: nil}, + {Str: "ite", A: -1, B: 1, F: nil}, + {Str: "ereste", A: -1, B: 1, F: nil}, + {Str: "ireste", A: -1, B: 1, F: nil}, + {Str: "ute", A: -1, B: 1, F: nil}, + {Str: "erai", A: -1, B: 1, F: nil}, + {Str: "irai", A: -1, B: 1, F: nil}, + {Str: "isci", A: -1, B: 1, F: nil}, + {Str: "endi", A: -1, B: 1, F: nil}, + {Str: "erei", A: -1, B: 1, F: nil}, + {Str: "irei", A: -1, B: 1, F: nil}, + {Str: "assi", A: -1, B: 1, F: nil}, + {Str: "ati", A: -1, B: 1, F: nil}, + {Str: "iti", A: -1, B: 1, F: nil}, + {Str: "eresti", A: -1, B: 1, F: nil}, + {Str: "iresti", A: -1, B: 1, F: nil}, + {Str: "uti", A: -1, B: 1, F: nil}, + {Str: "avi", A: -1, B: 1, F: nil}, + {Str: "evi", A: -1, B: 1, F: nil}, + {Str: "ivi", A: -1, B: 1, F: nil}, + {Str: "isco", A: -1, B: 1, F: nil}, + {Str: "ando", A: -1, B: 1, F: nil}, + {Str: "endo", A: -1, B: 1, F: nil}, + {Str: "Yamo", A: -1, B: 1, F: nil}, + {Str: "iamo", A: -1, B: 1, F: nil}, + {Str: "avamo", A: -1, B: 1, F: nil}, + {Str: "evamo", A: -1, B: 1, F: nil}, + {Str: "ivamo", A: -1, B: 1, F: nil}, + {Str: "eremo", A: -1, B: 1, F: nil}, + {Str: "iremo", A: -1, B: 1, F: nil}, + {Str: "assimo", A: -1, B: 1, F: nil}, + {Str: "ammo", A: -1, B: 1, F: nil}, + {Str: "emmo", A: -1, B: 1, F: nil}, + {Str: "eremmo", A: 54, B: 1, F: nil}, + {Str: "iremmo", A: 54, B: 1, F: nil}, + {Str: "immo", A: -1, B: 1, F: nil}, + {Str: "ano", A: -1, B: 1, F: nil}, + {Str: "iscano", A: 58, B: 1, F: nil}, + {Str: "avano", A: 58, B: 1, F: nil}, + {Str: "evano", A: 58, B: 1, F: nil}, + {Str: "ivano", A: 58, B: 1, F: nil}, + {Str: "eranno", A: -1, B: 1, F: nil}, + {Str: "iranno", A: -1, B: 1, F: nil}, + {Str: "ono", A: -1, B: 1, F: nil}, + {Str: "iscono", A: 65, B: 1, F: nil}, + {Str: "arono", A: 65, B: 1, F: nil}, + {Str: "erono", A: 65, B: 1, F: nil}, + {Str: "irono", A: 65, B: 1, F: nil}, + {Str: "erebbero", A: -1, B: 1, F: nil}, + {Str: "irebbero", A: -1, B: 1, F: nil}, + {Str: "assero", A: -1, B: 1, F: nil}, + {Str: "essero", A: -1, B: 1, F: nil}, + {Str: "issero", A: -1, B: 1, F: nil}, + {Str: "ato", A: -1, B: 1, F: nil}, + {Str: "ito", A: -1, B: 1, F: nil}, + {Str: "uto", A: -1, B: 1, F: nil}, + {Str: "avo", A: -1, B: 1, F: nil}, + {Str: "evo", A: -1, B: 1, F: nil}, + {Str: "ivo", A: -1, B: 1, F: nil}, + {Str: "ar", A: -1, B: 1, F: nil}, + {Str: "ir", A: -1, B: 1, F: nil}, + {Str: "er\u00E0", A: -1, B: 1, F: nil}, + {Str: "ir\u00E0", A: -1, B: 1, F: nil}, + {Str: "er\u00F2", A: -1, B: 1, F: nil}, + {Str: "ir\u00F2", A: -1, B: 1, F: nil}, +} + +var G_v = []byte{17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 8, 2, 1} + +var G_AEIO = []byte{17, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 8, 2} + +var G_CG = []byte{17} + +type Context struct { + i_p2 int + i_p1 int + i_pV int +} + +func r_prelude(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 34 + // test, line 35 + var v_1 = env.Cursor + // repeat, line 35 +replab0: + for { + var v_2 = env.Cursor + lab1: + for range [2]struct{}{} { + // (, line 35 + // [, line 36 + env.Bra = env.Cursor + // substring, line 36 + among_var = env.FindAmong(A_0, context) + if among_var == 0 { + break lab1 + } + // ], line 36 + env.Ket = env.Cursor + if among_var == 0 { + break lab1 + } else if among_var == 1 { + // (, line 37 + // <-, line 37 + if !env.SliceFrom("\u00E0") { + return false + } + } else if among_var == 2 { + // (, line 38 + // <-, line 38 + if !env.SliceFrom("\u00E8") { + return false + } + } else if among_var == 3 { + // (, line 39 + // <-, line 39 + if !env.SliceFrom("\u00EC") { + return false + } + } else if among_var == 4 { + // (, line 40 + // <-, line 40 + if !env.SliceFrom("\u00F2") { + return false + } + } else if among_var == 5 { + // (, line 41 + // <-, line 41 + if !env.SliceFrom("\u00F9") { + return false + } + } else if among_var == 6 { + // (, line 42 + // <-, line 42 + if !env.SliceFrom("qU") { + return false + } + } else if among_var == 7 { + // (, line 43 + // next, line 43 + if env.Cursor >= env.Limit { + break lab1 + } + env.NextChar() + } + continue replab0 + } + env.Cursor = v_2 + break replab0 + } + env.Cursor = v_1 + // repeat, line 46 +replab2: + for { + var v_3 = env.Cursor + lab3: + for range [2]struct{}{} { + // goto, line 46 + golab4: + for { + var v_4 = env.Cursor + lab5: + for { + // (, line 46 + if !env.InGrouping(G_v, 97, 249) { + break lab5 + } + // [, line 47 + env.Bra = env.Cursor + // or, line 47 + lab6: + for { + var v_5 = env.Cursor + lab7: + for { + // (, line 47 + // literal, line 47 + if !env.EqS("u") { + break lab7 + } + // ], line 47 + env.Ket = env.Cursor + if !env.InGrouping(G_v, 97, 249) { + break lab7 + } + // <-, line 47 + if !env.SliceFrom("U") { + return false + } + break lab6 + } + env.Cursor = v_5 + // (, line 48 + // literal, line 48 + if !env.EqS("i") { + break lab5 + } + // ], line 48 + env.Ket = env.Cursor + if !env.InGrouping(G_v, 97, 249) { + break lab5 + } + // <-, line 48 + if !env.SliceFrom("I") { + return false + } + break lab6 + } + env.Cursor = v_4 + break golab4 + } + env.Cursor = v_4 + if env.Cursor >= env.Limit { + break lab3 + } + env.NextChar() + } + continue replab2 + } + env.Cursor = v_3 + break replab2 + } + return true +} + +func r_mark_regions(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 52 + context.i_pV = env.Limit + context.i_p1 = env.Limit + context.i_p2 = env.Limit + // do, line 58 + var v_1 = env.Cursor +lab0: + for { + // (, line 58 + // or, line 60 + lab1: + for { + var v_2 = env.Cursor + lab2: + for { + // (, line 59 + if !env.InGrouping(G_v, 97, 249) { + break lab2 + } + // or, line 59 + lab3: + for { + var v_3 = env.Cursor + lab4: + for { + // (, line 59 + if !env.OutGrouping(G_v, 97, 249) { + break lab4 + } + // gopast, line 59 + golab5: + for { + lab6: + for { + if !env.InGrouping(G_v, 97, 249) { + break lab6 + } + break golab5 + } + if env.Cursor >= env.Limit { + break lab4 + } + env.NextChar() + } + break lab3 + } + env.Cursor = v_3 + // (, line 59 + if !env.InGrouping(G_v, 97, 249) { + break lab2 + } + // gopast, line 59 + golab7: + for { + lab8: + for { + if !env.OutGrouping(G_v, 97, 249) { + break lab8 + } + break golab7 + } + if env.Cursor >= env.Limit { + break lab2 + } + env.NextChar() + } + break lab3 + } + break lab1 + } + env.Cursor = v_2 + // (, line 61 + if !env.OutGrouping(G_v, 97, 249) { + break lab0 + } + // or, line 61 + lab9: + for { + var v_6 = env.Cursor + lab10: + for { + // (, line 61 + if !env.OutGrouping(G_v, 97, 249) { + break lab10 + } + // gopast, line 61 + golab11: + for { + lab12: + for { + if !env.InGrouping(G_v, 97, 249) { + break lab12 + } + break golab11 + } + if env.Cursor >= env.Limit { + break lab10 + } + env.NextChar() + } + break lab9 + } + env.Cursor = v_6 + // (, line 61 + if !env.InGrouping(G_v, 97, 249) { + break lab0 + } + // next, line 61 + if env.Cursor >= env.Limit { + break lab0 + } + env.NextChar() + break lab9 + } + break lab1 + } + // setmark pV, line 62 + context.i_pV = env.Cursor + break lab0 + } + env.Cursor = v_1 + // do, line 64 + var v_8 = env.Cursor +lab13: + for { + // (, line 64 + // gopast, line 65 + golab14: + for { + lab15: + for { + if !env.InGrouping(G_v, 97, 249) { + break lab15 + } + break golab14 + } + if env.Cursor >= env.Limit { + break lab13 + } + env.NextChar() + } + // gopast, line 65 + golab16: + for { + lab17: + for { + if !env.OutGrouping(G_v, 97, 249) { + break lab17 + } + break golab16 + } + if env.Cursor >= env.Limit { + break lab13 + } + env.NextChar() + } + // setmark p1, line 65 + context.i_p1 = env.Cursor + // gopast, line 66 + golab18: + for { + lab19: + for { + if !env.InGrouping(G_v, 97, 249) { + break lab19 + } + break golab18 + } + if env.Cursor >= env.Limit { + break lab13 + } + env.NextChar() + } + // gopast, line 66 + golab20: + for { + lab21: + for { + if !env.OutGrouping(G_v, 97, 249) { + break lab21 + } + break golab20 + } + if env.Cursor >= env.Limit { + break lab13 + } + env.NextChar() + } + // setmark p2, line 66 + context.i_p2 = env.Cursor + break lab13 + } + env.Cursor = v_8 + return true +} + +func r_postlude(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // repeat, line 70 +replab0: + for { + var v_1 = env.Cursor + lab1: + for range [2]struct{}{} { + // (, line 70 + // [, line 72 + env.Bra = env.Cursor + // substring, line 72 + among_var = env.FindAmong(A_1, context) + if among_var == 0 { + break lab1 + } + // ], line 72 + env.Ket = env.Cursor + if among_var == 0 { + break lab1 + } else if among_var == 1 { + // (, line 73 + // <-, line 73 + if !env.SliceFrom("i") { + return false + } + } else if among_var == 2 { + // (, line 74 + // <-, line 74 + if !env.SliceFrom("u") { + return false + } + } else if among_var == 3 { + // (, line 75 + // next, line 75 + if env.Cursor >= env.Limit { + break lab1 + } + env.NextChar() + } + continue replab0 + } + env.Cursor = v_1 + break replab0 + } + return true +} + +func r_RV(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + if !(context.i_pV <= env.Cursor) { + return false + } + return true +} + +func r_R1(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + if !(context.i_p1 <= env.Cursor) { + return false + } + return true +} + +func r_R2(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + if !(context.i_p2 <= env.Cursor) { + return false + } + return true +} + +func r_attached_pronoun(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 86 + // [, line 87 + env.Ket = env.Cursor + // substring, line 87 + if env.FindAmongB(A_2, context) == 0 { + return false + } + // ], line 87 + env.Bra = env.Cursor + // among, line 97 + among_var = env.FindAmongB(A_3, context) + if among_var == 0 { + return false + } + // (, line 97 + // call RV, line 97 + if !r_RV(env, context) { + return false + } + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 98 + // delete, line 98 + if !env.SliceDel() { + return false + } + } else if among_var == 2 { + // (, line 99 + // <-, line 99 + if !env.SliceFrom("e") { + return false + } + } + return true +} + +func r_standard_suffix(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 103 + // [, line 104 + env.Ket = env.Cursor + // substring, line 104 + among_var = env.FindAmongB(A_6, context) + if among_var == 0 { + return false + } + // ], line 104 + env.Bra = env.Cursor + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 111 + // call R2, line 111 + if !r_R2(env, context) { + return false + } + // delete, line 111 + if !env.SliceDel() { + return false + } + } else if among_var == 2 { + // (, line 113 + // call R2, line 113 + if !r_R2(env, context) { + return false + } + // delete, line 113 + if !env.SliceDel() { + return false + } + // try, line 114 + var v_1 = env.Limit - env.Cursor + lab0: + for { + // (, line 114 + // [, line 114 + env.Ket = env.Cursor + // literal, line 114 + if !env.EqSB("ic") { + env.Cursor = env.Limit - v_1 + break lab0 + } + // ], line 114 + env.Bra = env.Cursor + // call R2, line 114 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_1 + break lab0 + } + // delete, line 114 + if !env.SliceDel() { + return false + } + break lab0 + } + } else if among_var == 3 { + // (, line 117 + // call R2, line 117 + if !r_R2(env, context) { + return false + } + // <-, line 117 + if !env.SliceFrom("log") { + return false + } + } else if among_var == 4 { + // (, line 119 + // call R2, line 119 + if !r_R2(env, context) { + return false + } + // <-, line 119 + if !env.SliceFrom("u") { + return false + } + } else if among_var == 5 { + // (, line 121 + // call R2, line 121 + if !r_R2(env, context) { + return false + } + // <-, line 121 + if !env.SliceFrom("ente") { + return false + } + } else if among_var == 6 { + // (, line 123 + // call RV, line 123 + if !r_RV(env, context) { + return false + } + // delete, line 123 + if !env.SliceDel() { + return false + } + } else if among_var == 7 { + // (, line 124 + // call R1, line 125 + if !r_R1(env, context) { + return false + } + // delete, line 125 + if !env.SliceDel() { + return false + } + // try, line 126 + var v_2 = env.Limit - env.Cursor + lab1: + for { + // (, line 126 + // [, line 127 + env.Ket = env.Cursor + // substring, line 127 + among_var = env.FindAmongB(A_4, context) + if among_var == 0 { + env.Cursor = env.Limit - v_2 + break lab1 + } + // ], line 127 + env.Bra = env.Cursor + // call R2, line 127 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_2 + break lab1 + } + // delete, line 127 + if !env.SliceDel() { + return false + } + if among_var == 0 { + env.Cursor = env.Limit - v_2 + break lab1 + } else if among_var == 1 { + // (, line 128 + // [, line 128 + env.Ket = env.Cursor + // literal, line 128 + if !env.EqSB("at") { + env.Cursor = env.Limit - v_2 + break lab1 + } + // ], line 128 + env.Bra = env.Cursor + // call R2, line 128 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_2 + break lab1 + } + // delete, line 128 + if !env.SliceDel() { + return false + } + } + break lab1 + } + } else if among_var == 8 { + // (, line 133 + // call R2, line 134 + if !r_R2(env, context) { + return false + } + // delete, line 134 + if !env.SliceDel() { + return false + } + // try, line 135 + var v_3 = env.Limit - env.Cursor + lab2: + for { + // (, line 135 + // [, line 136 + env.Ket = env.Cursor + // substring, line 136 + among_var = env.FindAmongB(A_5, context) + if among_var == 0 { + env.Cursor = env.Limit - v_3 + break lab2 + } + // ], line 136 + env.Bra = env.Cursor + if among_var == 0 { + env.Cursor = env.Limit - v_3 + break lab2 + } else if among_var == 1 { + // (, line 137 + // call R2, line 137 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_3 + break lab2 + } + // delete, line 137 + if !env.SliceDel() { + return false + } + } + break lab2 + } + } else if among_var == 9 { + // (, line 141 + // call R2, line 142 + if !r_R2(env, context) { + return false + } + // delete, line 142 + if !env.SliceDel() { + return false + } + // try, line 143 + var v_4 = env.Limit - env.Cursor + lab3: + for { + // (, line 143 + // [, line 143 + env.Ket = env.Cursor + // literal, line 143 + if !env.EqSB("at") { + env.Cursor = env.Limit - v_4 + break lab3 + } + // ], line 143 + env.Bra = env.Cursor + // call R2, line 143 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_4 + break lab3 + } + // delete, line 143 + if !env.SliceDel() { + return false + } + // [, line 143 + env.Ket = env.Cursor + // literal, line 143 + if !env.EqSB("ic") { + env.Cursor = env.Limit - v_4 + break lab3 + } + // ], line 143 + env.Bra = env.Cursor + // call R2, line 143 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_4 + break lab3 + } + // delete, line 143 + if !env.SliceDel() { + return false + } + break lab3 + } + } + return true +} + +func r_verb_suffix(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // setlimit, line 148 + var v_1 = env.Limit - env.Cursor + // tomark, line 148 + if env.Cursor < context.i_pV { + return false + } + env.Cursor = context.i_pV + var v_2 = env.LimitBackward + env.LimitBackward = env.Cursor + env.Cursor = env.Limit - v_1 + // (, line 148 + // [, line 149 + env.Ket = env.Cursor + // substring, line 149 + among_var = env.FindAmongB(A_7, context) + if among_var == 0 { + env.LimitBackward = v_2 + return false + } + // ], line 149 + env.Bra = env.Cursor + if among_var == 0 { + env.LimitBackward = v_2 + return false + } else if among_var == 1 { + // (, line 163 + // delete, line 163 + if !env.SliceDel() { + return false + } + } + env.LimitBackward = v_2 + return true +} + +func r_vowel_suffix(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 170 + // try, line 171 + var v_1 = env.Limit - env.Cursor +lab0: + for { + // (, line 171 + // [, line 172 + env.Ket = env.Cursor + if !env.InGroupingB(G_AEIO, 97, 242) { + env.Cursor = env.Limit - v_1 + break lab0 + } + // ], line 172 + env.Bra = env.Cursor + // call RV, line 172 + if !r_RV(env, context) { + env.Cursor = env.Limit - v_1 + break lab0 + } + // delete, line 172 + if !env.SliceDel() { + return false + } + // [, line 173 + env.Ket = env.Cursor + // literal, line 173 + if !env.EqSB("i") { + env.Cursor = env.Limit - v_1 + break lab0 + } + // ], line 173 + env.Bra = env.Cursor + // call RV, line 173 + if !r_RV(env, context) { + env.Cursor = env.Limit - v_1 + break lab0 + } + // delete, line 173 + if !env.SliceDel() { + return false + } + break lab0 + } + // try, line 175 + var v_2 = env.Limit - env.Cursor +lab1: + for { + // (, line 175 + // [, line 176 + env.Ket = env.Cursor + // literal, line 176 + if !env.EqSB("h") { + env.Cursor = env.Limit - v_2 + break lab1 + } + // ], line 176 + env.Bra = env.Cursor + if !env.InGroupingB(G_CG, 99, 103) { + env.Cursor = env.Limit - v_2 + break lab1 + } + // call RV, line 176 + if !r_RV(env, context) { + env.Cursor = env.Limit - v_2 + break lab1 + } + // delete, line 176 + if !env.SliceDel() { + return false + } + break lab1 + } + return true +} + +func Stem(env *snowballRuntime.Env) bool { + var context = &Context{ + i_p2: 0, + i_p1: 0, + i_pV: 0, + } + _ = context + // (, line 181 + // do, line 182 + var v_1 = env.Cursor +lab0: + for { + // call prelude, line 182 + if !r_prelude(env, context) { + break lab0 + } + break lab0 + } + env.Cursor = v_1 + // do, line 183 + var v_2 = env.Cursor +lab1: + for { + // call mark_regions, line 183 + if !r_mark_regions(env, context) { + break lab1 + } + break lab1 + } + env.Cursor = v_2 + // backwards, line 184 + env.LimitBackward = env.Cursor + env.Cursor = env.Limit + // (, line 184 + // do, line 185 + var v_3 = env.Limit - env.Cursor +lab2: + for { + // call attached_pronoun, line 185 + if !r_attached_pronoun(env, context) { + break lab2 + } + break lab2 + } + env.Cursor = env.Limit - v_3 + // do, line 186 + var v_4 = env.Limit - env.Cursor +lab3: + for { + // (, line 186 + // or, line 186 + lab4: + for { + var v_5 = env.Limit - env.Cursor + lab5: + for { + // call standard_suffix, line 186 + if !r_standard_suffix(env, context) { + break lab5 + } + break lab4 + } + env.Cursor = env.Limit - v_5 + // call verb_suffix, line 186 + if !r_verb_suffix(env, context) { + break lab3 + } + break lab4 + } + break lab3 + } + env.Cursor = env.Limit - v_4 + // do, line 187 + var v_6 = env.Limit - env.Cursor +lab6: + for { + // call vowel_suffix, line 187 + if !r_vowel_suffix(env, context) { + break lab6 + } + break lab6 + } + env.Cursor = env.Limit - v_6 + env.Cursor = env.LimitBackward + // do, line 189 + var v_7 = env.Cursor +lab7: + for { + // call postlude, line 189 + if !r_postlude(env, context) { + break lab7 + } + break lab7 + } + env.Cursor = v_7 + return true +} diff --git a/backend/vendor/github.com/blevesearch/snowballstem/russian/russian_stemmer.go b/backend/vendor/github.com/blevesearch/snowballstem/russian/russian_stemmer.go new file mode 100644 index 0000000000..6110ec144d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/snowballstem/russian/russian_stemmer.go @@ -0,0 +1,737 @@ +//! This file was generated automatically by the Snowball to Go compiler +//! http://snowballstem.org/ + +package russian + +import ( + snowballRuntime "github.com/blevesearch/snowballstem" +) + +var A_0 = []*snowballRuntime.Among{ + {Str: "\u0432\u0448\u0438\u0441\u044C", A: -1, B: 1, F: nil}, + {Str: "\u044B\u0432\u0448\u0438\u0441\u044C", A: 0, B: 2, F: nil}, + {Str: "\u0438\u0432\u0448\u0438\u0441\u044C", A: 0, B: 2, F: nil}, + {Str: "\u0432", A: -1, B: 1, F: nil}, + {Str: "\u044B\u0432", A: 3, B: 2, F: nil}, + {Str: "\u0438\u0432", A: 3, B: 2, F: nil}, + {Str: "\u0432\u0448\u0438", A: -1, B: 1, F: nil}, + {Str: "\u044B\u0432\u0448\u0438", A: 6, B: 2, F: nil}, + {Str: "\u0438\u0432\u0448\u0438", A: 6, B: 2, F: nil}, +} + +var A_1 = []*snowballRuntime.Among{ + {Str: "\u0435\u043C\u0443", A: -1, B: 1, F: nil}, + {Str: "\u043E\u043C\u0443", A: -1, B: 1, F: nil}, + {Str: "\u044B\u0445", A: -1, B: 1, F: nil}, + {Str: "\u0438\u0445", A: -1, B: 1, F: nil}, + {Str: "\u0443\u044E", A: -1, B: 1, F: nil}, + {Str: "\u044E\u044E", A: -1, B: 1, F: nil}, + {Str: "\u0435\u044E", A: -1, B: 1, F: nil}, + {Str: "\u043E\u044E", A: -1, B: 1, F: nil}, + {Str: "\u044F\u044F", A: -1, B: 1, F: nil}, + {Str: "\u0430\u044F", A: -1, B: 1, F: nil}, + {Str: "\u044B\u0435", A: -1, B: 1, F: nil}, + {Str: "\u0435\u0435", A: -1, B: 1, F: nil}, + {Str: "\u0438\u0435", A: -1, B: 1, F: nil}, + {Str: "\u043E\u0435", A: -1, B: 1, F: nil}, + {Str: "\u044B\u043C\u0438", A: -1, B: 1, F: nil}, + {Str: "\u0438\u043C\u0438", A: -1, B: 1, F: nil}, + {Str: "\u044B\u0439", A: -1, B: 1, F: nil}, + {Str: "\u0435\u0439", A: -1, B: 1, F: nil}, + {Str: "\u0438\u0439", A: -1, B: 1, F: nil}, + {Str: "\u043E\u0439", A: -1, B: 1, F: nil}, + {Str: "\u044B\u043C", A: -1, B: 1, F: nil}, + {Str: "\u0435\u043C", A: -1, B: 1, F: nil}, + {Str: "\u0438\u043C", A: -1, B: 1, F: nil}, + {Str: "\u043E\u043C", A: -1, B: 1, F: nil}, + {Str: "\u0435\u0433\u043E", A: -1, B: 1, F: nil}, + {Str: "\u043E\u0433\u043E", A: -1, B: 1, F: nil}, +} + +var A_2 = []*snowballRuntime.Among{ + {Str: "\u0432\u0448", A: -1, B: 1, F: nil}, + {Str: "\u044B\u0432\u0448", A: 0, B: 2, F: nil}, + {Str: "\u0438\u0432\u0448", A: 0, B: 2, F: nil}, + {Str: "\u0449", A: -1, B: 1, F: nil}, + {Str: "\u044E\u0449", A: 3, B: 1, F: nil}, + {Str: "\u0443\u044E\u0449", A: 4, B: 2, F: nil}, + {Str: "\u0435\u043C", A: -1, B: 1, F: nil}, + {Str: "\u043D\u043D", A: -1, B: 1, F: nil}, +} + +var A_3 = []*snowballRuntime.Among{ + {Str: "\u0441\u044C", A: -1, B: 1, F: nil}, + {Str: "\u0441\u044F", A: -1, B: 1, F: nil}, +} + +var A_4 = []*snowballRuntime.Among{ + {Str: "\u044B\u0442", A: -1, B: 2, F: nil}, + {Str: "\u044E\u0442", A: -1, B: 1, F: nil}, + {Str: "\u0443\u044E\u0442", A: 1, B: 2, F: nil}, + {Str: "\u044F\u0442", A: -1, B: 2, F: nil}, + {Str: "\u0435\u0442", A: -1, B: 1, F: nil}, + {Str: "\u0443\u0435\u0442", A: 4, B: 2, F: nil}, + {Str: "\u0438\u0442", A: -1, B: 2, F: nil}, + {Str: "\u043D\u044B", A: -1, B: 1, F: nil}, + {Str: "\u0435\u043D\u044B", A: 7, B: 2, F: nil}, + {Str: "\u0442\u044C", A: -1, B: 1, F: nil}, + {Str: "\u044B\u0442\u044C", A: 9, B: 2, F: nil}, + {Str: "\u0438\u0442\u044C", A: 9, B: 2, F: nil}, + {Str: "\u0435\u0448\u044C", A: -1, B: 1, F: nil}, + {Str: "\u0438\u0448\u044C", A: -1, B: 2, F: nil}, + {Str: "\u044E", A: -1, B: 2, F: nil}, + {Str: "\u0443\u044E", A: 14, B: 2, F: nil}, + {Str: "\u043B\u0430", A: -1, B: 1, F: nil}, + {Str: "\u044B\u043B\u0430", A: 16, B: 2, F: nil}, + {Str: "\u0438\u043B\u0430", A: 16, B: 2, F: nil}, + {Str: "\u043D\u0430", A: -1, B: 1, F: nil}, + {Str: "\u0435\u043D\u0430", A: 19, B: 2, F: nil}, + {Str: "\u0435\u0442\u0435", A: -1, B: 1, F: nil}, + {Str: "\u0438\u0442\u0435", A: -1, B: 2, F: nil}, + {Str: "\u0439\u0442\u0435", A: -1, B: 1, F: nil}, + {Str: "\u0443\u0439\u0442\u0435", A: 23, B: 2, F: nil}, + {Str: "\u0435\u0439\u0442\u0435", A: 23, B: 2, F: nil}, + {Str: "\u043B\u0438", A: -1, B: 1, F: nil}, + {Str: "\u044B\u043B\u0438", A: 26, B: 2, F: nil}, + {Str: "\u0438\u043B\u0438", A: 26, B: 2, F: nil}, + {Str: "\u0439", A: -1, B: 1, F: nil}, + {Str: "\u0443\u0439", A: 29, B: 2, F: nil}, + {Str: "\u0435\u0439", A: 29, B: 2, F: nil}, + {Str: "\u043B", A: -1, B: 1, F: nil}, + {Str: "\u044B\u043B", A: 32, B: 2, F: nil}, + {Str: "\u0438\u043B", A: 32, B: 2, F: nil}, + {Str: "\u044B\u043C", A: -1, B: 2, F: nil}, + {Str: "\u0435\u043C", A: -1, B: 1, F: nil}, + {Str: "\u0438\u043C", A: -1, B: 2, F: nil}, + {Str: "\u043D", A: -1, B: 1, F: nil}, + {Str: "\u0435\u043D", A: 38, B: 2, F: nil}, + {Str: "\u043B\u043E", A: -1, B: 1, F: nil}, + {Str: "\u044B\u043B\u043E", A: 40, B: 2, F: nil}, + {Str: "\u0438\u043B\u043E", A: 40, B: 2, F: nil}, + {Str: "\u043D\u043E", A: -1, B: 1, F: nil}, + {Str: "\u0435\u043D\u043E", A: 43, B: 2, F: nil}, + {Str: "\u043D\u043D\u043E", A: 43, B: 1, F: nil}, +} + +var A_5 = []*snowballRuntime.Among{ + {Str: "\u0443", A: -1, B: 1, F: nil}, + {Str: "\u044F\u0445", A: -1, B: 1, F: nil}, + {Str: "\u0438\u044F\u0445", A: 1, B: 1, F: nil}, + {Str: "\u0430\u0445", A: -1, B: 1, F: nil}, + {Str: "\u044B", A: -1, B: 1, F: nil}, + {Str: "\u044C", A: -1, B: 1, F: nil}, + {Str: "\u044E", A: -1, B: 1, F: nil}, + {Str: "\u044C\u044E", A: 6, B: 1, F: nil}, + {Str: "\u0438\u044E", A: 6, B: 1, F: nil}, + {Str: "\u044F", A: -1, B: 1, F: nil}, + {Str: "\u044C\u044F", A: 9, B: 1, F: nil}, + {Str: "\u0438\u044F", A: 9, B: 1, F: nil}, + {Str: "\u0430", A: -1, B: 1, F: nil}, + {Str: "\u0435\u0432", A: -1, B: 1, F: nil}, + {Str: "\u043E\u0432", A: -1, B: 1, F: nil}, + {Str: "\u0435", A: -1, B: 1, F: nil}, + {Str: "\u044C\u0435", A: 15, B: 1, F: nil}, + {Str: "\u0438\u0435", A: 15, B: 1, F: nil}, + {Str: "\u0438", A: -1, B: 1, F: nil}, + {Str: "\u0435\u0438", A: 18, B: 1, F: nil}, + {Str: "\u0438\u0438", A: 18, B: 1, F: nil}, + {Str: "\u044F\u043C\u0438", A: 18, B: 1, F: nil}, + {Str: "\u0438\u044F\u043C\u0438", A: 21, B: 1, F: nil}, + {Str: "\u0430\u043C\u0438", A: 18, B: 1, F: nil}, + {Str: "\u0439", A: -1, B: 1, F: nil}, + {Str: "\u0435\u0439", A: 24, B: 1, F: nil}, + {Str: "\u0438\u0435\u0439", A: 25, B: 1, F: nil}, + {Str: "\u0438\u0439", A: 24, B: 1, F: nil}, + {Str: "\u043E\u0439", A: 24, B: 1, F: nil}, + {Str: "\u044F\u043C", A: -1, B: 1, F: nil}, + {Str: "\u0438\u044F\u043C", A: 29, B: 1, F: nil}, + {Str: "\u0430\u043C", A: -1, B: 1, F: nil}, + {Str: "\u0435\u043C", A: -1, B: 1, F: nil}, + {Str: "\u0438\u0435\u043C", A: 32, B: 1, F: nil}, + {Str: "\u043E\u043C", A: -1, B: 1, F: nil}, + {Str: "\u043E", A: -1, B: 1, F: nil}, +} + +var A_6 = []*snowballRuntime.Among{ + {Str: "\u043E\u0441\u0442", A: -1, B: 1, F: nil}, + {Str: "\u043E\u0441\u0442\u044C", A: -1, B: 1, F: nil}, +} + +var A_7 = []*snowballRuntime.Among{ + {Str: "\u0435\u0439\u0448", A: -1, B: 1, F: nil}, + {Str: "\u044C", A: -1, B: 3, F: nil}, + {Str: "\u0435\u0439\u0448\u0435", A: -1, B: 1, F: nil}, + {Str: "\u043D", A: -1, B: 2, F: nil}, +} + +var G_v = []byte{33, 65, 8, 232} + +type Context struct { + i_p2 int + i_pV int +} + +func r_mark_regions(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 57 + context.i_pV = env.Limit + context.i_p2 = env.Limit + // do, line 61 + var v_1 = env.Cursor +lab0: + for { + // (, line 61 + // gopast, line 62 + golab1: + for { + lab2: + for { + if !env.InGrouping(G_v, 1072, 1103) { + break lab2 + } + break golab1 + } + if env.Cursor >= env.Limit { + break lab0 + } + env.NextChar() + } + // setmark pV, line 62 + context.i_pV = env.Cursor + // gopast, line 62 + golab3: + for { + lab4: + for { + if !env.OutGrouping(G_v, 1072, 1103) { + break lab4 + } + break golab3 + } + if env.Cursor >= env.Limit { + break lab0 + } + env.NextChar() + } + // gopast, line 63 + golab5: + for { + lab6: + for { + if !env.InGrouping(G_v, 1072, 1103) { + break lab6 + } + break golab5 + } + if env.Cursor >= env.Limit { + break lab0 + } + env.NextChar() + } + // gopast, line 63 + golab7: + for { + lab8: + for { + if !env.OutGrouping(G_v, 1072, 1103) { + break lab8 + } + break golab7 + } + if env.Cursor >= env.Limit { + break lab0 + } + env.NextChar() + } + // setmark p2, line 63 + context.i_p2 = env.Cursor + break lab0 + } + env.Cursor = v_1 + return true +} + +func r_R2(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + if !(context.i_p2 <= env.Cursor) { + return false + } + return true +} + +func r_perfective_gerund(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 71 + // [, line 72 + env.Ket = env.Cursor + // substring, line 72 + among_var = env.FindAmongB(A_0, context) + if among_var == 0 { + return false + } + // ], line 72 + env.Bra = env.Cursor + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 76 + // or, line 76 + lab0: + for { + var v_1 = env.Limit - env.Cursor + lab1: + for { + // literal, line 76 + if !env.EqSB("\u0430") { + break lab1 + } + break lab0 + } + env.Cursor = env.Limit - v_1 + // literal, line 76 + if !env.EqSB("\u044F") { + return false + } + break lab0 + } + // delete, line 76 + if !env.SliceDel() { + return false + } + } else if among_var == 2 { + // (, line 83 + // delete, line 83 + if !env.SliceDel() { + return false + } + } + return true +} + +func r_adjective(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 87 + // [, line 88 + env.Ket = env.Cursor + // substring, line 88 + among_var = env.FindAmongB(A_1, context) + if among_var == 0 { + return false + } + // ], line 88 + env.Bra = env.Cursor + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 97 + // delete, line 97 + if !env.SliceDel() { + return false + } + } + return true +} + +func r_adjectival(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 101 + // call adjective, line 102 + if !r_adjective(env, context) { + return false + } + // try, line 109 + var v_1 = env.Limit - env.Cursor +lab0: + for { + // (, line 109 + // [, line 110 + env.Ket = env.Cursor + // substring, line 110 + among_var = env.FindAmongB(A_2, context) + if among_var == 0 { + env.Cursor = env.Limit - v_1 + break lab0 + } + // ], line 110 + env.Bra = env.Cursor + if among_var == 0 { + env.Cursor = env.Limit - v_1 + break lab0 + } else if among_var == 1 { + // (, line 115 + // or, line 115 + lab1: + for { + var v_2 = env.Limit - env.Cursor + lab2: + for { + // literal, line 115 + if !env.EqSB("\u0430") { + break lab2 + } + break lab1 + } + env.Cursor = env.Limit - v_2 + // literal, line 115 + if !env.EqSB("\u044F") { + env.Cursor = env.Limit - v_1 + break lab0 + } + break lab1 + } + // delete, line 115 + if !env.SliceDel() { + return false + } + } else if among_var == 2 { + // (, line 122 + // delete, line 122 + if !env.SliceDel() { + return false + } + } + break lab0 + } + return true +} + +func r_reflexive(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 128 + // [, line 129 + env.Ket = env.Cursor + // substring, line 129 + among_var = env.FindAmongB(A_3, context) + if among_var == 0 { + return false + } + // ], line 129 + env.Bra = env.Cursor + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 132 + // delete, line 132 + if !env.SliceDel() { + return false + } + } + return true +} + +func r_verb(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 136 + // [, line 137 + env.Ket = env.Cursor + // substring, line 137 + among_var = env.FindAmongB(A_4, context) + if among_var == 0 { + return false + } + // ], line 137 + env.Bra = env.Cursor + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 143 + // or, line 143 + lab0: + for { + var v_1 = env.Limit - env.Cursor + lab1: + for { + // literal, line 143 + if !env.EqSB("\u0430") { + break lab1 + } + break lab0 + } + env.Cursor = env.Limit - v_1 + // literal, line 143 + if !env.EqSB("\u044F") { + return false + } + break lab0 + } + // delete, line 143 + if !env.SliceDel() { + return false + } + } else if among_var == 2 { + // (, line 151 + // delete, line 151 + if !env.SliceDel() { + return false + } + } + return true +} + +func r_noun(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 159 + // [, line 160 + env.Ket = env.Cursor + // substring, line 160 + among_var = env.FindAmongB(A_5, context) + if among_var == 0 { + return false + } + // ], line 160 + env.Bra = env.Cursor + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 167 + // delete, line 167 + if !env.SliceDel() { + return false + } + } + return true +} + +func r_derivational(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 175 + // [, line 176 + env.Ket = env.Cursor + // substring, line 176 + among_var = env.FindAmongB(A_6, context) + if among_var == 0 { + return false + } + // ], line 176 + env.Bra = env.Cursor + // call R2, line 176 + if !r_R2(env, context) { + return false + } + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 179 + // delete, line 179 + if !env.SliceDel() { + return false + } + } + return true +} + +func r_tidy_up(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 183 + // [, line 184 + env.Ket = env.Cursor + // substring, line 184 + among_var = env.FindAmongB(A_7, context) + if among_var == 0 { + return false + } + // ], line 184 + env.Bra = env.Cursor + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 188 + // delete, line 188 + if !env.SliceDel() { + return false + } + // [, line 189 + env.Ket = env.Cursor + // literal, line 189 + if !env.EqSB("\u043D") { + return false + } + // ], line 189 + env.Bra = env.Cursor + // literal, line 189 + if !env.EqSB("\u043D") { + return false + } + // delete, line 189 + if !env.SliceDel() { + return false + } + } else if among_var == 2 { + // (, line 192 + // literal, line 192 + if !env.EqSB("\u043D") { + return false + } + // delete, line 192 + if !env.SliceDel() { + return false + } + } else if among_var == 3 { + // (, line 194 + // delete, line 194 + if !env.SliceDel() { + return false + } + } + return true +} + +func Stem(env *snowballRuntime.Env) bool { + var context = &Context{ + i_p2: 0, + i_pV: 0, + } + _ = context + // (, line 199 + // do, line 201 + var v_1 = env.Cursor +lab0: + for { + // call mark_regions, line 201 + if !r_mark_regions(env, context) { + break lab0 + } + break lab0 + } + env.Cursor = v_1 + // backwards, line 202 + env.LimitBackward = env.Cursor + env.Cursor = env.Limit + // setlimit, line 202 + var v_2 = env.Limit - env.Cursor + // tomark, line 202 + if env.Cursor < context.i_pV { + return false + } + env.Cursor = context.i_pV + var v_3 = env.LimitBackward + env.LimitBackward = env.Cursor + env.Cursor = env.Limit - v_2 + // (, line 202 + // do, line 203 + var v_4 = env.Limit - env.Cursor +lab1: + for { + // (, line 203 + // or, line 204 + lab2: + for { + var v_5 = env.Limit - env.Cursor + lab3: + for { + // call perfective_gerund, line 204 + if !r_perfective_gerund(env, context) { + break lab3 + } + break lab2 + } + env.Cursor = env.Limit - v_5 + // (, line 205 + // try, line 205 + var v_6 = env.Limit - env.Cursor + lab4: + for { + // call reflexive, line 205 + if !r_reflexive(env, context) { + env.Cursor = env.Limit - v_6 + break lab4 + } + break lab4 + } + // or, line 206 + lab5: + for { + var v_7 = env.Limit - env.Cursor + lab6: + for { + // call adjectival, line 206 + if !r_adjectival(env, context) { + break lab6 + } + break lab5 + } + env.Cursor = env.Limit - v_7 + lab7: + for { + // call verb, line 206 + if !r_verb(env, context) { + break lab7 + } + break lab5 + } + env.Cursor = env.Limit - v_7 + // call noun, line 206 + if !r_noun(env, context) { + break lab1 + } + break lab5 + } + break lab2 + } + break lab1 + } + env.Cursor = env.Limit - v_4 + // try, line 209 + var v_8 = env.Limit - env.Cursor +lab8: + for { + // (, line 209 + // [, line 209 + env.Ket = env.Cursor + // literal, line 209 + if !env.EqSB("\u0438") { + env.Cursor = env.Limit - v_8 + break lab8 + } + // ], line 209 + env.Bra = env.Cursor + // delete, line 209 + if !env.SliceDel() { + return false + } + break lab8 + } + // do, line 212 + var v_9 = env.Limit - env.Cursor +lab9: + for { + // call derivational, line 212 + if !r_derivational(env, context) { + break lab9 + } + break lab9 + } + env.Cursor = env.Limit - v_9 + // do, line 213 + var v_10 = env.Limit - env.Cursor +lab10: + for { + // call tidy_up, line 213 + if !r_tidy_up(env, context) { + break lab10 + } + break lab10 + } + env.Cursor = env.Limit - v_10 + env.LimitBackward = v_3 + env.Cursor = env.LimitBackward + return true +} diff --git a/backend/vendor/github.com/blevesearch/snowballstem/spanish/spanish_stemmer.go b/backend/vendor/github.com/blevesearch/snowballstem/spanish/spanish_stemmer.go new file mode 100644 index 0000000000..496edd46cf --- /dev/null +++ b/backend/vendor/github.com/blevesearch/snowballstem/spanish/spanish_stemmer.go @@ -0,0 +1,1179 @@ +//! This file was generated automatically by the Snowball to Go compiler +//! http://snowballstem.org/ + +package spanish + +import ( + snowballRuntime "github.com/blevesearch/snowballstem" +) + +var A_0 = []*snowballRuntime.Among{ + {Str: "", A: -1, B: 6, F: nil}, + {Str: "\u00E1", A: 0, B: 1, F: nil}, + {Str: "\u00E9", A: 0, B: 2, F: nil}, + {Str: "\u00ED", A: 0, B: 3, F: nil}, + {Str: "\u00F3", A: 0, B: 4, F: nil}, + {Str: "\u00FA", A: 0, B: 5, F: nil}, +} + +var A_1 = []*snowballRuntime.Among{ + {Str: "la", A: -1, B: -1, F: nil}, + {Str: "sela", A: 0, B: -1, F: nil}, + {Str: "le", A: -1, B: -1, F: nil}, + {Str: "me", A: -1, B: -1, F: nil}, + {Str: "se", A: -1, B: -1, F: nil}, + {Str: "lo", A: -1, B: -1, F: nil}, + {Str: "selo", A: 5, B: -1, F: nil}, + {Str: "las", A: -1, B: -1, F: nil}, + {Str: "selas", A: 7, B: -1, F: nil}, + {Str: "les", A: -1, B: -1, F: nil}, + {Str: "los", A: -1, B: -1, F: nil}, + {Str: "selos", A: 10, B: -1, F: nil}, + {Str: "nos", A: -1, B: -1, F: nil}, +} + +var A_2 = []*snowballRuntime.Among{ + {Str: "ando", A: -1, B: 6, F: nil}, + {Str: "iendo", A: -1, B: 6, F: nil}, + {Str: "yendo", A: -1, B: 7, F: nil}, + {Str: "\u00E1ndo", A: -1, B: 2, F: nil}, + {Str: "i\u00E9ndo", A: -1, B: 1, F: nil}, + {Str: "ar", A: -1, B: 6, F: nil}, + {Str: "er", A: -1, B: 6, F: nil}, + {Str: "ir", A: -1, B: 6, F: nil}, + {Str: "\u00E1r", A: -1, B: 3, F: nil}, + {Str: "\u00E9r", A: -1, B: 4, F: nil}, + {Str: "\u00EDr", A: -1, B: 5, F: nil}, +} + +var A_3 = []*snowballRuntime.Among{ + {Str: "ic", A: -1, B: -1, F: nil}, + {Str: "ad", A: -1, B: -1, F: nil}, + {Str: "os", A: -1, B: -1, F: nil}, + {Str: "iv", A: -1, B: 1, F: nil}, +} + +var A_4 = []*snowballRuntime.Among{ + {Str: "able", A: -1, B: 1, F: nil}, + {Str: "ible", A: -1, B: 1, F: nil}, + {Str: "ante", A: -1, B: 1, F: nil}, +} + +var A_5 = []*snowballRuntime.Among{ + {Str: "ic", A: -1, B: 1, F: nil}, + {Str: "abil", A: -1, B: 1, F: nil}, + {Str: "iv", A: -1, B: 1, F: nil}, +} + +var A_6 = []*snowballRuntime.Among{ + {Str: "ica", A: -1, B: 1, F: nil}, + {Str: "ancia", A: -1, B: 2, F: nil}, + {Str: "encia", A: -1, B: 5, F: nil}, + {Str: "adora", A: -1, B: 2, F: nil}, + {Str: "osa", A: -1, B: 1, F: nil}, + {Str: "ista", A: -1, B: 1, F: nil}, + {Str: "iva", A: -1, B: 9, F: nil}, + {Str: "anza", A: -1, B: 1, F: nil}, + {Str: "log\u00EDa", A: -1, B: 3, F: nil}, + {Str: "idad", A: -1, B: 8, F: nil}, + {Str: "able", A: -1, B: 1, F: nil}, + {Str: "ible", A: -1, B: 1, F: nil}, + {Str: "ante", A: -1, B: 2, F: nil}, + {Str: "mente", A: -1, B: 7, F: nil}, + {Str: "amente", A: 13, B: 6, F: nil}, + {Str: "aci\u00F3n", A: -1, B: 2, F: nil}, + {Str: "uci\u00F3n", A: -1, B: 4, F: nil}, + {Str: "ico", A: -1, B: 1, F: nil}, + {Str: "ismo", A: -1, B: 1, F: nil}, + {Str: "oso", A: -1, B: 1, F: nil}, + {Str: "amiento", A: -1, B: 1, F: nil}, + {Str: "imiento", A: -1, B: 1, F: nil}, + {Str: "ivo", A: -1, B: 9, F: nil}, + {Str: "ador", A: -1, B: 2, F: nil}, + {Str: "icas", A: -1, B: 1, F: nil}, + {Str: "ancias", A: -1, B: 2, F: nil}, + {Str: "encias", A: -1, B: 5, F: nil}, + {Str: "adoras", A: -1, B: 2, F: nil}, + {Str: "osas", A: -1, B: 1, F: nil}, + {Str: "istas", A: -1, B: 1, F: nil}, + {Str: "ivas", A: -1, B: 9, F: nil}, + {Str: "anzas", A: -1, B: 1, F: nil}, + {Str: "log\u00EDas", A: -1, B: 3, F: nil}, + {Str: "idades", A: -1, B: 8, F: nil}, + {Str: "ables", A: -1, B: 1, F: nil}, + {Str: "ibles", A: -1, B: 1, F: nil}, + {Str: "aciones", A: -1, B: 2, F: nil}, + {Str: "uciones", A: -1, B: 4, F: nil}, + {Str: "adores", A: -1, B: 2, F: nil}, + {Str: "antes", A: -1, B: 2, F: nil}, + {Str: "icos", A: -1, B: 1, F: nil}, + {Str: "ismos", A: -1, B: 1, F: nil}, + {Str: "osos", A: -1, B: 1, F: nil}, + {Str: "amientos", A: -1, B: 1, F: nil}, + {Str: "imientos", A: -1, B: 1, F: nil}, + {Str: "ivos", A: -1, B: 9, F: nil}, +} + +var A_7 = []*snowballRuntime.Among{ + {Str: "ya", A: -1, B: 1, F: nil}, + {Str: "ye", A: -1, B: 1, F: nil}, + {Str: "yan", A: -1, B: 1, F: nil}, + {Str: "yen", A: -1, B: 1, F: nil}, + {Str: "yeron", A: -1, B: 1, F: nil}, + {Str: "yendo", A: -1, B: 1, F: nil}, + {Str: "yo", A: -1, B: 1, F: nil}, + {Str: "yas", A: -1, B: 1, F: nil}, + {Str: "yes", A: -1, B: 1, F: nil}, + {Str: "yais", A: -1, B: 1, F: nil}, + {Str: "yamos", A: -1, B: 1, F: nil}, + {Str: "y\u00F3", A: -1, B: 1, F: nil}, +} + +var A_8 = []*snowballRuntime.Among{ + {Str: "aba", A: -1, B: 2, F: nil}, + {Str: "ada", A: -1, B: 2, F: nil}, + {Str: "ida", A: -1, B: 2, F: nil}, + {Str: "ara", A: -1, B: 2, F: nil}, + {Str: "iera", A: -1, B: 2, F: nil}, + {Str: "\u00EDa", A: -1, B: 2, F: nil}, + {Str: "ar\u00EDa", A: 5, B: 2, F: nil}, + {Str: "er\u00EDa", A: 5, B: 2, F: nil}, + {Str: "ir\u00EDa", A: 5, B: 2, F: nil}, + {Str: "ad", A: -1, B: 2, F: nil}, + {Str: "ed", A: -1, B: 2, F: nil}, + {Str: "id", A: -1, B: 2, F: nil}, + {Str: "ase", A: -1, B: 2, F: nil}, + {Str: "iese", A: -1, B: 2, F: nil}, + {Str: "aste", A: -1, B: 2, F: nil}, + {Str: "iste", A: -1, B: 2, F: nil}, + {Str: "an", A: -1, B: 2, F: nil}, + {Str: "aban", A: 16, B: 2, F: nil}, + {Str: "aran", A: 16, B: 2, F: nil}, + {Str: "ieran", A: 16, B: 2, F: nil}, + {Str: "\u00EDan", A: 16, B: 2, F: nil}, + {Str: "ar\u00EDan", A: 20, B: 2, F: nil}, + {Str: "er\u00EDan", A: 20, B: 2, F: nil}, + {Str: "ir\u00EDan", A: 20, B: 2, F: nil}, + {Str: "en", A: -1, B: 1, F: nil}, + {Str: "asen", A: 24, B: 2, F: nil}, + {Str: "iesen", A: 24, B: 2, F: nil}, + {Str: "aron", A: -1, B: 2, F: nil}, + {Str: "ieron", A: -1, B: 2, F: nil}, + {Str: "ar\u00E1n", A: -1, B: 2, F: nil}, + {Str: "er\u00E1n", A: -1, B: 2, F: nil}, + {Str: "ir\u00E1n", A: -1, B: 2, F: nil}, + {Str: "ado", A: -1, B: 2, F: nil}, + {Str: "ido", A: -1, B: 2, F: nil}, + {Str: "ando", A: -1, B: 2, F: nil}, + {Str: "iendo", A: -1, B: 2, F: nil}, + {Str: "ar", A: -1, B: 2, F: nil}, + {Str: "er", A: -1, B: 2, F: nil}, + {Str: "ir", A: -1, B: 2, F: nil}, + {Str: "as", A: -1, B: 2, F: nil}, + {Str: "abas", A: 39, B: 2, F: nil}, + {Str: "adas", A: 39, B: 2, F: nil}, + {Str: "idas", A: 39, B: 2, F: nil}, + {Str: "aras", A: 39, B: 2, F: nil}, + {Str: "ieras", A: 39, B: 2, F: nil}, + {Str: "\u00EDas", A: 39, B: 2, F: nil}, + {Str: "ar\u00EDas", A: 45, B: 2, F: nil}, + {Str: "er\u00EDas", A: 45, B: 2, F: nil}, + {Str: "ir\u00EDas", A: 45, B: 2, F: nil}, + {Str: "es", A: -1, B: 1, F: nil}, + {Str: "ases", A: 49, B: 2, F: nil}, + {Str: "ieses", A: 49, B: 2, F: nil}, + {Str: "abais", A: -1, B: 2, F: nil}, + {Str: "arais", A: -1, B: 2, F: nil}, + {Str: "ierais", A: -1, B: 2, F: nil}, + {Str: "\u00EDais", A: -1, B: 2, F: nil}, + {Str: "ar\u00EDais", A: 55, B: 2, F: nil}, + {Str: "er\u00EDais", A: 55, B: 2, F: nil}, + {Str: "ir\u00EDais", A: 55, B: 2, F: nil}, + {Str: "aseis", A: -1, B: 2, F: nil}, + {Str: "ieseis", A: -1, B: 2, F: nil}, + {Str: "asteis", A: -1, B: 2, F: nil}, + {Str: "isteis", A: -1, B: 2, F: nil}, + {Str: "\u00E1is", A: -1, B: 2, F: nil}, + {Str: "\u00E9is", A: -1, B: 1, F: nil}, + {Str: "ar\u00E9is", A: 64, B: 2, F: nil}, + {Str: "er\u00E9is", A: 64, B: 2, F: nil}, + {Str: "ir\u00E9is", A: 64, B: 2, F: nil}, + {Str: "ados", A: -1, B: 2, F: nil}, + {Str: "idos", A: -1, B: 2, F: nil}, + {Str: "amos", A: -1, B: 2, F: nil}, + {Str: "\u00E1bamos", A: 70, B: 2, F: nil}, + {Str: "\u00E1ramos", A: 70, B: 2, F: nil}, + {Str: "i\u00E9ramos", A: 70, B: 2, F: nil}, + {Str: "\u00EDamos", A: 70, B: 2, F: nil}, + {Str: "ar\u00EDamos", A: 74, B: 2, F: nil}, + {Str: "er\u00EDamos", A: 74, B: 2, F: nil}, + {Str: "ir\u00EDamos", A: 74, B: 2, F: nil}, + {Str: "emos", A: -1, B: 1, F: nil}, + {Str: "aremos", A: 78, B: 2, F: nil}, + {Str: "eremos", A: 78, B: 2, F: nil}, + {Str: "iremos", A: 78, B: 2, F: nil}, + {Str: "\u00E1semos", A: 78, B: 2, F: nil}, + {Str: "i\u00E9semos", A: 78, B: 2, F: nil}, + {Str: "imos", A: -1, B: 2, F: nil}, + {Str: "ar\u00E1s", A: -1, B: 2, F: nil}, + {Str: "er\u00E1s", A: -1, B: 2, F: nil}, + {Str: "ir\u00E1s", A: -1, B: 2, F: nil}, + {Str: "\u00EDs", A: -1, B: 2, F: nil}, + {Str: "ar\u00E1", A: -1, B: 2, F: nil}, + {Str: "er\u00E1", A: -1, B: 2, F: nil}, + {Str: "ir\u00E1", A: -1, B: 2, F: nil}, + {Str: "ar\u00E9", A: -1, B: 2, F: nil}, + {Str: "er\u00E9", A: -1, B: 2, F: nil}, + {Str: "ir\u00E9", A: -1, B: 2, F: nil}, + {Str: "i\u00F3", A: -1, B: 2, F: nil}, +} + +var A_9 = []*snowballRuntime.Among{ + {Str: "a", A: -1, B: 1, F: nil}, + {Str: "e", A: -1, B: 2, F: nil}, + {Str: "o", A: -1, B: 1, F: nil}, + {Str: "os", A: -1, B: 1, F: nil}, + {Str: "\u00E1", A: -1, B: 1, F: nil}, + {Str: "\u00E9", A: -1, B: 2, F: nil}, + {Str: "\u00ED", A: -1, B: 1, F: nil}, + {Str: "\u00F3", A: -1, B: 1, F: nil}, +} + +var G_v = []byte{17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 10} + +type Context struct { + i_p2 int + i_p1 int + i_pV int +} + +func r_mark_regions(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + // (, line 31 + context.i_pV = env.Limit + context.i_p1 = env.Limit + context.i_p2 = env.Limit + // do, line 37 + var v_1 = env.Cursor +lab0: + for { + // (, line 37 + // or, line 39 + lab1: + for { + var v_2 = env.Cursor + lab2: + for { + // (, line 38 + if !env.InGrouping(G_v, 97, 252) { + break lab2 + } + // or, line 38 + lab3: + for { + var v_3 = env.Cursor + lab4: + for { + // (, line 38 + if !env.OutGrouping(G_v, 97, 252) { + break lab4 + } + // gopast, line 38 + golab5: + for { + lab6: + for { + if !env.InGrouping(G_v, 97, 252) { + break lab6 + } + break golab5 + } + if env.Cursor >= env.Limit { + break lab4 + } + env.NextChar() + } + break lab3 + } + env.Cursor = v_3 + // (, line 38 + if !env.InGrouping(G_v, 97, 252) { + break lab2 + } + // gopast, line 38 + golab7: + for { + lab8: + for { + if !env.OutGrouping(G_v, 97, 252) { + break lab8 + } + break golab7 + } + if env.Cursor >= env.Limit { + break lab2 + } + env.NextChar() + } + break lab3 + } + break lab1 + } + env.Cursor = v_2 + // (, line 40 + if !env.OutGrouping(G_v, 97, 252) { + break lab0 + } + // or, line 40 + lab9: + for { + var v_6 = env.Cursor + lab10: + for { + // (, line 40 + if !env.OutGrouping(G_v, 97, 252) { + break lab10 + } + // gopast, line 40 + golab11: + for { + lab12: + for { + if !env.InGrouping(G_v, 97, 252) { + break lab12 + } + break golab11 + } + if env.Cursor >= env.Limit { + break lab10 + } + env.NextChar() + } + break lab9 + } + env.Cursor = v_6 + // (, line 40 + if !env.InGrouping(G_v, 97, 252) { + break lab0 + } + // next, line 40 + if env.Cursor >= env.Limit { + break lab0 + } + env.NextChar() + break lab9 + } + break lab1 + } + // setmark pV, line 41 + context.i_pV = env.Cursor + break lab0 + } + env.Cursor = v_1 + // do, line 43 + var v_8 = env.Cursor +lab13: + for { + // (, line 43 + // gopast, line 44 + golab14: + for { + lab15: + for { + if !env.InGrouping(G_v, 97, 252) { + break lab15 + } + break golab14 + } + if env.Cursor >= env.Limit { + break lab13 + } + env.NextChar() + } + // gopast, line 44 + golab16: + for { + lab17: + for { + if !env.OutGrouping(G_v, 97, 252) { + break lab17 + } + break golab16 + } + if env.Cursor >= env.Limit { + break lab13 + } + env.NextChar() + } + // setmark p1, line 44 + context.i_p1 = env.Cursor + // gopast, line 45 + golab18: + for { + lab19: + for { + if !env.InGrouping(G_v, 97, 252) { + break lab19 + } + break golab18 + } + if env.Cursor >= env.Limit { + break lab13 + } + env.NextChar() + } + // gopast, line 45 + golab20: + for { + lab21: + for { + if !env.OutGrouping(G_v, 97, 252) { + break lab21 + } + break golab20 + } + if env.Cursor >= env.Limit { + break lab13 + } + env.NextChar() + } + // setmark p2, line 45 + context.i_p2 = env.Cursor + break lab13 + } + env.Cursor = v_8 + return true +} + +func r_postlude(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // repeat, line 49 +replab0: + for { + var v_1 = env.Cursor + lab1: + for range [2]struct{}{} { + // (, line 49 + // [, line 50 + env.Bra = env.Cursor + // substring, line 50 + among_var = env.FindAmong(A_0, context) + if among_var == 0 { + break lab1 + } + // ], line 50 + env.Ket = env.Cursor + if among_var == 0 { + break lab1 + } else if among_var == 1 { + // (, line 51 + // <-, line 51 + if !env.SliceFrom("a") { + return false + } + } else if among_var == 2 { + // (, line 52 + // <-, line 52 + if !env.SliceFrom("e") { + return false + } + } else if among_var == 3 { + // (, line 53 + // <-, line 53 + if !env.SliceFrom("i") { + return false + } + } else if among_var == 4 { + // (, line 54 + // <-, line 54 + if !env.SliceFrom("o") { + return false + } + } else if among_var == 5 { + // (, line 55 + // <-, line 55 + if !env.SliceFrom("u") { + return false + } + } else if among_var == 6 { + // (, line 57 + // next, line 57 + if env.Cursor >= env.Limit { + break lab1 + } + env.NextChar() + } + continue replab0 + } + env.Cursor = v_1 + break replab0 + } + return true +} + +func r_RV(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + if !(context.i_pV <= env.Cursor) { + return false + } + return true +} + +func r_R1(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + if !(context.i_p1 <= env.Cursor) { + return false + } + return true +} + +func r_R2(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + if !(context.i_p2 <= env.Cursor) { + return false + } + return true +} + +func r_attached_pronoun(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 67 + // [, line 68 + env.Ket = env.Cursor + // substring, line 68 + if env.FindAmongB(A_1, context) == 0 { + return false + } + // ], line 68 + env.Bra = env.Cursor + // substring, line 72 + among_var = env.FindAmongB(A_2, context) + if among_var == 0 { + return false + } + // call RV, line 72 + if !r_RV(env, context) { + return false + } + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 73 + // ], line 73 + env.Bra = env.Cursor + // <-, line 73 + if !env.SliceFrom("iendo") { + return false + } + } else if among_var == 2 { + // (, line 74 + // ], line 74 + env.Bra = env.Cursor + // <-, line 74 + if !env.SliceFrom("ando") { + return false + } + } else if among_var == 3 { + // (, line 75 + // ], line 75 + env.Bra = env.Cursor + // <-, line 75 + if !env.SliceFrom("ar") { + return false + } + } else if among_var == 4 { + // (, line 76 + // ], line 76 + env.Bra = env.Cursor + // <-, line 76 + if !env.SliceFrom("er") { + return false + } + } else if among_var == 5 { + // (, line 77 + // ], line 77 + env.Bra = env.Cursor + // <-, line 77 + if !env.SliceFrom("ir") { + return false + } + } else if among_var == 6 { + // (, line 81 + // delete, line 81 + if !env.SliceDel() { + return false + } + } else if among_var == 7 { + // (, line 82 + // literal, line 82 + if !env.EqSB("u") { + return false + } + // delete, line 82 + if !env.SliceDel() { + return false + } + } + return true +} + +func r_standard_suffix(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 86 + // [, line 87 + env.Ket = env.Cursor + // substring, line 87 + among_var = env.FindAmongB(A_6, context) + if among_var == 0 { + return false + } + // ], line 87 + env.Bra = env.Cursor + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 98 + // call R2, line 99 + if !r_R2(env, context) { + return false + } + // delete, line 99 + if !env.SliceDel() { + return false + } + } else if among_var == 2 { + // (, line 104 + // call R2, line 105 + if !r_R2(env, context) { + return false + } + // delete, line 105 + if !env.SliceDel() { + return false + } + // try, line 106 + var v_1 = env.Limit - env.Cursor + lab0: + for { + // (, line 106 + // [, line 106 + env.Ket = env.Cursor + // literal, line 106 + if !env.EqSB("ic") { + env.Cursor = env.Limit - v_1 + break lab0 + } + // ], line 106 + env.Bra = env.Cursor + // call R2, line 106 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_1 + break lab0 + } + // delete, line 106 + if !env.SliceDel() { + return false + } + break lab0 + } + } else if among_var == 3 { + // (, line 110 + // call R2, line 111 + if !r_R2(env, context) { + return false + } + // <-, line 111 + if !env.SliceFrom("log") { + return false + } + } else if among_var == 4 { + // (, line 114 + // call R2, line 115 + if !r_R2(env, context) { + return false + } + // <-, line 115 + if !env.SliceFrom("u") { + return false + } + } else if among_var == 5 { + // (, line 118 + // call R2, line 119 + if !r_R2(env, context) { + return false + } + // <-, line 119 + if !env.SliceFrom("ente") { + return false + } + } else if among_var == 6 { + // (, line 122 + // call R1, line 123 + if !r_R1(env, context) { + return false + } + // delete, line 123 + if !env.SliceDel() { + return false + } + // try, line 124 + var v_2 = env.Limit - env.Cursor + lab1: + for { + // (, line 124 + // [, line 125 + env.Ket = env.Cursor + // substring, line 125 + among_var = env.FindAmongB(A_3, context) + if among_var == 0 { + env.Cursor = env.Limit - v_2 + break lab1 + } + // ], line 125 + env.Bra = env.Cursor + // call R2, line 125 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_2 + break lab1 + } + // delete, line 125 + if !env.SliceDel() { + return false + } + if among_var == 0 { + env.Cursor = env.Limit - v_2 + break lab1 + } else if among_var == 1 { + // (, line 126 + // [, line 126 + env.Ket = env.Cursor + // literal, line 126 + if !env.EqSB("at") { + env.Cursor = env.Limit - v_2 + break lab1 + } + // ], line 126 + env.Bra = env.Cursor + // call R2, line 126 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_2 + break lab1 + } + // delete, line 126 + if !env.SliceDel() { + return false + } + } + break lab1 + } + } else if among_var == 7 { + // (, line 134 + // call R2, line 135 + if !r_R2(env, context) { + return false + } + // delete, line 135 + if !env.SliceDel() { + return false + } + // try, line 136 + var v_3 = env.Limit - env.Cursor + lab2: + for { + // (, line 136 + // [, line 137 + env.Ket = env.Cursor + // substring, line 137 + among_var = env.FindAmongB(A_4, context) + if among_var == 0 { + env.Cursor = env.Limit - v_3 + break lab2 + } + // ], line 137 + env.Bra = env.Cursor + if among_var == 0 { + env.Cursor = env.Limit - v_3 + break lab2 + } else if among_var == 1 { + // (, line 140 + // call R2, line 140 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_3 + break lab2 + } + // delete, line 140 + if !env.SliceDel() { + return false + } + } + break lab2 + } + } else if among_var == 8 { + // (, line 146 + // call R2, line 147 + if !r_R2(env, context) { + return false + } + // delete, line 147 + if !env.SliceDel() { + return false + } + // try, line 148 + var v_4 = env.Limit - env.Cursor + lab3: + for { + // (, line 148 + // [, line 149 + env.Ket = env.Cursor + // substring, line 149 + among_var = env.FindAmongB(A_5, context) + if among_var == 0 { + env.Cursor = env.Limit - v_4 + break lab3 + } + // ], line 149 + env.Bra = env.Cursor + if among_var == 0 { + env.Cursor = env.Limit - v_4 + break lab3 + } else if among_var == 1 { + // (, line 152 + // call R2, line 152 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_4 + break lab3 + } + // delete, line 152 + if !env.SliceDel() { + return false + } + } + break lab3 + } + } else if among_var == 9 { + // (, line 158 + // call R2, line 159 + if !r_R2(env, context) { + return false + } + // delete, line 159 + if !env.SliceDel() { + return false + } + // try, line 160 + var v_5 = env.Limit - env.Cursor + lab4: + for { + // (, line 160 + // [, line 161 + env.Ket = env.Cursor + // literal, line 161 + if !env.EqSB("at") { + env.Cursor = env.Limit - v_5 + break lab4 + } + // ], line 161 + env.Bra = env.Cursor + // call R2, line 161 + if !r_R2(env, context) { + env.Cursor = env.Limit - v_5 + break lab4 + } + // delete, line 161 + if !env.SliceDel() { + return false + } + break lab4 + } + } + return true +} + +func r_y_verb_suffix(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 167 + // setlimit, line 168 + var v_1 = env.Limit - env.Cursor + // tomark, line 168 + if env.Cursor < context.i_pV { + return false + } + env.Cursor = context.i_pV + var v_2 = env.LimitBackward + env.LimitBackward = env.Cursor + env.Cursor = env.Limit - v_1 + // (, line 168 + // [, line 168 + env.Ket = env.Cursor + // substring, line 168 + among_var = env.FindAmongB(A_7, context) + if among_var == 0 { + env.LimitBackward = v_2 + return false + } + // ], line 168 + env.Bra = env.Cursor + env.LimitBackward = v_2 + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 171 + // literal, line 171 + if !env.EqSB("u") { + return false + } + // delete, line 171 + if !env.SliceDel() { + return false + } + } + return true +} + +func r_verb_suffix(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 175 + // setlimit, line 176 + var v_1 = env.Limit - env.Cursor + // tomark, line 176 + if env.Cursor < context.i_pV { + return false + } + env.Cursor = context.i_pV + var v_2 = env.LimitBackward + env.LimitBackward = env.Cursor + env.Cursor = env.Limit - v_1 + // (, line 176 + // [, line 176 + env.Ket = env.Cursor + // substring, line 176 + among_var = env.FindAmongB(A_8, context) + if among_var == 0 { + env.LimitBackward = v_2 + return false + } + // ], line 176 + env.Bra = env.Cursor + env.LimitBackward = v_2 + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 179 + // try, line 179 + var v_3 = env.Limit - env.Cursor + lab0: + for { + // (, line 179 + // literal, line 179 + if !env.EqSB("u") { + env.Cursor = env.Limit - v_3 + break lab0 + } + // test, line 179 + var v_4 = env.Limit - env.Cursor + // literal, line 179 + if !env.EqSB("g") { + env.Cursor = env.Limit - v_3 + break lab0 + } + env.Cursor = env.Limit - v_4 + break lab0 + } + // ], line 179 + env.Bra = env.Cursor + // delete, line 179 + if !env.SliceDel() { + return false + } + } else if among_var == 2 { + // (, line 200 + // delete, line 200 + if !env.SliceDel() { + return false + } + } + return true +} + +func r_residual_suffix(env *snowballRuntime.Env, ctx interface{}) bool { + context := ctx.(*Context) + _ = context + var among_var int32 + // (, line 204 + // [, line 205 + env.Ket = env.Cursor + // substring, line 205 + among_var = env.FindAmongB(A_9, context) + if among_var == 0 { + return false + } + // ], line 205 + env.Bra = env.Cursor + if among_var == 0 { + return false + } else if among_var == 1 { + // (, line 208 + // call RV, line 208 + if !r_RV(env, context) { + return false + } + // delete, line 208 + if !env.SliceDel() { + return false + } + } else if among_var == 2 { + // (, line 210 + // call RV, line 210 + if !r_RV(env, context) { + return false + } + // delete, line 210 + if !env.SliceDel() { + return false + } + // try, line 210 + var v_1 = env.Limit - env.Cursor + lab0: + for { + // (, line 210 + // [, line 210 + env.Ket = env.Cursor + // literal, line 210 + if !env.EqSB("u") { + env.Cursor = env.Limit - v_1 + break lab0 + } + // ], line 210 + env.Bra = env.Cursor + // test, line 210 + var v_2 = env.Limit - env.Cursor + // literal, line 210 + if !env.EqSB("g") { + env.Cursor = env.Limit - v_1 + break lab0 + } + env.Cursor = env.Limit - v_2 + // call RV, line 210 + if !r_RV(env, context) { + env.Cursor = env.Limit - v_1 + break lab0 + } + // delete, line 210 + if !env.SliceDel() { + return false + } + break lab0 + } + } + return true +} + +func Stem(env *snowballRuntime.Env) bool { + var context = &Context{ + i_p2: 0, + i_p1: 0, + i_pV: 0, + } + _ = context + // (, line 215 + // do, line 216 + var v_1 = env.Cursor +lab0: + for { + // call mark_regions, line 216 + if !r_mark_regions(env, context) { + break lab0 + } + break lab0 + } + env.Cursor = v_1 + // backwards, line 217 + env.LimitBackward = env.Cursor + env.Cursor = env.Limit + // (, line 217 + // do, line 218 + var v_2 = env.Limit - env.Cursor +lab1: + for { + // call attached_pronoun, line 218 + if !r_attached_pronoun(env, context) { + break lab1 + } + break lab1 + } + env.Cursor = env.Limit - v_2 + // do, line 219 + var v_3 = env.Limit - env.Cursor +lab2: + for { + // (, line 219 + // or, line 219 + lab3: + for { + var v_4 = env.Limit - env.Cursor + lab4: + for { + // call standard_suffix, line 219 + if !r_standard_suffix(env, context) { + break lab4 + } + break lab3 + } + env.Cursor = env.Limit - v_4 + lab5: + for { + // call y_verb_suffix, line 220 + if !r_y_verb_suffix(env, context) { + break lab5 + } + break lab3 + } + env.Cursor = env.Limit - v_4 + // call verb_suffix, line 221 + if !r_verb_suffix(env, context) { + break lab2 + } + break lab3 + } + break lab2 + } + env.Cursor = env.Limit - v_3 + // do, line 223 + var v_5 = env.Limit - env.Cursor +lab6: + for { + // call residual_suffix, line 223 + if !r_residual_suffix(env, context) { + break lab6 + } + break lab6 + } + env.Cursor = env.Limit - v_5 + env.Cursor = env.LimitBackward + // do, line 225 + var v_6 = env.Cursor +lab7: + for { + // call postlude, line 225 + if !r_postlude(env, context) { + break lab7 + } + break lab7 + } + env.Cursor = v_6 + return true +} diff --git a/backend/vendor/github.com/blevesearch/snowballstem/util.go b/backend/vendor/github.com/blevesearch/snowballstem/util.go new file mode 100644 index 0000000000..7c68f6e750 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/snowballstem/util.go @@ -0,0 +1,34 @@ +package snowballstem + +import ( + "math" + "unicode/utf8" +) + +const MaxInt = math.MaxInt32 +const MinInt = math.MinInt32 + +func splitAt(str string, mid int) (string, string) { + return str[:mid], str[mid:] +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func onCharBoundary(s string, pos int) bool { + if pos <= 0 || pos >= len(s) { + return true + } + return utf8.RuneStart(s[pos]) +} + +// RuneCountInString is a wrapper around utf8.RuneCountInString +// this allows us to not have to conditionally include +// the utf8 package into some stemmers and not others +func RuneCountInString(str string) int { + return utf8.RuneCountInString(str) +} diff --git a/backend/vendor/github.com/blevesearch/upsidedown_store_api/LICENSE b/backend/vendor/github.com/blevesearch/upsidedown_store_api/LICENSE new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/upsidedown_store_api/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/backend/vendor/github.com/blevesearch/upsidedown_store_api/README.md b/backend/vendor/github.com/blevesearch/upsidedown_store_api/README.md new file mode 100644 index 0000000000..9192819473 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/upsidedown_store_api/README.md @@ -0,0 +1,7 @@ +# Upsidedown Store API + +Upsidedown supports a pluggable Key/Value storage interface. + +By placing these interfaces in their own, *hopefully* slowly evolving module, it frees up Upsidedown and the underlying storage implementations to each introduce new major versions without interfering with one another. + +With that in mind, we anticipate introducing non-breaking changes only to this module, and keeping the major version at 1.x for some time. diff --git a/backend/vendor/github.com/blevesearch/upsidedown_store_api/batch.go b/backend/vendor/github.com/blevesearch/upsidedown_store_api/batch.go new file mode 100644 index 0000000000..7110526610 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/upsidedown_store_api/batch.go @@ -0,0 +1,62 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package store + +type op struct { + K []byte + V []byte +} + +type EmulatedBatch struct { + Ops []*op + Merger *EmulatedMerge +} + +func NewEmulatedBatch(mo MergeOperator) *EmulatedBatch { + return &EmulatedBatch{ + Ops: make([]*op, 0, 1000), + Merger: NewEmulatedMerge(mo), + } +} + +func (b *EmulatedBatch) Set(key, val []byte) { + ck := make([]byte, len(key)) + copy(ck, key) + cv := make([]byte, len(val)) + copy(cv, val) + b.Ops = append(b.Ops, &op{ck, cv}) +} + +func (b *EmulatedBatch) Delete(key []byte) { + ck := make([]byte, len(key)) + copy(ck, key) + b.Ops = append(b.Ops, &op{ck, nil}) +} + +func (b *EmulatedBatch) Merge(key, val []byte) { + ck := make([]byte, len(key)) + copy(ck, key) + cv := make([]byte, len(val)) + copy(cv, val) + b.Merger.Merge(key, val) +} + +func (b *EmulatedBatch) Reset() { + b.Ops = b.Ops[:0] +} + +func (b *EmulatedBatch) Close() error { + return nil +} diff --git a/backend/vendor/github.com/blevesearch/upsidedown_store_api/kvstore.go b/backend/vendor/github.com/blevesearch/upsidedown_store_api/kvstore.go new file mode 100644 index 0000000000..34698c7bda --- /dev/null +++ b/backend/vendor/github.com/blevesearch/upsidedown_store_api/kvstore.go @@ -0,0 +1,174 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package store + +import "encoding/json" + +// KVStore is an abstraction for working with KV stores. Note that +// in order to be used with the bleve.registry, it must also implement +// a constructor function of the registry.KVStoreConstructor type. +type KVStore interface { + + // Writer returns a KVWriter which can be used to + // make changes to the KVStore. If a writer cannot + // be obtained a non-nil error is returned. + Writer() (KVWriter, error) + + // Reader returns a KVReader which can be used to + // read data from the KVStore. If a reader cannot + // be obtained a non-nil error is returned. + Reader() (KVReader, error) + + // Close closes the KVStore + Close() error +} + +// KVReader is an abstraction of an **ISOLATED** reader +// In this context isolated is defined to mean that +// writes/deletes made after the KVReader is opened +// are not observed. +// Because there is usually a cost associated with +// keeping isolated readers active, users should +// close them as soon as they are no longer needed. +type KVReader interface { + + // Get returns the value associated with the key + // If the key does not exist, nil is returned. + // The caller owns the bytes returned. + Get(key []byte) ([]byte, error) + + // MultiGet retrieves multiple values in one call. + MultiGet(keys [][]byte) ([][]byte, error) + + // PrefixIterator returns a KVIterator that will + // visit all K/V pairs with the provided prefix + PrefixIterator(prefix []byte) KVIterator + + // RangeIterator returns a KVIterator that will + // visit all K/V pairs >= start AND < end + RangeIterator(start, end []byte) KVIterator + + // Close closes the iterator + Close() error +} + +// KVIterator is an abstraction around key iteration +type KVIterator interface { + + // Seek will advance the iterator to the specified key + Seek(key []byte) + + // Next will advance the iterator to the next key + Next() + + // Key returns the key pointed to by the iterator + // The bytes returned are **ONLY** valid until the next call to Seek/Next/Close + // Continued use after that requires that they be copied. + Key() []byte + + // Value returns the value pointed to by the iterator + // The bytes returned are **ONLY** valid until the next call to Seek/Next/Close + // Continued use after that requires that they be copied. + Value() []byte + + // Valid returns whether or not the iterator is in a valid state + Valid() bool + + // Current returns Key(),Value(),Valid() in a single operation + Current() ([]byte, []byte, bool) + + // Close closes the iterator + Close() error +} + +// KVWriter is an abstraction for mutating the KVStore +// KVWriter does **NOT** enforce restrictions of a single writer +// if the underlying KVStore allows concurrent writes, the +// KVWriter interface should also do so, it is up to the caller +// to do this in a way that is safe and makes sense +type KVWriter interface { + + // NewBatch returns a KVBatch for performing batch operations on this kvstore + NewBatch() KVBatch + + // NewBatchEx returns a KVBatch and an associated byte array + // that's pre-sized based on the KVBatchOptions. The caller can + // use the returned byte array for keys and values associated with + // the batch. Once the batch is either executed or closed, the + // associated byte array should no longer be accessed by the + // caller. + NewBatchEx(KVBatchOptions) ([]byte, KVBatch, error) + + // ExecuteBatch will execute the KVBatch, the provided KVBatch **MUST** have + // been created by the same KVStore (though not necessarily the same KVWriter) + // Batch execution is atomic, either all the operations or none will be performed + ExecuteBatch(batch KVBatch) error + + // Close closes the writer + Close() error +} + +// KVBatchOptions provides the KVWriter.NewBatchEx() method with batch +// preparation and preallocation information. +type KVBatchOptions struct { + // TotalBytes is the sum of key and value bytes needed by the + // caller for the entire batch. It affects the size of the + // returned byte array of KVWrite.NewBatchEx(). + TotalBytes int + + // NumSets is the number of Set() calls the caller will invoke on + // the KVBatch. + NumSets int + + // NumDeletes is the number of Delete() calls the caller will invoke + // on the KVBatch. + NumDeletes int + + // NumMerges is the number of Merge() calls the caller will invoke + // on the KVBatch. + NumMerges int +} + +// KVBatch is an abstraction for making multiple KV mutations at once +type KVBatch interface { + + // Set updates the key with the specified value + // both key and value []byte may be reused as soon as this call returns + Set(key, val []byte) + + // Delete removes the specified key + // the key []byte may be reused as soon as this call returns + Delete(key []byte) + + // Merge merges old value with the new value at the specified key + // as prescribed by the KVStores merge operator + // both key and value []byte may be reused as soon as this call returns + Merge(key, val []byte) + + // Reset frees resources for this batch and allows reuse + Reset() + + // Close frees resources + Close() error +} + +// KVStoreStats is an optional interface that KVStores can implement +// if they're able to report any useful stats +type KVStoreStats interface { + // Stats returns a JSON serializable object representing stats for this KVStore + Stats() json.Marshaler + + StatsMap() map[string]interface{} +} diff --git a/backend/vendor/github.com/blevesearch/upsidedown_store_api/merge.go b/backend/vendor/github.com/blevesearch/upsidedown_store_api/merge.go new file mode 100644 index 0000000000..ca2561b0a9 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/upsidedown_store_api/merge.go @@ -0,0 +1,64 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package store + +// At the moment this happens to be the same interface as described by +// RocksDB, but this may not always be the case. + +type MergeOperator interface { + + // FullMerge the full sequence of operands on top of the existingValue + // if no value currently exists, existingValue is nil + // return the merged value, and success/failure + FullMerge(key, existingValue []byte, operands [][]byte) ([]byte, bool) + + // Partially merge these two operands. + // If partial merge cannot be done, return nil,false, which will defer + // all processing until the FullMerge is done. + PartialMerge(key, leftOperand, rightOperand []byte) ([]byte, bool) + + // Name returns an identifier for the operator + Name() string +} + +type EmulatedMerge struct { + Merges map[string][][]byte + mo MergeOperator +} + +func NewEmulatedMerge(mo MergeOperator) *EmulatedMerge { + return &EmulatedMerge{ + Merges: make(map[string][][]byte), + mo: mo, + } +} + +func (m *EmulatedMerge) Merge(key, val []byte) { + ops, ok := m.Merges[string(key)] + if ok && len(ops) > 0 { + last := ops[len(ops)-1] + mergedVal, partialMergeOk := m.mo.PartialMerge(key, last, val) + if partialMergeOk { + // replace last entry with the result of the merge + ops[len(ops)-1] = mergedVal + } else { + // could not partial merge, append this to the end + ops = append(ops, val) + } + } else { + ops = [][]byte{val} + } + m.Merges[string(key)] = ops +} diff --git a/backend/vendor/github.com/blevesearch/upsidedown_store_api/multiget.go b/backend/vendor/github.com/blevesearch/upsidedown_store_api/multiget.go new file mode 100644 index 0000000000..635bcd4116 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/upsidedown_store_api/multiget.go @@ -0,0 +1,33 @@ +// Copyright (c) 2016 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package store + +// MultiGet is a helper function to retrieve mutiple keys from a +// KVReader, and might be used by KVStore implementations that don't +// have a native multi-get facility. +func MultiGet(kvreader KVReader, keys [][]byte) ([][]byte, error) { + vals := make([][]byte, 0, len(keys)) + + for i, key := range keys { + val, err := kvreader.Get(key) + if err != nil { + return nil, err + } + + vals[i] = val + } + + return vals, nil +} diff --git a/backend/vendor/github.com/blevesearch/vellum/CONTRIBUTING.md b/backend/vendor/github.com/blevesearch/vellum/CONTRIBUTING.md new file mode 100644 index 0000000000..b85ec82b6b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/CONTRIBUTING.md @@ -0,0 +1,16 @@ +# Contributing to Vellum + +We look forward to your contributions, but ask that you first review these guidelines. + +### Sign the CLA + +As Vellum is a Couchbase project we require contributors accept the [Couchbase Contributor License Agreement](http://review.couchbase.org/static/individual_agreement.html). To sign this agreement log into the Couchbase [code review tool](http://review.couchbase.org/). The Vellum project does not use this code review tool but it is still used to track acceptance of the contributor license agreements. + +### Submitting a Pull Request + +All types of contributions are welcome, but please keep the following in mind: + +- If you're planning a large change, you should really discuss it in a github issue first. This helps avoid duplicate effort and spending time on something that may not be merged. +- Existing tests should continue to pass, new tests for the contribution are nice to have. +- All code should have gone through `go fmt` +- All code should pass `go vet` diff --git a/backend/vendor/github.com/blevesearch/vellum/LICENSE b/backend/vendor/github.com/blevesearch/vellum/LICENSE new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/backend/vendor/github.com/blevesearch/vellum/README.md b/backend/vendor/github.com/blevesearch/vellum/README.md new file mode 100644 index 0000000000..e5c4a8bce8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/README.md @@ -0,0 +1,183 @@ +# ![vellum](docs/logo.png) vellum + +[![Tests](https://github.com/couchbase/vellum/workflows/Tests/badge.svg?branch=master&event=push)](https://github.com/couchbase/vellum/actions?query=workflow%3ATests+event%3Apush+branch%3Amaster) +[![Coverage Status](https://coveralls.io/repos/github/couchbase/vellum/badge.svg?branch=master)](https://coveralls.io/github/couchbase/vellum?branch=master) +[![GoDoc](https://godoc.org/github.com/couchbase/vellum?status.svg)](https://godoc.org/github.com/couchbase/vellum) +[![Go Report Card](https://goreportcard.com/badge/github.com/couchbase/vellum)](https://goreportcard.com/report/github.com/couchbase/vellum) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) + +A Go library implementing an FST (finite state transducer) capable of: + - mapping between keys ([]byte) and a value (uint64) + - enumerating keys in lexicographic order + +Some additional goals of this implementation: + - bounded memory use while building the FST + - streaming out FST data while building + - mmap FST runtime to support very large FTSs (optional) + +## Usage + +### Building an FST + +To build an FST, create a new builder using the `New()` method. This method takes an `io.Writer` as an argument. As the FST is being built, data will be streamed to the writer as soon as possible. With this builder you **MUST** insert keys in lexicographic order. Inserting keys out of order will result in an error. After inserting the last key into the builder, you **MUST** call `Close()` on the builder. This will flush all remaining data to the underlying writer. + +In memory: +```go + var buf bytes.Buffer + builder, err := vellum.New(&buf, nil) + if err != nil { + log.Fatal(err) + } +``` + +To disk: +```go + f, err := os.Create("/tmp/vellum.fst") + if err != nil { + log.Fatal(err) + } + builder, err := vellum.New(f, nil) + if err != nil { + log.Fatal(err) + } +``` + +**MUST** insert keys in lexicographic order: +```go +err = builder.Insert([]byte("cat"), 1) +if err != nil { + log.Fatal(err) +} + +err = builder.Insert([]byte("dog"), 2) +if err != nil { + log.Fatal(err) +} + +err = builder.Insert([]byte("fish"), 3) +if err != nil { + log.Fatal(err) +} + +err = builder.Close() +if err != nil { + log.Fatal(err) +} +``` + +### Using an FST + +After closing the builder, the data can be used to instantiate an FST. If the data was written to disk, you can use the `Open()` method to mmap the file. If the data is already in memory, or you wish to load/mmap the data yourself, you can instantiate the FST with the `Load()` method. + +Load in memory: +```go + fst, err := vellum.Load(buf.Bytes()) + if err != nil { + log.Fatal(err) + } +``` + +Open from disk: +```go + fst, err := vellum.Open("/tmp/vellum.fst") + if err != nil { + log.Fatal(err) + } +``` + +Get key/value: +```go + val, exists, err = fst.Get([]byte("dog")) + if err != nil { + log.Fatal(err) + } + if exists { + fmt.Printf("contains dog with val: %d\n", val) + } else { + fmt.Printf("does not contain dog") + } +``` + +Iterate key/values: +```go + itr, err := fst.Iterator(startKeyInclusive, endKeyExclusive) + for err == nil { + key, val := itr.Current() + fmt.Printf("contains key: %s val: %d", key, val) + err = itr.Next() + } + if err != nil { + log.Fatal(err) + } +``` + +### How does the FST get built? + +A full example of the implementation is beyond the scope of this README, but let's consider a small example where we want to insert 3 key/value pairs. + +First we insert "are" with the value 4. + +![step1](docs/demo1.png) + +Next, we insert "ate" with the value 2. + +![step2](docs/demo2.png) + +Notice how the values associated with the transitions were adjusted so that by summing them while traversing we still get the expected value. + +At this point, we see that state 5 looks like state 3, and state 4 looks like state 2. But, we cannot yet combine them because future inserts could change this. + +Now, we insert "see" with value 3. Once it has been added, we now know that states 5 and 4 can longer change. Since they are identical to 3 and 2, we replace them. + +![step3](docs/demo3.png) + +Again, we see that states 7 and 8 appear to be identical to 2 and 3. + +Having inserted our last key, we call `Close()` on the builder. + +![step4](docs/demo4.png) + +Now, states 7 and 8 can safely be replaced with 2 and 3. + +For additional information, see the references at the bottom of this document. + +### What does the serialized format look like? + +We've broken out a separate document on the [vellum disk format v1](docs/format.md). + +### What if I want to use this on a system that doesn't have mmap? + +The mmap library itself is guarded with system/architecture build tags, but we've also added an additional build tag in vellum. If you'd like to Open() a file based representation of an FST, but not use mmap, you can build the library with the `nommap` build tag. NOTE: if you do this, the entire FST will be read into memory. + +### Can I use this with Unicode strings? + +Yes, however this implementation is only aware of the byte representation you choose. In order to find matches, you must work with some canonical byte representation of the string. In the future, some encoding-aware traversals may be possible on top of the lower-level byte transitions. + +### How did this library come to be? + +In my work on the [Bleve](https://github.com/blevesearch/bleve) project I became aware of the power of the FST for many search-related tasks. The obvious starting point for such a thing in Go was the [mafsa](https://github.com/smartystreets/mafsa) project. While working with mafsa I encountered some issues. First, it did not stream data to disk while building. Second, it chose to use a rune as the fundamental unit of transition in the FST, but I felt using a byte would be more powerful in the end. My hope is that higher-level encoding-aware traversals will be possible when necessary. Finally, as I reported bugs and submitted PRs I learned that the mafsa project was mainly a research project and no longer being maintained. I wanted to build something that could be used in production. As the project advanced more and more techniques from the [BurntSushi/fst](https://github.com/BurntSushi/fst) were adapted to our implementation. + +### Are there tools to work with vellum files? + +Under the cmd/vellum subdirectory, there's a command-line tool which +features subcommands that can allow you to create, inspect and query +vellum files. + +### How can I generate a state transition diagram from a vellum file? + +The vellum command-line tool has a "dot" subcommand that can emit +graphviz dot output data from an input vellum file. The dot file can +in turn be converted into an image using graphviz tools. Example... + + $ vellum dot myFile.vellum > output.dot + $ dot -Tpng output.dot -o output.png + +## Related Work + +Much credit goes to two existing projects: + - [mafsa](https://github.com/smartystreets/mafsa) + - [BurntSushi/fst](https://github.com/BurntSushi/fst) + +Most of the original implementation here started with my digging into the internals of mafsa. As the implementation progressed, I continued to borrow ideas/approaches from the BurntSushi/fst library as well. + +For a great introduction to this topic, please read the blog post [Index 1,600,000,000 Keys with Automata and Rust](http://blog.burntsushi.net/transducers/) diff --git a/backend/vendor/github.com/blevesearch/vellum/automaton.go b/backend/vendor/github.com/blevesearch/vellum/automaton.go new file mode 100644 index 0000000000..70398f2d47 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/automaton.go @@ -0,0 +1,85 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vellum + +// Automaton represents the general contract of a byte-based finite automaton +type Automaton interface { + + // Start returns the start state + Start() int + + // IsMatch returns true if and only if the state is a match + IsMatch(int) bool + + // CanMatch returns true if and only if it is possible to reach a match + // in zero or more steps + CanMatch(int) bool + + // WillAlwaysMatch returns true if and only if the current state matches + // and will always match no matter what steps are taken + WillAlwaysMatch(int) bool + + // Accept returns the next state given the input to the specified state + Accept(int, byte) int +} + +// AutomatonContains implements an generic Contains() method which works +// on any implementation of Automaton +func AutomatonContains(a Automaton, k []byte) bool { + i := 0 + curr := a.Start() + for a.CanMatch(curr) && i < len(k) { + curr = a.Accept(curr, k[i]) + if curr == noneAddr { + break + } + i++ + } + if i != len(k) { + return false + } + return a.IsMatch(curr) +} + +// AlwaysMatch is an Automaton implementation which always matches +type AlwaysMatch struct{} + +// Start returns the AlwaysMatch start state +func (m *AlwaysMatch) Start() int { + return 0 +} + +// IsMatch always returns true +func (m *AlwaysMatch) IsMatch(int) bool { + return true +} + +// CanMatch always returns true +func (m *AlwaysMatch) CanMatch(int) bool { + return true +} + +// WillAlwaysMatch always returns true +func (m *AlwaysMatch) WillAlwaysMatch(int) bool { + return true +} + +// Accept returns the next AlwaysMatch state +func (m *AlwaysMatch) Accept(int, byte) int { + return 0 +} + +// creating an alwaysMatchAutomaton to avoid unnecessary repeated allocations. +var alwaysMatchAutomaton = &AlwaysMatch{} diff --git a/backend/vendor/github.com/blevesearch/vellum/builder.go b/backend/vendor/github.com/blevesearch/vellum/builder.go new file mode 100644 index 0000000000..f793329575 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/builder.go @@ -0,0 +1,452 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vellum + +import ( + "bytes" + "io" +) + +var defaultBuilderOpts = &BuilderOpts{ + Encoder: 1, + RegistryTableSize: 10000, + RegistryMRUSize: 2, +} + +// A Builder is used to build a new FST. When possible data is +// streamed out to the underlying Writer as soon as possible. +type Builder struct { + unfinished *unfinishedNodes + registry *registry + last []byte + len int + + lastAddr int + + encoder encoder + opts *BuilderOpts + + builderNodePool *builderNodePool +} + +const noneAddr = 1 +const emptyAddr = 0 + +// NewBuilder returns a new Builder which will stream out the +// underlying representation to the provided Writer as the set is built. +func newBuilder(w io.Writer, opts *BuilderOpts) (*Builder, error) { + if opts == nil { + opts = defaultBuilderOpts + } + builderNodePool := &builderNodePool{} + rv := &Builder{ + unfinished: newUnfinishedNodes(builderNodePool), + registry: newRegistry(builderNodePool, opts.RegistryTableSize, opts.RegistryMRUSize), + builderNodePool: builderNodePool, + opts: opts, + lastAddr: noneAddr, + } + + var err error + rv.encoder, err = loadEncoder(opts.Encoder, w) + if err != nil { + return nil, err + } + err = rv.encoder.start() + if err != nil { + return nil, err + } + return rv, nil +} + +func (b *Builder) Reset(w io.Writer) error { + b.unfinished.Reset() + b.registry.Reset() + b.lastAddr = noneAddr + b.encoder.reset(w) + b.last = nil + b.len = 0 + + err := b.encoder.start() + if err != nil { + return err + } + return nil +} + +// Insert the provided value to the set being built. +// NOTE: values must be inserted in lexicographical order. +func (b *Builder) Insert(key []byte, val uint64) error { + // ensure items are added in lexicographic order + if bytes.Compare(key, b.last) < 0 { + return ErrOutOfOrder + } + if len(key) == 0 { + b.len = 1 + b.unfinished.setRootOutput(val) + return nil + } + + prefixLen, out := b.unfinished.findCommonPrefixAndSetOutput(key, val) + b.len++ + err := b.compileFrom(prefixLen) + if err != nil { + return err + } + b.copyLastKey(key) + b.unfinished.addSuffix(key[prefixLen:], out) + + return nil +} + +func (b *Builder) copyLastKey(key []byte) { + if b.last == nil { + b.last = make([]byte, 0, 64) + } else { + b.last = b.last[:0] + } + b.last = append(b.last, key...) +} + +// Close MUST be called after inserting all values. +func (b *Builder) Close() error { + err := b.compileFrom(0) + if err != nil { + return err + } + root := b.unfinished.popRoot() + rootAddr, err := b.compile(root) + if err != nil { + return err + } + return b.encoder.finish(b.len, rootAddr) +} + +func (b *Builder) compileFrom(iState int) error { + addr := noneAddr + for iState+1 < len(b.unfinished.stack) { + var node *builderNode + if addr == noneAddr { + node = b.unfinished.popEmpty() + } else { + node = b.unfinished.popFreeze(addr) + } + var err error + addr, err = b.compile(node) + if err != nil { + return nil + } + } + b.unfinished.topLastFreeze(addr) + return nil +} + +func (b *Builder) compile(node *builderNode) (int, error) { + if node.final && len(node.trans) == 0 && + node.finalOutput == 0 { + return 0, nil + } + found, addr, entry := b.registry.entry(node) + if found { + return addr, nil + } + addr, err := b.encoder.encodeState(node, b.lastAddr) + if err != nil { + return 0, err + } + + b.lastAddr = addr + entry.addr = addr + return addr, nil +} + +type unfinishedNodes struct { + stack []*builderNodeUnfinished + + // cache allocates a reasonable number of builderNodeUnfinished + // objects up front and tries to keep reusing them + // because the main data structure is a stack, we assume the + // same access pattern, and don't track items separately + // this means calls get() and pushXYZ() must be paired, + // as well as calls put() and popXYZ() + cache []builderNodeUnfinished + + builderNodePool *builderNodePool +} + +func (u *unfinishedNodes) Reset() { + u.stack = u.stack[:0] + for i := 0; i < len(u.cache); i++ { + u.cache[i] = builderNodeUnfinished{} + } + u.pushEmpty(false) +} + +func newUnfinishedNodes(p *builderNodePool) *unfinishedNodes { + rv := &unfinishedNodes{ + stack: make([]*builderNodeUnfinished, 0, 64), + cache: make([]builderNodeUnfinished, 64), + builderNodePool: p, + } + rv.pushEmpty(false) + return rv +} + +// get new builderNodeUnfinished, reusing cache if possible +func (u *unfinishedNodes) get() *builderNodeUnfinished { + if len(u.stack) < len(u.cache) { + return &u.cache[len(u.stack)] + } + // full now allocate a new one + return &builderNodeUnfinished{} +} + +// return builderNodeUnfinished, clearing it for reuse +func (u *unfinishedNodes) put() { + if len(u.stack) >= len(u.cache) { + return + // do nothing, not part of cache + } + u.cache[len(u.stack)] = builderNodeUnfinished{} +} + +func (u *unfinishedNodes) findCommonPrefixAndSetOutput(key []byte, + out uint64) (int, uint64) { + var i int + for i < len(key) { + if i >= len(u.stack) { + break + } + var addPrefix uint64 + if !u.stack[i].hasLastT { + break + } + if u.stack[i].lastIn == key[i] { + commonPre := outputPrefix(u.stack[i].lastOut, out) + addPrefix = outputSub(u.stack[i].lastOut, commonPre) + out = outputSub(out, commonPre) + u.stack[i].lastOut = commonPre + i++ + } else { + break + } + + if addPrefix != 0 { + u.stack[i].addOutputPrefix(addPrefix) + } + } + + return i, out +} + +func (u *unfinishedNodes) pushEmpty(final bool) { + next := u.get() + next.node = u.builderNodePool.Get() + next.node.final = final + u.stack = append(u.stack, next) +} + +func (u *unfinishedNodes) popRoot() *builderNode { + l := len(u.stack) + var unfinished *builderNodeUnfinished + u.stack, unfinished = u.stack[:l-1], u.stack[l-1] + rv := unfinished.node + u.put() + return rv +} + +func (u *unfinishedNodes) popFreeze(addr int) *builderNode { + l := len(u.stack) + var unfinished *builderNodeUnfinished + u.stack, unfinished = u.stack[:l-1], u.stack[l-1] + unfinished.lastCompiled(addr) + rv := unfinished.node + u.put() + return rv +} + +func (u *unfinishedNodes) popEmpty() *builderNode { + l := len(u.stack) + var unfinished *builderNodeUnfinished + u.stack, unfinished = u.stack[:l-1], u.stack[l-1] + rv := unfinished.node + u.put() + return rv +} + +func (u *unfinishedNodes) setRootOutput(out uint64) { + u.stack[0].node.final = true + u.stack[0].node.finalOutput = out +} + +func (u *unfinishedNodes) topLastFreeze(addr int) { + last := len(u.stack) - 1 + u.stack[last].lastCompiled(addr) +} + +func (u *unfinishedNodes) addSuffix(bs []byte, out uint64) { + if len(bs) == 0 { + return + } + last := len(u.stack) - 1 + u.stack[last].hasLastT = true + u.stack[last].lastIn = bs[0] + u.stack[last].lastOut = out + for _, b := range bs[1:] { + next := u.get() + next.node = u.builderNodePool.Get() + next.hasLastT = true + next.lastIn = b + next.lastOut = 0 + u.stack = append(u.stack, next) + } + u.pushEmpty(true) +} + +type builderNodeUnfinished struct { + node *builderNode + lastOut uint64 + lastIn byte + hasLastT bool +} + +func (b *builderNodeUnfinished) lastCompiled(addr int) { + if b.hasLastT { + transIn := b.lastIn + transOut := b.lastOut + b.hasLastT = false + b.lastOut = 0 + b.node.trans = append(b.node.trans, transition{ + in: transIn, + out: transOut, + addr: addr, + }) + } +} + +func (b *builderNodeUnfinished) addOutputPrefix(prefix uint64) { + if b.node.final { + b.node.finalOutput = outputCat(prefix, b.node.finalOutput) + } + for i := range b.node.trans { + b.node.trans[i].out = outputCat(prefix, b.node.trans[i].out) + } + if b.hasLastT { + b.lastOut = outputCat(prefix, b.lastOut) + } +} + +type builderNode struct { + finalOutput uint64 + trans []transition + final bool + + // intrusive linked list + next *builderNode +} + +// reset resets the receiver builderNode to a re-usable state. +func (n *builderNode) reset() { + n.final = false + n.finalOutput = 0 + for i := range n.trans { + n.trans[i] = emptyTransition + } + n.trans = n.trans[:0] + n.next = nil +} + +func (n *builderNode) equiv(o *builderNode) bool { + if n.final != o.final { + return false + } + if n.finalOutput != o.finalOutput { + return false + } + if len(n.trans) != len(o.trans) { + return false + } + for i, ntrans := range n.trans { + otrans := o.trans[i] + if ntrans.in != otrans.in { + return false + } + if ntrans.addr != otrans.addr { + return false + } + if ntrans.out != otrans.out { + return false + } + } + return true +} + +var emptyTransition = transition{} + +type transition struct { + out uint64 + addr int + in byte +} + +func outputPrefix(l, r uint64) uint64 { + if l < r { + return l + } + return r +} + +func outputSub(l, r uint64) uint64 { + return l - r +} + +func outputCat(l, r uint64) uint64 { + return l + r +} + +// builderNodePool pools builderNodes using a singly linked list. +// +// NB: builderNode lifecylce is described by the following interactions - +// +------------------------+ +----------------------+ +// | Unfinished Nodes | Transfer once | Registry | +// |(not frozen builderNode)|-----builderNode is ------->| (frozen builderNode) | +// +------------------------+ marked frozen +----------------------+ +// ^ | +// | | +// | Put() +// | Get() on +-------------------+ when +// +-new char--------| builderNode Pool |<-----------evicted +// +-------------------+ +type builderNodePool struct { + head *builderNode +} + +func (p *builderNodePool) Get() *builderNode { + if p.head == nil { + return &builderNode{} + } + head := p.head + p.head = p.head.next + return head +} + +func (p *builderNodePool) Put(v *builderNode) { + if v == nil { + return + } + v.reset() + v.next = p.head + p.head = v +} diff --git a/backend/vendor/github.com/blevesearch/vellum/common.go b/backend/vendor/github.com/blevesearch/vellum/common.go new file mode 100644 index 0000000000..cd3e6a0d0b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/common.go @@ -0,0 +1,547 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vellum + +const maxCommon = 1<<6 - 1 + +func encodeCommon(in byte) byte { + val := byte((int(commonInputs[in]) + 1) % 256) + if val > maxCommon { + return 0 + } + return val +} + +func decodeCommon(in byte) byte { + return commonInputsInv[in-1] +} + +var commonInputs = []byte{ + 84, // '\x00' + 85, // '\x01' + 86, // '\x02' + 87, // '\x03' + 88, // '\x04' + 89, // '\x05' + 90, // '\x06' + 91, // '\x07' + 92, // '\x08' + 93, // '\t' + 94, // '\n' + 95, // '\x0b' + 96, // '\x0c' + 97, // '\r' + 98, // '\x0e' + 99, // '\x0f' + 100, // '\x10' + 101, // '\x11' + 102, // '\x12' + 103, // '\x13' + 104, // '\x14' + 105, // '\x15' + 106, // '\x16' + 107, // '\x17' + 108, // '\x18' + 109, // '\x19' + 110, // '\x1a' + 111, // '\x1b' + 112, // '\x1c' + 113, // '\x1d' + 114, // '\x1e' + 115, // '\x1f' + 116, // ' ' + 80, // '!' + 117, // '"' + 118, // '#' + 79, // '$' + 39, // '%' + 30, // '&' + 81, // "'" + 75, // '(' + 74, // ')' + 82, // '*' + 57, // '+' + 66, // ',' + 16, // '-' + 12, // '.' + 2, // '/' + 19, // '0' + 20, // '1' + 21, // '2' + 27, // '3' + 32, // '4' + 29, // '5' + 35, // '6' + 36, // '7' + 37, // '8' + 34, // '9' + 24, // ':' + 73, // ';' + 119, // '<' + 23, // '=' + 120, // '>' + 40, // '?' + 83, // '@' + 44, // 'A' + 48, // 'B' + 42, // 'C' + 43, // 'D' + 49, // 'E' + 46, // 'F' + 62, // 'G' + 61, // 'H' + 47, // 'I' + 69, // 'J' + 68, // 'K' + 58, // 'L' + 56, // 'M' + 55, // 'N' + 59, // 'O' + 51, // 'P' + 72, // 'Q' + 54, // 'R' + 45, // 'S' + 52, // 'T' + 64, // 'U' + 65, // 'V' + 63, // 'W' + 71, // 'X' + 67, // 'Y' + 70, // 'Z' + 77, // '[' + 121, // '\\' + 78, // ']' + 122, // '^' + 31, // '_' + 123, // '`' + 4, // 'a' + 25, // 'b' + 9, // 'c' + 17, // 'd' + 1, // 'e' + 26, // 'f' + 22, // 'g' + 13, // 'h' + 7, // 'i' + 50, // 'j' + 38, // 'k' + 14, // 'l' + 15, // 'm' + 10, // 'n' + 3, // 'o' + 8, // 'p' + 60, // 'q' + 6, // 'r' + 5, // 's' + 0, // 't' + 18, // 'u' + 33, // 'v' + 11, // 'w' + 41, // 'x' + 28, // 'y' + 53, // 'z' + 124, // '{' + 125, // '|' + 126, // '}' + 76, // '~' + 127, // '\x7f' + 128, // '\x80' + 129, // '\x81' + 130, // '\x82' + 131, // '\x83' + 132, // '\x84' + 133, // '\x85' + 134, // '\x86' + 135, // '\x87' + 136, // '\x88' + 137, // '\x89' + 138, // '\x8a' + 139, // '\x8b' + 140, // '\x8c' + 141, // '\x8d' + 142, // '\x8e' + 143, // '\x8f' + 144, // '\x90' + 145, // '\x91' + 146, // '\x92' + 147, // '\x93' + 148, // '\x94' + 149, // '\x95' + 150, // '\x96' + 151, // '\x97' + 152, // '\x98' + 153, // '\x99' + 154, // '\x9a' + 155, // '\x9b' + 156, // '\x9c' + 157, // '\x9d' + 158, // '\x9e' + 159, // '\x9f' + 160, // '\xa0' + 161, // '¡' + 162, // '¢' + 163, // '£' + 164, // '¤' + 165, // '¥' + 166, // '¦' + 167, // '§' + 168, // '¨' + 169, // '©' + 170, // 'ª' + 171, // '«' + 172, // '¬' + 173, // '\xad' + 174, // '®' + 175, // '¯' + 176, // '°' + 177, // '±' + 178, // '²' + 179, // '³' + 180, // '´' + 181, // 'µ' + 182, // '¶' + 183, // '·' + 184, // '¸' + 185, // '¹' + 186, // 'º' + 187, // '»' + 188, // '¼' + 189, // '½' + 190, // '¾' + 191, // '¿' + 192, // 'À' + 193, // 'Á' + 194, // 'Â' + 195, // 'Ã' + 196, // 'Ä' + 197, // 'Å' + 198, // 'Æ' + 199, // 'Ç' + 200, // 'È' + 201, // 'É' + 202, // 'Ê' + 203, // 'Ë' + 204, // 'Ì' + 205, // 'Í' + 206, // 'Î' + 207, // 'Ï' + 208, // 'Ð' + 209, // 'Ñ' + 210, // 'Ò' + 211, // 'Ó' + 212, // 'Ô' + 213, // 'Õ' + 214, // 'Ö' + 215, // '×' + 216, // 'Ø' + 217, // 'Ù' + 218, // 'Ú' + 219, // 'Û' + 220, // 'Ü' + 221, // 'Ý' + 222, // 'Þ' + 223, // 'ß' + 224, // 'à' + 225, // 'á' + 226, // 'â' + 227, // 'ã' + 228, // 'ä' + 229, // 'å' + 230, // 'æ' + 231, // 'ç' + 232, // 'è' + 233, // 'é' + 234, // 'ê' + 235, // 'ë' + 236, // 'ì' + 237, // 'í' + 238, // 'î' + 239, // 'ï' + 240, // 'ð' + 241, // 'ñ' + 242, // 'ò' + 243, // 'ó' + 244, // 'ô' + 245, // 'õ' + 246, // 'ö' + 247, // '÷' + 248, // 'ø' + 249, // 'ù' + 250, // 'ú' + 251, // 'û' + 252, // 'ü' + 253, // 'ý' + 254, // 'þ' + 255, // 'ÿ' +} + +var commonInputsInv = []byte{ + 't', + 'e', + '/', + 'o', + 'a', + 's', + 'r', + 'i', + 'p', + 'c', + 'n', + 'w', + '.', + 'h', + 'l', + 'm', + '-', + 'd', + 'u', + '0', + '1', + '2', + 'g', + '=', + ':', + 'b', + 'f', + '3', + 'y', + '5', + '&', + '_', + '4', + 'v', + '9', + '6', + '7', + '8', + 'k', + '%', + '?', + 'x', + 'C', + 'D', + 'A', + 'S', + 'F', + 'I', + 'B', + 'E', + 'j', + 'P', + 'T', + 'z', + 'R', + 'N', + 'M', + '+', + 'L', + 'O', + 'q', + 'H', + 'G', + 'W', + 'U', + 'V', + ',', + 'Y', + 'K', + 'J', + 'Z', + 'X', + 'Q', + ';', + ')', + '(', + '~', + '[', + ']', + '$', + '!', + '\'', + '*', + '@', + '\x00', + '\x01', + '\x02', + '\x03', + '\x04', + '\x05', + '\x06', + '\x07', + '\x08', + '\t', + '\n', + '\x0b', + '\x0c', + '\r', + '\x0e', + '\x0f', + '\x10', + '\x11', + '\x12', + '\x13', + '\x14', + '\x15', + '\x16', + '\x17', + '\x18', + '\x19', + '\x1a', + '\x1b', + '\x1c', + '\x1d', + '\x1e', + '\x1f', + ' ', + '"', + '#', + '<', + '>', + '\\', + '^', + '`', + '{', + '|', + '}', + '\x7f', + '\x80', + '\x81', + '\x82', + '\x83', + '\x84', + '\x85', + '\x86', + '\x87', + '\x88', + '\x89', + '\x8a', + '\x8b', + '\x8c', + '\x8d', + '\x8e', + '\x8f', + '\x90', + '\x91', + '\x92', + '\x93', + '\x94', + '\x95', + '\x96', + '\x97', + '\x98', + '\x99', + '\x9a', + '\x9b', + '\x9c', + '\x9d', + '\x9e', + '\x9f', + '\xa0', + '\xa1', + '\xa2', + '\xa3', + '\xa4', + '\xa5', + '\xa6', + '\xa7', + '\xa8', + '\xa9', + '\xaa', + '\xab', + '\xac', + '\xad', + '\xae', + '\xaf', + '\xb0', + '\xb1', + '\xb2', + '\xb3', + '\xb4', + '\xb5', + '\xb6', + '\xb7', + '\xb8', + '\xb9', + '\xba', + '\xbb', + '\xbc', + '\xbd', + '\xbe', + '\xbf', + '\xc0', + '\xc1', + '\xc2', + '\xc3', + '\xc4', + '\xc5', + '\xc6', + '\xc7', + '\xc8', + '\xc9', + '\xca', + '\xcb', + '\xcc', + '\xcd', + '\xce', + '\xcf', + '\xd0', + '\xd1', + '\xd2', + '\xd3', + '\xd4', + '\xd5', + '\xd6', + '\xd7', + '\xd8', + '\xd9', + '\xda', + '\xdb', + '\xdc', + '\xdd', + '\xde', + '\xdf', + '\xe0', + '\xe1', + '\xe2', + '\xe3', + '\xe4', + '\xe5', + '\xe6', + '\xe7', + '\xe8', + '\xe9', + '\xea', + '\xeb', + '\xec', + '\xed', + '\xee', + '\xef', + '\xf0', + '\xf1', + '\xf2', + '\xf3', + '\xf4', + '\xf5', + '\xf6', + '\xf7', + '\xf8', + '\xf9', + '\xfa', + '\xfb', + '\xfc', + '\xfd', + '\xfe', + '\xff', +} diff --git a/backend/vendor/github.com/blevesearch/vellum/decoder_v1.go b/backend/vendor/github.com/blevesearch/vellum/decoder_v1.go new file mode 100644 index 0000000000..d56e61db58 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/decoder_v1.go @@ -0,0 +1,314 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vellum + +import ( + "bytes" + "encoding/binary" + "fmt" + "strconv" +) + +func init() { + registerDecoder(versionV1, func(data []byte) decoder { + return newDecoderV1(data) + }) +} + +type decoderV1 struct { + data []byte +} + +func newDecoderV1(data []byte) *decoderV1 { + return &decoderV1{ + data: data, + } +} + +func (d *decoderV1) getRoot() int { + if len(d.data) < footerSizeV1 { + return noneAddr + } + footer := d.data[len(d.data)-footerSizeV1:] + root := binary.LittleEndian.Uint64(footer[8:]) + return int(root) +} + +func (d *decoderV1) getLen() int { + if len(d.data) < footerSizeV1 { + return 0 + } + footer := d.data[len(d.data)-footerSizeV1:] + dlen := binary.LittleEndian.Uint64(footer) + return int(dlen) +} + +func (d *decoderV1) stateAt(addr int, prealloc fstState) (fstState, error) { + state, ok := prealloc.(*fstStateV1) + if ok && state != nil { + *state = fstStateV1{} // clear the struct + } else { + state = &fstStateV1{} + } + err := state.at(d.data, addr) + if err != nil { + return nil, err + } + return state, nil +} + +type fstStateV1 struct { + data []byte + top int + bottom int + numTrans int + + // single trans only + singleTransChar byte + singleTransNext bool + singleTransAddr uint64 + singleTransOut uint64 + + // shared + transSize int + outSize int + + // multiple trans only + final bool + transTop int + transBottom int + destTop int + destBottom int + outTop int + outBottom int + outFinal int +} + +func (f *fstStateV1) isEncodedSingle() bool { + if f.data[f.top]>>7 > 0 { + return true + } + return false +} + +func (f *fstStateV1) at(data []byte, addr int) error { + f.data = data + if addr == emptyAddr { + return f.atZero() + } else if addr == noneAddr { + return f.atNone() + } + if addr > len(data) || addr < 16 { + return fmt.Errorf("invalid address %d/%d", addr, len(data)) + } + f.top = addr + f.bottom = addr + if f.isEncodedSingle() { + return f.atSingle(data, addr) + } + return f.atMulti(data, addr) +} + +func (f *fstStateV1) atZero() error { + f.top = 0 + f.bottom = 1 + f.numTrans = 0 + f.final = true + f.outFinal = 0 + return nil +} + +func (f *fstStateV1) atNone() error { + f.top = 0 + f.bottom = 1 + f.numTrans = 0 + f.final = false + f.outFinal = 0 + return nil +} + +func (f *fstStateV1) atSingle(data []byte, addr int) error { + // handle single transition case + f.numTrans = 1 + f.singleTransNext = data[f.top]&transitionNext > 0 + f.singleTransChar = data[f.top] & maxCommon + if f.singleTransChar == 0 { + f.bottom-- // extra byte for uncommon + f.singleTransChar = data[f.bottom] + } else { + f.singleTransChar = decodeCommon(f.singleTransChar) + } + if f.singleTransNext { + // now we know the bottom, can compute next addr + f.singleTransAddr = uint64(f.bottom - 1) + f.singleTransOut = 0 + } else { + f.bottom-- // extra byte with pack sizes + f.transSize, f.outSize = decodePackSize(data[f.bottom]) + f.bottom -= f.transSize // exactly one trans + f.singleTransAddr = readPackedUint(data[f.bottom : f.bottom+f.transSize]) + if f.outSize > 0 { + f.bottom -= f.outSize // exactly one out (could be length 0 though) + f.singleTransOut = readPackedUint(data[f.bottom : f.bottom+f.outSize]) + } else { + f.singleTransOut = 0 + } + // need to wait till we know bottom + if f.singleTransAddr != 0 { + f.singleTransAddr = uint64(f.bottom) - f.singleTransAddr + } + } + return nil +} + +func (f *fstStateV1) atMulti(data []byte, addr int) error { + // handle multiple transitions case + f.final = data[f.top]&stateFinal > 0 + f.numTrans = int(data[f.top] & maxNumTrans) + if f.numTrans == 0 { + f.bottom-- // extra byte for number of trans + f.numTrans = int(data[f.bottom]) + if f.numTrans == 1 { + // can't really be 1 here, this is special case that means 256 + f.numTrans = 256 + } + } + f.bottom-- // extra byte with pack sizes + f.transSize, f.outSize = decodePackSize(data[f.bottom]) + + f.transTop = f.bottom + f.bottom -= f.numTrans // one byte for each transition + f.transBottom = f.bottom + + f.destTop = f.bottom + f.bottom -= f.numTrans * f.transSize + f.destBottom = f.bottom + + if f.outSize > 0 { + f.outTop = f.bottom + f.bottom -= f.numTrans * f.outSize + f.outBottom = f.bottom + if f.final { + f.bottom -= f.outSize + f.outFinal = f.bottom + } + } + return nil +} + +func (f *fstStateV1) Address() int { + return f.top +} + +func (f *fstStateV1) Final() bool { + return f.final +} + +func (f *fstStateV1) FinalOutput() uint64 { + if f.final && f.outSize > 0 { + return readPackedUint(f.data[f.outFinal : f.outFinal+f.outSize]) + } + return 0 +} + +func (f *fstStateV1) NumTransitions() int { + return f.numTrans +} + +func (f *fstStateV1) TransitionAt(i int) byte { + if f.isEncodedSingle() { + return f.singleTransChar + } + transitionKeys := f.data[f.transBottom:f.transTop] + return transitionKeys[f.numTrans-i-1] +} + +func (f *fstStateV1) TransitionFor(b byte) (int, int, uint64) { + if f.isEncodedSingle() { + if f.singleTransChar == b { + return 0, int(f.singleTransAddr), f.singleTransOut + } + return -1, noneAddr, 0 + } + transitionKeys := f.data[f.transBottom:f.transTop] + pos := bytes.IndexByte(transitionKeys, b) + if pos < 0 { + return -1, noneAddr, 0 + } + transDests := f.data[f.destBottom:f.destTop] + dest := int(readPackedUint(transDests[pos*f.transSize : pos*f.transSize+f.transSize])) + if dest > 0 { + // convert delta + dest = f.bottom - dest + } + transVals := f.data[f.outBottom:f.outTop] + var out uint64 + if f.outSize > 0 { + out = readPackedUint(transVals[pos*f.outSize : pos*f.outSize+f.outSize]) + } + return f.numTrans - pos - 1, dest, out +} + +func (f *fstStateV1) String() string { + rv := "" + rv += fmt.Sprintf("State: %d (%#x)", f.top, f.top) + if f.final { + rv += " final" + fout := f.FinalOutput() + if fout != 0 { + rv += fmt.Sprintf(" (%d)", fout) + } + } + rv += "\n" + rv += fmt.Sprintf("Data: % x\n", f.data[f.bottom:f.top+1]) + + for i := 0; i < f.numTrans; i++ { + transChar := f.TransitionAt(i) + _, transDest, transOut := f.TransitionFor(transChar) + rv += fmt.Sprintf(" - %d (%#x) '%s' ---> %d (%#x) with output: %d", transChar, transChar, string(transChar), transDest, transDest, transOut) + rv += "\n" + } + if f.numTrans == 0 { + rv += "\n" + } + return rv +} + +func (f *fstStateV1) DotString(num int) string { + rv := "" + label := fmt.Sprintf("%d", num) + final := "" + if f.final { + final = ",peripheries=2" + } + rv += fmt.Sprintf(" %d [label=\"%s\"%s];\n", f.top, label, final) + + for i := 0; i < f.numTrans; i++ { + transChar := f.TransitionAt(i) + _, transDest, transOut := f.TransitionFor(transChar) + out := "" + if transOut != 0 { + out = fmt.Sprintf("/%d", transOut) + } + rv += fmt.Sprintf(" %d -> %d [label=\"%s%s\"];\n", f.top, transDest, escapeInput(transChar), out) + } + + return rv +} + +func escapeInput(b byte) string { + x := strconv.AppendQuoteRune(nil, rune(b)) + return string(x[1:(len(x) - 1)]) +} diff --git a/backend/vendor/github.com/blevesearch/vellum/encoder_v1.go b/backend/vendor/github.com/blevesearch/vellum/encoder_v1.go new file mode 100644 index 0000000000..0651fc8614 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/encoder_v1.go @@ -0,0 +1,227 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vellum + +import ( + "encoding/binary" + "fmt" + "io" +) + +const versionV1 = 1 +const oneTransition = 1 << 7 +const transitionNext = 1 << 6 +const stateFinal = 1 << 6 +const footerSizeV1 = 16 + +func init() { + registerEncoder(versionV1, func(w io.Writer) encoder { + return newEncoderV1(w) + }) +} + +type encoderV1 struct { + bw *writer +} + +func newEncoderV1(w io.Writer) *encoderV1 { + return &encoderV1{ + bw: newWriter(w), + } +} + +func (e *encoderV1) reset(w io.Writer) { + e.bw.Reset(w) +} + +func (e *encoderV1) start() error { + header := make([]byte, headerSize) + binary.LittleEndian.PutUint64(header, versionV1) + binary.LittleEndian.PutUint64(header[8:], uint64(0)) // type + n, err := e.bw.Write(header) + if err != nil { + return err + } + if n != headerSize { + return fmt.Errorf("short write of header %d/%d", n, headerSize) + } + return nil +} + +func (e *encoderV1) encodeState(s *builderNode, lastAddr int) (int, error) { + if len(s.trans) == 0 && s.final && s.finalOutput == 0 { + return 0, nil + } else if len(s.trans) != 1 || s.final { + return e.encodeStateMany(s) + } else if !s.final && s.trans[0].out == 0 && s.trans[0].addr == lastAddr { + return e.encodeStateOneFinish(s, transitionNext) + } + return e.encodeStateOne(s) +} + +func (e *encoderV1) encodeStateOne(s *builderNode) (int, error) { + start := uint64(e.bw.counter) + outPackSize := 0 + if s.trans[0].out != 0 { + outPackSize = packedSize(s.trans[0].out) + err := e.bw.WritePackedUintIn(s.trans[0].out, outPackSize) + if err != nil { + return 0, err + } + } + delta := deltaAddr(start, uint64(s.trans[0].addr)) + transPackSize := packedSize(delta) + err := e.bw.WritePackedUintIn(delta, transPackSize) + if err != nil { + return 0, err + } + + packSize := encodePackSize(transPackSize, outPackSize) + err = e.bw.WriteByte(packSize) + if err != nil { + return 0, err + } + + return e.encodeStateOneFinish(s, 0) +} + +func (e *encoderV1) encodeStateOneFinish(s *builderNode, next byte) (int, error) { + enc := encodeCommon(s.trans[0].in) + + // not a common input + if enc == 0 { + err := e.bw.WriteByte(s.trans[0].in) + if err != nil { + return 0, err + } + } + err := e.bw.WriteByte(oneTransition | next | enc) + if err != nil { + return 0, err + } + + return e.bw.counter - 1, nil +} + +func (e *encoderV1) encodeStateMany(s *builderNode) (int, error) { + start := uint64(e.bw.counter) + transPackSize := 0 + outPackSize := packedSize(s.finalOutput) + anyOutputs := s.finalOutput != 0 + for i := range s.trans { + delta := deltaAddr(start, uint64(s.trans[i].addr)) + tsize := packedSize(delta) + if tsize > transPackSize { + transPackSize = tsize + } + osize := packedSize(s.trans[i].out) + if osize > outPackSize { + outPackSize = osize + } + anyOutputs = anyOutputs || s.trans[i].out != 0 + } + if !anyOutputs { + outPackSize = 0 + } + + if anyOutputs { + // output final value + if s.final { + err := e.bw.WritePackedUintIn(s.finalOutput, outPackSize) + if err != nil { + return 0, err + } + } + // output transition values (in reverse) + for j := len(s.trans) - 1; j >= 0; j-- { + err := e.bw.WritePackedUintIn(s.trans[j].out, outPackSize) + if err != nil { + return 0, err + } + } + } + + // output transition dests (in reverse) + for j := len(s.trans) - 1; j >= 0; j-- { + delta := deltaAddr(start, uint64(s.trans[j].addr)) + err := e.bw.WritePackedUintIn(delta, transPackSize) + if err != nil { + return 0, err + } + } + + // output transition keys (in reverse) + for j := len(s.trans) - 1; j >= 0; j-- { + err := e.bw.WriteByte(s.trans[j].in) + if err != nil { + return 0, err + } + } + + packSize := encodePackSize(transPackSize, outPackSize) + err := e.bw.WriteByte(packSize) + if err != nil { + return 0, err + } + + numTrans := encodeNumTrans(len(s.trans)) + + // if number of transitions wont fit in edge header byte + // write out separately + if numTrans == 0 { + if len(s.trans) == 256 { + // this wouldn't fit in single byte, but reuse value 1 + // which would have always fit in the edge header instead + err = e.bw.WriteByte(1) + if err != nil { + return 0, err + } + } else { + err = e.bw.WriteByte(byte(len(s.trans))) + if err != nil { + return 0, err + } + } + } + + // finally write edge header + if s.final { + numTrans |= stateFinal + } + err = e.bw.WriteByte(numTrans) + if err != nil { + return 0, err + } + + return e.bw.counter - 1, nil +} + +func (e *encoderV1) finish(count, rootAddr int) error { + footer := make([]byte, footerSizeV1) + binary.LittleEndian.PutUint64(footer, uint64(count)) // root addr + binary.LittleEndian.PutUint64(footer[8:], uint64(rootAddr)) // root addr + n, err := e.bw.Write(footer) + if err != nil { + return err + } + if n != footerSizeV1 { + return fmt.Errorf("short write of footer %d/%d", n, footerSizeV1) + } + err = e.bw.Flush() + if err != nil { + return err + } + return nil +} diff --git a/backend/vendor/github.com/blevesearch/vellum/encoding.go b/backend/vendor/github.com/blevesearch/vellum/encoding.go new file mode 100644 index 0000000000..988d486499 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/encoding.go @@ -0,0 +1,87 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vellum + +import ( + "encoding/binary" + "fmt" + "io" +) + +const headerSize = 16 + +type encoderConstructor func(w io.Writer) encoder +type decoderConstructor func([]byte) decoder + +var encoders = map[int]encoderConstructor{} +var decoders = map[int]decoderConstructor{} + +type encoder interface { + start() error + encodeState(s *builderNode, addr int) (int, error) + finish(count, rootAddr int) error + reset(w io.Writer) +} + +func loadEncoder(ver int, w io.Writer) (encoder, error) { + if cons, ok := encoders[ver]; ok { + return cons(w), nil + } + return nil, fmt.Errorf("no encoder for version %d registered", ver) +} + +func registerEncoder(ver int, cons encoderConstructor) { + encoders[ver] = cons +} + +type decoder interface { + getRoot() int + getLen() int + stateAt(addr int, prealloc fstState) (fstState, error) +} + +func loadDecoder(ver int, data []byte) (decoder, error) { + if cons, ok := decoders[ver]; ok { + return cons(data), nil + } + return nil, fmt.Errorf("no decoder for version %d registered", ver) +} + +func registerDecoder(ver int, cons decoderConstructor) { + decoders[ver] = cons +} + +func decodeHeader(header []byte) (ver int, typ int, err error) { + if len(header) < headerSize { + err = fmt.Errorf("invalid header < 16 bytes") + return + } + ver = int(binary.LittleEndian.Uint64(header[0:8])) + typ = int(binary.LittleEndian.Uint64(header[8:16])) + return +} + +// fstState represents a state inside the FTS runtime +// It is the main contract between the FST impl and the decoder +// The FST impl should work only with this interface, while only the decoder +// impl knows the physical representation. +type fstState interface { + Address() int + Final() bool + FinalOutput() uint64 + NumTransitions() int + TransitionFor(b byte) (int, int, uint64) + TransitionAt(i int) byte +} diff --git a/backend/vendor/github.com/blevesearch/vellum/fst.go b/backend/vendor/github.com/blevesearch/vellum/fst.go new file mode 100644 index 0000000000..3140042b64 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/fst.go @@ -0,0 +1,300 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vellum + +import ( + "io" + + "github.com/bits-and-blooms/bitset" +) + +// FST is an in-memory representation of a finite state transducer, +// capable of returning the uint64 value associated with +// each []byte key stored, as well as enumerating all of the keys +// in order. +type FST struct { + f io.Closer + ver int + len int + typ int + data []byte + decoder decoder +} + +func new(data []byte, f io.Closer) (rv *FST, err error) { + rv = &FST{ + data: data, + f: f, + } + + rv.ver, rv.typ, err = decodeHeader(data) + if err != nil { + return nil, err + } + + rv.decoder, err = loadDecoder(rv.ver, rv.data) + if err != nil { + return nil, err + } + + rv.len = rv.decoder.getLen() + + return rv, nil +} + +// Contains returns true if this FST contains the specified key. +func (f *FST) Contains(val []byte) (bool, error) { + _, exists, err := f.Get(val) + return exists, err +} + +// Get returns the value associated with the key. NOTE: a value of zero +// does not imply the key does not exist, you must consult the second +// return value as well. +func (f *FST) Get(input []byte) (uint64, bool, error) { + return f.get(input, nil) +} + +func (f *FST) get(input []byte, prealloc fstState) (uint64, bool, error) { + var total uint64 + curr := f.decoder.getRoot() + state, err := f.decoder.stateAt(curr, prealloc) + if err != nil { + return 0, false, err + } + for _, c := range input { + _, curr, output := state.TransitionFor(c) + if curr == noneAddr { + return 0, false, nil + } + + state, err = f.decoder.stateAt(curr, state) + if err != nil { + return 0, false, err + } + + total += output + } + + if state.Final() { + total += state.FinalOutput() + return total, true, nil + } + return 0, false, nil +} + +// Version returns the encoding version used by this FST instance. +func (f *FST) Version() int { + return f.ver +} + +// Len returns the number of entries in this FST instance. +func (f *FST) Len() int { + return f.len +} + +// Type returns the type of this FST instance. +func (f *FST) Type() int { + return f.typ +} + +// Close will unmap any mmap'd data (if managed by vellum) and it will close +// the backing file (if managed by vellum). You MUST call Close() for any +// FST instance that is created. +func (f *FST) Close() error { + if f.f != nil { + err := f.f.Close() + if err != nil { + return err + } + } + f.data = nil + f.decoder = nil + return nil +} + +// Start returns the start state of this Automaton +func (f *FST) Start() int { + return f.decoder.getRoot() +} + +// IsMatch returns if this state is a matching state in this Automaton +func (f *FST) IsMatch(addr int) bool { + match, _ := f.IsMatchWithVal(addr) + return match +} + +// CanMatch returns if this state can ever transition to a matching state +// in this Automaton +func (f *FST) CanMatch(addr int) bool { + if addr == noneAddr { + return false + } + return true +} + +// WillAlwaysMatch returns if from this state the Automaton will always +// be in a matching state +func (f *FST) WillAlwaysMatch(int) bool { + return false +} + +// Accept returns the next state for this Automaton on input of byte b +func (f *FST) Accept(addr int, b byte) int { + next, _ := f.AcceptWithVal(addr, b) + return next +} + +// IsMatchWithVal returns if this state is a matching state in this Automaton +// and also returns the final output value for this state +func (f *FST) IsMatchWithVal(addr int) (bool, uint64) { + s, err := f.decoder.stateAt(addr, nil) + if err != nil { + return false, 0 + } + return s.Final(), s.FinalOutput() +} + +// AcceptWithVal returns the next state for this Automaton on input of byte b +// and also returns the output value for the transition +func (f *FST) AcceptWithVal(addr int, b byte) (int, uint64) { + s, err := f.decoder.stateAt(addr, nil) + if err != nil { + return noneAddr, 0 + } + _, next, output := s.TransitionFor(b) + return next, output +} + +// Iterator returns a new Iterator capable of enumerating the key/value pairs +// between the provided startKeyInclusive and endKeyExclusive. +func (f *FST) Iterator(startKeyInclusive, endKeyExclusive []byte) (*FSTIterator, error) { + return newIterator(f, startKeyInclusive, endKeyExclusive, nil) +} + +// Search returns a new Iterator capable of enumerating the key/value pairs +// between the provided startKeyInclusive and endKeyExclusive that also +// satisfy the provided automaton. +func (f *FST) Search(aut Automaton, startKeyInclusive, endKeyExclusive []byte) (*FSTIterator, error) { + return newIterator(f, startKeyInclusive, endKeyExclusive, aut) +} + +// Debug is only intended for debug purposes, it simply asks the underlying +// decoder visit each state, and pass it to the provided callback. +func (f *FST) Debug(callback func(int, interface{}) error) error { + + addr := f.decoder.getRoot() + set := bitset.New(uint(addr)) + stack := addrStack{addr} + + stateNumber := 0 + stack, addr = stack[:len(stack)-1], stack[len(stack)-1] + for addr != noneAddr { + if set.Test(uint(addr)) { + stack, addr = stack.Pop() + continue + } + set.Set(uint(addr)) + state, err := f.decoder.stateAt(addr, nil) + if err != nil { + return err + } + err = callback(stateNumber, state) + if err != nil { + return err + } + for i := 0; i < state.NumTransitions(); i++ { + tchar := state.TransitionAt(i) + _, dest, _ := state.TransitionFor(tchar) + stack = append(stack, dest) + } + stateNumber++ + stack, addr = stack.Pop() + } + + return nil +} + +type addrStack []int + +func (a addrStack) Pop() (addrStack, int) { + l := len(a) + if l < 1 { + return a, noneAddr + } + return a[:l-1], a[l-1] +} + +// Reader() returns a Reader instance that a single thread may use to +// retrieve data from the FST +func (f *FST) Reader() (*Reader, error) { + return &Reader{f: f}, nil +} + +func (f *FST) GetMinKey() ([]byte, error) { + var rv []byte + + curr := f.decoder.getRoot() + state, err := f.decoder.stateAt(curr, nil) + if err != nil { + return nil, err + } + + for !state.Final() { + nextTrans := state.TransitionAt(0) + _, curr, _ = state.TransitionFor(nextTrans) + state, err = f.decoder.stateAt(curr, state) + if err != nil { + return nil, err + } + + rv = append(rv, nextTrans) + } + + return rv, nil +} + +func (f *FST) GetMaxKey() ([]byte, error) { + var rv []byte + + curr := f.decoder.getRoot() + state, err := f.decoder.stateAt(curr, nil) + if err != nil { + return nil, err + } + + for state.NumTransitions() > 0 { + nextTrans := state.TransitionAt(state.NumTransitions() - 1) + _, curr, _ = state.TransitionFor(nextTrans) + state, err = f.decoder.stateAt(curr, state) + if err != nil { + return nil, err + } + + rv = append(rv, nextTrans) + } + + return rv, nil +} + +// A Reader is meant for a single threaded use +type Reader struct { + f *FST + prealloc fstStateV1 +} + +func (r *Reader) Get(input []byte) (uint64, bool, error) { + return r.f.get(input, &r.prealloc) +} diff --git a/backend/vendor/github.com/blevesearch/vellum/fst_iterator.go b/backend/vendor/github.com/blevesearch/vellum/fst_iterator.go new file mode 100644 index 0000000000..2c6b0d68ef --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/fst_iterator.go @@ -0,0 +1,303 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vellum + +import ( + "bytes" +) + +// Iterator represents a means of visiting key/value pairs in order. +type Iterator interface { + + // Current() returns the key/value pair currently pointed to. + // The []byte of the key is ONLY guaranteed to be valid until + // another call to Next/Seek/Close. If you need it beyond that + // point you MUST make a copy. + Current() ([]byte, uint64) + + // Next() advances the iterator to the next key/value pair. + // If no more key/value pairs exist, ErrIteratorDone is returned. + Next() error + + // Seek() advances the iterator the specified key, or the next key + // if it does not exist. + // If no keys exist after that point, ErrIteratorDone is returned. + Seek(key []byte) error + + // Reset resets the Iterator' internal state to allow for iterator + // reuse (e.g. pooling). + Reset(f *FST, startKeyInclusive, endKeyExclusive []byte, aut Automaton) error + + // Close() frees any resources held by this iterator. + Close() error +} + +// FSTIterator is a structure for iterating key/value pairs in this FST in +// lexicographic order. Iterators should be constructed with the FSTIterator +// method on the parent FST structure. +type FSTIterator struct { + f *FST + aut Automaton + + startKeyInclusive []byte + endKeyExclusive []byte + + statesStack []fstState + keysStack []byte + keysPosStack []int + valsStack []uint64 + autStatesStack []int + + nextStart []byte +} + +func newIterator(f *FST, startKeyInclusive, endKeyExclusive []byte, + aut Automaton) (*FSTIterator, error) { + + rv := &FSTIterator{} + err := rv.Reset(f, startKeyInclusive, endKeyExclusive, aut) + if err != nil { + return nil, err + } + return rv, nil +} + +// Reset resets the Iterator' internal state to allow for iterator +// reuse (e.g. pooling). +func (i *FSTIterator) Reset(f *FST, + startKeyInclusive, endKeyExclusive []byte, aut Automaton) error { + if aut == nil { + aut = alwaysMatchAutomaton + } + + i.f = f + i.startKeyInclusive = startKeyInclusive + i.endKeyExclusive = endKeyExclusive + i.aut = aut + + return i.pointTo(startKeyInclusive) +} + +// pointTo attempts to point us to the specified location +func (i *FSTIterator) pointTo(key []byte) error { + // tried to seek before start + if bytes.Compare(key, i.startKeyInclusive) < 0 { + key = i.startKeyInclusive + } + + // tried to see past end + if i.endKeyExclusive != nil && + bytes.Compare(key, i.endKeyExclusive) > 0 { + key = i.endKeyExclusive + } + + // reset any state, pointTo always starts over + i.statesStack = i.statesStack[:0] + i.keysStack = i.keysStack[:0] + i.keysPosStack = i.keysPosStack[:0] + i.valsStack = i.valsStack[:0] + i.autStatesStack = i.autStatesStack[:0] + + root, err := i.f.decoder.stateAt(i.f.decoder.getRoot(), nil) + if err != nil { + return err + } + + autStart := i.aut.Start() + + maxQ := -1 + // root is always part of the path + i.statesStack = append(i.statesStack, root) + i.autStatesStack = append(i.autStatesStack, autStart) + for j := 0; j < len(key); j++ { + keyJ := key[j] + curr := i.statesStack[len(i.statesStack)-1] + autCurr := i.autStatesStack[len(i.autStatesStack)-1] + + pos, nextAddr, nextVal := curr.TransitionFor(keyJ) + if nextAddr == noneAddr { + // needed transition doesn't exist + // find last trans before the one we needed + for q := curr.NumTransitions() - 1; q >= 0; q-- { + if curr.TransitionAt(q) < keyJ { + maxQ = q + break + } + } + break + } + autNext := i.aut.Accept(autCurr, keyJ) + + next, err := i.f.decoder.stateAt(nextAddr, nil) + if err != nil { + return err + } + + i.statesStack = append(i.statesStack, next) + i.keysStack = append(i.keysStack, keyJ) + i.keysPosStack = append(i.keysPosStack, pos) + i.valsStack = append(i.valsStack, nextVal) + i.autStatesStack = append(i.autStatesStack, autNext) + continue + } + + if !i.statesStack[len(i.statesStack)-1].Final() || + !i.aut.IsMatch(i.autStatesStack[len(i.autStatesStack)-1]) || + bytes.Compare(i.keysStack, key) < 0 { + return i.next(maxQ) + } + + return nil +} + +// Current returns the key and value currently pointed to by the iterator. +// If the iterator is not pointing at a valid value (because Iterator/Next/Seek) +// returned an error previously, it may return nil,0. +func (i *FSTIterator) Current() ([]byte, uint64) { + curr := i.statesStack[len(i.statesStack)-1] + if curr.Final() { + var total uint64 + for _, v := range i.valsStack { + total += v + } + total += curr.FinalOutput() + return i.keysStack, total + } + return nil, 0 +} + +// Next advances this iterator to the next key/value pair. If there is none +// or the advancement goes beyond the configured endKeyExclusive, then +// ErrIteratorDone is returned. +func (i *FSTIterator) Next() error { + return i.next(-1) +} + +func (i *FSTIterator) next(lastOffset int) error { + // remember where we started with keysStack in this next() call + i.nextStart = append(i.nextStart[:0], i.keysStack...) + + nextOffset := lastOffset + 1 + allowCompare := false + +OUTER: + for true { + curr := i.statesStack[len(i.statesStack)-1] + autCurr := i.autStatesStack[len(i.autStatesStack)-1] + + if curr.Final() && i.aut.IsMatch(autCurr) && allowCompare { + // check to see if new keystack might have gone too far + if i.endKeyExclusive != nil && + bytes.Compare(i.keysStack, i.endKeyExclusive) >= 0 { + return ErrIteratorDone + } + + cmp := bytes.Compare(i.keysStack, i.nextStart) + if cmp > 0 { + // in final state greater than start key + return nil + } + } + + numTrans := curr.NumTransitions() + + INNER: + for nextOffset < numTrans { + t := curr.TransitionAt(nextOffset) + + autNext := i.aut.Accept(autCurr, t) + if !i.aut.CanMatch(autNext) { + // TODO: potential optimization to skip nextOffset + // forwards more directly to something that the + // automaton likes rather than a linear scan? + nextOffset += 1 + continue INNER + } + + pos, nextAddr, v := curr.TransitionFor(t) + + // the next slot in the statesStack might have an + // fstState instance that we can reuse + var nextPrealloc fstState + if len(i.statesStack) < cap(i.statesStack) { + nextPrealloc = i.statesStack[0:cap(i.statesStack)][len(i.statesStack)] + } + + // push onto stack + next, err := i.f.decoder.stateAt(nextAddr, nextPrealloc) + if err != nil { + return err + } + + i.statesStack = append(i.statesStack, next) + i.keysStack = append(i.keysStack, t) + i.keysPosStack = append(i.keysPosStack, pos) + i.valsStack = append(i.valsStack, v) + i.autStatesStack = append(i.autStatesStack, autNext) + + nextOffset = 0 + allowCompare = true + + continue OUTER + } + + // no more transitions, so need to backtrack and stack pop + if len(i.statesStack) <= 1 { + // stack len is 1 (root), can't go back further, we're done + break + } + + // if the top of the stack represents a linear chain of states + // (i.e., a suffix of nodes linked by single transitions), + // then optimize by popping the suffix in one shot without + // going back all the way to the OUTER loop + var popNum int + for j := len(i.statesStack) - 1; j > 0; j-- { + if j == 1 || i.statesStack[j].NumTransitions() != 1 { + popNum = len(i.statesStack) - 1 - j + break + } + } + if popNum < 1 { // always pop at least 1 entry from the stacks + popNum = 1 + } + + nextOffset = i.keysPosStack[len(i.keysPosStack)-popNum] + 1 + allowCompare = false + + i.statesStack = i.statesStack[:len(i.statesStack)-popNum] + i.keysStack = i.keysStack[:len(i.keysStack)-popNum] + i.keysPosStack = i.keysPosStack[:len(i.keysPosStack)-popNum] + i.valsStack = i.valsStack[:len(i.valsStack)-popNum] + i.autStatesStack = i.autStatesStack[:len(i.autStatesStack)-popNum] + } + + return ErrIteratorDone +} + +// Seek advances this iterator to the specified key/value pair. If this key +// is not in the FST, Current() will return the next largest key. If this +// seek operation would go past the last key, or outside the configured +// startKeyInclusive/endKeyExclusive then ErrIteratorDone is returned. +func (i *FSTIterator) Seek(key []byte) error { + return i.pointTo(key) +} + +// Close will free any resources held by this iterator. +func (i *FSTIterator) Close() error { + // at the moment we don't do anything, + // but wanted this for API completeness + return nil +} diff --git a/backend/vendor/github.com/blevesearch/vellum/levenshtein/LICENSE b/backend/vendor/github.com/blevesearch/vellum/levenshtein/LICENSE new file mode 100644 index 0000000000..6b0b1270ff --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/levenshtein/LICENSE @@ -0,0 +1,203 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/backend/vendor/github.com/blevesearch/vellum/levenshtein/README.md b/backend/vendor/github.com/blevesearch/vellum/levenshtein/README.md new file mode 100644 index 0000000000..582b69c77e --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/levenshtein/README.md @@ -0,0 +1,33 @@ +# levenshtein +levenshtein automaton + +This package makes it fast and simple to build a finite determinic automaton that computes the levenshtein distance from a given string. + +# Sample usage: + +``` +// build a re-usable builder +lb := NewLevenshteinAutomatonBuilder(2, false) + +origTerm := "couchbasefts" +dfa := lb.BuildDfa("couchbases", 2) +ed := dfa.eval([]byte(origTerm)) +if ed.distance() != 2 { + log.Errorf("expected distance 2, actual: %d", ed.distance()) +} + +``` + +This implementation is inspired by [blog post](https://fulmicoton.com/posts/levenshtein/) and is intended to be +a port of original rust implementation: https://github.com/tantivy-search/levenshtein-automata + + +Micro Benchmark Results against the current vellum/levenshtein is as below. + +``` +BenchmarkNewEditDistance1-8 30000 52684 ns/op 89985 B/op 295 allocs/op +BenchmarkOlderEditDistance1-8 10000 132931 ns/op 588892 B/op 363 allocs/op + +BenchmarkNewEditDistance2-8 10000 199127 ns/op 377532 B/op 1019 allocs/op +BenchmarkOlderEditDistance2-8 2000 988109 ns/op 4236609 B/op 1898 allocs/op +``` diff --git a/backend/vendor/github.com/blevesearch/vellum/levenshtein/alphabet.go b/backend/vendor/github.com/blevesearch/vellum/levenshtein/alphabet.go new file mode 100644 index 0000000000..ec285129ca --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/levenshtein/alphabet.go @@ -0,0 +1,125 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package levenshtein + +import ( + "fmt" + "sort" + "unicode/utf8" +) + +type FullCharacteristicVector []uint32 + +func (fcv FullCharacteristicVector) shiftAndMask(offset, mask uint32) uint32 { + bucketID := offset / 32 + align := offset - bucketID*32 + if align == 0 { + return fcv[bucketID] & mask + } + left := fcv[bucketID] >> align + right := fcv[bucketID+1] << (32 - align) + return (left | right) & mask +} + +type tuple struct { + char rune + fcv FullCharacteristicVector +} + +type sortRunes []rune + +func (s sortRunes) Less(i, j int) bool { + return s[i] < s[j] +} + +func (s sortRunes) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s sortRunes) Len() int { + return len(s) +} + +func sortRune(r []rune) []rune { + sort.Sort(sortRunes(r)) + return r +} + +type Alphabet struct { + charset []tuple + index uint32 +} + +func (a *Alphabet) resetNext() { + a.index = 0 +} + +func (a *Alphabet) next() (rune, FullCharacteristicVector, error) { + if int(a.index) >= len(a.charset) { + return 0, nil, fmt.Errorf("eof") + } + + rv := a.charset[a.index] + a.index++ + return rv.char, rv.fcv, nil +} + +func dedupe(in string) string { + lookUp := make(map[rune]struct{}, len(in)) + var rv string + for len(in) > 0 { + r, size := utf8.DecodeRuneInString(in) + in = in[size:] + if _, ok := lookUp[r]; !ok { + rv += string(r) + lookUp[r] = struct{}{} + } + } + return rv +} + +func queryChars(qChars string) Alphabet { + chars := dedupe(qChars) + inChars := sortRune([]rune(chars)) + charsets := make([]tuple, 0, len(inChars)) + + for _, c := range inChars { + tempChars := qChars + var bits []uint32 + for len(tempChars) > 0 { + var chunk string + if len(tempChars) > 32 { + chunk = tempChars[0:32] + tempChars = tempChars[32:] + } else { + chunk = tempChars + tempChars = tempChars[:0] + } + + chunkBits := uint32(0) + bit := uint32(1) + for _, chr := range chunk { + if chr == c { + chunkBits |= bit + } + bit <<= 1 + } + bits = append(bits, chunkBits) + } + bits = append(bits, 0) + charsets = append(charsets, tuple{char: c, fcv: FullCharacteristicVector(bits)}) + } + return Alphabet{charset: charsets} +} diff --git a/backend/vendor/github.com/blevesearch/vellum/levenshtein/dfa.go b/backend/vendor/github.com/blevesearch/vellum/levenshtein/dfa.go new file mode 100644 index 0000000000..d0e43cac24 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/levenshtein/dfa.go @@ -0,0 +1,250 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package levenshtein + +import ( + "fmt" + "math" +) + +const SinkState = uint32(0) + +type DFA struct { + transitions [][256]uint32 + distances []Distance + initState int + ed uint8 +} + +/// Returns the initial state +func (d *DFA) initialState() int { + return d.initState +} + +/// Returns the Levenshtein distance associated to the +/// current state. +func (d *DFA) distance(stateId int) Distance { + return d.distances[stateId] +} + +/// Returns the number of states in the `DFA`. +func (d *DFA) numStates() int { + return len(d.transitions) +} + +/// Returns the destination state reached after consuming a given byte. +func (d *DFA) transition(fromState int, b uint8) int { + return int(d.transitions[fromState][b]) +} + +func (d *DFA) eval(bytes []uint8) Distance { + state := d.initialState() + + for _, b := range bytes { + state = d.transition(state, b) + } + + return d.distance(state) +} + +func (d *DFA) Start() int { + return int(d.initialState()) +} + +func (d *DFA) IsMatch(state int) bool { + if _, ok := d.distance(state).(Exact); ok { + return true + } + return false +} + +func (d *DFA) CanMatch(state int) bool { + return state > 0 && state < d.numStates() +} + +func (d *DFA) Accept(state int, b byte) int { + return int(d.transition(state, b)) +} + +// WillAlwaysMatch returns if the specified state will always end in a +// matching state. +func (d *DFA) WillAlwaysMatch(state int) bool { + return false +} + +func fill(dest []uint32, val uint32) { + for i := range dest { + dest[i] = val + } +} + +func fillTransitions(dest *[256]uint32, val uint32) { + for i := range dest { + dest[i] = val + } +} + +type Utf8DFAStateBuilder struct { + dfaBuilder *Utf8DFABuilder + stateID uint32 + defaultSuccessor []uint32 +} + +func (sb *Utf8DFAStateBuilder) addTransitionID(fromStateID uint32, b uint8, + toStateID uint32) { + sb.dfaBuilder.transitions[fromStateID][b] = toStateID +} + +func (sb *Utf8DFAStateBuilder) addTransition(in rune, toStateID uint32) { + fromStateID := sb.stateID + chars := []byte(string(in)) + lastByte := chars[len(chars)-1] + + for i, ch := range chars[:len(chars)-1] { + remNumBytes := len(chars) - i - 1 + defaultSuccessor := sb.defaultSuccessor[remNumBytes] + intermediateStateID := sb.dfaBuilder.transitions[fromStateID][ch] + + if intermediateStateID == defaultSuccessor { + intermediateStateID = sb.dfaBuilder.allocate() + fillTransitions(&sb.dfaBuilder.transitions[intermediateStateID], + sb.defaultSuccessor[remNumBytes-1]) + } + + sb.addTransitionID(fromStateID, ch, intermediateStateID) + fromStateID = intermediateStateID + } + + toStateIDDecoded := sb.dfaBuilder.getOrAllocate(original(toStateID)) + sb.addTransitionID(fromStateID, lastByte, toStateIDDecoded) +} + +type Utf8StateId uint32 + +func original(stateId uint32) Utf8StateId { + return predecessor(stateId, 0) +} + +func predecessor(stateId uint32, numSteps uint8) Utf8StateId { + return Utf8StateId(stateId*4 + uint32(numSteps)) +} + +// Utf8DFABuilder makes it possible to define a DFA +// that takes unicode character, and build a `DFA` +// that operates on utf-8 encoded +type Utf8DFABuilder struct { + index []uint32 + distances []Distance + transitions [][256]uint32 + initialState uint32 + numStates uint32 + maxNumStates uint32 +} + +func withMaxStates(maxStates uint32) *Utf8DFABuilder { + rv := &Utf8DFABuilder{ + index: make([]uint32, maxStates*2+100), + distances: make([]Distance, 0, maxStates), + transitions: make([][256]uint32, 0, maxStates), + maxNumStates: maxStates, + } + + for i := range rv.index { + rv.index[i] = math.MaxUint32 + } + + return rv +} + +func (dfab *Utf8DFABuilder) allocate() uint32 { + newState := dfab.numStates + dfab.numStates++ + + dfab.distances = append(dfab.distances, Atleast{d: 255}) + dfab.transitions = append(dfab.transitions, [256]uint32{}) + + return newState +} + +func (dfab *Utf8DFABuilder) getOrAllocate(state Utf8StateId) uint32 { + if int(state) >= cap(dfab.index) { + cloneIndex := make([]uint32, int(state)*2) + copy(cloneIndex, dfab.index) + dfab.index = cloneIndex + } + if dfab.index[state] != math.MaxUint32 { + return dfab.index[state] + } + + nstate := dfab.allocate() + dfab.index[state] = nstate + + return nstate +} + +func (dfab *Utf8DFABuilder) setInitialState(iState uint32) { + decodedID := dfab.getOrAllocate(original(iState)) + dfab.initialState = decodedID +} + +func (dfab *Utf8DFABuilder) build(ed uint8) *DFA { + return &DFA{ + transitions: dfab.transitions, + distances: dfab.distances, + initState: int(dfab.initialState), + ed: ed, + } +} + +func (dfab *Utf8DFABuilder) addState(state, default_suc_orig uint32, + distance Distance) (*Utf8DFAStateBuilder, error) { + if state > dfab.maxNumStates { + return nil, fmt.Errorf("State id is larger than maxNumStates") + } + + stateID := dfab.getOrAllocate(original(state)) + dfab.distances[stateID] = distance + + defaultSuccID := dfab.getOrAllocate(original(default_suc_orig)) + // creates a chain of states of predecessors of `default_suc_orig`. + // Accepting k-bytes (whatever the bytes are) from `predecessor_states[k-1]` + // leads to the `default_suc_orig` state. + predecessorStates := []uint32{defaultSuccID, + defaultSuccID, + defaultSuccID, + defaultSuccID} + + for numBytes := uint8(1); numBytes < 4; numBytes++ { + predecessorState := predecessor(default_suc_orig, numBytes) + predecessorStateID := dfab.getOrAllocate(predecessorState) + predecessorStates[numBytes] = predecessorStateID + succ := predecessorStates[numBytes-1] + fillTransitions(&dfab.transitions[predecessorStateID], succ) + } + + // 1-byte encoded chars. + fill(dfab.transitions[stateID][0:192], predecessorStates[0]) + // 2-bytes encoded chars. + fill(dfab.transitions[stateID][192:224], predecessorStates[1]) + // 3-bytes encoded chars. + fill(dfab.transitions[stateID][224:240], predecessorStates[2]) + // 4-bytes encoded chars. + fill(dfab.transitions[stateID][240:256], predecessorStates[3]) + + return &Utf8DFAStateBuilder{ + dfaBuilder: dfab, + stateID: stateID, + defaultSuccessor: predecessorStates}, nil +} diff --git a/backend/vendor/github.com/blevesearch/vellum/levenshtein/levenshtein.go b/backend/vendor/github.com/blevesearch/vellum/levenshtein/levenshtein.go new file mode 100644 index 0000000000..aa652df844 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/levenshtein/levenshtein.go @@ -0,0 +1,64 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package levenshtein + +import "fmt" + +// StateLimit is the maximum number of states allowed +const StateLimit = 10000 + +// ErrTooManyStates is returned if you attempt to build a Levenshtein +// automaton which requires too many states. +var ErrTooManyStates = fmt.Errorf("dfa contains more than %d states", + StateLimit) + +// LevenshteinAutomatonBuilder wraps a precomputed +// datastructure that allows to produce small (but not minimal) DFA. +type LevenshteinAutomatonBuilder struct { + pDfa *ParametricDFA +} + +// NewLevenshteinAutomatonBuilder creates a +// reusable, threadsafe Levenshtein automaton builder. +// `maxDistance` - maximum distance considered by the automaton. +// `transposition` - assign a distance of 1 for transposition +// +// Building this automaton builder is computationally intensive. +// While it takes only a few milliseconds for `d=2`, it grows +// exponentially with `d`. It is only reasonable to `d <= 5`. +func NewLevenshteinAutomatonBuilder(maxDistance uint8, + transposition bool) (*LevenshteinAutomatonBuilder, error) { + lnfa := newLevenshtein(maxDistance, transposition) + + pdfa, err := fromNfa(lnfa) + if err != nil { + return nil, err + } + + return &LevenshteinAutomatonBuilder{pDfa: pdfa}, nil +} + +// BuildDfa builds the levenshtein automaton for serving +// queries with a given edit distance. +func (lab *LevenshteinAutomatonBuilder) BuildDfa(query string, + fuzziness uint8) (*DFA, error) { + return lab.pDfa.buildDfa(query, fuzziness, false) +} + +// MaxDistance returns the MaxEdit distance supported by the +// LevenshteinAutomatonBuilder builder. +func (lab *LevenshteinAutomatonBuilder) MaxDistance() uint8 { + return lab.pDfa.maxDistance +} diff --git a/backend/vendor/github.com/blevesearch/vellum/levenshtein/levenshtein_nfa.go b/backend/vendor/github.com/blevesearch/vellum/levenshtein/levenshtein_nfa.go new file mode 100644 index 0000000000..68db5d191c --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/levenshtein/levenshtein_nfa.go @@ -0,0 +1,292 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package levenshtein + +import ( + "math" + "sort" +) + +/// Levenshtein Distance computed by a Levenshtein Automaton. +/// +/// Levenshtein automata can only compute the exact Levenshtein distance +/// up to a given `max_distance`. +/// +/// Over this distance, the automaton will invariably +/// return `Distance::AtLeast(max_distance + 1)`. +type Distance interface { + distance() uint8 +} + +type Exact struct { + d uint8 +} + +func (e Exact) distance() uint8 { + return e.d +} + +type Atleast struct { + d uint8 +} + +func (a Atleast) distance() uint8 { + return a.d +} + +func characteristicVector(query []rune, c rune) uint64 { + chi := uint64(0) + for i := 0; i < len(query); i++ { + if query[i] == c { + chi |= 1 << uint64(i) + } + } + return chi +} + +type NFAState struct { + Offset uint32 + Distance uint8 + InTranspose bool +} + +type NFAStates []NFAState + +func (ns NFAStates) Len() int { + return len(ns) +} + +func (ns NFAStates) Less(i, j int) bool { + if ns[i].Offset != ns[j].Offset { + return ns[i].Offset < ns[j].Offset + } + + if ns[i].Distance != ns[j].Distance { + return ns[i].Distance < ns[j].Distance + } + + return !ns[i].InTranspose && ns[j].InTranspose +} + +func (ns NFAStates) Swap(i, j int) { + ns[i], ns[j] = ns[j], ns[i] +} + +func (ns *NFAState) imply(other NFAState) bool { + transposeImply := ns.InTranspose + if !other.InTranspose { + transposeImply = !other.InTranspose + } + + deltaOffset := ns.Offset - other.Offset + if ns.Offset < other.Offset { + deltaOffset = other.Offset - ns.Offset + } + + if transposeImply { + return uint32(other.Distance) >= (uint32(ns.Distance) + deltaOffset) + } + + return uint32(other.Distance) > (uint32(ns.Distance) + deltaOffset) +} + +type MultiState struct { + states []NFAState +} + +func (ms *MultiState) States() []NFAState { + return ms.states +} + +func (ms *MultiState) Clear() { + ms.states = ms.states[:0] +} + +func newMultiState() *MultiState { + return &MultiState{states: make([]NFAState, 0)} +} + +func (ms *MultiState) normalize() uint32 { + minOffset := uint32(math.MaxUint32) + + for _, s := range ms.states { + if s.Offset < minOffset { + minOffset = s.Offset + } + } + if minOffset == uint32(math.MaxUint32) { + minOffset = 0 + } + + for i := 0; i < len(ms.states); i++ { + ms.states[i].Offset -= minOffset + } + + sort.Sort(NFAStates(ms.states)) + + return minOffset +} + +func (ms *MultiState) addStates(nState NFAState) { + + for _, s := range ms.states { + if s.imply(nState) { + return + } + } + + i := 0 + for i < len(ms.states) { + if nState.imply(ms.states[i]) { + ms.states = append(ms.states[:i], ms.states[i+1:]...) + } else { + i++ + } + } + ms.states = append(ms.states, nState) + +} + +func extractBit(bitset uint64, pos uint8) bool { + shift := bitset >> pos + bit := shift & 1 + return bit == uint64(1) +} + +func dist(left, right uint32) uint32 { + if left > right { + return left - right + } + return right - left +} + +type LevenshteinNFA struct { + mDistance uint8 + damerau bool +} + +func newLevenshtein(maxD uint8, transposition bool) *LevenshteinNFA { + return &LevenshteinNFA{mDistance: maxD, + damerau: transposition, + } +} + +func (la *LevenshteinNFA) maxDistance() uint8 { + return la.mDistance +} + +func (la *LevenshteinNFA) msDiameter() uint8 { + return 2*la.mDistance + 1 +} + +func (la *LevenshteinNFA) initialStates() *MultiState { + ms := MultiState{} + nfaState := NFAState{} + ms.addStates(nfaState) + return &ms +} + +func (la *LevenshteinNFA) multistateDistance(ms *MultiState, + queryLen uint32) Distance { + minDistance := Atleast{d: la.mDistance + 1} + for _, s := range ms.states { + t := s.Distance + uint8(dist(queryLen, s.Offset)) + if t <= uint8(la.mDistance) { + if minDistance.distance() > t { + minDistance.d = t + } + } + } + + if minDistance.distance() == la.mDistance+1 { + return Atleast{d: la.mDistance + 1} + } + + return minDistance +} + +func (la *LevenshteinNFA) simpleTransition(state NFAState, + symbol uint64, ms *MultiState) { + + if state.Distance < la.mDistance { + // insertion + ms.addStates(NFAState{Offset: state.Offset, + Distance: state.Distance + 1, + InTranspose: false}) + + // substitution + ms.addStates(NFAState{Offset: state.Offset + 1, + Distance: state.Distance + 1, + InTranspose: false}) + + n := la.mDistance + 1 - state.Distance + for d := uint8(1); d < n; d++ { + if extractBit(symbol, d) { + // for d > 0, as many deletion and character match + ms.addStates(NFAState{Offset: state.Offset + 1 + uint32(d), + Distance: state.Distance + d, + InTranspose: false}) + } + } + + if la.damerau && extractBit(symbol, 1) { + ms.addStates(NFAState{ + Offset: state.Offset, + Distance: state.Distance + 1, + InTranspose: true}) + } + + } + + if extractBit(symbol, 0) { + ms.addStates(NFAState{Offset: state.Offset + 1, + Distance: state.Distance, + InTranspose: false}) + } + + if state.InTranspose && extractBit(symbol, 0) { + ms.addStates(NFAState{Offset: state.Offset + 2, + Distance: state.Distance, + InTranspose: false}) + } + +} + +func (la *LevenshteinNFA) transition(cState *MultiState, + dState *MultiState, scv uint64) { + dState.Clear() + mask := (uint64(1) << la.msDiameter()) - uint64(1) + + for _, state := range cState.states { + cv := (scv >> state.Offset) & mask + la.simpleTransition(state, cv, dState) + } + + sort.Sort(NFAStates(dState.states)) +} + +func (la *LevenshteinNFA) computeDistance(query, other []rune) Distance { + cState := la.initialStates() + nState := newMultiState() + + for _, i := range other { + nState.Clear() + chi := characteristicVector(query, i) + la.transition(cState, nState, chi) + cState, nState = nState, cState + } + + return la.multistateDistance(cState, uint32(len(query))) +} diff --git a/backend/vendor/github.com/blevesearch/vellum/levenshtein/parametric_dfa.go b/backend/vendor/github.com/blevesearch/vellum/levenshtein/parametric_dfa.go new file mode 100644 index 0000000000..d08e5da639 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/levenshtein/parametric_dfa.go @@ -0,0 +1,349 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package levenshtein + +import ( + "crypto/md5" + "encoding/json" + "fmt" + "math" +) + +type ParametricState struct { + shapeID uint32 + offset uint32 +} + +func newParametricState() ParametricState { + return ParametricState{} +} + +func (ps *ParametricState) isDeadEnd() bool { + return ps.shapeID == 0 +} + +type Transition struct { + destShapeID uint32 + deltaOffset uint32 +} + +func (t *Transition) apply(state ParametricState) ParametricState { + ps := ParametricState{ + shapeID: t.destShapeID} + // don't need any offset if we are in the dead state, + // this ensures we have only one dead state. + if t.destShapeID != 0 { + ps.offset = state.offset + t.deltaOffset + } + + return ps +} + +type ParametricStateIndex struct { + stateIndex []uint32 + stateQueue []ParametricState + numOffsets uint32 +} + +func newParametricStateIndex(queryLen, + numParamState uint32) ParametricStateIndex { + numOffsets := queryLen + 1 + if numParamState == 0 { + numParamState = numOffsets + } + maxNumStates := numParamState * numOffsets + psi := ParametricStateIndex{ + stateIndex: make([]uint32, maxNumStates), + stateQueue: make([]ParametricState, 0, 150), + numOffsets: numOffsets, + } + + for i := uint32(0); i < maxNumStates; i++ { + psi.stateIndex[i] = math.MaxUint32 + } + return psi +} + +func (psi *ParametricStateIndex) numStates() int { + return len(psi.stateQueue) +} + +func (psi *ParametricStateIndex) maxNumStates() int { + return len(psi.stateIndex) +} + +func (psi *ParametricStateIndex) get(stateID uint32) ParametricState { + return psi.stateQueue[stateID] +} + +func (psi *ParametricStateIndex) getOrAllocate(ps ParametricState) uint32 { + bucket := ps.shapeID*psi.numOffsets + ps.offset + if bucket < uint32(len(psi.stateIndex)) && + psi.stateIndex[bucket] != math.MaxUint32 { + return psi.stateIndex[bucket] + } + nState := uint32(len(psi.stateQueue)) + psi.stateQueue = append(psi.stateQueue, ps) + + psi.stateIndex[bucket] = nState + return nState +} + +type ParametricDFA struct { + distance []uint8 + transitions []Transition + maxDistance uint8 + transitionStride uint32 + diameter uint32 +} + +func (pdfa *ParametricDFA) initialState() ParametricState { + return ParametricState{shapeID: 1} +} + +// Returns true iff whatever characters come afterward, +// we will never reach a shorter distance +func (pdfa *ParametricDFA) isPrefixSink(state ParametricState, queryLen uint32) bool { + if state.isDeadEnd() { + return true + } + + remOffset := queryLen - state.offset + if remOffset < pdfa.diameter { + stateDistances := pdfa.distance[pdfa.diameter*state.shapeID:] + prefixDistance := stateDistances[remOffset] + if prefixDistance > pdfa.maxDistance { + return false + } + + for _, d := range stateDistances { + if d < prefixDistance { + return false + } + } + return true + } + return false +} + +func (pdfa *ParametricDFA) numStates() int { + return len(pdfa.transitions) / int(pdfa.transitionStride) +} + +func min(x, y uint32) uint32 { + if x < y { + return x + } + return y +} + +func (pdfa *ParametricDFA) transition(state ParametricState, + chi uint32) Transition { + return pdfa.transitions[pdfa.transitionStride*state.shapeID+chi] +} + +func (pdfa *ParametricDFA) getDistance(state ParametricState, + qLen uint32) Distance { + remainingOffset := qLen - state.offset + if state.isDeadEnd() || remainingOffset >= pdfa.diameter { + return Atleast{d: pdfa.maxDistance + 1} + } + dist := pdfa.distance[int(pdfa.diameter*state.shapeID)+int(remainingOffset)] + if dist > pdfa.maxDistance { + return Atleast{d: dist} + } + return Exact{d: dist} +} + +func (pdfa *ParametricDFA) computeDistance(left, right string) Distance { + state := pdfa.initialState() + leftChars := []rune(left) + for _, chr := range []rune(right) { + start := state.offset + stop := min(start+pdfa.diameter, uint32(len(leftChars))) + chi := characteristicVector(leftChars[start:stop], chr) + transition := pdfa.transition(state, uint32(chi)) + state = transition.apply(state) + if state.isDeadEnd() { + return Atleast{d: pdfa.maxDistance + 1} + } + } + return pdfa.getDistance(state, uint32(len(left))) +} + +func (pdfa *ParametricDFA) buildDfa(query string, distance uint8, + prefix bool) (*DFA, error) { + qLen := uint32(len([]rune(query))) + alphabet := queryChars(query) + + psi := newParametricStateIndex(qLen, uint32(pdfa.numStates())) + maxNumStates := psi.maxNumStates() + deadEndStateID := psi.getOrAllocate(newParametricState()) + if deadEndStateID != 0 { + return nil, fmt.Errorf("Invalid dead end state") + } + + initialStateID := psi.getOrAllocate(pdfa.initialState()) + dfaBuilder := withMaxStates(uint32(maxNumStates)) + mask := uint32((1 << pdfa.diameter) - 1) + + var stateID int + for stateID = 0; stateID < StateLimit; stateID++ { + if stateID == psi.numStates() { + break + } + state := psi.get(uint32(stateID)) + if prefix && pdfa.isPrefixSink(state, qLen) { + distance := pdfa.getDistance(state, qLen) + dfaBuilder.addState(uint32(stateID), uint32(stateID), distance) + } else { + transition := pdfa.transition(state, 0) + defSuccessor := transition.apply(state) + defSuccessorID := psi.getOrAllocate(defSuccessor) + distance := pdfa.getDistance(state, qLen) + stateBuilder, err := dfaBuilder.addState(uint32(stateID), defSuccessorID, distance) + + if err != nil { + return nil, fmt.Errorf("parametric_dfa: buildDfa, err: %v", err) + } + + alphabet.resetNext() + chr, cv, err := alphabet.next() + for err == nil { + chi := cv.shiftAndMask(state.offset, mask) + + transition := pdfa.transition(state, chi) + + destState := transition.apply(state) + + destStateID := psi.getOrAllocate(destState) + + stateBuilder.addTransition(chr, destStateID) + + chr, cv, err = alphabet.next() + } + } + } + + if stateID == StateLimit { + return nil, ErrTooManyStates + } + + dfaBuilder.setInitialState(initialStateID) + return dfaBuilder.build(distance), nil +} + +func fromNfa(nfa *LevenshteinNFA) (*ParametricDFA, error) { + lookUp := newHash() + lookUp.getOrAllocate(*newMultiState()) + initialState := nfa.initialStates() + lookUp.getOrAllocate(*initialState) + + maxDistance := nfa.maxDistance() + msDiameter := nfa.msDiameter() + + numChi := 1 << msDiameter + chiValues := make([]uint64, numChi) + for i := 0; i < numChi; i++ { + chiValues[i] = uint64(i) + } + + transitions := make([]Transition, 0, numChi*int(msDiameter)) + var stateID int + for stateID = 0; stateID < StateLimit; stateID++ { + if stateID == len(lookUp.items) { + break + } + + for _, chi := range chiValues { + destMs := newMultiState() + + ms := lookUp.getFromID(stateID) + + nfa.transition(ms, destMs, chi) + + translation := destMs.normalize() + + destID := lookUp.getOrAllocate(*destMs) + + transitions = append(transitions, Transition{ + destShapeID: uint32(destID), + deltaOffset: translation, + }) + } + } + + if stateID == StateLimit { + return nil, ErrTooManyStates + } + + ns := len(lookUp.items) + diameter := int(msDiameter) + + distances := make([]uint8, 0, diameter*ns) + for stateID := 0; stateID < ns; stateID++ { + ms := lookUp.getFromID(stateID) + for offset := 0; offset < diameter; offset++ { + dist := nfa.multistateDistance(ms, uint32(offset)) + distances = append(distances, dist.distance()) + } + } + + return &ParametricDFA{ + diameter: uint32(msDiameter), + transitions: transitions, + maxDistance: maxDistance, + transitionStride: uint32(numChi), + distance: distances, + }, nil +} + +type hash struct { + index map[[16]byte]int + items []MultiState +} + +func newHash() *hash { + return &hash{ + index: make(map[[16]byte]int, 100), + items: make([]MultiState, 0, 100), + } +} + +func (h *hash) getOrAllocate(m MultiState) int { + size := len(h.items) + var exists bool + var pos int + md5 := getHash(&m) + if pos, exists = h.index[md5]; !exists { + h.index[md5] = size + pos = size + h.items = append(h.items, m) + } + return pos +} + +func (h *hash) getFromID(id int) *MultiState { + return &h.items[id] +} + +func getHash(ms *MultiState) [16]byte { + msBytes := []byte{} + for _, state := range ms.states { + jsonBytes, _ := json.Marshal(&state) + msBytes = append(msBytes, jsonBytes...) + } + return md5.Sum(msBytes) +} diff --git a/backend/vendor/github.com/blevesearch/vellum/merge_iterator.go b/backend/vendor/github.com/blevesearch/vellum/merge_iterator.go new file mode 100644 index 0000000000..f00f7783e1 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/merge_iterator.go @@ -0,0 +1,188 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vellum + +import ( + "bytes" +) + +// MergeFunc is used to choose the new value for a key when merging a slice +// of iterators, and the same key is observed with multiple values. +// Values presented to the MergeFunc will be in the same order as the +// original slice creating the MergeIterator. This allows some MergeFunc +// implementations to prioritize one iterator over another. +type MergeFunc func([]uint64) uint64 + +// MergeIterator implements the Iterator interface by traversing a slice +// of iterators and merging the contents of them. If the same key exists +// in mulitipe underlying iterators, a user-provided MergeFunc will be +// invoked to choose the new value. +type MergeIterator struct { + itrs []Iterator + f MergeFunc + currKs [][]byte + currVs []uint64 + + lowK []byte + lowV uint64 + lowIdxs []int + + mergeV []uint64 +} + +// NewMergeIterator creates a new MergeIterator over the provided slice of +// Iterators and with the specified MergeFunc to resolve duplicate keys. +func NewMergeIterator(itrs []Iterator, f MergeFunc) (*MergeIterator, error) { + rv := &MergeIterator{ + itrs: itrs, + f: f, + currKs: make([][]byte, len(itrs)), + currVs: make([]uint64, len(itrs)), + lowIdxs: make([]int, 0, len(itrs)), + mergeV: make([]uint64, 0, len(itrs)), + } + rv.init() + if rv.lowK == nil { + return rv, ErrIteratorDone + } + return rv, nil +} + +func (m *MergeIterator) init() { + for i, itr := range m.itrs { + m.currKs[i], m.currVs[i] = itr.Current() + } + m.updateMatches() +} + +func (m *MergeIterator) updateMatches() { + if len(m.itrs) < 1 { + return + } + m.lowK = m.currKs[0] + m.lowIdxs = m.lowIdxs[:0] + m.lowIdxs = append(m.lowIdxs, 0) + for i := 1; i < len(m.itrs); i++ { + if m.currKs[i] == nil { + continue + } + cmp := bytes.Compare(m.currKs[i], m.lowK) + if m.lowK == nil || cmp < 0 { + // reached a new low + m.lowK = m.currKs[i] + m.lowIdxs = m.lowIdxs[:0] + m.lowIdxs = append(m.lowIdxs, i) + } else if cmp == 0 { + m.lowIdxs = append(m.lowIdxs, i) + } + } + if len(m.lowIdxs) > 1 { + // merge multiple values + m.mergeV = m.mergeV[:0] + for _, vi := range m.lowIdxs { + m.mergeV = append(m.mergeV, m.currVs[vi]) + } + m.lowV = m.f(m.mergeV) + } else if len(m.lowIdxs) == 1 { + m.lowV = m.currVs[m.lowIdxs[0]] + } +} + +// Current returns the key and value currently pointed to by this iterator. +// If the iterator is not pointing at a valid value (because Iterator/Next/Seek) +// returned an error previously, it may return nil,0. +func (m *MergeIterator) Current() ([]byte, uint64) { + return m.lowK, m.lowV +} + +// Next advances this iterator to the next key/value pair. If there is none, +// then ErrIteratorDone is returned. +func (m *MergeIterator) Next() error { + // move all the current low iterators to next + for _, vi := range m.lowIdxs { + err := m.itrs[vi].Next() + if err != nil && err != ErrIteratorDone { + return err + } + m.currKs[vi], m.currVs[vi] = m.itrs[vi].Current() + } + m.updateMatches() + if m.lowK == nil { + return ErrIteratorDone + } + return nil +} + +// Seek advances this iterator to the specified key/value pair. If this key +// is not in the FST, Current() will return the next largest key. If this +// seek operation would go past the last key, then ErrIteratorDone is returned. +func (m *MergeIterator) Seek(key []byte) error { + for i := range m.itrs { + err := m.itrs[i].Seek(key) + if err != nil && err != ErrIteratorDone { + return err + } + } + m.updateMatches() + if m.lowK == nil { + return ErrIteratorDone + } + return nil +} + +// Close will attempt to close all the underlying Iterators. If any errors +// are encountered, the first will be returned. +func (m *MergeIterator) Close() error { + var rv error + for i := range m.itrs { + // close all iterators, return first error if any + err := m.itrs[i].Close() + if rv == nil { + rv = err + } + } + return rv +} + +// MergeMin chooses the minimum value +func MergeMin(vals []uint64) uint64 { + rv := vals[0] + for _, v := range vals[1:] { + if v < rv { + rv = v + } + } + return rv +} + +// MergeMax chooses the maximum value +func MergeMax(vals []uint64) uint64 { + rv := vals[0] + for _, v := range vals[1:] { + if v > rv { + rv = v + } + } + return rv +} + +// MergeSum sums the values +func MergeSum(vals []uint64) uint64 { + rv := vals[0] + for _, v := range vals[1:] { + rv += v + } + return rv +} diff --git a/backend/vendor/github.com/blevesearch/vellum/pack.go b/backend/vendor/github.com/blevesearch/vellum/pack.go new file mode 100644 index 0000000000..78f3dcd588 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/pack.go @@ -0,0 +1,55 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vellum + +func deltaAddr(base, trans uint64) uint64 { + // transition dest of 0 is special case + if trans == 0 { + return 0 + } + return base - trans +} + +const packOutMask = 1<<4 - 1 + +func encodePackSize(transSize, outSize int) byte { + var rv byte + rv = byte(transSize << 4) + rv |= byte(outSize) + return rv +} + +func decodePackSize(pack byte) (transSize int, packSize int) { + transSize = int(pack >> 4) + packSize = int(pack & packOutMask) + return +} + +const maxNumTrans = 1<<6 - 1 + +func encodeNumTrans(n int) byte { + if n <= maxNumTrans { + return byte(n) + } + return 0 +} + +func readPackedUint(data []byte) (rv uint64) { + for i := range data { + shifted := uint64(data[i]) << uint(i*8) + rv |= shifted + } + return +} diff --git a/backend/vendor/github.com/blevesearch/vellum/regexp/compile.go b/backend/vendor/github.com/blevesearch/vellum/regexp/compile.go new file mode 100644 index 0000000000..558ce41985 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/regexp/compile.go @@ -0,0 +1,343 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package regexp + +import ( + "regexp/syntax" + "unicode" + + unicode_utf8 "unicode/utf8" + + "github.com/blevesearch/vellum/utf8" +) + +type compiler struct { + sizeLimit uint + insts prog + instsPool []inst + + sequences utf8.Sequences + rangeStack utf8.RangeStack + startBytes []byte + endBytes []byte +} + +func newCompiler(sizeLimit uint) *compiler { + return &compiler{ + sizeLimit: sizeLimit, + startBytes: make([]byte, unicode_utf8.UTFMax), + endBytes: make([]byte, unicode_utf8.UTFMax), + } +} + +func (c *compiler) compile(ast *syntax.Regexp) (prog, error) { + err := c.c(ast) + if err != nil { + return nil, err + } + inst := c.allocInst() + inst.op = OpMatch + c.insts = append(c.insts, inst) + return c.insts, nil +} + +func (c *compiler) c(ast *syntax.Regexp) (err error) { + if ast.Flags&syntax.NonGreedy > 1 { + return ErrNoLazy + } + + switch ast.Op { + case syntax.OpEndLine, syntax.OpBeginLine, + syntax.OpBeginText, syntax.OpEndText: + return ErrNoEmpty + case syntax.OpWordBoundary, syntax.OpNoWordBoundary: + return ErrNoWordBoundary + case syntax.OpEmptyMatch: + return nil + case syntax.OpLiteral: + for _, r := range ast.Rune { + if ast.Flags&syntax.FoldCase > 0 { + next := syntax.Regexp{ + Op: syntax.OpCharClass, + Flags: ast.Flags & syntax.FoldCase, + Rune0: [2]rune{r, r}, + } + next.Rune = next.Rune0[0:2] + // try to find more folded runes + for r1 := unicode.SimpleFold(r); r1 != r; r1 = unicode.SimpleFold(r1) { + next.Rune = append(next.Rune, r1, r1) + } + err = c.c(&next) + if err != nil { + return err + } + } else { + c.sequences, c.rangeStack, err = utf8.NewSequencesPrealloc( + r, r, c.sequences, c.rangeStack, c.startBytes, c.endBytes) + if err != nil { + return err + } + for _, seq := range c.sequences { + c.compileUtf8Ranges(seq) + } + } + } + case syntax.OpAnyChar: + next := syntax.Regexp{ + Op: syntax.OpCharClass, + Flags: ast.Flags & syntax.FoldCase, + Rune0: [2]rune{0, unicode.MaxRune}, + } + next.Rune = next.Rune0[:2] + return c.c(&next) + case syntax.OpAnyCharNotNL: + next := syntax.Regexp{ + Op: syntax.OpCharClass, + Flags: ast.Flags & syntax.FoldCase, + Rune: []rune{0, 0x09, 0x0B, unicode.MaxRune}, + } + return c.c(&next) + case syntax.OpCharClass: + return c.compileClass(ast) + case syntax.OpCapture: + return c.c(ast.Sub[0]) + case syntax.OpConcat: + for _, sub := range ast.Sub { + err := c.c(sub) + if err != nil { + return err + } + } + return nil + case syntax.OpAlternate: + if len(ast.Sub) == 0 { + return nil + } + jmpsToEnd := make([]uint, 0, len(ast.Sub)-1) + // does not handle last entry + for i := 0; i < len(ast.Sub)-1; i++ { + sub := ast.Sub[i] + split := c.emptySplit() + j1 := c.top() + err := c.c(sub) + if err != nil { + return err + } + jmpsToEnd = append(jmpsToEnd, c.emptyJump()) + j2 := c.top() + c.setSplit(split, j1, j2) + } + // handle last entry + err := c.c(ast.Sub[len(ast.Sub)-1]) + if err != nil { + return err + } + end := uint(len(c.insts)) + for _, jmpToEnd := range jmpsToEnd { + c.setJump(jmpToEnd, end) + } + case syntax.OpQuest: + split := c.emptySplit() + j1 := c.top() + err := c.c(ast.Sub[0]) + if err != nil { + return err + } + j2 := c.top() + c.setSplit(split, j1, j2) + + case syntax.OpStar: + j1 := c.top() + split := c.emptySplit() + j2 := c.top() + err := c.c(ast.Sub[0]) + if err != nil { + return err + } + jmp := c.emptyJump() + j3 := uint(len(c.insts)) + + c.setJump(jmp, j1) + c.setSplit(split, j2, j3) + + case syntax.OpPlus: + j1 := c.top() + err := c.c(ast.Sub[0]) + if err != nil { + return err + } + split := c.emptySplit() + j2 := c.top() + c.setSplit(split, j1, j2) + + case syntax.OpRepeat: + if ast.Max == -1 { + for i := 0; i < ast.Min; i++ { + err := c.c(ast.Sub[0]) + if err != nil { + return err + } + } + next := syntax.Regexp{ + Op: syntax.OpStar, + Flags: ast.Flags, + Sub: ast.Sub, + Sub0: ast.Sub0, + Rune: ast.Rune, + Rune0: ast.Rune0, + } + return c.c(&next) + } + for i := 0; i < ast.Min; i++ { + err := c.c(ast.Sub[0]) + if err != nil { + return err + } + } + splits := make([]uint, 0, ast.Max-ast.Min) + starts := make([]uint, 0, ast.Max-ast.Min) + for i := ast.Min; i < ast.Max; i++ { + splits = append(splits, c.emptySplit()) + starts = append(starts, uint(len(c.insts))) + err := c.c(ast.Sub[0]) + if err != nil { + return err + } + } + end := uint(len(c.insts)) + for i := 0; i < len(splits); i++ { + c.setSplit(splits[i], starts[i], end) + } + + } + + return c.checkSize() +} + +func (c *compiler) checkSize() error { + if uint(len(c.insts)*instSize) > c.sizeLimit { + return ErrCompiledTooBig + } + return nil +} + +func (c *compiler) compileClass(ast *syntax.Regexp) error { + if len(ast.Rune) == 0 { + return nil + } + jmps := make([]uint, 0, len(ast.Rune)-2) + // does not do last pair + for i := 0; i < len(ast.Rune)-2; i += 2 { + rstart := ast.Rune[i] + rend := ast.Rune[i+1] + + split := c.emptySplit() + j1 := c.top() + err := c.compileClassRange(rstart, rend) + if err != nil { + return err + } + jmps = append(jmps, c.emptyJump()) + j2 := c.top() + c.setSplit(split, j1, j2) + } + // handle last pair + rstart := ast.Rune[len(ast.Rune)-2] + rend := ast.Rune[len(ast.Rune)-1] + err := c.compileClassRange(rstart, rend) + if err != nil { + return err + } + end := c.top() + for _, jmp := range jmps { + c.setJump(jmp, end) + } + return nil +} + +func (c *compiler) compileClassRange(startR, endR rune) (err error) { + c.sequences, c.rangeStack, err = utf8.NewSequencesPrealloc( + startR, endR, c.sequences, c.rangeStack, c.startBytes, c.endBytes) + if err != nil { + return err + } + jmps := make([]uint, 0, len(c.sequences)-1) + // does not do last entry + for i := 0; i < len(c.sequences)-1; i++ { + seq := c.sequences[i] + split := c.emptySplit() + j1 := c.top() + c.compileUtf8Ranges(seq) + jmps = append(jmps, c.emptyJump()) + j2 := c.top() + c.setSplit(split, j1, j2) + } + // handle last entry + c.compileUtf8Ranges(c.sequences[len(c.sequences)-1]) + end := c.top() + for _, jmp := range jmps { + c.setJump(jmp, end) + } + + return nil +} + +func (c *compiler) compileUtf8Ranges(seq utf8.Sequence) { + for _, r := range seq { + inst := c.allocInst() + inst.op = OpRange + inst.rangeStart = r.Start + inst.rangeEnd = r.End + c.insts = append(c.insts, inst) + } +} + +func (c *compiler) emptySplit() uint { + inst := c.allocInst() + inst.op = OpSplit + c.insts = append(c.insts, inst) + return c.top() - 1 +} + +func (c *compiler) emptyJump() uint { + inst := c.allocInst() + inst.op = OpJmp + c.insts = append(c.insts, inst) + return c.top() - 1 +} + +func (c *compiler) setSplit(i, pc1, pc2 uint) { + split := c.insts[i] + split.splitA = pc1 + split.splitB = pc2 +} + +func (c *compiler) setJump(i, pc uint) { + jmp := c.insts[i] + jmp.to = pc +} + +func (c *compiler) top() uint { + return uint(len(c.insts)) +} + +func (c *compiler) allocInst() *inst { + if len(c.instsPool) <= 0 { + c.instsPool = make([]inst, 16) + } + inst := &c.instsPool[0] + c.instsPool = c.instsPool[1:] + return inst +} diff --git a/backend/vendor/github.com/blevesearch/vellum/regexp/dfa.go b/backend/vendor/github.com/blevesearch/vellum/regexp/dfa.go new file mode 100644 index 0000000000..7e6fb29dac --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/regexp/dfa.go @@ -0,0 +1,196 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package regexp + +import ( + "encoding/binary" + "fmt" +) + +// StateLimit is the maximum number of states allowed +const StateLimit = 10000 + +// ErrTooManyStates is returned if you attempt to build a Levenshtein +// automaton which requires too many states. +var ErrTooManyStates = fmt.Errorf("dfa contains more than %d states", + StateLimit) + +type dfaBuilder struct { + dfa *dfa + cache map[string]int + keyBuf []byte +} + +func newDfaBuilder(insts prog) *dfaBuilder { + d := &dfaBuilder{ + dfa: &dfa{ + insts: insts, + states: make([]state, 0, 16), + }, + cache: make(map[string]int, 1024), + } + // add 0 state that is invalid + d.dfa.states = append(d.dfa.states, state{ + next: make([]int, 256), + match: false, + }) + return d +} + +func (d *dfaBuilder) build() (*dfa, error) { + cur := newSparseSet(uint(len(d.dfa.insts))) + next := newSparseSet(uint(len(d.dfa.insts))) + + d.dfa.add(cur, 0) + ns, instsReuse := d.cachedState(cur, nil) + states := intStack{ns} + seen := make(map[int]struct{}) + var s int + states, s = states.Pop() + for s != 0 { + for b := 0; b < 256; b++ { + var ns int + ns, instsReuse = d.runState(cur, next, s, byte(b), instsReuse) + if ns != 0 { + if _, ok := seen[ns]; !ok { + seen[ns] = struct{}{} + states = states.Push(ns) + } + } + if len(d.dfa.states) > StateLimit { + return nil, ErrTooManyStates + } + } + states, s = states.Pop() + } + return d.dfa, nil +} + +func (d *dfaBuilder) runState(cur, next *sparseSet, state int, b byte, instsReuse []uint) ( + int, []uint) { + cur.Clear() + for _, ip := range d.dfa.states[state].insts { + cur.Add(ip) + } + d.dfa.run(cur, next, b) + var nextState int + nextState, instsReuse = d.cachedState(next, instsReuse) + d.dfa.states[state].next[b] = nextState + return nextState, instsReuse +} + +func instsKey(insts []uint, buf []byte) []byte { + if cap(buf) < 8*len(insts) { + buf = make([]byte, 8*len(insts)) + } else { + buf = buf[0 : 8*len(insts)] + } + for i, inst := range insts { + binary.LittleEndian.PutUint64(buf[i*8:], uint64(inst)) + } + return buf +} + +func (d *dfaBuilder) cachedState(set *sparseSet, + instsReuse []uint) (int, []uint) { + insts := instsReuse[:0] + if cap(insts) == 0 { + insts = make([]uint, 0, set.Len()) + } + var isMatch bool + for i := uint(0); i < uint(set.Len()); i++ { + ip := set.Get(i) + switch d.dfa.insts[ip].op { + case OpRange: + insts = append(insts, ip) + case OpMatch: + isMatch = true + insts = append(insts, ip) + } + } + if len(insts) == 0 { + return 0, insts + } + d.keyBuf = instsKey(insts, d.keyBuf) + v, ok := d.cache[string(d.keyBuf)] + if ok { + return v, insts + } + d.dfa.states = append(d.dfa.states, state{ + insts: insts, + next: make([]int, 256), + match: isMatch, + }) + newV := len(d.dfa.states) - 1 + d.cache[string(d.keyBuf)] = newV + return newV, nil +} + +type dfa struct { + insts prog + states []state +} + +func (d *dfa) add(set *sparseSet, ip uint) { + if set.Contains(ip) { + return + } + set.Add(ip) + switch d.insts[ip].op { + case OpJmp: + d.add(set, d.insts[ip].to) + case OpSplit: + d.add(set, d.insts[ip].splitA) + d.add(set, d.insts[ip].splitB) + } +} + +func (d *dfa) run(from, to *sparseSet, b byte) bool { + to.Clear() + var isMatch bool + for i := uint(0); i < uint(from.Len()); i++ { + ip := from.Get(i) + switch d.insts[ip].op { + case OpMatch: + isMatch = true + case OpRange: + if d.insts[ip].rangeStart <= b && + b <= d.insts[ip].rangeEnd { + d.add(to, ip+1) + } + } + } + return isMatch +} + +type state struct { + insts []uint + next []int + match bool +} + +type intStack []int + +func (s intStack) Push(v int) intStack { + return append(s, v) +} + +func (s intStack) Pop() (intStack, int) { + l := len(s) + if l < 1 { + return s, 0 + } + return s[:l-1], s[l-1] +} diff --git a/backend/vendor/github.com/blevesearch/vellum/regexp/inst.go b/backend/vendor/github.com/blevesearch/vellum/regexp/inst.go new file mode 100644 index 0000000000..36f2e602df --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/regexp/inst.go @@ -0,0 +1,62 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package regexp + +import "fmt" + +// instOp represents a instruction operation +type instOp int + +// the enumeration of operations +const ( + OpMatch instOp = iota + OpJmp + OpSplit + OpRange +) + +// instSize is the approximate size of the an inst struct in bytes +const instSize = 40 + +type inst struct { + op instOp + to uint + splitA uint + splitB uint + rangeStart byte + rangeEnd byte +} + +func (i *inst) String() string { + switch i.op { + case OpJmp: + return fmt.Sprintf("JMP: %d", i.to) + case OpSplit: + return fmt.Sprintf("SPLIT: %d - %d", i.splitA, i.splitB) + case OpRange: + return fmt.Sprintf("RANGE: %x - %x", i.rangeStart, i.rangeEnd) + } + return "MATCH" +} + +type prog []*inst + +func (p prog) String() string { + rv := "\n" + for i, pi := range p { + rv += fmt.Sprintf("%d %v\n", i, pi) + } + return rv +} diff --git a/backend/vendor/github.com/blevesearch/vellum/regexp/regexp.go b/backend/vendor/github.com/blevesearch/vellum/regexp/regexp.go new file mode 100644 index 0000000000..920ddc3708 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/regexp/regexp.go @@ -0,0 +1,119 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package regexp + +import ( + "fmt" + "regexp/syntax" +) + +// ErrNoEmpty returned when "zero width assertions" are used +var ErrNoEmpty = fmt.Errorf("zero width assertions not allowed") + +// ErrNoWordBoundary returned when word boundaries are used +var ErrNoWordBoundary = fmt.Errorf("word boundaries are not allowed") + +// ErrNoBytes returned when byte literals are used +var ErrNoBytes = fmt.Errorf("byte literals are not allowed") + +// ErrNoLazy returned when lazy quantifiers are used +var ErrNoLazy = fmt.Errorf("lazy quantifiers are not allowed") + +// ErrCompiledTooBig returned when regular expression parses into +// too many instructions +var ErrCompiledTooBig = fmt.Errorf("too many instructions") + +var DefaultLimit = uint(10 * (1 << 20)) + +// Regexp implements the vellum.Automaton interface for matcing a user +// specified regular expression. +type Regexp struct { + orig string + dfa *dfa +} + +// NewRegexp creates a new Regular Expression automaton with the specified +// expression. By default it is limited to approximately 10MB for the +// compiled finite state automaton. If this size is exceeded, +// ErrCompiledTooBig will be returned. +func New(expr string) (*Regexp, error) { + return NewWithLimit(expr, DefaultLimit) +} + +// NewRegexpWithLimit creates a new Regular Expression automaton with +// the specified expression. The size of the compiled finite state +// automaton exceeds the user specified size, ErrCompiledTooBig will be +// returned. +func NewWithLimit(expr string, size uint) (*Regexp, error) { + parsed, err := syntax.Parse(expr, syntax.Perl) + if err != nil { + return nil, err + } + return NewParsedWithLimit(expr, parsed, size) +} + +func NewParsedWithLimit(expr string, parsed *syntax.Regexp, size uint) (*Regexp, error) { + compiler := newCompiler(size) + insts, err := compiler.compile(parsed) + if err != nil { + return nil, err + } + dfaBuilder := newDfaBuilder(insts) + dfa, err := dfaBuilder.build() + if err != nil { + return nil, err + } + return &Regexp{ + orig: expr, + dfa: dfa, + }, nil +} + +// Start returns the start state of this automaton. +func (r *Regexp) Start() int { + return 1 +} + +// IsMatch returns if the specified state is a matching state. +func (r *Regexp) IsMatch(s int) bool { + if s < len(r.dfa.states) { + return r.dfa.states[s].match + } + return false +} + +// CanMatch returns if the specified state can ever transition to a matching +// state. +func (r *Regexp) CanMatch(s int) bool { + if s < len(r.dfa.states) && s > 0 { + return true + } + return false +} + +// WillAlwaysMatch returns if the specified state will always end in a +// matching state. +func (r *Regexp) WillAlwaysMatch(int) bool { + return false +} + +// Accept returns the new state, resulting from the transition byte b +// when currently in the state s. +func (r *Regexp) Accept(s int, b byte) int { + if s < len(r.dfa.states) { + return r.dfa.states[s].next[b] + } + return 0 +} diff --git a/backend/vendor/github.com/blevesearch/vellum/regexp/sparse.go b/backend/vendor/github.com/blevesearch/vellum/regexp/sparse.go new file mode 100644 index 0000000000..7afbfceba6 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/regexp/sparse.go @@ -0,0 +1,54 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package regexp + +type sparseSet struct { + dense []uint + sparse []uint + size uint +} + +func newSparseSet(size uint) *sparseSet { + return &sparseSet{ + dense: make([]uint, size), + sparse: make([]uint, size), + size: 0, + } +} + +func (s *sparseSet) Len() int { + return int(s.size) +} + +func (s *sparseSet) Add(ip uint) uint { + i := s.size + s.dense[i] = ip + s.sparse[ip] = i + s.size++ + return i +} + +func (s *sparseSet) Get(i uint) uint { + return s.dense[i] +} + +func (s *sparseSet) Contains(ip uint) bool { + i := s.sparse[ip] + return i < s.size && s.dense[i] == ip +} + +func (s *sparseSet) Clear() { + s.size = 0 +} diff --git a/backend/vendor/github.com/blevesearch/vellum/registry.go b/backend/vendor/github.com/blevesearch/vellum/registry.go new file mode 100644 index 0000000000..f5b9b4d59c --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/registry.go @@ -0,0 +1,114 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vellum + +type registryCell struct { + addr int + node *builderNode +} + +type registry struct { + builderNodePool *builderNodePool + table []registryCell + tableSize uint + mruSize uint +} + +func newRegistry(p *builderNodePool, tableSize, mruSize int) *registry { + nsize := tableSize * mruSize + rv := ®istry{ + builderNodePool: p, + table: make([]registryCell, nsize), + tableSize: uint(tableSize), + mruSize: uint(mruSize), + } + return rv +} + +func (r *registry) Reset() { + var empty registryCell + for i := range r.table { + r.builderNodePool.Put(r.table[i].node) + r.table[i] = empty + } +} + +func (r *registry) entry(node *builderNode) (bool, int, *registryCell) { + if len(r.table) == 0 { + return false, 0, nil + } + bucket := r.hash(node) + start := r.mruSize * uint(bucket) + end := start + r.mruSize + rc := registryCache(r.table[start:end]) + return rc.entry(node, r.builderNodePool) +} + +const fnvPrime = 1099511628211 + +func (r *registry) hash(b *builderNode) int { + var final uint64 + if b.final { + final = 1 + } + + var h uint64 = 14695981039346656037 + h = (h ^ final) * fnvPrime + h = (h ^ b.finalOutput) * fnvPrime + for _, t := range b.trans { + h = (h ^ uint64(t.in)) * fnvPrime + h = (h ^ t.out) * fnvPrime + h = (h ^ uint64(t.addr)) * fnvPrime + } + return int(h % uint64(r.tableSize)) +} + +type registryCache []registryCell + +func (r registryCache) entry(node *builderNode, pool *builderNodePool) (bool, int, *registryCell) { + if len(r) == 1 { + if r[0].node != nil && r[0].node.equiv(node) { + return true, r[0].addr, nil + } + pool.Put(r[0].node) + r[0].node = node + return false, 0, &r[0] + } + for i := range r { + if r[i].node != nil && r[i].node.equiv(node) { + addr := r[i].addr + r.promote(i) + return true, addr, nil + } + } + // no match + last := len(r) - 1 + pool.Put(r[last].node) + r[last].node = node // discard LRU + r.promote(last) + return false, 0, &r[0] + +} + +func (r registryCache) promote(i int) { + for i > 0 { + r.swap(i-1, i) + i-- + } +} + +func (r registryCache) swap(i, j int) { + r[i], r[j] = r[j], r[i] +} diff --git a/backend/vendor/github.com/blevesearch/vellum/transducer.go b/backend/vendor/github.com/blevesearch/vellum/transducer.go new file mode 100644 index 0000000000..753c422d57 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/transducer.go @@ -0,0 +1,55 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vellum + +// Transducer represents the general contract of a byte-based finite transducer +type Transducer interface { + + // all transducers are also automatons + Automaton + + // IsMatchWithValue returns true if and only if the state is a match + // additionally it returns a states final value (if any) + IsMatchWithVal(int) (bool, uint64) + + // Accept returns the next state given the input to the specified state + // additionally it returns the value associated with the transition + AcceptWithVal(int, byte) (int, uint64) +} + +// TransducerGet implements an generic Get() method which works +// on any implementation of Transducer +// The caller MUST check the boolean return value for a match. +// Zero is a valid value regardless of match status, +// and if it is NOT a match, the value collected so far is returned. +func TransducerGet(t Transducer, k []byte) (bool, uint64) { + var total uint64 + i := 0 + curr := t.Start() + for t.CanMatch(curr) && i < len(k) { + var transVal uint64 + curr, transVal = t.AcceptWithVal(curr, k[i]) + if curr == noneAddr { + break + } + total += transVal + i++ + } + if i != len(k) { + return false, total + } + match, finalVal := t.IsMatchWithVal(curr) + return match, total + finalVal +} diff --git a/backend/vendor/github.com/blevesearch/vellum/utf8/utf8.go b/backend/vendor/github.com/blevesearch/vellum/utf8/utf8.go new file mode 100644 index 0000000000..54e23b937c --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/utf8/utf8.go @@ -0,0 +1,268 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package utf8 + +import ( + "fmt" + "unicode/utf8" +) + +// Sequences is a collection of Sequence +type Sequences []Sequence + +// NewSequences constructs a collection of Sequence which describe the +// byte ranges covered between the start and end runes. +func NewSequences(start, end rune) (Sequences, error) { + rv, _, err := NewSequencesPrealloc(start, end, nil, nil, nil, nil) + return rv, err +} + +func NewSequencesPrealloc(start, end rune, + preallocSequences Sequences, + preallocRangeStack RangeStack, + preallocStartBytes, preallocEndBytes []byte) (Sequences, RangeStack, error) { + rv := preallocSequences[:0] + + startBytes := preallocStartBytes + if cap(startBytes) < utf8.UTFMax { + startBytes = make([]byte, utf8.UTFMax) + } + startBytes = startBytes[:utf8.UTFMax] + + endBytes := preallocEndBytes + if cap(endBytes) < utf8.UTFMax { + endBytes = make([]byte, utf8.UTFMax) + } + endBytes = endBytes[:utf8.UTFMax] + + rangeStack := preallocRangeStack[:0] + rangeStack = rangeStack.Push(scalarRange{start, end}) + + rangeStack, r := rangeStack.Pop() +TOP: + for r != nilScalarRange { + INNER: + for { + r1, r2 := r.split() + if r1 != nilScalarRange { + rangeStack = rangeStack.Push(scalarRange{r2.start, r2.end}) + r.start = r1.start + r.end = r1.end + continue INNER + } + if !r.valid() { + rangeStack, r = rangeStack.Pop() + continue TOP + } + for i := 1; i < utf8.UTFMax; i++ { + max := maxScalarValue(i) + if r.start <= max && max < r.end { + rangeStack = rangeStack.Push(scalarRange{max + 1, r.end}) + r.end = max + continue INNER + } + } + asciiRange := r.ascii() + if asciiRange != nilRange { + rv = append(rv, Sequence{ + asciiRange, + }) + rangeStack, r = rangeStack.Pop() + continue TOP + } + for i := uint(1); i < utf8.UTFMax; i++ { + m := rune((1 << (6 * i)) - 1) + if (r.start & ^m) != (r.end & ^m) { + if (r.start & m) != 0 { + rangeStack = rangeStack.Push(scalarRange{(r.start | m) + 1, r.end}) + r.end = r.start | m + continue INNER + } + if (r.end & m) != m { + rangeStack = rangeStack.Push(scalarRange{r.end & ^m, r.end}) + r.end = (r.end & ^m) - 1 + continue INNER + } + } + } + n, m := r.encode(startBytes, endBytes) + seq, err := SequenceFromEncodedRange(startBytes[0:n], endBytes[0:m]) + if err != nil { + return nil, nil, err + } + rv = append(rv, seq) + rangeStack, r = rangeStack.Pop() + continue TOP + } + } + + return rv, rangeStack, nil +} + +// Sequence is a collection of Range +type Sequence []Range + +// SequenceFromEncodedRange creates sequence from the encoded bytes +func SequenceFromEncodedRange(start, end []byte) (Sequence, error) { + if len(start) != len(end) { + return nil, fmt.Errorf("byte slices must be the same length") + } + switch len(start) { + case 2: + return Sequence{ + Range{start[0], end[0]}, + Range{start[1], end[1]}, + }, nil + case 3: + return Sequence{ + Range{start[0], end[0]}, + Range{start[1], end[1]}, + Range{start[2], end[2]}, + }, nil + case 4: + return Sequence{ + Range{start[0], end[0]}, + Range{start[1], end[1]}, + Range{start[2], end[2]}, + Range{start[3], end[3]}, + }, nil + } + + return nil, fmt.Errorf("invalid encoded byte length") +} + +// Matches checks to see if the provided byte slice matches the Sequence +func (u Sequence) Matches(bytes []byte) bool { + if len(bytes) < len(u) { + return false + } + for i := 0; i < len(u); i++ { + if !u[i].matches(bytes[i]) { + return false + } + } + return true +} + +func (u Sequence) String() string { + switch len(u) { + case 1: + return fmt.Sprintf("%v", u[0]) + case 2: + return fmt.Sprintf("%v%v", u[0], u[1]) + case 3: + return fmt.Sprintf("%v%v%v", u[0], u[1], u[2]) + case 4: + return fmt.Sprintf("%v%v%v%v", u[0], u[1], u[2], u[3]) + default: + return fmt.Sprintf("invalid utf8 sequence") + } +} + +// Range describes a single range of byte values +type Range struct { + Start byte + End byte +} + +var nilRange = Range{0xff, 0} + +func (u Range) matches(b byte) bool { + if u.Start <= b && b <= u.End { + return true + } + return false +} + +func (u Range) String() string { + if u.Start == u.End { + return fmt.Sprintf("[%X]", u.Start) + } + return fmt.Sprintf("[%X-%X]", u.Start, u.End) +} + +type scalarRange struct { + start rune + end rune +} + +var nilScalarRange = scalarRange{0xffff, 0} + +func (s *scalarRange) String() string { + return fmt.Sprintf("ScalarRange(%d,%d)", s.start, s.end) +} + +// split this scalar range if it overlaps with a surrogate codepoint +func (s *scalarRange) split() (scalarRange, scalarRange) { + if s.start < 0xe000 && s.end > 0xd7ff { + return scalarRange{ + start: s.start, + end: 0xd7ff, + }, + scalarRange{ + start: 0xe000, + end: s.end, + } + } + return nilScalarRange, nilScalarRange +} + +func (s *scalarRange) valid() bool { + return s.start <= s.end +} + +func (s *scalarRange) ascii() Range { + if s.valid() && s.end <= 0x7f { + return Range{ + Start: byte(s.start), + End: byte(s.end), + } + } + return nilRange +} + +// start and end MUST have capacity for utf8.UTFMax bytes +func (s *scalarRange) encode(start, end []byte) (int, int) { + n := utf8.EncodeRune(start, s.start) + m := utf8.EncodeRune(end, s.end) + return n, m +} + +type RangeStack []scalarRange + +func (s RangeStack) Push(v scalarRange) RangeStack { + return append(s, v) +} + +func (s RangeStack) Pop() (RangeStack, scalarRange) { + l := len(s) + if l < 1 { + return s, nilScalarRange + } + return s[:l-1], s[l-1] +} + +func maxScalarValue(nbytes int) rune { + switch nbytes { + case 1: + return 0x007f + case 2: + return 0x07FF + case 3: + return 0xFFFF + default: + return 0x10FFFF + } +} diff --git a/backend/vendor/github.com/blevesearch/vellum/vellum.go b/backend/vendor/github.com/blevesearch/vellum/vellum.go new file mode 100644 index 0000000000..b2537b3f00 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/vellum.go @@ -0,0 +1,111 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* +Package vellum is a library for building, serializing and executing an FST (finite +state transducer). + +There are two distinct phases, building an FST and using it. + +When building an FST, you insert keys ([]byte) and their associated value +(uint64). Insert operations MUST be done in lexicographic order. While +building the FST, data is streamed to an underlying Writer. At the conclusion +of building, you MUST call Close() on the builder. + +After completion of the build phase, you can either Open() the FST if you +serialized it to disk. Alternatively, if you already have the bytes in +memory, you can use Load(). By default, Open() will use mmap to avoid loading +the entire file into memory. + +Once the FST is ready, you can use the Contains() method to see if a keys is +in the FST. You can use the Get() method to see if a key is in the FST and +retrieve it's associated value. And, you can use the Iterator method to +enumerate key/value pairs within a specified range. + +*/ +package vellum + +import ( + "errors" + "io" +) + +// ErrOutOfOrder is returned when values are not inserted in +// lexicographic order. +var ErrOutOfOrder = errors.New("values not inserted in lexicographic order") + +// ErrIteratorDone is returned by Iterator/Next/Seek methods when the +// Current() value pointed to by the iterator is greater than the last +// key in this FST, or outside the configured startKeyInclusive/endKeyExclusive +// range of the Iterator. +var ErrIteratorDone = errors.New("iterator-done") + +// BuilderOpts is a structure to let advanced users customize the behavior +// of the builder and some aspects of the generated FST. +type BuilderOpts struct { + Encoder int + RegistryTableSize int + RegistryMRUSize int +} + +// New returns a new Builder which will stream out the +// underlying representation to the provided Writer as the set is built. +func New(w io.Writer, opts *BuilderOpts) (*Builder, error) { + return newBuilder(w, opts) +} + +// Open loads the FST stored in the provided path +func Open(path string) (*FST, error) { + return open(path) +} + +// Load will return the FST represented by the provided byte slice. +func Load(data []byte) (*FST, error) { + return new(data, nil) +} + +// Merge will iterate through the provided Iterators, merge duplicate keys +// with the provided MergeFunc, and build a new FST to the provided Writer. +func Merge(w io.Writer, opts *BuilderOpts, itrs []Iterator, f MergeFunc) error { + builder, err := New(w, opts) + if err != nil { + return err + } + + itr, err := NewMergeIterator(itrs, f) + for err == nil { + k, v := itr.Current() + err = builder.Insert(k, v) + if err != nil { + return err + } + err = itr.Next() + } + + if err != nil && err != ErrIteratorDone { + return err + } + + err = itr.Close() + if err != nil { + return err + } + + err = builder.Close() + if err != nil { + return err + } + + return nil +} diff --git a/backend/vendor/github.com/blevesearch/vellum/vellum_mmap.go b/backend/vendor/github.com/blevesearch/vellum/vellum_mmap.go new file mode 100644 index 0000000000..81ea165091 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/vellum_mmap.go @@ -0,0 +1,60 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !nommap + +package vellum + +import ( + "os" + + mmap "github.com/blevesearch/mmap-go" +) + +type mmapWrapper struct { + f *os.File + mm mmap.MMap +} + +func (m *mmapWrapper) Close() (err error) { + if m.mm != nil { + err = m.mm.Unmap() + } + // try to close file even if unmap failed + if m.f != nil { + err2 := m.f.Close() + if err == nil { + // try to return first error + err = err2 + } + } + return +} + +func open(path string) (*FST, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + mm, err := mmap.Map(f, mmap.RDONLY, 0) + if err != nil { + // mmap failed, try to close the file + _ = f.Close() + return nil, err + } + return new(mm, &mmapWrapper{ + f: f, + mm: mm, + }) +} diff --git a/backend/vendor/github.com/blevesearch/vellum/vellum_nommap.go b/backend/vendor/github.com/blevesearch/vellum/vellum_nommap.go new file mode 100644 index 0000000000..e985272872 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/vellum_nommap.go @@ -0,0 +1,27 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build nommap + +package vellum + +import "io/ioutil" + +func open(path string) (*FST, error) { + data, err := ioutil.ReadFile(string) + if err != nil { + return nil, err + } + return new(data, nil) +} diff --git a/backend/vendor/github.com/blevesearch/vellum/writer.go b/backend/vendor/github.com/blevesearch/vellum/writer.go new file mode 100644 index 0000000000..d655d47f7f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/vellum/writer.go @@ -0,0 +1,92 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vellum + +import ( + "bufio" + "io" +) + +// A writer is a buffered writer used by vellum. It counts how many bytes have +// been written and has some convenience methods used for encoding the data. +type writer struct { + w *bufio.Writer + counter int +} + +func newWriter(w io.Writer) *writer { + return &writer{ + w: bufio.NewWriter(w), + } +} + +func (w *writer) Reset(newWriter io.Writer) { + w.w.Reset(newWriter) + w.counter = 0 +} + +func (w *writer) WriteByte(c byte) error { + err := w.w.WriteByte(c) + if err != nil { + return err + } + w.counter++ + return nil +} + +func (w *writer) Write(p []byte) (int, error) { + n, err := w.w.Write(p) + w.counter += n + return n, err +} + +func (w *writer) Flush() error { + return w.w.Flush() +} + +func (w *writer) WritePackedUintIn(v uint64, n int) error { + for shift := uint(0); shift < uint(n*8); shift += 8 { + err := w.WriteByte(byte(v >> shift)) + if err != nil { + return err + } + } + + return nil +} + +func (w *writer) WritePackedUint(v uint64) error { + n := packedSize(v) + return w.WritePackedUintIn(v, n) +} + +func packedSize(n uint64) int { + if n < 1<<8 { + return 1 + } else if n < 1<<16 { + return 2 + } else if n < 1<<24 { + return 3 + } else if n < 1<<32 { + return 4 + } else if n < 1<<40 { + return 5 + } else if n < 1<<48 { + return 6 + } else if n < 1<<56 { + return 7 + } + return 8 +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/.gitignore b/backend/vendor/github.com/blevesearch/zapx/v11/.gitignore new file mode 100644 index 0000000000..46d1cfad54 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/.gitignore @@ -0,0 +1,12 @@ +#* +*.sublime-* +*~ +.#* +.project +.settings +**/.idea/ +**/*.iml +.DS_Store +/cmd/zap/zap +*.test +tags diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/.golangci.yml b/backend/vendor/github.com/blevesearch/zapx/v11/.golangci.yml new file mode 100644 index 0000000000..1d55bfc00d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/.golangci.yml @@ -0,0 +1,28 @@ +linters: + # please, do not use `enable-all`: it's deprecated and will be removed soon. + # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint + disable-all: true + enable: + - bodyclose + - deadcode + - depguard + - dupl + - errcheck + - gofmt + - goimports + - goprintffuncname + - gosec + - gosimple + - govet + - ineffassign + - misspell + - nakedret + - nolintlint + - rowserrcheck + - staticcheck + - structcheck + - typecheck + - unused + - varcheck + - whitespace + diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/LICENSE b/backend/vendor/github.com/blevesearch/zapx/v11/LICENSE new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/README.md b/backend/vendor/github.com/blevesearch/zapx/v11/README.md new file mode 100644 index 0000000000..4cbf1a145b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/README.md @@ -0,0 +1,163 @@ +# zapx file format + +The zapx module is fork of [zap](https://github.com/blevesearch/zap) module which maintains file format compatibility, but removes dependency on bleve, and instead depends only on the indepenent interface modules: + +- [bleve_index_api](https://github.com/blevesearch/scorch_segment_api) +- [scorch_segment_api](https://github.com/blevesearch/scorch_segment_api) + +Advanced ZAP File Format Documentation is [here](zap.md). + +The file is written in the reverse order that we typically access data. This helps us write in one pass since later sections of the file require file offsets of things we've already written. + +Current usage: + +- mmap the entire file +- crc-32 bytes and version are in fixed position at end of the file +- reading remainder of footer could be version specific +- remainder of footer gives us: + - 3 important offsets (docValue , fields index and stored data index) + - 2 important values (number of docs and chunk factor) +- field data is processed once and memoized onto the heap so that we never have to go back to disk for it +- access to stored data by doc number means first navigating to the stored data index, then accessing a fixed position offset into that slice, which gives us the actual address of the data. the first bytes of that section tell us the size of data so that we know where it ends. +- access to all other indexed data follows the following pattern: + - first know the field name -> convert to id + - next navigate to term dictionary for that field + - some operations stop here and do dictionary ops + - next use dictionary to navigate to posting list for a specific term + - walk posting list + - if necessary, walk posting details as we go + - if location info is desired, consult location bitmap to see if it is there + +## stored fields section + +- for each document + - preparation phase: + - produce a slice of metadata bytes and data bytes + - produce these slices in field id order + - field value is appended to the data slice + - metadata slice is varint encoded with the following values for each field value + - field id (uint16) + - field type (byte) + - field value start offset in uncompressed data slice (uint64) + - field value length (uint64) + - field number of array positions (uint64) + - one additional value for each array position (uint64) + - compress the data slice using snappy + - file writing phase: + - remember the start offset for this document + - write out meta data length (varint uint64) + - write out compressed data length (varint uint64) + - write out the metadata bytes + - write out the compressed data bytes + +## stored fields idx + +- for each document + - write start offset (remembered from previous section) of stored data (big endian uint64) + +With this index and a known document number, we have direct access to all the stored field data. + +## posting details (freq/norm) section + +- for each posting list + - produce a slice containing multiple consecutive chunks (each chunk is varint stream) + - produce a slice remembering offsets of where each chunk starts + - preparation phase: + - for each hit in the posting list + - if this hit is in next chunk close out encoding of last chunk and record offset start of next + - encode term frequency (uint64) + - encode norm factor (float32) + - file writing phase: + - remember start position for this posting list details + - write out number of chunks that follow (varint uint64) + - write out length of each chunk (each a varint uint64) + - write out the byte slice containing all the chunk data + +If you know the doc number you're interested in, this format lets you jump to the correct chunk (docNum/chunkFactor) directly and then seek within that chunk until you find it. + +## posting details (location) section + +- for each posting list + - produce a slice containing multiple consecutive chunks (each chunk is varint stream) + - produce a slice remembering offsets of where each chunk starts + - preparation phase: + - for each hit in the posting list + - if this hit is in next chunk close out encoding of last chunk and record offset start of next + - encode field (uint16) + - encode field pos (uint64) + - encode field start (uint64) + - encode field end (uint64) + - encode number of array positions to follow (uint64) + - encode each array position (each uint64) + - file writing phase: + - remember start position for this posting list details + - write out number of chunks that follow (varint uint64) + - write out length of each chunk (each a varint uint64) + - write out the byte slice containing all the chunk data + +If you know the doc number you're interested in, this format lets you jump to the correct chunk (docNum/chunkFactor) directly and then seek within that chunk until you find it. + +## postings list section + +- for each posting list + - preparation phase: + - encode roaring bitmap posting list to bytes (so we know the length) + - file writing phase: + - remember the start position for this posting list + - write freq/norm details offset (remembered from previous, as varint uint64) + - write location details offset (remembered from previous, as varint uint64) + - write length of encoded roaring bitmap + - write the serialized roaring bitmap data + +## dictionary + +- for each field + - preparation phase: + - encode vellum FST with dictionary data pointing to file offset of posting list (remembered from previous) + - file writing phase: + - remember the start position of this persistDictionary + - write length of vellum data (varint uint64) + - write out vellum data + +## fields section + +- for each field + - file writing phase: + - remember start offset for each field + - write dictionary address (remembered from previous) (varint uint64) + - write length of field name (varint uint64) + - write field name bytes + +## fields idx + +- for each field + - file writing phase: + - write big endian uint64 of start offset for each field + +NOTE: currently we don't know or record the length of this fields index. Instead we rely on the fact that we know it immediately precedes a footer of known size. + +## fields DocValue + +- for each field + - preparation phase: + - produce a slice containing multiple consecutive chunks, where each chunk is composed of a meta section followed by compressed columnar field data + - produce a slice remembering the length of each chunk + - file writing phase: + - remember the start position of this first field DocValue offset in the footer + - write out number of chunks that follow (varint uint64) + - write out length of each chunk (each a varint uint64) + - write out the byte slice containing all the chunk data + +NOTE: currently the meta header inside each chunk gives clue to the location offsets and size of the data pertaining to a given docID and any +read operation leverage that meta information to extract the document specific data from the file. + +## footer + +- file writing phase + - write number of docs (big endian uint64) + - write stored field index location (big endian uint64) + - write field index location (big endian uint64) + - write field docValue location (big endian uint64) + - write out chunk factor (big endian uint32) + - write out version (big endian uint32) + - write out file CRC of everything preceding this (big endian uint32) diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/build.go b/backend/vendor/github.com/blevesearch/zapx/v11/build.go new file mode 100644 index 0000000000..3f13a2a6c6 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/build.go @@ -0,0 +1,186 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bufio" + "fmt" + "io" + "math" + "os" + + "github.com/blevesearch/vellum" +) + +const Version uint32 = 11 + +const Type string = "zap" + +const fieldNotUninverted = math.MaxUint64 + +func (sb *SegmentBase) Persist(path string) error { + return PersistSegmentBase(sb, path) +} + +// WriteTo is an implementation of io.WriterTo interface. +func (sb *SegmentBase) WriteTo(w io.Writer) (int64, error) { + if w == nil { + return 0, fmt.Errorf("invalid writer found") + } + + n, err := persistSegmentBaseToWriter(sb, w) + return int64(n), err +} + +// PersistSegmentBase persists SegmentBase in the zap file format. +func PersistSegmentBase(sb *SegmentBase, path string) error { + flag := os.O_RDWR | os.O_CREATE + + f, err := os.OpenFile(path, flag, 0600) + if err != nil { + return err + } + + cleanup := func() { + _ = f.Close() + _ = os.Remove(path) + } + + _, err = persistSegmentBaseToWriter(sb, f) + if err != nil { + cleanup() + return err + } + + err = f.Sync() + if err != nil { + cleanup() + return err + } + + err = f.Close() + if err != nil { + cleanup() + return err + } + + return err +} + +type bufWriter struct { + w *bufio.Writer + n int +} + +func (br *bufWriter) Write(in []byte) (int, error) { + n, err := br.w.Write(in) + br.n += n + return n, err +} + +func persistSegmentBaseToWriter(sb *SegmentBase, w io.Writer) (int, error) { + br := &bufWriter{w: bufio.NewWriter(w)} + + _, err := br.Write(sb.mem) + if err != nil { + return 0, err + } + + err = persistFooter(sb.numDocs, sb.storedIndexOffset, sb.fieldsIndexOffset, + sb.docValueOffset, sb.chunkFactor, sb.memCRC, br) + if err != nil { + return 0, err + } + + err = br.w.Flush() + if err != nil { + return 0, err + } + + return br.n, nil +} + +func persistStoredFieldValues(fieldID int, + storedFieldValues [][]byte, stf []byte, spf [][]uint64, + curr int, metaEncode varintEncoder, data []byte) ( + int, []byte, error) { + for i := 0; i < len(storedFieldValues); i++ { + // encode field + _, err := metaEncode(uint64(fieldID)) + if err != nil { + return 0, nil, err + } + // encode type + _, err = metaEncode(uint64(stf[i])) + if err != nil { + return 0, nil, err + } + // encode start offset + _, err = metaEncode(uint64(curr)) + if err != nil { + return 0, nil, err + } + // end len + _, err = metaEncode(uint64(len(storedFieldValues[i]))) + if err != nil { + return 0, nil, err + } + // encode number of array pos + _, err = metaEncode(uint64(len(spf[i]))) + if err != nil { + return 0, nil, err + } + // encode all array positions + for _, pos := range spf[i] { + _, err = metaEncode(pos) + if err != nil { + return 0, nil, err + } + } + + data = append(data, storedFieldValues[i]...) + curr += len(storedFieldValues[i]) + } + + return curr, data, nil +} + +func InitSegmentBase(mem []byte, memCRC uint32, chunkFactor uint32, + fieldsMap map[string]uint16, fieldsInv []string, numDocs uint64, + storedIndexOffset uint64, fieldsIndexOffset uint64, docValueOffset uint64, + dictLocs []uint64) (*SegmentBase, error) { + sb := &SegmentBase{ + mem: mem, + memCRC: memCRC, + chunkFactor: chunkFactor, + fieldsMap: fieldsMap, + fieldsInv: fieldsInv, + numDocs: numDocs, + storedIndexOffset: storedIndexOffset, + fieldsIndexOffset: fieldsIndexOffset, + docValueOffset: docValueOffset, + dictLocs: dictLocs, + fieldDvReaders: make(map[uint16]*docValueReader), + fieldFSTs: make(map[uint16]*vellum.FST), + } + sb.updateSize() + + err := sb.loadDvReaders() + if err != nil { + return nil, err + } + + return sb, nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/contentcoder.go b/backend/vendor/github.com/blevesearch/zapx/v11/contentcoder.go new file mode 100644 index 0000000000..b9ff8179b3 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/contentcoder.go @@ -0,0 +1,230 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "io" + "reflect" + + "github.com/golang/snappy" +) + +var reflectStaticSizeMetaData int + +func init() { + var md MetaData + reflectStaticSizeMetaData = int(reflect.TypeOf(md).Size()) +} + +var termSeparator byte = 0xff +var termSeparatorSplitSlice = []byte{termSeparator} + +type chunkedContentCoder struct { + final []byte + chunkSize uint64 + currChunk uint64 + chunkLens []uint64 + + w io.Writer + progressiveWrite bool + + chunkMetaBuf bytes.Buffer + chunkBuf bytes.Buffer + + chunkMeta []MetaData + + compressed []byte // temp buf for snappy compression +} + +// MetaData represents the data information inside a +// chunk. +type MetaData struct { + DocNum uint64 // docNum of the data inside the chunk + DocDvOffset uint64 // offset of data inside the chunk for the given docid +} + +// newChunkedContentCoder returns a new chunk content coder which +// packs data into chunks based on the provided chunkSize +func newChunkedContentCoder(chunkSize uint64, maxDocNum uint64, + w io.Writer, progressiveWrite bool) *chunkedContentCoder { + total := maxDocNum/chunkSize + 1 + rv := &chunkedContentCoder{ + chunkSize: chunkSize, + chunkLens: make([]uint64, total), + chunkMeta: make([]MetaData, 0, total), + w: w, + progressiveWrite: progressiveWrite, + } + + return rv +} + +// Reset lets you reuse this chunked content coder. Buffers are reset +// and re used. You cannot change the chunk size. +func (c *chunkedContentCoder) Reset() { + c.currChunk = 0 + c.final = c.final[:0] + c.chunkBuf.Reset() + c.chunkMetaBuf.Reset() + for i := range c.chunkLens { + c.chunkLens[i] = 0 + } + c.chunkMeta = c.chunkMeta[:0] +} + +// Close indicates you are done calling Add() this allows +// the final chunk to be encoded. +func (c *chunkedContentCoder) Close() error { + return c.flushContents() +} + +func (c *chunkedContentCoder) flushContents() error { + // flush the contents, with meta information at first + buf := make([]byte, binary.MaxVarintLen64) + n := binary.PutUvarint(buf, uint64(len(c.chunkMeta))) + _, err := c.chunkMetaBuf.Write(buf[:n]) + if err != nil { + return err + } + + // write out the metaData slice + for _, meta := range c.chunkMeta { + _, err := writeUvarints(&c.chunkMetaBuf, meta.DocNum, meta.DocDvOffset) + if err != nil { + return err + } + } + + // write the metadata to final data + metaData := c.chunkMetaBuf.Bytes() + c.final = append(c.final, c.chunkMetaBuf.Bytes()...) + // write the compressed data to the final data + c.compressed = snappy.Encode(c.compressed[:cap(c.compressed)], c.chunkBuf.Bytes()) + c.final = append(c.final, c.compressed...) + + c.chunkLens[c.currChunk] = uint64(len(c.compressed) + len(metaData)) + + if c.progressiveWrite { + _, err := c.w.Write(c.final) + if err != nil { + return err + } + c.final = c.final[:0] + } + + return nil +} + +// Add encodes the provided byte slice into the correct chunk for the provided +// doc num. You MUST call Add() with increasing docNums. +func (c *chunkedContentCoder) Add(docNum uint64, vals []byte) error { + chunk := docNum / c.chunkSize + if chunk != c.currChunk { + // flush out the previous chunk details + err := c.flushContents() + if err != nil { + return err + } + // clearing the chunk specific meta for next chunk + c.chunkBuf.Reset() + c.chunkMetaBuf.Reset() + c.chunkMeta = c.chunkMeta[:0] + c.currChunk = chunk + } + + // get the starting offset for this doc + dvOffset := c.chunkBuf.Len() + dvSize, err := c.chunkBuf.Write(vals) + if err != nil { + return err + } + + c.chunkMeta = append(c.chunkMeta, MetaData{ + DocNum: docNum, + DocDvOffset: uint64(dvOffset + dvSize), + }) + return nil +} + +// Write commits all the encoded chunked contents to the provided writer. +// +// | ..... data ..... | chunk offsets (varints) +// | position of chunk offsets (uint64) | number of offsets (uint64) | +// +func (c *chunkedContentCoder) Write() (int, error) { + var tw int + + if c.final != nil { + // write out the data section first + nw, err := c.w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + } + + chunkOffsetsStart := uint64(tw) + + if cap(c.final) < binary.MaxVarintLen64 { + c.final = make([]byte, binary.MaxVarintLen64) + } else { + c.final = c.final[0:binary.MaxVarintLen64] + } + chunkOffsets := modifyLengthsToEndOffsets(c.chunkLens) + // write out the chunk offsets + for _, chunkOffset := range chunkOffsets { + n := binary.PutUvarint(c.final, chunkOffset) + nw, err := c.w.Write(c.final[:n]) + tw += nw + if err != nil { + return tw, err + } + } + + chunkOffsetsLen := uint64(tw) - chunkOffsetsStart + + c.final = c.final[0:8] + // write out the length of chunk offsets + binary.BigEndian.PutUint64(c.final, chunkOffsetsLen) + nw, err := c.w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + + // write out the number of chunks + binary.BigEndian.PutUint64(c.final, uint64(len(c.chunkLens))) + nw, err = c.w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + + c.final = c.final[:0] + + return tw, nil +} + +// ReadDocValueBoundary elicits the start, end offsets from a +// metaData header slice +func ReadDocValueBoundary(chunk int, metaHeaders []MetaData) (uint64, uint64) { + var start uint64 + if chunk > 0 { + start = metaHeaders[chunk-1].DocDvOffset + } + return start, metaHeaders[chunk].DocDvOffset +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/count.go b/backend/vendor/github.com/blevesearch/zapx/v11/count.go new file mode 100644 index 0000000000..b6135359fb --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/count.go @@ -0,0 +1,61 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "hash/crc32" + "io" + + segment "github.com/blevesearch/scorch_segment_api/v2" +) + +// CountHashWriter is a wrapper around a Writer which counts the number of +// bytes which have been written and computes a crc32 hash +type CountHashWriter struct { + w io.Writer + crc uint32 + n int + s segment.StatsReporter +} + +// NewCountHashWriter returns a CountHashWriter which wraps the provided Writer +func NewCountHashWriter(w io.Writer) *CountHashWriter { + return &CountHashWriter{w: w} +} + +func NewCountHashWriterWithStatsReporter(w io.Writer, s segment.StatsReporter) *CountHashWriter { + return &CountHashWriter{w: w, s: s} +} + +// Write writes the provided bytes to the wrapped writer and counts the bytes +func (c *CountHashWriter) Write(b []byte) (int, error) { + n, err := c.w.Write(b) + c.crc = crc32.Update(c.crc, crc32.IEEETable, b[:n]) + c.n += n + if c.s != nil { + c.s.ReportBytesWritten(uint64(n)) + } + return n, err +} + +// Count returns the number of bytes written +func (c *CountHashWriter) Count() int { + return c.n +} + +// Sum32 returns the CRC-32 hash of the content written to this writer +func (c *CountHashWriter) Sum32() uint32 { + return c.crc +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/dict.go b/backend/vendor/github.com/blevesearch/zapx/v11/dict.go new file mode 100644 index 0000000000..e30bf2420d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/dict.go @@ -0,0 +1,158 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "fmt" + + "github.com/RoaringBitmap/roaring" + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" +) + +// Dictionary is the zap representation of the term dictionary +type Dictionary struct { + sb *SegmentBase + field string + fieldID uint16 + fst *vellum.FST + fstReader *vellum.Reader +} + +// represents an immutable, empty dictionary +var emptyDictionary = &Dictionary{} + +// PostingsList returns the postings list for the specified term +func (d *Dictionary) PostingsList(term []byte, except *roaring.Bitmap, + prealloc segment.PostingsList) (segment.PostingsList, error) { + var preallocPL *PostingsList + pl, ok := prealloc.(*PostingsList) + if ok && pl != nil { + preallocPL = pl + } + return d.postingsList(term, except, preallocPL) +} + +func (d *Dictionary) postingsList(term []byte, except *roaring.Bitmap, rv *PostingsList) (*PostingsList, error) { + if d.fstReader == nil { + if rv == nil || rv == emptyPostingsList { + return emptyPostingsList, nil + } + return d.postingsListInit(rv, except), nil + } + + postingsOffset, exists, err := d.fstReader.Get(term) + if err != nil { + return nil, fmt.Errorf("vellum err: %v", err) + } + if !exists { + if rv == nil || rv == emptyPostingsList { + return emptyPostingsList, nil + } + return d.postingsListInit(rv, except), nil + } + + return d.postingsListFromOffset(postingsOffset, except, rv) +} + +func (d *Dictionary) postingsListFromOffset(postingsOffset uint64, except *roaring.Bitmap, rv *PostingsList) (*PostingsList, error) { + rv = d.postingsListInit(rv, except) + + err := rv.read(postingsOffset, d) + if err != nil { + return nil, err + } + + return rv, nil +} + +func (d *Dictionary) postingsListInit(rv *PostingsList, except *roaring.Bitmap) *PostingsList { + if rv == nil || rv == emptyPostingsList { + rv = &PostingsList{} + } else { + postings := rv.postings + if postings != nil { + postings.Clear() + } + + *rv = PostingsList{} // clear the struct + + rv.postings = postings + } + rv.sb = d.sb + rv.except = except + return rv +} + +func (d *Dictionary) Contains(key []byte) (bool, error) { + if d.fst != nil { + return d.fst.Contains(key) + } + return false, nil +} + +// AutomatonIterator returns an iterator which only visits terms +// having the the vellum automaton and start/end key range +func (d *Dictionary) AutomatonIterator(a segment.Automaton, + startKeyInclusive, endKeyExclusive []byte) segment.DictionaryIterator { + if d.fst != nil { + rv := &DictionaryIterator{ + d: d, + } + + itr, err := d.fst.Search(a, startKeyInclusive, endKeyExclusive) + if err == nil { + rv.itr = itr + } else if err != vellum.ErrIteratorDone { + rv.err = err + } + + return rv + } + return emptyDictionaryIterator +} + +// DictionaryIterator is an iterator for term dictionary +type DictionaryIterator struct { + d *Dictionary + itr vellum.Iterator + err error + tmp PostingsList + entry index.DictEntry + omitCount bool +} + +var emptyDictionaryIterator = &DictionaryIterator{} + +// Next returns the next entry in the dictionary +func (i *DictionaryIterator) Next() (*index.DictEntry, error) { + if i.err != nil && i.err != vellum.ErrIteratorDone { + return nil, i.err + } else if i.itr == nil || i.err == vellum.ErrIteratorDone { + return nil, nil + } + term, postingsOffset := i.itr.Current() + i.entry.Term = string(term) + if !i.omitCount { + i.err = i.tmp.read(postingsOffset, i.d) + if i.err != nil { + return nil, i.err + } + i.entry.Count = i.tmp.Count() + } + i.err = i.itr.Next() + return &i.entry, nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/docvalues.go b/backend/vendor/github.com/blevesearch/zapx/v11/docvalues.go new file mode 100644 index 0000000000..2f284d07c7 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/docvalues.go @@ -0,0 +1,318 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "fmt" + "math" + "reflect" + "sort" + + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/golang/snappy" +) + +var reflectStaticSizedocValueReader int + +func init() { + var dvi docValueReader + reflectStaticSizedocValueReader = int(reflect.TypeOf(dvi).Size()) +} + +type docNumTermsVisitor func(docNum uint64, terms []byte) error + +type docVisitState struct { + dvrs map[uint16]*docValueReader + segment *SegmentBase +} + +// No-op implementations for DiskStatsReporter interface. +// Supported only in v15 +func (d *docVisitState) BytesRead() uint64 { + return 0 +} + +func (d *docVisitState) BytesWritten() uint64 { + return 0 +} + +func (d *docVisitState) ResetBytesRead(val uint64) {} + +type docValueReader struct { + field string + curChunkNum uint64 + chunkOffsets []uint64 + dvDataLoc uint64 + curChunkHeader []MetaData + curChunkData []byte // compressed data cache + uncompressed []byte // temp buf for snappy decompression +} + +func (di *docValueReader) size() int { + return reflectStaticSizedocValueReader + SizeOfPtr + + len(di.field) + + len(di.chunkOffsets)*SizeOfUint64 + + len(di.curChunkHeader)*reflectStaticSizeMetaData + + len(di.curChunkData) +} + +func (di *docValueReader) cloneInto(rv *docValueReader) *docValueReader { + if rv == nil { + rv = &docValueReader{} + } + + rv.field = di.field + rv.curChunkNum = math.MaxUint64 + rv.chunkOffsets = di.chunkOffsets // immutable, so it's sharable + rv.dvDataLoc = di.dvDataLoc + rv.curChunkHeader = rv.curChunkHeader[:0] + rv.curChunkData = nil + rv.uncompressed = rv.uncompressed[:0] + + return rv +} + +func (di *docValueReader) curChunkNumber() uint64 { + return di.curChunkNum +} + +func (s *SegmentBase) loadFieldDocValueReader(field string, + fieldDvLocStart, fieldDvLocEnd uint64) (*docValueReader, error) { + // get the docValue offset for the given fields + if fieldDvLocStart == fieldNotUninverted { + // no docValues found, nothing to do + return nil, nil + } + + // read the number of chunks, and chunk offsets position + var numChunks, chunkOffsetsPosition uint64 + + if fieldDvLocEnd-fieldDvLocStart > 16 { + numChunks = binary.BigEndian.Uint64(s.mem[fieldDvLocEnd-8 : fieldDvLocEnd]) + // read the length of chunk offsets + chunkOffsetsLen := binary.BigEndian.Uint64(s.mem[fieldDvLocEnd-16 : fieldDvLocEnd-8]) + // acquire position of chunk offsets + chunkOffsetsPosition = (fieldDvLocEnd - 16) - chunkOffsetsLen + } else { + return nil, fmt.Errorf("loadFieldDocValueReader: fieldDvLoc too small: %d-%d", fieldDvLocEnd, fieldDvLocStart) + } + + fdvIter := &docValueReader{ + curChunkNum: math.MaxUint64, + field: field, + chunkOffsets: make([]uint64, int(numChunks)), + } + + // read the chunk offsets + var offset uint64 + for i := 0; i < int(numChunks); i++ { + loc, read := binary.Uvarint(s.mem[chunkOffsetsPosition+offset : chunkOffsetsPosition+offset+binary.MaxVarintLen64]) + if read <= 0 { + return nil, fmt.Errorf("corrupted chunk offset during segment load") + } + fdvIter.chunkOffsets[i] = loc + offset += uint64(read) + } + + // set the data offset + fdvIter.dvDataLoc = fieldDvLocStart + + return fdvIter, nil +} + +func (di *docValueReader) loadDvChunk(chunkNumber uint64, s *SegmentBase) error { + // advance to the chunk where the docValues + // reside for the given docNum + destChunkDataLoc, curChunkEnd := di.dvDataLoc, di.dvDataLoc + start, end := readChunkBoundary(int(chunkNumber), di.chunkOffsets) + if start >= end { + di.curChunkHeader = di.curChunkHeader[:0] + di.curChunkData = nil + di.curChunkNum = chunkNumber + di.uncompressed = di.uncompressed[:0] + return nil + } + + destChunkDataLoc += start + curChunkEnd += end + + // read the number of docs reside in the chunk + numDocs, read := binary.Uvarint(s.mem[destChunkDataLoc : destChunkDataLoc+binary.MaxVarintLen64]) + if read <= 0 { + return fmt.Errorf("failed to read the chunk") + } + chunkMetaLoc := destChunkDataLoc + uint64(read) + + offset := uint64(0) + if cap(di.curChunkHeader) < int(numDocs) { + di.curChunkHeader = make([]MetaData, int(numDocs)) + } else { + di.curChunkHeader = di.curChunkHeader[:int(numDocs)] + } + for i := 0; i < int(numDocs); i++ { + di.curChunkHeader[i].DocNum, read = binary.Uvarint(s.mem[chunkMetaLoc+offset : chunkMetaLoc+offset+binary.MaxVarintLen64]) + offset += uint64(read) + di.curChunkHeader[i].DocDvOffset, read = binary.Uvarint(s.mem[chunkMetaLoc+offset : chunkMetaLoc+offset+binary.MaxVarintLen64]) + offset += uint64(read) + } + + compressedDataLoc := chunkMetaLoc + offset + dataLength := curChunkEnd - compressedDataLoc + di.curChunkData = s.mem[compressedDataLoc : compressedDataLoc+dataLength] + di.curChunkNum = chunkNumber + di.uncompressed = di.uncompressed[:0] + return nil +} + +func (di *docValueReader) iterateAllDocValues(s *SegmentBase, visitor docNumTermsVisitor) error { + for i := 0; i < len(di.chunkOffsets); i++ { + err := di.loadDvChunk(uint64(i), s) + if err != nil { + return err + } + if di.curChunkData == nil || len(di.curChunkHeader) == 0 { + continue + } + + // uncompress the already loaded data + uncompressed, err := snappy.Decode(di.uncompressed[:cap(di.uncompressed)], di.curChunkData) + if err != nil { + return err + } + di.uncompressed = uncompressed + + start := uint64(0) + for _, entry := range di.curChunkHeader { + err = visitor(entry.DocNum, uncompressed[start:entry.DocDvOffset]) + if err != nil { + return err + } + + start = entry.DocDvOffset + } + } + + return nil +} + +func (di *docValueReader) visitDocValues(docNum uint64, + visitor index.DocValueVisitor) error { + // binary search the term locations for the docNum + start, end := di.getDocValueLocs(docNum) + if start == math.MaxUint64 || end == math.MaxUint64 || start == end { + return nil + } + + var uncompressed []byte + var err error + // use the uncompressed copy if available + if len(di.uncompressed) > 0 { + uncompressed = di.uncompressed + } else { + // uncompress the already loaded data + uncompressed, err = snappy.Decode(di.uncompressed[:cap(di.uncompressed)], di.curChunkData) + if err != nil { + return err + } + di.uncompressed = uncompressed + } + + // pick the terms for the given docNum + uncompressed = uncompressed[start:end] + for { + i := bytes.Index(uncompressed, termSeparatorSplitSlice) + if i < 0 { + break + } + + visitor(di.field, uncompressed[0:i]) + uncompressed = uncompressed[i+1:] + } + + return nil +} + +func (di *docValueReader) getDocValueLocs(docNum uint64) (uint64, uint64) { + i := sort.Search(len(di.curChunkHeader), func(i int) bool { + return di.curChunkHeader[i].DocNum >= docNum + }) + if i < len(di.curChunkHeader) && di.curChunkHeader[i].DocNum == docNum { + return ReadDocValueBoundary(i, di.curChunkHeader) + } + return math.MaxUint64, math.MaxUint64 +} + +// VisitDocValues is an implementation of the +// DocValueVisitable interface +func (s *SegmentBase) VisitDocValues(localDocNum uint64, fields []string, + visitor index.DocValueVisitor, dvsIn segment.DocVisitState) ( + segment.DocVisitState, error) { + dvs, ok := dvsIn.(*docVisitState) + if !ok || dvs == nil { + dvs = &docVisitState{} + } else { + if dvs.segment != s { + dvs.segment = s + dvs.dvrs = nil + } + } + + var fieldIDPlus1 uint16 + if dvs.dvrs == nil { + dvs.dvrs = make(map[uint16]*docValueReader, len(fields)) + for _, field := range fields { + if fieldIDPlus1, ok = s.fieldsMap[field]; !ok { + continue + } + fieldID := fieldIDPlus1 - 1 + if dvIter, exists := s.fieldDvReaders[fieldID]; exists && + dvIter != nil { + dvs.dvrs[fieldID] = dvIter.cloneInto(dvs.dvrs[fieldID]) + } + } + } + + // find the chunkNumber where the docValues are stored + docInChunk := localDocNum / uint64(s.chunkFactor) + var dvr *docValueReader + for _, field := range fields { + if fieldIDPlus1, ok = s.fieldsMap[field]; !ok { + continue + } + fieldID := fieldIDPlus1 - 1 + if dvr, ok = dvs.dvrs[fieldID]; ok && dvr != nil { + // check if the chunk is already loaded + if docInChunk != dvr.curChunkNumber() { + err := dvr.loadDvChunk(docInChunk, s) + if err != nil { + return dvs, err + } + } + + _ = dvr.visitDocValues(localDocNum, visitor) + } + } + return dvs, nil +} + +// VisitableDocValueFields returns the list of fields with +// persisted doc value terms ready to be visitable using the +// VisitDocumentFieldTerms method. +func (s *SegmentBase) VisitableDocValueFields() ([]string, error) { + return s.fieldDvNames, nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/enumerator.go b/backend/vendor/github.com/blevesearch/zapx/v11/enumerator.go new file mode 100644 index 0000000000..5531d2cf1d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/enumerator.go @@ -0,0 +1,126 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + + "github.com/blevesearch/vellum" +) + +// enumerator provides an ordered traversal of multiple vellum +// iterators. Like JOIN of iterators, the enumerator produces a +// sequence of (key, iteratorIndex, value) tuples, sorted by key ASC, +// then iteratorIndex ASC, where the same key might be seen or +// repeated across multiple child iterators. +type enumerator struct { + itrs []vellum.Iterator + currKs [][]byte + currVs []uint64 + + lowK []byte + lowIdxs []int + lowCurr int +} + +// newEnumerator returns a new enumerator over the vellum Iterators +func newEnumerator(itrs []vellum.Iterator) (*enumerator, error) { + rv := &enumerator{ + itrs: itrs, + currKs: make([][]byte, len(itrs)), + currVs: make([]uint64, len(itrs)), + lowIdxs: make([]int, 0, len(itrs)), + } + for i, itr := range rv.itrs { + rv.currKs[i], rv.currVs[i] = itr.Current() + } + rv.updateMatches(false) + if rv.lowK == nil && len(rv.lowIdxs) == 0 { + return rv, vellum.ErrIteratorDone + } + return rv, nil +} + +// updateMatches maintains the low key matches based on the currKs +func (m *enumerator) updateMatches(skipEmptyKey bool) { + m.lowK = nil + m.lowIdxs = m.lowIdxs[:0] + m.lowCurr = 0 + + for i, key := range m.currKs { + if (key == nil && m.currVs[i] == 0) || // in case of empty iterator + (len(key) == 0 && skipEmptyKey) { // skip empty keys + continue + } + + cmp := bytes.Compare(key, m.lowK) + if cmp < 0 || len(m.lowIdxs) == 0 { + // reached a new low + m.lowK = key + m.lowIdxs = m.lowIdxs[:0] + m.lowIdxs = append(m.lowIdxs, i) + } else if cmp == 0 { + m.lowIdxs = append(m.lowIdxs, i) + } + } +} + +// Current returns the enumerator's current key, iterator-index, and +// value. If the enumerator is not pointing at a valid value (because +// Next returned an error previously), Current will return nil,0,0. +func (m *enumerator) Current() ([]byte, int, uint64) { + var i int + var v uint64 + if m.lowCurr < len(m.lowIdxs) { + i = m.lowIdxs[m.lowCurr] + v = m.currVs[i] + } + return m.lowK, i, v +} + +// Next advances the enumerator to the next key/iterator/value result, +// else vellum.ErrIteratorDone is returned. +func (m *enumerator) Next() error { + m.lowCurr += 1 + if m.lowCurr >= len(m.lowIdxs) { + // move all the current low iterators forwards + for _, vi := range m.lowIdxs { + err := m.itrs[vi].Next() + if err != nil && err != vellum.ErrIteratorDone { + return err + } + m.currKs[vi], m.currVs[vi] = m.itrs[vi].Current() + } + // can skip any empty keys encountered at this point + m.updateMatches(true) + } + if m.lowK == nil && len(m.lowIdxs) == 0 { + return vellum.ErrIteratorDone + } + return nil +} + +// Close all the underlying Iterators. The first error, if any, will +// be returned. +func (m *enumerator) Close() error { + var rv error + for _, itr := range m.itrs { + err := itr.Close() + if rv == nil { + rv = err + } + } + return rv +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/intcoder.go b/backend/vendor/github.com/blevesearch/zapx/v11/intcoder.go new file mode 100644 index 0000000000..571d06edb6 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/intcoder.go @@ -0,0 +1,172 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "io" +) + +type chunkedIntCoder struct { + final []byte + chunkSize uint64 + chunkBuf bytes.Buffer + chunkLens []uint64 + currChunk uint64 + + buf []byte +} + +// newChunkedIntCoder returns a new chunk int coder which packs data into +// chunks based on the provided chunkSize and supports up to the specified +// maxDocNum +func newChunkedIntCoder(chunkSize uint64, maxDocNum uint64) *chunkedIntCoder { + total := maxDocNum/chunkSize + 1 + rv := &chunkedIntCoder{ + chunkSize: chunkSize, + chunkLens: make([]uint64, total), + final: make([]byte, 0, 64), + } + + return rv +} + +// Reset lets you reuse this chunked int coder. buffers are reset and reused +// from previous use. you cannot change the chunk size or max doc num. +func (c *chunkedIntCoder) Reset() { + c.final = c.final[:0] + c.chunkBuf.Reset() + c.currChunk = 0 + for i := range c.chunkLens { + c.chunkLens[i] = 0 + } +} + +// Add encodes the provided integers into the correct chunk for the provided +// doc num. You MUST call Add() with increasing docNums. +func (c *chunkedIntCoder) Add(docNum uint64, vals ...uint64) error { + chunk := docNum / c.chunkSize + if chunk != c.currChunk { + // starting a new chunk + c.Close() + c.chunkBuf.Reset() + c.currChunk = chunk + } + + if len(c.buf) < binary.MaxVarintLen64 { + c.buf = make([]byte, binary.MaxVarintLen64) + } + + for _, val := range vals { + wb := binary.PutUvarint(c.buf, val) + _, err := c.chunkBuf.Write(c.buf[:wb]) + if err != nil { + return err + } + } + + return nil +} + +func (c *chunkedIntCoder) AddBytes(docNum uint64, buf []byte) error { + chunk := docNum / c.chunkSize + if chunk != c.currChunk { + // starting a new chunk + c.Close() + c.chunkBuf.Reset() + c.currChunk = chunk + } + + _, err := c.chunkBuf.Write(buf) + return err +} + +// Close indicates you are done calling Add() this allows the final chunk +// to be encoded. +func (c *chunkedIntCoder) Close() { + encodingBytes := c.chunkBuf.Bytes() + c.chunkLens[c.currChunk] = uint64(len(encodingBytes)) + c.final = append(c.final, encodingBytes...) + c.currChunk = uint64(cap(c.chunkLens)) // sentinel to detect double close +} + +// Write commits all the encoded chunked integers to the provided writer. +func (c *chunkedIntCoder) Write(w io.Writer) (int, error) { + bufNeeded := binary.MaxVarintLen64 * (1 + len(c.chunkLens)) + if len(c.buf) < bufNeeded { + c.buf = make([]byte, bufNeeded) + } + buf := c.buf + + // convert the chunk lengths into chunk offsets + chunkOffsets := modifyLengthsToEndOffsets(c.chunkLens) + + // write out the number of chunks & each chunk offsets + n := binary.PutUvarint(buf, uint64(len(chunkOffsets))) + for _, chunkOffset := range chunkOffsets { + n += binary.PutUvarint(buf[n:], chunkOffset) + } + + tw, err := w.Write(buf[:n]) + if err != nil { + return tw, err + } + + // write out the data + nw, err := w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + return tw, nil +} + +func (c *chunkedIntCoder) FinalSize() int { + return len(c.final) +} + +// modifyLengthsToEndOffsets converts the chunk length array +// to a chunk offset array. The readChunkBoundary +// will figure out the start and end of every chunk from +// these offsets. Starting offset of i'th index is stored +// in i-1'th position except for 0'th index and ending offset +// is stored at i'th index position. +// For 0'th element, starting position is always zero. +// eg: +// Lens -> 5 5 5 5 => 5 10 15 20 +// Lens -> 0 5 0 5 => 0 5 5 10 +// Lens -> 0 0 0 5 => 0 0 0 5 +// Lens -> 5 0 0 0 => 5 5 5 5 +// Lens -> 0 5 0 0 => 0 5 5 5 +// Lens -> 0 0 5 0 => 0 0 5 5 +func modifyLengthsToEndOffsets(lengths []uint64) []uint64 { + var runningOffset uint64 + var index, i int + for i = 1; i <= len(lengths); i++ { + runningOffset += lengths[i-1] + lengths[index] = runningOffset + index++ + } + return lengths +} + +func readChunkBoundary(chunk int, offsets []uint64) (uint64, uint64) { + var start uint64 + if chunk > 0 { + start = offsets[chunk-1] + } + return start, offsets[chunk] +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/memuvarint.go b/backend/vendor/github.com/blevesearch/zapx/v11/memuvarint.go new file mode 100644 index 0000000000..48a57f9c85 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/memuvarint.go @@ -0,0 +1,103 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "fmt" +) + +type memUvarintReader struct { + C int // index of next byte to read from S + S []byte +} + +func newMemUvarintReader(s []byte) *memUvarintReader { + return &memUvarintReader{S: s} +} + +// Len returns the number of unread bytes. +func (r *memUvarintReader) Len() int { + n := len(r.S) - r.C + if n < 0 { + return 0 + } + return n +} + +// ReadUvarint reads an encoded uint64. The original code this was +// based on is at encoding/binary/ReadUvarint(). +func (r *memUvarintReader) ReadUvarint() (uint64, error) { + if r.C >= len(r.S) { + // nothing else to read + return 0, nil + } + + var x uint64 + var s uint + var C = r.C + var S = r.S + + for { + b := S[C] + C++ + + if b < 0x80 { + r.C = C + + // why 63? The original code had an 'i += 1' loop var and + // checked for i > 9 || i == 9 ...; but, we no longer + // check for the i var, but instead check here for s, + // which is incremented by 7. So, 7*9 == 63. + // + // why the "extra" >= check? The normal case is that s < + // 63, so we check this single >= guard first so that we + // hit the normal, nil-error return pathway sooner. + if s >= 63 && (s > 63 || b > 1) { + return 0, fmt.Errorf("memUvarintReader overflow") + } + + return x | uint64(b)<= len(r.S) { + return + } + + b := r.S[r.C] + r.C++ + + if b < 0x80 { + return + } + } +} + +// SkipBytes skips a count number of bytes. +func (r *memUvarintReader) SkipBytes(count int) { + r.C = r.C + count +} + +func (r *memUvarintReader) Reset(s []byte) { + r.C = 0 + r.S = s +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/merge.go b/backend/vendor/github.com/blevesearch/zapx/v11/merge.go new file mode 100644 index 0000000000..f0770e990b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/merge.go @@ -0,0 +1,856 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bufio" + "bytes" + "encoding/binary" + "fmt" + "math" + "os" + "sort" + + "github.com/RoaringBitmap/roaring" + seg "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" + "github.com/golang/snappy" +) + +var DefaultFileMergerBufferSize = 1024 * 1024 + +const docDropped = math.MaxUint64 // sentinel docNum to represent a deleted doc + +// Merge takes a slice of segments and bit masks describing which +// documents may be dropped, and creates a new segment containing the +// remaining data. This new segment is built at the specified path. +func (*ZapPlugin) Merge(segments []seg.Segment, drops []*roaring.Bitmap, path string, + closeCh chan struct{}, s seg.StatsReporter) ( + [][]uint64, uint64, error) { + segmentBases := make([]*SegmentBase, len(segments)) + for segmenti, segment := range segments { + switch segmentx := segment.(type) { + case *Segment: + segmentBases[segmenti] = &segmentx.SegmentBase + case *SegmentBase: + segmentBases[segmenti] = segmentx + default: + panic(fmt.Sprintf("oops, unexpected segment type: %T", segment)) + } + } + return mergeSegmentBases(segmentBases, drops, path, defaultChunkFactor, closeCh, s) +} + +func mergeSegmentBases(segmentBases []*SegmentBase, drops []*roaring.Bitmap, path string, + chunkFactor uint32, closeCh chan struct{}, s seg.StatsReporter) ( + [][]uint64, uint64, error) { + flag := os.O_RDWR | os.O_CREATE + + f, err := os.OpenFile(path, flag, 0600) + if err != nil { + return nil, 0, err + } + + cleanup := func() { + _ = f.Close() + _ = os.Remove(path) + } + + // buffer the output + br := bufio.NewWriterSize(f, DefaultFileMergerBufferSize) + + // wrap it for counting (tracking offsets) + cr := NewCountHashWriterWithStatsReporter(br, s) + + newDocNums, numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset, _, _, _, err := + MergeToWriter(segmentBases, drops, chunkFactor, cr, closeCh) + if err != nil { + cleanup() + return nil, 0, err + } + + err = persistFooter(numDocs, storedIndexOffset, fieldsIndexOffset, + docValueOffset, chunkFactor, cr.Sum32(), cr) + if err != nil { + cleanup() + return nil, 0, err + } + + err = br.Flush() + if err != nil { + cleanup() + return nil, 0, err + } + + err = f.Sync() + if err != nil { + cleanup() + return nil, 0, err + } + + err = f.Close() + if err != nil { + cleanup() + return nil, 0, err + } + + return newDocNums, uint64(cr.Count()), nil +} + +func MergeToWriter(segments []*SegmentBase, drops []*roaring.Bitmap, + chunkFactor uint32, cr *CountHashWriter, closeCh chan struct{}) ( + newDocNums [][]uint64, + numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset uint64, + dictLocs []uint64, fieldsInv []string, fieldsMap map[string]uint16, + err error) { + docValueOffset = uint64(fieldNotUninverted) + + var fieldsSame bool + fieldsSame, fieldsInv = mergeFields(segments) + fieldsMap = mapFields(fieldsInv) + + numDocs = computeNewDocCount(segments, drops) + + if isClosed(closeCh) { + return nil, 0, 0, 0, 0, nil, nil, nil, seg.ErrClosed + } + + if numDocs > 0 { + storedIndexOffset, newDocNums, err = mergeStoredAndRemap(segments, drops, + fieldsMap, fieldsInv, fieldsSame, numDocs, cr, closeCh) + if err != nil { + return nil, 0, 0, 0, 0, nil, nil, nil, err + } + + dictLocs, docValueOffset, err = persistMergedRest(segments, drops, + fieldsInv, fieldsMap, fieldsSame, + newDocNums, numDocs, chunkFactor, cr, closeCh) + if err != nil { + return nil, 0, 0, 0, 0, nil, nil, nil, err + } + } else { + dictLocs = make([]uint64, len(fieldsInv)) + } + + fieldsIndexOffset, err = persistFields(fieldsInv, cr, dictLocs) + if err != nil { + return nil, 0, 0, 0, 0, nil, nil, nil, err + } + + return newDocNums, numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset, dictLocs, fieldsInv, fieldsMap, nil +} + +// mapFields takes the fieldsInv list and returns a map of fieldName +// to fieldID+1 +func mapFields(fields []string) map[string]uint16 { + rv := make(map[string]uint16, len(fields)) + for i, fieldName := range fields { + rv[fieldName] = uint16(i) + 1 + } + return rv +} + +// computeNewDocCount determines how many documents will be in the newly +// merged segment when obsoleted docs are dropped +func computeNewDocCount(segments []*SegmentBase, drops []*roaring.Bitmap) uint64 { + var newDocCount uint64 + for segI, segment := range segments { + newDocCount += segment.numDocs + if drops[segI] != nil { + newDocCount -= drops[segI].GetCardinality() + } + } + return newDocCount +} + +func persistMergedRest(segments []*SegmentBase, dropsIn []*roaring.Bitmap, + fieldsInv []string, fieldsMap map[string]uint16, fieldsSame bool, + newDocNumsIn [][]uint64, newSegDocCount uint64, chunkFactor uint32, + w *CountHashWriter, closeCh chan struct{}) ([]uint64, uint64, error) { + var bufMaxVarintLen64 []byte = make([]byte, binary.MaxVarintLen64) + var bufLoc []uint64 + + var postings *PostingsList + var postItr *PostingsIterator + + rv := make([]uint64, len(fieldsInv)) + fieldDvLocsStart := make([]uint64, len(fieldsInv)) + fieldDvLocsEnd := make([]uint64, len(fieldsInv)) + + tfEncoder := newChunkedIntCoder(uint64(chunkFactor), newSegDocCount-1) + locEncoder := newChunkedIntCoder(uint64(chunkFactor), newSegDocCount-1) + + var vellumBuf bytes.Buffer + newVellum, err := vellum.New(&vellumBuf, nil) + if err != nil { + return nil, 0, err + } + + newRoaring := roaring.NewBitmap() + + // for each field + for fieldID, fieldName := range fieldsInv { + // collect FST iterators from all active segments for this field + var newDocNums [][]uint64 + var drops []*roaring.Bitmap + var dicts []*Dictionary + var itrs []vellum.Iterator + + var segmentsInFocus []*SegmentBase + + for segmentI, segment := range segments { + // check for the closure in meantime + if isClosed(closeCh) { + return nil, 0, seg.ErrClosed + } + + dict, err2 := segment.dictionary(fieldName) + if err2 != nil { + return nil, 0, err2 + } + if dict != nil && dict.fst != nil { + itr, err2 := dict.fst.Iterator(nil, nil) + if err2 != nil && err2 != vellum.ErrIteratorDone { + return nil, 0, err2 + } + if itr != nil { + newDocNums = append(newDocNums, newDocNumsIn[segmentI]) + if dropsIn[segmentI] != nil && !dropsIn[segmentI].IsEmpty() { + drops = append(drops, dropsIn[segmentI]) + } else { + drops = append(drops, nil) + } + dicts = append(dicts, dict) + itrs = append(itrs, itr) + segmentsInFocus = append(segmentsInFocus, segment) + } + } + } + + var prevTerm []byte + + newRoaring.Clear() + + var lastDocNum, lastFreq, lastNorm uint64 + + // determines whether to use "1-hit" encoding optimization + // when a term appears in only 1 doc, with no loc info, + // has freq of 1, and the docNum fits into 31-bits + use1HitEncoding := func(termCardinality uint64) (bool, uint64, uint64) { + if termCardinality == uint64(1) && locEncoder.FinalSize() <= 0 { + docNum := uint64(newRoaring.Minimum()) + if under32Bits(docNum) && docNum == lastDocNum && lastFreq == 1 { + return true, docNum, lastNorm + } + } + return false, 0, 0 + } + + finishTerm := func(term []byte) error { + tfEncoder.Close() + locEncoder.Close() + + postingsOffset, err := writePostings(newRoaring, + tfEncoder, locEncoder, use1HitEncoding, w, bufMaxVarintLen64) + if err != nil { + return err + } + + if postingsOffset > 0 { + err = newVellum.Insert(term, postingsOffset) + if err != nil { + return err + } + } + + newRoaring.Clear() + + tfEncoder.Reset() + locEncoder.Reset() + + lastDocNum = 0 + lastFreq = 0 + lastNorm = 0 + + return nil + } + + enumerator, err := newEnumerator(itrs) + + for err == nil { + term, itrI, postingsOffset := enumerator.Current() + + if !bytes.Equal(prevTerm, term) { + // check for the closure in meantime + if isClosed(closeCh) { + return nil, 0, seg.ErrClosed + } + + // if the term changed, write out the info collected + // for the previous term + err = finishTerm(prevTerm) + if err != nil { + return nil, 0, err + } + } + + postings, err = dicts[itrI].postingsListFromOffset( + postingsOffset, drops[itrI], postings) + if err != nil { + return nil, 0, err + } + + postItr = postings.iterator(true, true, true, postItr) + + if fieldsSame { + // can optimize by copying freq/norm/loc bytes directly + lastDocNum, lastFreq, lastNorm, err = mergeTermFreqNormLocsByCopying( + term, postItr, newDocNums[itrI], newRoaring, + tfEncoder, locEncoder) + } else { + lastDocNum, lastFreq, lastNorm, bufLoc, err = mergeTermFreqNormLocs( + fieldsMap, term, postItr, newDocNums[itrI], newRoaring, + tfEncoder, locEncoder, bufLoc) + } + if err != nil { + return nil, 0, err + } + + prevTerm = prevTerm[:0] // copy to prevTerm in case Next() reuses term mem + prevTerm = append(prevTerm, term...) + + err = enumerator.Next() + } + if err != vellum.ErrIteratorDone { + return nil, 0, err + } + + err = finishTerm(prevTerm) + if err != nil { + return nil, 0, err + } + + dictOffset := uint64(w.Count()) + + err = newVellum.Close() + if err != nil { + return nil, 0, err + } + vellumData := vellumBuf.Bytes() + + // write out the length of the vellum data + n := binary.PutUvarint(bufMaxVarintLen64, uint64(len(vellumData))) + _, err = w.Write(bufMaxVarintLen64[:n]) + if err != nil { + return nil, 0, err + } + + // write this vellum to disk + _, err = w.Write(vellumData) + if err != nil { + return nil, 0, err + } + + rv[fieldID] = dictOffset + + // get the field doc value offset (start) + fieldDvLocsStart[fieldID] = uint64(w.Count()) + + // update the field doc values + fdvEncoder := newChunkedContentCoder(uint64(chunkFactor), newSegDocCount-1, w, true) + + fdvReadersAvailable := false + var dvIterClone *docValueReader + for segmentI, segment := range segmentsInFocus { + // check for the closure in meantime + if isClosed(closeCh) { + return nil, 0, seg.ErrClosed + } + + fieldIDPlus1 := uint16(segment.fieldsMap[fieldName]) + if dvIter, exists := segment.fieldDvReaders[fieldIDPlus1-1]; exists && + dvIter != nil { + fdvReadersAvailable = true + dvIterClone = dvIter.cloneInto(dvIterClone) + err = dvIterClone.iterateAllDocValues(segment, func(docNum uint64, terms []byte) error { + if newDocNums[segmentI][docNum] == docDropped { + return nil + } + err := fdvEncoder.Add(newDocNums[segmentI][docNum], terms) + if err != nil { + return err + } + return nil + }) + if err != nil { + return nil, 0, err + } + } + } + + if fdvReadersAvailable { + err = fdvEncoder.Close() + if err != nil { + return nil, 0, err + } + + // persist the doc value details for this field + _, err = fdvEncoder.Write() + if err != nil { + return nil, 0, err + } + + // get the field doc value offset (end) + fieldDvLocsEnd[fieldID] = uint64(w.Count()) + } else { + fieldDvLocsStart[fieldID] = fieldNotUninverted + fieldDvLocsEnd[fieldID] = fieldNotUninverted + } + + // reset vellum buffer and vellum builder + vellumBuf.Reset() + err = newVellum.Reset(&vellumBuf) + if err != nil { + return nil, 0, err + } + } + + fieldDvLocsOffset := uint64(w.Count()) + + buf := bufMaxVarintLen64 + for i := 0; i < len(fieldDvLocsStart); i++ { + n := binary.PutUvarint(buf, fieldDvLocsStart[i]) + _, err := w.Write(buf[:n]) + if err != nil { + return nil, 0, err + } + n = binary.PutUvarint(buf, fieldDvLocsEnd[i]) + _, err = w.Write(buf[:n]) + if err != nil { + return nil, 0, err + } + } + + return rv, fieldDvLocsOffset, nil +} + +func mergeTermFreqNormLocs(fieldsMap map[string]uint16, term []byte, postItr *PostingsIterator, + newDocNums []uint64, newRoaring *roaring.Bitmap, + tfEncoder *chunkedIntCoder, locEncoder *chunkedIntCoder, bufLoc []uint64) ( + lastDocNum uint64, lastFreq uint64, lastNorm uint64, bufLocOut []uint64, err error) { + next, err := postItr.Next() + for next != nil && err == nil { + hitNewDocNum := newDocNums[next.Number()] + if hitNewDocNum == docDropped { + return 0, 0, 0, nil, fmt.Errorf("see hit with dropped docNum") + } + + newRoaring.Add(uint32(hitNewDocNum)) + + nextFreq := next.Frequency() + nextNorm := uint64(math.Float32bits(float32(next.Norm()))) + + locs := next.Locations() + + err = tfEncoder.Add(hitNewDocNum, + encodeFreqHasLocs(nextFreq, len(locs) > 0), nextNorm) + if err != nil { + return 0, 0, 0, nil, err + } + + if len(locs) > 0 { + numBytesLocs := 0 + for _, loc := range locs { + ap := loc.ArrayPositions() + numBytesLocs += totalUvarintBytes(uint64(fieldsMap[loc.Field()]-1), + loc.Pos(), loc.Start(), loc.End(), uint64(len(ap)), ap) + } + + err = locEncoder.Add(hitNewDocNum, uint64(numBytesLocs)) + if err != nil { + return 0, 0, 0, nil, err + } + + for _, loc := range locs { + ap := loc.ArrayPositions() + if cap(bufLoc) < 5+len(ap) { + bufLoc = make([]uint64, 0, 5+len(ap)) + } + args := bufLoc[0:5] + args[0] = uint64(fieldsMap[loc.Field()] - 1) + args[1] = loc.Pos() + args[2] = loc.Start() + args[3] = loc.End() + args[4] = uint64(len(ap)) + args = append(args, ap...) + err = locEncoder.Add(hitNewDocNum, args...) + if err != nil { + return 0, 0, 0, nil, err + } + } + } + + lastDocNum = hitNewDocNum + lastFreq = nextFreq + lastNorm = nextNorm + + next, err = postItr.Next() + } + + return lastDocNum, lastFreq, lastNorm, bufLoc, err +} + +func mergeTermFreqNormLocsByCopying(term []byte, postItr *PostingsIterator, + newDocNums []uint64, newRoaring *roaring.Bitmap, + tfEncoder *chunkedIntCoder, locEncoder *chunkedIntCoder) ( + lastDocNum uint64, lastFreq uint64, lastNorm uint64, err error) { + nextDocNum, nextFreq, nextNorm, nextFreqNormBytes, nextLocBytes, err := + postItr.nextBytes() + for err == nil && len(nextFreqNormBytes) > 0 { + hitNewDocNum := newDocNums[nextDocNum] + if hitNewDocNum == docDropped { + return 0, 0, 0, fmt.Errorf("see hit with dropped doc num") + } + + newRoaring.Add(uint32(hitNewDocNum)) + err = tfEncoder.AddBytes(hitNewDocNum, nextFreqNormBytes) + if err != nil { + return 0, 0, 0, err + } + + if len(nextLocBytes) > 0 { + err = locEncoder.AddBytes(hitNewDocNum, nextLocBytes) + if err != nil { + return 0, 0, 0, err + } + } + + lastDocNum = hitNewDocNum + lastFreq = nextFreq + lastNorm = nextNorm + + nextDocNum, nextFreq, nextNorm, nextFreqNormBytes, nextLocBytes, err = + postItr.nextBytes() + } + + return lastDocNum, lastFreq, lastNorm, err +} + +func writePostings(postings *roaring.Bitmap, tfEncoder, locEncoder *chunkedIntCoder, + use1HitEncoding func(uint64) (bool, uint64, uint64), + w *CountHashWriter, bufMaxVarintLen64 []byte) ( + offset uint64, err error) { + termCardinality := postings.GetCardinality() + if termCardinality <= 0 { + return 0, nil + } + + if use1HitEncoding != nil { + encodeAs1Hit, docNum1Hit, normBits1Hit := use1HitEncoding(termCardinality) + if encodeAs1Hit { + return FSTValEncode1Hit(docNum1Hit, normBits1Hit), nil + } + } + + tfOffset := uint64(w.Count()) + _, err = tfEncoder.Write(w) + if err != nil { + return 0, err + } + + locOffset := uint64(w.Count()) + _, err = locEncoder.Write(w) + if err != nil { + return 0, err + } + + postingsOffset := uint64(w.Count()) + + n := binary.PutUvarint(bufMaxVarintLen64, tfOffset) + _, err = w.Write(bufMaxVarintLen64[:n]) + if err != nil { + return 0, err + } + + n = binary.PutUvarint(bufMaxVarintLen64, locOffset) + _, err = w.Write(bufMaxVarintLen64[:n]) + if err != nil { + return 0, err + } + + _, err = writeRoaringWithLen(postings, w, bufMaxVarintLen64) + if err != nil { + return 0, err + } + + return postingsOffset, nil +} + +type varintEncoder func(uint64) (int, error) + +func mergeStoredAndRemap(segments []*SegmentBase, drops []*roaring.Bitmap, + fieldsMap map[string]uint16, fieldsInv []string, fieldsSame bool, newSegDocCount uint64, + w *CountHashWriter, closeCh chan struct{}) (uint64, [][]uint64, error) { + var rv [][]uint64 // The remapped or newDocNums for each segment. + + var newDocNum uint64 + + var curr int + var data, compressed []byte + var metaBuf bytes.Buffer + varBuf := make([]byte, binary.MaxVarintLen64) + metaEncode := func(val uint64) (int, error) { + wb := binary.PutUvarint(varBuf, val) + return metaBuf.Write(varBuf[:wb]) + } + + vals := make([][][]byte, len(fieldsInv)) + typs := make([][]byte, len(fieldsInv)) + poss := make([][][]uint64, len(fieldsInv)) + + var posBuf []uint64 + + docNumOffsets := make([]uint64, newSegDocCount) + + vdc := visitDocumentCtxPool.Get().(*visitDocumentCtx) + defer visitDocumentCtxPool.Put(vdc) + + // for each segment + for segI, segment := range segments { + // check for the closure in meantime + if isClosed(closeCh) { + return 0, nil, seg.ErrClosed + } + + segNewDocNums := make([]uint64, segment.numDocs) + + dropsI := drops[segI] + + // optimize when the field mapping is the same across all + // segments and there are no deletions, via byte-copying + // of stored docs bytes directly to the writer + if fieldsSame && (dropsI == nil || dropsI.GetCardinality() == 0) { + err := segment.copyStoredDocs(newDocNum, docNumOffsets, w) + if err != nil { + return 0, nil, err + } + + for i := uint64(0); i < segment.numDocs; i++ { + segNewDocNums[i] = newDocNum + newDocNum++ + } + rv = append(rv, segNewDocNums) + + continue + } + + // for each doc num + for docNum := uint64(0); docNum < segment.numDocs; docNum++ { + // TODO: roaring's API limits docNums to 32-bits? + if dropsI != nil && dropsI.Contains(uint32(docNum)) { + segNewDocNums[docNum] = docDropped + continue + } + + segNewDocNums[docNum] = newDocNum + + curr = 0 + metaBuf.Reset() + data = data[:0] + + posTemp := posBuf + + // collect all the data + for i := 0; i < len(fieldsInv); i++ { + vals[i] = vals[i][:0] + typs[i] = typs[i][:0] + poss[i] = poss[i][:0] + } + err := segment.visitStoredFields(vdc, docNum, func(field string, typ byte, value []byte, pos []uint64) bool { + fieldID := int(fieldsMap[field]) - 1 + vals[fieldID] = append(vals[fieldID], value) + typs[fieldID] = append(typs[fieldID], typ) + + // copy array positions to preserve them beyond the scope of this callback + var curPos []uint64 + if len(pos) > 0 { + if cap(posTemp) < len(pos) { + posBuf = make([]uint64, len(pos)*len(fieldsInv)) + posTemp = posBuf + } + curPos = posTemp[0:len(pos)] + copy(curPos, pos) + posTemp = posTemp[len(pos):] + } + poss[fieldID] = append(poss[fieldID], curPos) + + return true + }) + if err != nil { + return 0, nil, err + } + + // _id field special case optimizes ExternalID() lookups + idFieldVal := vals[uint16(0)][0] + _, err = metaEncode(uint64(len(idFieldVal))) + if err != nil { + return 0, nil, err + } + + // now walk the non-"_id" fields in order + for fieldID := 1; fieldID < len(fieldsInv); fieldID++ { + storedFieldValues := vals[fieldID] + + stf := typs[fieldID] + spf := poss[fieldID] + + var err2 error + curr, data, err2 = persistStoredFieldValues(fieldID, + storedFieldValues, stf, spf, curr, metaEncode, data) + if err2 != nil { + return 0, nil, err2 + } + } + + metaBytes := metaBuf.Bytes() + + compressed = snappy.Encode(compressed[:cap(compressed)], data) + + // record where we're about to start writing + docNumOffsets[newDocNum] = uint64(w.Count()) + + // write out the meta len and compressed data len + _, err = writeUvarints(w, + uint64(len(metaBytes)), + uint64(len(idFieldVal)+len(compressed))) + if err != nil { + return 0, nil, err + } + // now write the meta + _, err = w.Write(metaBytes) + if err != nil { + return 0, nil, err + } + // now write the _id field val (counted as part of the 'compressed' data) + _, err = w.Write(idFieldVal) + if err != nil { + return 0, nil, err + } + // now write the compressed data + _, err = w.Write(compressed) + if err != nil { + return 0, nil, err + } + + newDocNum++ + } + + rv = append(rv, segNewDocNums) + } + + // return value is the start of the stored index + storedIndexOffset := uint64(w.Count()) + + // now write out the stored doc index + for _, docNumOffset := range docNumOffsets { + err := binary.Write(w, binary.BigEndian, docNumOffset) + if err != nil { + return 0, nil, err + } + } + + return storedIndexOffset, rv, nil +} + +// copyStoredDocs writes out a segment's stored doc info, optimized by +// using a single Write() call for the entire set of bytes. The +// newDocNumOffsets is filled with the new offsets for each doc. +func (s *SegmentBase) copyStoredDocs(newDocNum uint64, newDocNumOffsets []uint64, + w *CountHashWriter) error { + if s.numDocs <= 0 { + return nil + } + + indexOffset0, storedOffset0, _, _, _ := + s.getDocStoredOffsets(0) // the segment's first doc + + indexOffsetN, storedOffsetN, readN, metaLenN, dataLenN := + s.getDocStoredOffsets(s.numDocs - 1) // the segment's last doc + + storedOffset0New := uint64(w.Count()) + + storedBytes := s.mem[storedOffset0 : storedOffsetN+readN+metaLenN+dataLenN] + _, err := w.Write(storedBytes) + if err != nil { + return err + } + + // remap the storedOffset's for the docs into new offsets relative + // to storedOffset0New, filling the given docNumOffsetsOut array + for indexOffset := indexOffset0; indexOffset <= indexOffsetN; indexOffset += 8 { + storedOffset := binary.BigEndian.Uint64(s.mem[indexOffset : indexOffset+8]) + storedOffsetNew := storedOffset - storedOffset0 + storedOffset0New + newDocNumOffsets[newDocNum] = storedOffsetNew + newDocNum += 1 + } + + return nil +} + +// mergeFields builds a unified list of fields used across all the +// input segments, and computes whether the fields are the same across +// segments (which depends on fields to be sorted in the same way +// across segments) +func mergeFields(segments []*SegmentBase) (bool, []string) { + fieldsSame := true + + var segment0Fields []string + if len(segments) > 0 { + segment0Fields = segments[0].Fields() + } + + fieldsExist := map[string]struct{}{} + for _, segment := range segments { + fields := segment.Fields() + for fieldi, field := range fields { + fieldsExist[field] = struct{}{} + if len(segment0Fields) != len(fields) || segment0Fields[fieldi] != field { + fieldsSame = false + } + } + } + + rv := make([]string, 0, len(fieldsExist)) + // ensure _id stays first + rv = append(rv, "_id") + for k := range fieldsExist { + if k != "_id" { + rv = append(rv, k) + } + } + + sort.Strings(rv[1:]) // leave _id as first + + return fieldsSame, rv +} + +func isClosed(closeCh chan struct{}) bool { + select { + case <-closeCh: + return true + default: + return false + } +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/new.go b/backend/vendor/github.com/blevesearch/zapx/v11/new.go new file mode 100644 index 0000000000..4491422aa9 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/new.go @@ -0,0 +1,817 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "math" + "sort" + "sync" + + "github.com/RoaringBitmap/roaring" + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" + "github.com/golang/snappy" +) + +var NewSegmentBufferNumResultsBump int = 100 +var NewSegmentBufferNumResultsFactor float64 = 1.0 +var NewSegmentBufferAvgBytesPerDocFactor float64 = 1.0 + +// ValidateDocFields can be set by applications to perform additional checks +// on fields in a document being added to a new segment, by default it does +// nothing. +// This API is experimental and may be removed at any time. +var ValidateDocFields = func(field index.Field) error { + return nil +} + +var defaultChunkFactor uint32 = 1024 + +// New creates an in-memory zap-encoded SegmentBase from a set of Documents +func (z *ZapPlugin) New(results []index.Document) ( + segment.Segment, uint64, error) { + return z.newWithChunkFactor(results, defaultChunkFactor) +} + +func (*ZapPlugin) newWithChunkFactor(results []index.Document, + chunkFactor uint32) (segment.Segment, uint64, error) { + s := interimPool.Get().(*interim) + + var br bytes.Buffer + if s.lastNumDocs > 0 { + // use previous results to initialize the buf with an estimate + // size, but note that the interim instance comes from a + // global interimPool, so multiple scorch instances indexing + // different docs can lead to low quality estimates + estimateAvgBytesPerDoc := int(float64(s.lastOutSize/s.lastNumDocs) * + NewSegmentBufferNumResultsFactor) + estimateNumResults := int(float64(len(results)+NewSegmentBufferNumResultsBump) * + NewSegmentBufferAvgBytesPerDocFactor) + br.Grow(estimateAvgBytesPerDoc * estimateNumResults) + } + + s.results = results + s.chunkFactor = chunkFactor + s.w = NewCountHashWriter(&br) + + storedIndexOffset, fieldsIndexOffset, fdvIndexOffset, dictOffsets, + err := s.convert() + if err != nil { + return nil, uint64(0), err + } + + sb, err := InitSegmentBase(br.Bytes(), s.w.Sum32(), chunkFactor, + s.FieldsMap, s.FieldsInv, uint64(len(results)), + storedIndexOffset, fieldsIndexOffset, fdvIndexOffset, dictOffsets) + + if err == nil && s.reset() == nil { + s.lastNumDocs = len(results) + s.lastOutSize = len(br.Bytes()) + interimPool.Put(s) + } + + return sb, uint64(len(br.Bytes())), err +} + +var interimPool = sync.Pool{New: func() interface{} { return &interim{} }} + +// interim holds temporary working data used while converting from +// analysis results to a zap-encoded segment +type interim struct { + results []index.Document + + chunkFactor uint32 + + w *CountHashWriter + + // FieldsMap adds 1 to field id to avoid zero value issues + // name -> field id + 1 + FieldsMap map[string]uint16 + + // FieldsInv is the inverse of FieldsMap + // field id -> name + FieldsInv []string + + // Term dictionaries for each field + // field id -> term -> postings list id + 1 + Dicts []map[string]uint64 + + // Terms for each field, where terms are sorted ascending + // field id -> []term + DictKeys [][]string + + // Fields whose IncludeDocValues is true + // field id -> bool + IncludeDocValues []bool + + // postings id -> bitmap of docNums + Postings []*roaring.Bitmap + + // postings id -> freq/norm's, one for each docNum in postings + FreqNorms [][]interimFreqNorm + freqNormsBacking []interimFreqNorm + + // postings id -> locs, one for each freq + Locs [][]interimLoc + locsBacking []interimLoc + + numTermsPerPostingsList []int // key is postings list id + numLocsPerPostingsList []int // key is postings list id + + builder *vellum.Builder + builderBuf bytes.Buffer + + metaBuf bytes.Buffer + + tmp0 []byte + tmp1 []byte + + lastNumDocs int + lastOutSize int +} + +func (s *interim) reset() (err error) { + s.results = nil + s.chunkFactor = 0 + s.w = nil + s.FieldsMap = nil + s.FieldsInv = nil + for i := range s.Dicts { + s.Dicts[i] = nil + } + s.Dicts = s.Dicts[:0] + for i := range s.DictKeys { + s.DictKeys[i] = s.DictKeys[i][:0] + } + s.DictKeys = s.DictKeys[:0] + for i := range s.IncludeDocValues { + s.IncludeDocValues[i] = false + } + s.IncludeDocValues = s.IncludeDocValues[:0] + for _, idn := range s.Postings { + idn.Clear() + } + s.Postings = s.Postings[:0] + s.FreqNorms = s.FreqNorms[:0] + for i := range s.freqNormsBacking { + s.freqNormsBacking[i] = interimFreqNorm{} + } + s.freqNormsBacking = s.freqNormsBacking[:0] + s.Locs = s.Locs[:0] + for i := range s.locsBacking { + s.locsBacking[i] = interimLoc{} + } + s.locsBacking = s.locsBacking[:0] + s.numTermsPerPostingsList = s.numTermsPerPostingsList[:0] + s.numLocsPerPostingsList = s.numLocsPerPostingsList[:0] + s.builderBuf.Reset() + if s.builder != nil { + err = s.builder.Reset(&s.builderBuf) + } + s.metaBuf.Reset() + s.tmp0 = s.tmp0[:0] + s.tmp1 = s.tmp1[:0] + s.lastNumDocs = 0 + s.lastOutSize = 0 + + return err +} + +func (s *interim) grabBuf(size int) []byte { + buf := s.tmp0 + if cap(buf) < size { + buf = make([]byte, size) + s.tmp0 = buf + } + return buf[0:size] +} + +type interimStoredField struct { + vals [][]byte + typs []byte + arrayposs [][]uint64 // array positions +} + +type interimFreqNorm struct { + freq uint64 + norm float32 + numLocs int +} + +type interimLoc struct { + fieldID uint16 + pos uint64 + start uint64 + end uint64 + arrayposs []uint64 +} + +func (s *interim) convert() (uint64, uint64, uint64, []uint64, error) { + s.FieldsMap = map[string]uint16{} + + s.getOrDefineField("_id") // _id field is fieldID 0 + + for _, result := range s.results { + result.VisitComposite(func(field index.CompositeField) { + s.getOrDefineField(field.Name()) + }) + result.VisitFields(func(field index.Field) { + s.getOrDefineField(field.Name()) + }) + } + + sort.Strings(s.FieldsInv[1:]) // keep _id as first field + + for fieldID, fieldName := range s.FieldsInv { + s.FieldsMap[fieldName] = uint16(fieldID + 1) + } + + if cap(s.IncludeDocValues) >= len(s.FieldsInv) { + s.IncludeDocValues = s.IncludeDocValues[:len(s.FieldsInv)] + } else { + s.IncludeDocValues = make([]bool, len(s.FieldsInv)) + } + + s.prepareDicts() + + for _, dict := range s.DictKeys { + sort.Strings(dict) + } + + s.processDocuments() + + storedIndexOffset, err := s.writeStoredFields() + if err != nil { + return 0, 0, 0, nil, err + } + + var fdvIndexOffset uint64 + var dictOffsets []uint64 + + if len(s.results) > 0 { + fdvIndexOffset, dictOffsets, err = s.writeDicts() + if err != nil { + return 0, 0, 0, nil, err + } + } else { + dictOffsets = make([]uint64, len(s.FieldsInv)) + } + + fieldsIndexOffset, err := persistFields(s.FieldsInv, s.w, dictOffsets) + if err != nil { + return 0, 0, 0, nil, err + } + + return storedIndexOffset, fieldsIndexOffset, fdvIndexOffset, dictOffsets, nil +} + +func (s *interim) getOrDefineField(fieldName string) int { + fieldIDPlus1, exists := s.FieldsMap[fieldName] + if !exists { + fieldIDPlus1 = uint16(len(s.FieldsInv) + 1) + s.FieldsMap[fieldName] = fieldIDPlus1 + s.FieldsInv = append(s.FieldsInv, fieldName) + + s.Dicts = append(s.Dicts, make(map[string]uint64)) + + n := len(s.DictKeys) + if n < cap(s.DictKeys) { + s.DictKeys = s.DictKeys[:n+1] + s.DictKeys[n] = s.DictKeys[n][:0] + } else { + s.DictKeys = append(s.DictKeys, []string(nil)) + } + } + + return int(fieldIDPlus1 - 1) +} + +// fill Dicts and DictKeys from analysis results +func (s *interim) prepareDicts() { + var pidNext int + + var totTFs int + var totLocs int + + visitField := func(field index.Field) { + fieldID := uint16(s.getOrDefineField(field.Name())) + + dict := s.Dicts[fieldID] + dictKeys := s.DictKeys[fieldID] + + tfs := field.AnalyzedTokenFrequencies() + for term, tf := range tfs { + pidPlus1, exists := dict[term] + if !exists { + pidNext++ + pidPlus1 = uint64(pidNext) + + dict[term] = pidPlus1 + dictKeys = append(dictKeys, term) + + s.numTermsPerPostingsList = append(s.numTermsPerPostingsList, 0) + s.numLocsPerPostingsList = append(s.numLocsPerPostingsList, 0) + } + + pid := pidPlus1 - 1 + + s.numTermsPerPostingsList[pid] += 1 + s.numLocsPerPostingsList[pid] += len(tf.Locations) + + totLocs += len(tf.Locations) + } + + totTFs += len(tfs) + + s.DictKeys[fieldID] = dictKeys + } + + for _, result := range s.results { + // walk each composite field + result.VisitComposite(func(field index.CompositeField) { + visitField(field) + }) + + // walk each field + result.VisitFields(visitField) + } + + numPostingsLists := pidNext + + if cap(s.Postings) >= numPostingsLists { + s.Postings = s.Postings[:numPostingsLists] + } else { + postings := make([]*roaring.Bitmap, numPostingsLists) + copy(postings, s.Postings[:cap(s.Postings)]) + for i := 0; i < numPostingsLists; i++ { + if postings[i] == nil { + postings[i] = roaring.New() + } + } + s.Postings = postings + } + + if cap(s.FreqNorms) >= numPostingsLists { + s.FreqNorms = s.FreqNorms[:numPostingsLists] + } else { + s.FreqNorms = make([][]interimFreqNorm, numPostingsLists) + } + + if cap(s.freqNormsBacking) >= totTFs { + s.freqNormsBacking = s.freqNormsBacking[:totTFs] + } else { + s.freqNormsBacking = make([]interimFreqNorm, totTFs) + } + + freqNormsBacking := s.freqNormsBacking + for pid, numTerms := range s.numTermsPerPostingsList { + s.FreqNorms[pid] = freqNormsBacking[0:0] + freqNormsBacking = freqNormsBacking[numTerms:] + } + + if cap(s.Locs) >= numPostingsLists { + s.Locs = s.Locs[:numPostingsLists] + } else { + s.Locs = make([][]interimLoc, numPostingsLists) + } + + if cap(s.locsBacking) >= totLocs { + s.locsBacking = s.locsBacking[:totLocs] + } else { + s.locsBacking = make([]interimLoc, totLocs) + } + + locsBacking := s.locsBacking + for pid, numLocs := range s.numLocsPerPostingsList { + s.Locs[pid] = locsBacking[0:0] + locsBacking = locsBacking[numLocs:] + } +} + +func (s *interim) processDocuments() { + numFields := len(s.FieldsInv) + reuseFieldLens := make([]int, numFields) + reuseFieldTFs := make([]index.TokenFrequencies, numFields) + + for docNum, result := range s.results { + for i := 0; i < numFields; i++ { // clear these for reuse + reuseFieldLens[i] = 0 + reuseFieldTFs[i] = nil + } + + s.processDocument(uint64(docNum), result, + reuseFieldLens, reuseFieldTFs) + } +} + +func (s *interim) processDocument(docNum uint64, + result index.Document, + fieldLens []int, fieldTFs []index.TokenFrequencies) { + visitField := func(field index.Field) { + fieldID := uint16(s.getOrDefineField(field.Name())) + fieldLens[fieldID] += field.AnalyzedLength() + + existingFreqs := fieldTFs[fieldID] + if existingFreqs != nil { + existingFreqs.MergeAll(field.Name(), field.AnalyzedTokenFrequencies()) + } else { + fieldTFs[fieldID] = field.AnalyzedTokenFrequencies() + } + } + + // walk each composite field + result.VisitComposite(func(field index.CompositeField) { + visitField(field) + }) + + // walk each field + result.VisitFields(visitField) + + // now that it's been rolled up into fieldTFs, walk that + for fieldID, tfs := range fieldTFs { + dict := s.Dicts[fieldID] + norm := float32(1.0 / math.Sqrt(float64(fieldLens[fieldID]))) + + for term, tf := range tfs { + pid := dict[term] - 1 + bs := s.Postings[pid] + bs.Add(uint32(docNum)) + + s.FreqNorms[pid] = append(s.FreqNorms[pid], + interimFreqNorm{ + freq: uint64(tf.Frequency()), + norm: norm, + numLocs: len(tf.Locations), + }) + + if len(tf.Locations) > 0 { + locs := s.Locs[pid] + + for _, loc := range tf.Locations { + var locf = uint16(fieldID) + if loc.Field != "" { + locf = uint16(s.getOrDefineField(loc.Field)) + } + var arrayposs []uint64 + if len(loc.ArrayPositions) > 0 { + arrayposs = loc.ArrayPositions + } + locs = append(locs, interimLoc{ + fieldID: locf, + pos: uint64(loc.Position), + start: uint64(loc.Start), + end: uint64(loc.End), + arrayposs: arrayposs, + }) + } + + s.Locs[pid] = locs + } + } + } +} + +func (s *interim) writeStoredFields() ( + storedIndexOffset uint64, err error) { + varBuf := make([]byte, binary.MaxVarintLen64) + metaEncode := func(val uint64) (int, error) { + wb := binary.PutUvarint(varBuf, val) + return s.metaBuf.Write(varBuf[:wb]) + } + + data, compressed := s.tmp0[:0], s.tmp1[:0] + defer func() { s.tmp0, s.tmp1 = data, compressed }() + + // keyed by docNum + docStoredOffsets := make([]uint64, len(s.results)) + + // keyed by fieldID, for the current doc in the loop + docStoredFields := map[uint16]interimStoredField{} + + for docNum, result := range s.results { + for fieldID := range docStoredFields { // reset for next doc + delete(docStoredFields, fieldID) + } + + var validationErr error + result.VisitFields(func(field index.Field) { + fieldID := uint16(s.getOrDefineField(field.Name())) + + if field.Options().IsStored() { + isf := docStoredFields[fieldID] + isf.vals = append(isf.vals, field.Value()) + isf.typs = append(isf.typs, field.EncodedFieldType()) + isf.arrayposs = append(isf.arrayposs, field.ArrayPositions()) + docStoredFields[fieldID] = isf + } + + if field.Options().IncludeDocValues() { + s.IncludeDocValues[fieldID] = true + } + + err := ValidateDocFields(field) + if err != nil && validationErr == nil { + validationErr = err + } + }) + if validationErr != nil { + return 0, validationErr + } + + var curr int + + s.metaBuf.Reset() + data = data[:0] + + // _id field special case optimizes ExternalID() lookups + idFieldVal := docStoredFields[uint16(0)].vals[0] + _, err = metaEncode(uint64(len(idFieldVal))) + if err != nil { + return 0, err + } + + // handle non-"_id" fields + for fieldID := 1; fieldID < len(s.FieldsInv); fieldID++ { + isf, exists := docStoredFields[uint16(fieldID)] + if exists { + curr, data, err = persistStoredFieldValues( + fieldID, isf.vals, isf.typs, isf.arrayposs, + curr, metaEncode, data) + if err != nil { + return 0, err + } + } + } + + metaBytes := s.metaBuf.Bytes() + + compressed = snappy.Encode(compressed[:cap(compressed)], data) + + docStoredOffsets[docNum] = uint64(s.w.Count()) + + _, err := writeUvarints(s.w, + uint64(len(metaBytes)), + uint64(len(idFieldVal)+len(compressed))) + if err != nil { + return 0, err + } + + _, err = s.w.Write(metaBytes) + if err != nil { + return 0, err + } + + _, err = s.w.Write(idFieldVal) + if err != nil { + return 0, err + } + + _, err = s.w.Write(compressed) + if err != nil { + return 0, err + } + } + + storedIndexOffset = uint64(s.w.Count()) + + for _, docStoredOffset := range docStoredOffsets { + err = binary.Write(s.w, binary.BigEndian, docStoredOffset) + if err != nil { + return 0, err + } + } + + return storedIndexOffset, nil +} + +func (s *interim) writeDicts() (fdvIndexOffset uint64, dictOffsets []uint64, err error) { + dictOffsets = make([]uint64, len(s.FieldsInv)) + + fdvOffsetsStart := make([]uint64, len(s.FieldsInv)) + fdvOffsetsEnd := make([]uint64, len(s.FieldsInv)) + + buf := s.grabBuf(binary.MaxVarintLen64) + + tfEncoder := newChunkedIntCoder(uint64(s.chunkFactor), uint64(len(s.results)-1)) + locEncoder := newChunkedIntCoder(uint64(s.chunkFactor), uint64(len(s.results)-1)) + fdvEncoder := newChunkedContentCoder(uint64(s.chunkFactor), uint64(len(s.results)-1), s.w, false) + + var docTermMap [][]byte + + if s.builder == nil { + s.builder, err = vellum.New(&s.builderBuf, nil) + if err != nil { + return 0, nil, err + } + } + + for fieldID, terms := range s.DictKeys { + if cap(docTermMap) < len(s.results) { + docTermMap = make([][]byte, len(s.results)) + } else { + docTermMap = docTermMap[0:len(s.results)] + for docNum := range docTermMap { // reset the docTermMap + docTermMap[docNum] = docTermMap[docNum][:0] + } + } + + dict := s.Dicts[fieldID] + + for _, term := range terms { // terms are already sorted + pid := dict[term] - 1 + + postingsBS := s.Postings[pid] + + freqNorms := s.FreqNorms[pid] + freqNormOffset := 0 + + locs := s.Locs[pid] + locOffset := 0 + + postingsItr := postingsBS.Iterator() + for postingsItr.HasNext() { + docNum := uint64(postingsItr.Next()) + + freqNorm := freqNorms[freqNormOffset] + + err = tfEncoder.Add(docNum, + encodeFreqHasLocs(freqNorm.freq, freqNorm.numLocs > 0), + uint64(math.Float32bits(freqNorm.norm))) + if err != nil { + return 0, nil, err + } + + if freqNorm.numLocs > 0 { + numBytesLocs := 0 + for _, loc := range locs[locOffset : locOffset+freqNorm.numLocs] { + numBytesLocs += totalUvarintBytes( + uint64(loc.fieldID), loc.pos, loc.start, loc.end, + uint64(len(loc.arrayposs)), loc.arrayposs) + } + + err = locEncoder.Add(docNum, uint64(numBytesLocs)) + if err != nil { + return 0, nil, err + } + + for _, loc := range locs[locOffset : locOffset+freqNorm.numLocs] { + err = locEncoder.Add(docNum, + uint64(loc.fieldID), loc.pos, loc.start, loc.end, + uint64(len(loc.arrayposs))) + if err != nil { + return 0, nil, err + } + + err = locEncoder.Add(docNum, loc.arrayposs...) + if err != nil { + return 0, nil, err + } + } + + locOffset += freqNorm.numLocs + } + + freqNormOffset++ + + docTermMap[docNum] = append( + append(docTermMap[docNum], term...), + termSeparator) + } + + tfEncoder.Close() + locEncoder.Close() + + postingsOffset, err := + writePostings(postingsBS, tfEncoder, locEncoder, nil, s.w, buf) + if err != nil { + return 0, nil, err + } + + if postingsOffset > uint64(0) { + err = s.builder.Insert([]byte(term), postingsOffset) + if err != nil { + return 0, nil, err + } + } + + tfEncoder.Reset() + locEncoder.Reset() + } + + err = s.builder.Close() + if err != nil { + return 0, nil, err + } + + // record where this dictionary starts + dictOffsets[fieldID] = uint64(s.w.Count()) + + vellumData := s.builderBuf.Bytes() + + // write out the length of the vellum data + n := binary.PutUvarint(buf, uint64(len(vellumData))) + _, err = s.w.Write(buf[:n]) + if err != nil { + return 0, nil, err + } + + // write this vellum to disk + _, err = s.w.Write(vellumData) + if err != nil { + return 0, nil, err + } + + // reset vellum for reuse + s.builderBuf.Reset() + + err = s.builder.Reset(&s.builderBuf) + if err != nil { + return 0, nil, err + } + + // write the field doc values + if s.IncludeDocValues[fieldID] { + for docNum, docTerms := range docTermMap { + if len(docTerms) > 0 { + err = fdvEncoder.Add(uint64(docNum), docTerms) + if err != nil { + return 0, nil, err + } + } + } + err = fdvEncoder.Close() + if err != nil { + return 0, nil, err + } + + fdvOffsetsStart[fieldID] = uint64(s.w.Count()) + + _, err = fdvEncoder.Write() + if err != nil { + return 0, nil, err + } + + fdvOffsetsEnd[fieldID] = uint64(s.w.Count()) + + fdvEncoder.Reset() + } else { + fdvOffsetsStart[fieldID] = fieldNotUninverted + fdvOffsetsEnd[fieldID] = fieldNotUninverted + } + } + + fdvIndexOffset = uint64(s.w.Count()) + + for i := 0; i < len(fdvOffsetsStart); i++ { + n := binary.PutUvarint(buf, fdvOffsetsStart[i]) + _, err := s.w.Write(buf[:n]) + if err != nil { + return 0, nil, err + } + n = binary.PutUvarint(buf, fdvOffsetsEnd[i]) + _, err = s.w.Write(buf[:n]) + if err != nil { + return 0, nil, err + } + } + + return fdvIndexOffset, dictOffsets, nil +} + +// returns the total # of bytes needed to encode the given uint64's +// into binary.PutUVarint() encoding +func totalUvarintBytes(a, b, c, d, e uint64, more []uint64) (n int) { + n = numUvarintBytes(a) + n += numUvarintBytes(b) + n += numUvarintBytes(c) + n += numUvarintBytes(d) + n += numUvarintBytes(e) + for _, v := range more { + n += numUvarintBytes(v) + } + return n +} + +// returns # of bytes needed to encode x in binary.PutUvarint() encoding +func numUvarintBytes(x uint64) (n int) { + for x >= 0x80 { + x >>= 7 + n++ + } + return n + 1 +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/plugin.go b/backend/vendor/github.com/blevesearch/zapx/v11/plugin.go new file mode 100644 index 0000000000..f67297ec2f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/plugin.go @@ -0,0 +1,27 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +// ZapPlugin implements the Plugin interface of +// the blevesearch/scorch_segment_api pkg +type ZapPlugin struct{} + +func (*ZapPlugin) Type() string { + return Type +} + +func (*ZapPlugin) Version() uint32 { + return Version +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/posting.go b/backend/vendor/github.com/blevesearch/zapx/v11/posting.go new file mode 100644 index 0000000000..71b8e52be0 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/posting.go @@ -0,0 +1,949 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "encoding/binary" + "fmt" + "math" + "reflect" + + "github.com/RoaringBitmap/roaring" + segment "github.com/blevesearch/scorch_segment_api/v2" +) + +var reflectStaticSizePostingsList int +var reflectStaticSizePostingsIterator int +var reflectStaticSizePosting int +var reflectStaticSizeLocation int + +func init() { + var pl PostingsList + reflectStaticSizePostingsList = int(reflect.TypeOf(pl).Size()) + var pi PostingsIterator + reflectStaticSizePostingsIterator = int(reflect.TypeOf(pi).Size()) + var p Posting + reflectStaticSizePosting = int(reflect.TypeOf(p).Size()) + var l Location + reflectStaticSizeLocation = int(reflect.TypeOf(l).Size()) +} + +// FST or vellum value (uint64) encoding is determined by the top two +// highest-order or most significant bits... +// +// encoding : MSB +// name : 63 62 61...to...bit #0 (LSB) +// ----------+---+---+--------------------------------------------------- +// general : 0 | 0 | 62-bits of postingsOffset. +// ~ : 0 | 1 | reserved for future. +// 1-hit : 1 | 0 | 31-bits of positive float31 norm | 31-bits docNum. +// ~ : 1 | 1 | reserved for future. +// +// Encoding "general" is able to handle all cases, where the +// postingsOffset points to more information about the postings for +// the term. +// +// Encoding "1-hit" is used to optimize a commonly seen case when a +// term has only a single hit. For example, a term in the _id field +// will have only 1 hit. The "1-hit" encoding is used for a term +// in a field when... +// +// - term vector info is disabled for that field; +// - and, the term appears in only a single doc for that field; +// - and, the term's freq is exactly 1 in that single doc for that field; +// - and, the docNum must fit into 31-bits; +// +// Otherwise, the "general" encoding is used instead. +// +// In the "1-hit" encoding, the field in that single doc may have +// other terms, which is supported in the "1-hit" encoding by the +// positive float31 norm. + +const FSTValEncodingMask = uint64(0xc000000000000000) +const FSTValEncodingGeneral = uint64(0x0000000000000000) +const FSTValEncoding1Hit = uint64(0x8000000000000000) + +func FSTValEncode1Hit(docNum uint64, normBits uint64) uint64 { + return FSTValEncoding1Hit | ((mask31Bits & normBits) << 31) | (mask31Bits & docNum) +} + +func FSTValDecode1Hit(v uint64) (docNum uint64, normBits uint64) { + return (mask31Bits & v), (mask31Bits & (v >> 31)) +} + +const mask31Bits = uint64(0x000000007fffffff) + +func under32Bits(x uint64) bool { + return x <= mask31Bits +} + +const DocNum1HitFinished = math.MaxUint64 + +var NormBits1Hit = uint64(math.Float32bits(float32(1))) + +// PostingsList is an in-memory representation of a postings list +type PostingsList struct { + sb *SegmentBase + postingsOffset uint64 + freqOffset uint64 + locOffset uint64 + postings *roaring.Bitmap + except *roaring.Bitmap + + // when normBits1Hit != 0, then this postings list came from a + // 1-hit encoding, and only the docNum1Hit & normBits1Hit apply + docNum1Hit uint64 + normBits1Hit uint64 +} + +// represents an immutable, empty postings list +var emptyPostingsList = &PostingsList{} + +// Following methods are dummy implementations for the interface +// DiskStatsReporter (for backward compatibility). +// The working implementations are supported only in zap v15.x +// and not in the earlier versions of zap. +func (i *PostingsList) ResetBytesRead(uint64) {} + +func (i *PostingsList) BytesRead() uint64 { + return 0 +} + +func (i *PostingsList) incrementBytesRead(uint64) {} + +func (i *PostingsList) BytesWritten() uint64 { + return 0 +} + +func (p *PostingsList) Size() int { + sizeInBytes := reflectStaticSizePostingsList + SizeOfPtr + + if p.except != nil { + sizeInBytes += int(p.except.GetSizeInBytes()) + } + + return sizeInBytes +} + +func (p *PostingsList) OrInto(receiver *roaring.Bitmap) { + if p.normBits1Hit != 0 { + receiver.Add(uint32(p.docNum1Hit)) + return + } + + if p.postings != nil { + receiver.Or(p.postings) + } +} + +// Iterator returns an iterator for this postings list +func (p *PostingsList) Iterator(includeFreq, includeNorm, includeLocs bool, + prealloc segment.PostingsIterator) segment.PostingsIterator { + if p.normBits1Hit == 0 && p.postings == nil { + return emptyPostingsIterator + } + + var preallocPI *PostingsIterator + pi, ok := prealloc.(*PostingsIterator) + if ok && pi != nil { + preallocPI = pi + } + if preallocPI == emptyPostingsIterator { + preallocPI = nil + } + + return p.iterator(includeFreq, includeNorm, includeLocs, preallocPI) +} + +func (p *PostingsList) iterator(includeFreq, includeNorm, includeLocs bool, + rv *PostingsIterator) *PostingsIterator { + if rv == nil { + rv = &PostingsIterator{} + } else { + freqNormReader := rv.freqNormReader + if freqNormReader != nil { + freqNormReader.Reset([]byte(nil)) + } + + locReader := rv.locReader + if locReader != nil { + locReader.Reset([]byte(nil)) + } + + freqChunkOffsets := rv.freqChunkOffsets[:0] + locChunkOffsets := rv.locChunkOffsets[:0] + + nextLocs := rv.nextLocs[:0] + nextSegmentLocs := rv.nextSegmentLocs[:0] + + buf := rv.buf + + *rv = PostingsIterator{} // clear the struct + + rv.freqNormReader = freqNormReader + rv.locReader = locReader + + rv.freqChunkOffsets = freqChunkOffsets + rv.locChunkOffsets = locChunkOffsets + + rv.nextLocs = nextLocs + rv.nextSegmentLocs = nextSegmentLocs + + rv.buf = buf + } + + rv.postings = p + rv.includeFreqNorm = includeFreq || includeNorm || includeLocs + rv.includeLocs = includeLocs + + if p.normBits1Hit != 0 { + // "1-hit" encoding + rv.docNum1Hit = p.docNum1Hit + rv.normBits1Hit = p.normBits1Hit + + if p.except != nil && p.except.Contains(uint32(rv.docNum1Hit)) { + rv.docNum1Hit = DocNum1HitFinished + } + + return rv + } + + // "general" encoding, check if empty + if p.postings == nil { + return rv + } + + var n uint64 + var read int + + // prepare the freq chunk details + if rv.includeFreqNorm { + var numFreqChunks uint64 + numFreqChunks, read = binary.Uvarint(p.sb.mem[p.freqOffset+n : p.freqOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + if cap(rv.freqChunkOffsets) >= int(numFreqChunks) { + rv.freqChunkOffsets = rv.freqChunkOffsets[:int(numFreqChunks)] + } else { + rv.freqChunkOffsets = make([]uint64, int(numFreqChunks)) + } + for i := 0; i < int(numFreqChunks); i++ { + rv.freqChunkOffsets[i], read = binary.Uvarint(p.sb.mem[p.freqOffset+n : p.freqOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + } + rv.freqChunkStart = p.freqOffset + n + } + + // prepare the loc chunk details + if rv.includeLocs { + n = 0 + var numLocChunks uint64 + numLocChunks, read = binary.Uvarint(p.sb.mem[p.locOffset+n : p.locOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + if cap(rv.locChunkOffsets) >= int(numLocChunks) { + rv.locChunkOffsets = rv.locChunkOffsets[:int(numLocChunks)] + } else { + rv.locChunkOffsets = make([]uint64, int(numLocChunks)) + } + for i := 0; i < int(numLocChunks); i++ { + rv.locChunkOffsets[i], read = binary.Uvarint(p.sb.mem[p.locOffset+n : p.locOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + } + rv.locChunkStart = p.locOffset + n + } + + rv.all = p.postings.Iterator() + if p.except != nil { + rv.ActualBM = roaring.AndNot(p.postings, p.except) + rv.Actual = rv.ActualBM.Iterator() + } else { + rv.ActualBM = p.postings + rv.Actual = rv.all // Optimize to use same iterator for all & Actual. + } + + return rv +} + +// Count returns the number of items on this postings list +func (p *PostingsList) Count() uint64 { + var n, e uint64 + if p.normBits1Hit != 0 { + n = 1 + if p.except != nil && p.except.Contains(uint32(p.docNum1Hit)) { + e = 1 + } + } else if p.postings != nil { + n = p.postings.GetCardinality() + if p.except != nil { + e = p.postings.AndCardinality(p.except) + } + } + return n - e +} + +func (rv *PostingsList) read(postingsOffset uint64, d *Dictionary) error { + rv.postingsOffset = postingsOffset + + // handle "1-hit" encoding special case + if rv.postingsOffset&FSTValEncodingMask == FSTValEncoding1Hit { + return rv.init1Hit(postingsOffset) + } + + // read the location of the freq/norm details + var n uint64 + var read int + + rv.freqOffset, read = binary.Uvarint(d.sb.mem[postingsOffset+n : postingsOffset+binary.MaxVarintLen64]) + n += uint64(read) + + rv.locOffset, read = binary.Uvarint(d.sb.mem[postingsOffset+n : postingsOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + + var postingsLen uint64 + postingsLen, read = binary.Uvarint(d.sb.mem[postingsOffset+n : postingsOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + + roaringBytes := d.sb.mem[postingsOffset+n : postingsOffset+n+postingsLen] + + if rv.postings == nil { + rv.postings = roaring.NewBitmap() + } + _, err := rv.postings.FromBuffer(roaringBytes) + if err != nil { + return fmt.Errorf("error loading roaring bitmap: %v", err) + } + + return nil +} + +func (rv *PostingsList) init1Hit(fstVal uint64) error { + docNum, normBits := FSTValDecode1Hit(fstVal) + + rv.docNum1Hit = docNum + rv.normBits1Hit = normBits + + return nil +} + +// PostingsIterator provides a way to iterate through the postings list +type PostingsIterator struct { + postings *PostingsList + all roaring.IntPeekable + Actual roaring.IntPeekable + ActualBM *roaring.Bitmap + + currChunk uint32 + currChunkFreqNorm []byte + currChunkLoc []byte + + freqNormReader *memUvarintReader + locReader *memUvarintReader + + freqChunkOffsets []uint64 + freqChunkStart uint64 + + locChunkOffsets []uint64 + locChunkStart uint64 + + next Posting // reused across Next() calls + nextLocs []Location // reused across Next() calls + nextSegmentLocs []segment.Location // reused across Next() calls + + docNum1Hit uint64 + normBits1Hit uint64 + + buf []byte + + includeFreqNorm bool + includeLocs bool +} + +var emptyPostingsIterator = &PostingsIterator{} + +// Following methods are dummy implementations for the interface +// DiskStatsReporter (for backward compatibility). +// The working implementations are supported only in zap v15.x +// and not in the earlier versions of zap. +func (i *PostingsIterator) ResetBytesRead(uint64) {} + +func (i *PostingsIterator) BytesRead() uint64 { + return 0 +} + +func (i *PostingsIterator) incrementBytesRead(uint64) {} + +func (i *PostingsIterator) BytesWritten() uint64 { + return 0 +} + +func (i *PostingsIterator) Size() int { + sizeInBytes := reflectStaticSizePostingsIterator + SizeOfPtr + + len(i.currChunkFreqNorm) + + len(i.currChunkLoc) + + len(i.freqChunkOffsets)*SizeOfUint64 + + len(i.locChunkOffsets)*SizeOfUint64 + + i.next.Size() + + for _, entry := range i.nextLocs { + sizeInBytes += entry.Size() + } + + return sizeInBytes +} + +func (i *PostingsIterator) loadChunk(chunk int) error { + if i.includeFreqNorm { + if chunk >= len(i.freqChunkOffsets) { + return fmt.Errorf("tried to load freq chunk that doesn't exist %d/(%d)", + chunk, len(i.freqChunkOffsets)) + } + + end, start := i.freqChunkStart, i.freqChunkStart + s, e := readChunkBoundary(chunk, i.freqChunkOffsets) + start += s + end += e + i.currChunkFreqNorm = i.postings.sb.mem[start:end] + if i.freqNormReader == nil { + i.freqNormReader = newMemUvarintReader(i.currChunkFreqNorm) + } else { + i.freqNormReader.Reset(i.currChunkFreqNorm) + } + } + + if i.includeLocs { + if chunk >= len(i.locChunkOffsets) { + return fmt.Errorf("tried to load loc chunk that doesn't exist %d/(%d)", + chunk, len(i.locChunkOffsets)) + } + + end, start := i.locChunkStart, i.locChunkStart + s, e := readChunkBoundary(chunk, i.locChunkOffsets) + start += s + end += e + i.currChunkLoc = i.postings.sb.mem[start:end] + if i.locReader == nil { + i.locReader = newMemUvarintReader(i.currChunkLoc) + } else { + i.locReader.Reset(i.currChunkLoc) + } + } + + i.currChunk = uint32(chunk) + return nil +} + +func (i *PostingsIterator) readFreqNormHasLocs() (uint64, uint64, bool, error) { + if i.normBits1Hit != 0 { + return 1, i.normBits1Hit, false, nil + } + + freqHasLocs, err := i.freqNormReader.ReadUvarint() + if err != nil { + return 0, 0, false, fmt.Errorf("error reading frequency: %v", err) + } + + freq, hasLocs := decodeFreqHasLocs(freqHasLocs) + + normBits, err := i.freqNormReader.ReadUvarint() + if err != nil { + return 0, 0, false, fmt.Errorf("error reading norm: %v", err) + } + + return freq, normBits, hasLocs, nil +} + +func (i *PostingsIterator) skipFreqNormReadHasLocs() (bool, error) { + if i.normBits1Hit != 0 { + return false, nil + } + + freqHasLocs, err := i.freqNormReader.ReadUvarint() + if err != nil { + return false, fmt.Errorf("error reading freqHasLocs: %v", err) + } + + i.freqNormReader.SkipUvarint() // Skip normBits. + + return freqHasLocs&0x01 != 0, nil // See decodeFreqHasLocs() / hasLocs. +} + +func encodeFreqHasLocs(freq uint64, hasLocs bool) uint64 { + rv := freq << 1 + if hasLocs { + rv = rv | 0x01 // 0'th LSB encodes whether there are locations + } + return rv +} + +func decodeFreqHasLocs(freqHasLocs uint64) (uint64, bool) { + freq := freqHasLocs >> 1 + hasLocs := freqHasLocs&0x01 != 0 + return freq, hasLocs +} + +// readLocation processes all the integers on the stream representing a single +// location. +func (i *PostingsIterator) readLocation(l *Location) error { + // read off field + fieldID, err := i.locReader.ReadUvarint() + if err != nil { + return fmt.Errorf("error reading location field: %v", err) + } + // read off pos + pos, err := i.locReader.ReadUvarint() + if err != nil { + return fmt.Errorf("error reading location pos: %v", err) + } + // read off start + start, err := i.locReader.ReadUvarint() + if err != nil { + return fmt.Errorf("error reading location start: %v", err) + } + // read off end + end, err := i.locReader.ReadUvarint() + if err != nil { + return fmt.Errorf("error reading location end: %v", err) + } + // read off num array pos + numArrayPos, err := i.locReader.ReadUvarint() + if err != nil { + return fmt.Errorf("error reading location num array pos: %v", err) + } + + l.field = i.postings.sb.fieldsInv[fieldID] + l.pos = pos + l.start = start + l.end = end + + if cap(l.ap) < int(numArrayPos) { + l.ap = make([]uint64, int(numArrayPos)) + } else { + l.ap = l.ap[:int(numArrayPos)] + } + + // read off array positions + for k := 0; k < int(numArrayPos); k++ { + ap, err := i.locReader.ReadUvarint() + if err != nil { + return fmt.Errorf("error reading array position: %v", err) + } + + l.ap[k] = ap + } + + return nil +} + +// Next returns the next posting on the postings list, or nil at the end +func (i *PostingsIterator) Next() (segment.Posting, error) { + return i.nextAtOrAfter(0) +} + +// Advance returns the posting at the specified docNum or it is not present +// the next posting, or if the end is reached, nil +func (i *PostingsIterator) Advance(docNum uint64) (segment.Posting, error) { + return i.nextAtOrAfter(docNum) +} + +// Next returns the next posting on the postings list, or nil at the end +func (i *PostingsIterator) nextAtOrAfter(atOrAfter uint64) (segment.Posting, error) { + docNum, exists, err := i.nextDocNumAtOrAfter(atOrAfter) + if err != nil || !exists { + return nil, err + } + + i.next = Posting{} // clear the struct + rv := &i.next + rv.docNum = docNum + + if !i.includeFreqNorm { + return rv, nil + } + + var normBits uint64 + var hasLocs bool + + rv.freq, normBits, hasLocs, err = i.readFreqNormHasLocs() + if err != nil { + return nil, err + } + + rv.norm = math.Float32frombits(uint32(normBits)) + + if i.includeLocs && hasLocs { + // prepare locations into reused slices, where we assume + // rv.freq >= "number of locs", since in a composite field, + // some component fields might have their IncludeTermVector + // flags disabled while other component fields are enabled + if cap(i.nextLocs) >= int(rv.freq) { + i.nextLocs = i.nextLocs[0:rv.freq] + } else { + i.nextLocs = make([]Location, rv.freq, rv.freq*2) + } + if cap(i.nextSegmentLocs) < int(rv.freq) { + i.nextSegmentLocs = make([]segment.Location, rv.freq, rv.freq*2) + } + rv.locs = i.nextSegmentLocs[:0] + + numLocsBytes, err := i.locReader.ReadUvarint() + if err != nil { + return nil, fmt.Errorf("error reading location numLocsBytes: %v", err) + } + + j := 0 + startBytesRemaining := i.locReader.Len() // # bytes remaining in the locReader + for startBytesRemaining-i.locReader.Len() < int(numLocsBytes) { + err := i.readLocation(&i.nextLocs[j]) + if err != nil { + return nil, err + } + rv.locs = append(rv.locs, &i.nextLocs[j]) + j++ + } + } + + return rv, nil +} + +var freqHasLocs1Hit = encodeFreqHasLocs(1, false) + +// nextBytes returns the docNum and the encoded freq & loc bytes for +// the next posting +func (i *PostingsIterator) nextBytes() ( + docNumOut uint64, freq uint64, normBits uint64, + bytesFreqNorm []byte, bytesLoc []byte, err error) { + docNum, exists, err := i.nextDocNumAtOrAfter(0) + if err != nil || !exists { + return 0, 0, 0, nil, nil, err + } + + if i.normBits1Hit != 0 { + if i.buf == nil { + i.buf = make([]byte, binary.MaxVarintLen64*2) + } + n := binary.PutUvarint(i.buf, freqHasLocs1Hit) + n += binary.PutUvarint(i.buf[n:], i.normBits1Hit) + return docNum, uint64(1), i.normBits1Hit, i.buf[:n], nil, nil + } + + startFreqNorm := len(i.currChunkFreqNorm) - i.freqNormReader.Len() + + var hasLocs bool + + freq, normBits, hasLocs, err = i.readFreqNormHasLocs() + if err != nil { + return 0, 0, 0, nil, nil, err + } + + endFreqNorm := len(i.currChunkFreqNorm) - i.freqNormReader.Len() + bytesFreqNorm = i.currChunkFreqNorm[startFreqNorm:endFreqNorm] + + if hasLocs { + startLoc := len(i.currChunkLoc) - i.locReader.Len() + + numLocsBytes, err := i.locReader.ReadUvarint() + if err != nil { + return 0, 0, 0, nil, nil, + fmt.Errorf("error reading location nextBytes numLocs: %v", err) + } + + // skip over all the location bytes + i.locReader.SkipBytes(int(numLocsBytes)) + + endLoc := len(i.currChunkLoc) - i.locReader.Len() + bytesLoc = i.currChunkLoc[startLoc:endLoc] + } + + return docNum, freq, normBits, bytesFreqNorm, bytesLoc, nil +} + +// nextDocNum returns the next docNum on the postings list, and also +// sets up the currChunk / loc related fields of the iterator. +func (i *PostingsIterator) nextDocNumAtOrAfter(atOrAfter uint64) (uint64, bool, error) { + if i.normBits1Hit != 0 { + if i.docNum1Hit == DocNum1HitFinished { + return 0, false, nil + } + if i.docNum1Hit < atOrAfter { + // advanced past our 1-hit + i.docNum1Hit = DocNum1HitFinished // consume our 1-hit docNum + return 0, false, nil + } + docNum := i.docNum1Hit + i.docNum1Hit = DocNum1HitFinished // consume our 1-hit docNum + return docNum, true, nil + } + + if i.Actual == nil || !i.Actual.HasNext() { + return 0, false, nil + } + + if i.postings == nil || i.postings == emptyPostingsList { + // couldn't find anything + return 0, false, nil + } + + if i.postings.postings == i.ActualBM { + return i.nextDocNumAtOrAfterClean(atOrAfter) + } + + i.Actual.AdvanceIfNeeded(uint32(atOrAfter)) + + if !i.Actual.HasNext() || !i.all.HasNext() { + // couldn't find anything + return 0, false, nil + } + + n := i.Actual.Next() + allN := i.all.Next() + + nChunk := n / i.postings.sb.chunkFactor + + // when allN becomes >= to here, then allN is in the same chunk as nChunk. + allNReachesNChunk := nChunk * i.postings.sb.chunkFactor + + // n is the next actual hit (excluding some postings), and + // allN is the next hit in the full postings, and + // if they don't match, move 'all' forwards until they do + for allN != n { + // we've reached same chunk, so move the freq/norm/loc decoders forward + if i.includeFreqNorm && allN >= allNReachesNChunk { + err := i.currChunkNext(nChunk) + if err != nil { + return 0, false, err + } + } + + if !i.all.HasNext() { + return 0, false, nil + } + + allN = i.all.Next() + } + + if i.includeFreqNorm && (i.currChunk != nChunk || i.currChunkFreqNorm == nil) { + err := i.loadChunk(int(nChunk)) + if err != nil { + return 0, false, fmt.Errorf("error loading chunk: %v", err) + } + } + + return uint64(n), true, nil +} + +// optimization when the postings list is "clean" (e.g., no updates & +// no deletions) where the all bitmap is the same as the actual bitmap +func (i *PostingsIterator) nextDocNumAtOrAfterClean( + atOrAfter uint64) (uint64, bool, error) { + if !i.includeFreqNorm { + i.Actual.AdvanceIfNeeded(uint32(atOrAfter)) + + if !i.Actual.HasNext() { + return 0, false, nil // couldn't find anything + } + + return uint64(i.Actual.Next()), true, nil + } + + // freq-norm's needed, so maintain freq-norm chunk reader + sameChunkNexts := 0 // # of times we called Next() in the same chunk + n := i.Actual.Next() + nChunk := n / i.postings.sb.chunkFactor + + for uint64(n) < atOrAfter && i.Actual.HasNext() { + n = i.Actual.Next() + + nChunkPrev := nChunk + nChunk = n / i.postings.sb.chunkFactor + + if nChunk != nChunkPrev { + sameChunkNexts = 0 + } else { + sameChunkNexts += 1 + } + } + + if uint64(n) < atOrAfter { + // couldn't find anything + return 0, false, nil + } + + for j := 0; j < sameChunkNexts; j++ { + err := i.currChunkNext(nChunk) + if err != nil { + return 0, false, fmt.Errorf("error optimized currChunkNext: %v", err) + } + } + + if i.currChunk != nChunk || i.currChunkFreqNorm == nil { + err := i.loadChunk(int(nChunk)) + if err != nil { + return 0, false, fmt.Errorf("error loading chunk: %v", err) + } + } + + return uint64(n), true, nil +} + +func (i *PostingsIterator) currChunkNext(nChunk uint32) error { + if i.currChunk != nChunk || i.currChunkFreqNorm == nil { + err := i.loadChunk(int(nChunk)) + if err != nil { + return fmt.Errorf("error loading chunk: %v", err) + } + } + + // read off freq/offsets even though we don't care about them + hasLocs, err := i.skipFreqNormReadHasLocs() + if err != nil { + return err + } + + if i.includeLocs && hasLocs { + numLocsBytes, err := i.locReader.ReadUvarint() + if err != nil { + return fmt.Errorf("error reading location numLocsBytes: %v", err) + } + + // skip over all the location bytes + i.locReader.SkipBytes(int(numLocsBytes)) + } + + return nil +} + +// DocNum1Hit returns the docNum and true if this is "1-hit" optimized +// and the docNum is available. +func (p *PostingsIterator) DocNum1Hit() (uint64, bool) { + if p.normBits1Hit != 0 && p.docNum1Hit != DocNum1HitFinished { + return p.docNum1Hit, true + } + return 0, false +} + +// ActualBitmap returns the underlying actual bitmap +// which can be used up the stack for optimizations +func (p *PostingsIterator) ActualBitmap() *roaring.Bitmap { + return p.ActualBM +} + +// ReplaceActual replaces the ActualBM with the provided +// bitmap +func (p *PostingsIterator) ReplaceActual(abm *roaring.Bitmap) { + p.ActualBM = abm + p.Actual = abm.Iterator() +} + +// PostingsIteratorFromBitmap constructs a PostingsIterator given an +// "actual" bitmap. +func PostingsIteratorFromBitmap(bm *roaring.Bitmap, + includeFreqNorm, includeLocs bool) (segment.PostingsIterator, error) { + return &PostingsIterator{ + ActualBM: bm, + Actual: bm.Iterator(), + includeFreqNorm: includeFreqNorm, + includeLocs: includeLocs, + }, nil +} + +// PostingsIteratorFrom1Hit constructs a PostingsIterator given a +// 1-hit docNum. +func PostingsIteratorFrom1Hit(docNum1Hit uint64, + includeFreqNorm, includeLocs bool) (segment.PostingsIterator, error) { + return &PostingsIterator{ + docNum1Hit: docNum1Hit, + normBits1Hit: NormBits1Hit, + includeFreqNorm: includeFreqNorm, + includeLocs: includeLocs, + }, nil +} + +// Posting is a single entry in a postings list +type Posting struct { + docNum uint64 + freq uint64 + norm float32 + locs []segment.Location +} + +func (p *Posting) Size() int { + sizeInBytes := reflectStaticSizePosting + + for _, entry := range p.locs { + sizeInBytes += entry.Size() + } + + return sizeInBytes +} + +// Number returns the document number of this posting in this segment +func (p *Posting) Number() uint64 { + return p.docNum +} + +// Frequency returns the frequencies of occurrence of this term in this doc/field +func (p *Posting) Frequency() uint64 { + return p.freq +} + +// Norm returns the normalization factor for this posting +func (p *Posting) Norm() float64 { + return float64(p.norm) +} + +// Locations returns the location information for each occurrence +func (p *Posting) Locations() []segment.Location { + return p.locs +} + +// Location represents the location of a single occurrence +type Location struct { + field string + pos uint64 + start uint64 + end uint64 + ap []uint64 +} + +func (l *Location) Size() int { + return reflectStaticSizeLocation + + len(l.field) + + len(l.ap)*SizeOfUint64 +} + +// Field returns the name of the field (useful in composite fields to know +// which original field the value came from) +func (l *Location) Field() string { + return l.field +} + +// Start returns the start byte offset of this occurrence +func (l *Location) Start() uint64 { + return l.start +} + +// End returns the end byte offset of this occurrence +func (l *Location) End() uint64 { + return l.end +} + +// Pos returns the 1-based phrase position of this occurrence +func (l *Location) Pos() uint64 { + return l.pos +} + +// ArrayPositions returns the array position vector associated with this occurrence +func (l *Location) ArrayPositions() []uint64 { + return l.ap +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/read.go b/backend/vendor/github.com/blevesearch/zapx/v11/read.go new file mode 100644 index 0000000000..e47d4c6abd --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/read.go @@ -0,0 +1,43 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import "encoding/binary" + +func (s *SegmentBase) getDocStoredMetaAndCompressed(docNum uint64) ([]byte, []byte) { + _, storedOffset, n, metaLen, dataLen := s.getDocStoredOffsets(docNum) + + meta := s.mem[storedOffset+n : storedOffset+n+metaLen] + data := s.mem[storedOffset+n+metaLen : storedOffset+n+metaLen+dataLen] + + return meta, data +} + +func (s *SegmentBase) getDocStoredOffsets(docNum uint64) ( + uint64, uint64, uint64, uint64, uint64) { + indexOffset := s.storedIndexOffset + (8 * docNum) + + storedOffset := binary.BigEndian.Uint64(s.mem[indexOffset : indexOffset+8]) + + var n uint64 + + metaLen, read := binary.Uvarint(s.mem[storedOffset : storedOffset+binary.MaxVarintLen64]) + n += uint64(read) + + dataLen, read := binary.Uvarint(s.mem[storedOffset+n : storedOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + + return indexOffset, storedOffset, n, metaLen, dataLen +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/segment.go b/backend/vendor/github.com/blevesearch/zapx/v11/segment.go new file mode 100644 index 0000000000..0b0b192f55 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/segment.go @@ -0,0 +1,600 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" + "os" + "sync" + "unsafe" + + "github.com/RoaringBitmap/roaring" + mmap "github.com/blevesearch/mmap-go" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" + "github.com/golang/snappy" +) + +var reflectStaticSizeSegmentBase int + +func init() { + var sb SegmentBase + reflectStaticSizeSegmentBase = int(unsafe.Sizeof(sb)) +} + +// Open returns a zap impl of a segment +func (*ZapPlugin) Open(path string) (segment.Segment, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + mm, err := mmap.Map(f, mmap.RDONLY, 0) + if err != nil { + // mmap failed, try to close the file + _ = f.Close() + return nil, err + } + + rv := &Segment{ + SegmentBase: SegmentBase{ + mem: mm[0 : len(mm)-FooterSize], + fieldsMap: make(map[string]uint16), + fieldDvReaders: make(map[uint16]*docValueReader), + fieldFSTs: make(map[uint16]*vellum.FST), + }, + f: f, + mm: mm, + path: path, + refs: 1, + } + rv.SegmentBase.updateSize() + + err = rv.loadConfig() + if err != nil { + _ = rv.Close() + return nil, err + } + + err = rv.loadFields() + if err != nil { + _ = rv.Close() + return nil, err + } + + err = rv.loadDvReaders() + if err != nil { + _ = rv.Close() + return nil, err + } + + return rv, nil +} + +// SegmentBase is a memory only, read-only implementation of the +// segment.Segment interface, using zap's data representation. +type SegmentBase struct { + mem []byte + memCRC uint32 + chunkFactor uint32 + fieldsMap map[string]uint16 // fieldName -> fieldID+1 + fieldsInv []string // fieldID -> fieldName + numDocs uint64 + storedIndexOffset uint64 + fieldsIndexOffset uint64 + docValueOffset uint64 + dictLocs []uint64 + fieldDvReaders map[uint16]*docValueReader // naive chunk cache per field + fieldDvNames []string // field names cached in fieldDvReaders + size uint64 + + m sync.Mutex + fieldFSTs map[uint16]*vellum.FST +} + +func (sb *SegmentBase) Size() int { + return int(sb.size) +} + +func (sb *SegmentBase) updateSize() { + sizeInBytes := reflectStaticSizeSegmentBase + + cap(sb.mem) + + // fieldsMap + for k := range sb.fieldsMap { + sizeInBytes += (len(k) + SizeOfString) + SizeOfUint16 + } + + // fieldsInv, dictLocs + for _, entry := range sb.fieldsInv { + sizeInBytes += len(entry) + SizeOfString + } + sizeInBytes += len(sb.dictLocs) * SizeOfUint64 + + // fieldDvReaders + for _, v := range sb.fieldDvReaders { + sizeInBytes += SizeOfUint16 + SizeOfPtr + if v != nil { + sizeInBytes += v.size() + } + } + + sb.size = uint64(sizeInBytes) +} + +func (sb *SegmentBase) AddRef() {} +func (sb *SegmentBase) DecRef() (err error) { return nil } +func (sb *SegmentBase) Close() (err error) { return nil } + +// Segment implements a persisted segment.Segment interface, by +// embedding an mmap()'ed SegmentBase. +type Segment struct { + SegmentBase + + f *os.File + mm mmap.MMap + path string + version uint32 + crc uint32 + + m sync.Mutex // Protects the fields that follow. + refs int64 +} + +func (s *Segment) Size() int { + // 8 /* size of file pointer */ + // 4 /* size of version -> uint32 */ + // 4 /* size of crc -> uint32 */ + sizeOfUints := 16 + + sizeInBytes := (len(s.path) + SizeOfString) + sizeOfUints + + // mutex, refs -> int64 + sizeInBytes += 16 + + // do not include the mmap'ed part + return sizeInBytes + s.SegmentBase.Size() - cap(s.mem) +} + +func (s *Segment) AddRef() { + s.m.Lock() + s.refs++ + s.m.Unlock() +} + +func (s *Segment) DecRef() (err error) { + s.m.Lock() + s.refs-- + if s.refs == 0 { + err = s.closeActual() + } + s.m.Unlock() + return err +} + +func (s *Segment) loadConfig() error { + crcOffset := len(s.mm) - 4 + s.crc = binary.BigEndian.Uint32(s.mm[crcOffset : crcOffset+4]) + + verOffset := crcOffset - 4 + s.version = binary.BigEndian.Uint32(s.mm[verOffset : verOffset+4]) + if s.version != Version { + return fmt.Errorf("unsupported version %d", s.version) + } + + chunkOffset := verOffset - 4 + s.chunkFactor = binary.BigEndian.Uint32(s.mm[chunkOffset : chunkOffset+4]) + + docValueOffset := chunkOffset - 8 + s.docValueOffset = binary.BigEndian.Uint64(s.mm[docValueOffset : docValueOffset+8]) + + fieldsIndexOffset := docValueOffset - 8 + s.fieldsIndexOffset = binary.BigEndian.Uint64(s.mm[fieldsIndexOffset : fieldsIndexOffset+8]) + + storedIndexOffset := fieldsIndexOffset - 8 + s.storedIndexOffset = binary.BigEndian.Uint64(s.mm[storedIndexOffset : storedIndexOffset+8]) + + numDocsOffset := storedIndexOffset - 8 + s.numDocs = binary.BigEndian.Uint64(s.mm[numDocsOffset : numDocsOffset+8]) + return nil +} + +// Following methods are dummy implementations for the interface +// DiskStatsReporter (for backward compatibility). +// The working implementations are supported only in zap v15.x +// and not in the earlier versions of zap. +func (s *Segment) ResetBytesRead(uint64) {} + +func (s *Segment) BytesRead() uint64 { + return 0 +} + +func (s *Segment) BytesWritten() uint64 { + return 0 +} + +func (s *Segment) incrementBytesRead(uint64) {} + +func (s *SegmentBase) BytesWritten() uint64 { + return 0 +} + +func (s *SegmentBase) setBytesWritten(uint64) {} + +func (s *SegmentBase) BytesRead() uint64 { + return 0 +} + +func (s *SegmentBase) ResetBytesRead(uint64) {} + +func (s *SegmentBase) incrementBytesRead(uint64) {} + +func (s *SegmentBase) loadFields() error { + // NOTE for now we assume the fields index immediately precedes + // the footer, and if this changes, need to adjust accordingly (or + // store explicit length), where s.mem was sliced from s.mm in Open(). + fieldsIndexEnd := uint64(len(s.mem)) + + // iterate through fields index + var fieldID uint64 + for s.fieldsIndexOffset+(8*fieldID) < fieldsIndexEnd { + addr := binary.BigEndian.Uint64(s.mem[s.fieldsIndexOffset+(8*fieldID) : s.fieldsIndexOffset+(8*fieldID)+8]) + + dictLoc, read := binary.Uvarint(s.mem[addr:fieldsIndexEnd]) + n := uint64(read) + s.dictLocs = append(s.dictLocs, dictLoc) + + var nameLen uint64 + nameLen, read = binary.Uvarint(s.mem[addr+n : fieldsIndexEnd]) + n += uint64(read) + + name := string(s.mem[addr+n : addr+n+nameLen]) + s.fieldsInv = append(s.fieldsInv, name) + s.fieldsMap[name] = uint16(fieldID + 1) + + fieldID++ + } + return nil +} + +// Dictionary returns the term dictionary for the specified field +func (s *SegmentBase) Dictionary(field string) (segment.TermDictionary, error) { + dict, err := s.dictionary(field) + if err == nil && dict == nil { + return emptyDictionary, nil + } + return dict, err +} + +func (sb *SegmentBase) dictionary(field string) (rv *Dictionary, err error) { + fieldIDPlus1 := sb.fieldsMap[field] + if fieldIDPlus1 > 0 { + rv = &Dictionary{ + sb: sb, + field: field, + fieldID: fieldIDPlus1 - 1, + } + + dictStart := sb.dictLocs[rv.fieldID] + if dictStart > 0 { + var ok bool + sb.m.Lock() + if rv.fst, ok = sb.fieldFSTs[rv.fieldID]; !ok { + // read the length of the vellum data + vellumLen, read := binary.Uvarint(sb.mem[dictStart : dictStart+binary.MaxVarintLen64]) + fstBytes := sb.mem[dictStart+uint64(read) : dictStart+uint64(read)+vellumLen] + rv.fst, err = vellum.Load(fstBytes) + if err != nil { + sb.m.Unlock() + return nil, fmt.Errorf("dictionary field %s vellum err: %v", field, err) + } + + sb.fieldFSTs[rv.fieldID] = rv.fst + } + + sb.m.Unlock() + rv.fstReader, err = rv.fst.Reader() + if err != nil { + return nil, fmt.Errorf("dictionary field %s vellum reader err: %v", field, err) + } + } + } + + return rv, nil +} + +// visitDocumentCtx holds data structures that are reusable across +// multiple VisitDocument() calls to avoid memory allocations +type visitDocumentCtx struct { + buf []byte + reader bytes.Reader + arrayPos []uint64 +} + +var visitDocumentCtxPool = sync.Pool{ + New: func() interface{} { + reuse := &visitDocumentCtx{} + return reuse + }, +} + +// VisitStoredFields invokes the StoredFieldValueVisitor for each stored field +// for the specified doc number +func (s *SegmentBase) VisitStoredFields(num uint64, visitor segment.StoredFieldValueVisitor) error { + vdc := visitDocumentCtxPool.Get().(*visitDocumentCtx) + defer visitDocumentCtxPool.Put(vdc) + return s.visitStoredFields(vdc, num, visitor) +} + +func (s *SegmentBase) visitStoredFields(vdc *visitDocumentCtx, num uint64, + visitor segment.StoredFieldValueVisitor) error { + // first make sure this is a valid number in this segment + if num < s.numDocs { + meta, compressed := s.getDocStoredMetaAndCompressed(num) + + vdc.reader.Reset(meta) + + // handle _id field special case + idFieldValLen, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + idFieldVal := compressed[:idFieldValLen] + + keepGoing := visitor("_id", byte('t'), idFieldVal, nil) + if !keepGoing { + visitDocumentCtxPool.Put(vdc) + return nil + } + + // handle non-"_id" fields + compressed = compressed[idFieldValLen:] + + uncompressed, err := snappy.Decode(vdc.buf[:cap(vdc.buf)], compressed) + if err != nil { + return err + } + + for keepGoing { + field, err := binary.ReadUvarint(&vdc.reader) + if err == io.EOF { + break + } + if err != nil { + return err + } + typ, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + offset, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + l, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + numap, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + var arrayPos []uint64 + if numap > 0 { + if cap(vdc.arrayPos) < int(numap) { + vdc.arrayPos = make([]uint64, numap) + } + arrayPos = vdc.arrayPos[:numap] + for i := 0; i < int(numap); i++ { + ap, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + arrayPos[i] = ap + } + } + + value := uncompressed[offset : offset+l] + keepGoing = visitor(s.fieldsInv[field], byte(typ), value, arrayPos) + } + + vdc.buf = uncompressed + } + return nil +} + +// DocID returns the value of the _id field for the given docNum +func (s *SegmentBase) DocID(num uint64) ([]byte, error) { + if num >= s.numDocs { + return nil, nil + } + + vdc := visitDocumentCtxPool.Get().(*visitDocumentCtx) + + meta, compressed := s.getDocStoredMetaAndCompressed(num) + + vdc.reader.Reset(meta) + + // handle _id field special case + idFieldValLen, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return nil, err + } + idFieldVal := compressed[:idFieldValLen] + + visitDocumentCtxPool.Put(vdc) + + return idFieldVal, nil +} + +// Count returns the number of documents in this segment. +func (s *SegmentBase) Count() uint64 { + return s.numDocs +} + +// DocNumbers returns a bitset corresponding to the doc numbers of all the +// provided _id strings +func (s *SegmentBase) DocNumbers(ids []string) (*roaring.Bitmap, error) { + rv := roaring.New() + + if len(s.fieldsMap) > 0 { + idDict, err := s.dictionary("_id") + if err != nil { + return nil, err + } + + postingsList := emptyPostingsList + + sMax, err := idDict.fst.GetMaxKey() + if err != nil { + return nil, err + } + sMaxStr := string(sMax) + filteredIds := make([]string, 0, len(ids)) + for _, id := range ids { + if id <= sMaxStr { + filteredIds = append(filteredIds, id) + } + } + + for _, id := range filteredIds { + postingsList, err = idDict.postingsList([]byte(id), nil, postingsList) + if err != nil { + return nil, err + } + postingsList.OrInto(rv) + } + } + + return rv, nil +} + +// Fields returns the field names used in this segment +func (s *SegmentBase) Fields() []string { + return s.fieldsInv +} + +// Path returns the path of this segment on disk +func (s *Segment) Path() string { + return s.path +} + +// Close releases all resources associated with this segment +func (s *Segment) Close() (err error) { + return s.DecRef() +} + +func (s *Segment) closeActual() (err error) { + if s.mm != nil { + err = s.mm.Unmap() + } + // try to close file even if unmap failed + if s.f != nil { + err2 := s.f.Close() + if err == nil { + // try to return first error + err = err2 + } + } + return +} + +// some helpers i started adding for the command-line utility + +// Data returns the underlying mmaped data slice +func (s *Segment) Data() []byte { + return s.mm +} + +// CRC returns the CRC value stored in the file footer +func (s *Segment) CRC() uint32 { + return s.crc +} + +// Version returns the file version in the file footer +func (s *Segment) Version() uint32 { + return s.version +} + +// ChunkFactor returns the chunk factor in the file footer +func (s *Segment) ChunkFactor() uint32 { + return s.chunkFactor +} + +// FieldsIndexOffset returns the fields index offset in the file footer +func (s *Segment) FieldsIndexOffset() uint64 { + return s.fieldsIndexOffset +} + +// StoredIndexOffset returns the stored value index offset in the file footer +func (s *Segment) StoredIndexOffset() uint64 { + return s.storedIndexOffset +} + +// DocValueOffset returns the docValue offset in the file footer +func (s *Segment) DocValueOffset() uint64 { + return s.docValueOffset +} + +// NumDocs returns the number of documents in the file footer +func (s *Segment) NumDocs() uint64 { + return s.numDocs +} + +// DictAddr is a helper function to compute the file offset where the +// dictionary is stored for the specified field. +func (s *Segment) DictAddr(field string) (uint64, error) { + fieldIDPlus1, ok := s.fieldsMap[field] + if !ok { + return 0, fmt.Errorf("no such field '%s'", field) + } + + return s.dictLocs[fieldIDPlus1-1], nil +} + +func (s *SegmentBase) loadDvReaders() error { + if s.docValueOffset == fieldNotUninverted || s.numDocs == 0 { + return nil + } + + var read uint64 + for fieldID, field := range s.fieldsInv { + var fieldLocStart, fieldLocEnd uint64 + var n int + fieldLocStart, n = binary.Uvarint(s.mem[s.docValueOffset+read : s.docValueOffset+read+binary.MaxVarintLen64]) + if n <= 0 { + return fmt.Errorf("loadDvReaders: failed to read the docvalue offset start for field %d", fieldID) + } + read += uint64(n) + fieldLocEnd, n = binary.Uvarint(s.mem[s.docValueOffset+read : s.docValueOffset+read+binary.MaxVarintLen64]) + if n <= 0 { + return fmt.Errorf("loadDvReaders: failed to read the docvalue offset end for field %d", fieldID) + } + read += uint64(n) + + fieldDvReader, err := s.loadFieldDocValueReader(field, fieldLocStart, fieldLocEnd) + if err != nil { + return err + } + if fieldDvReader != nil { + s.fieldDvReaders[uint16(fieldID)] = fieldDvReader + s.fieldDvNames = append(s.fieldDvNames, field) + } + } + + return nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/sizes.go b/backend/vendor/github.com/blevesearch/zapx/v11/sizes.go new file mode 100644 index 0000000000..34166ea330 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/sizes.go @@ -0,0 +1,59 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "reflect" +) + +func init() { + var b bool + SizeOfBool = int(reflect.TypeOf(b).Size()) + var f32 float32 + SizeOfFloat32 = int(reflect.TypeOf(f32).Size()) + var f64 float64 + SizeOfFloat64 = int(reflect.TypeOf(f64).Size()) + var i int + SizeOfInt = int(reflect.TypeOf(i).Size()) + var m map[int]int + SizeOfMap = int(reflect.TypeOf(m).Size()) + var ptr *int + SizeOfPtr = int(reflect.TypeOf(ptr).Size()) + var slice []int + SizeOfSlice = int(reflect.TypeOf(slice).Size()) + var str string + SizeOfString = int(reflect.TypeOf(str).Size()) + var u8 uint8 + SizeOfUint8 = int(reflect.TypeOf(u8).Size()) + var u16 uint16 + SizeOfUint16 = int(reflect.TypeOf(u16).Size()) + var u32 uint32 + SizeOfUint32 = int(reflect.TypeOf(u32).Size()) + var u64 uint64 + SizeOfUint64 = int(reflect.TypeOf(u64).Size()) +} + +var SizeOfBool int +var SizeOfFloat32 int +var SizeOfFloat64 int +var SizeOfInt int +var SizeOfMap int +var SizeOfPtr int +var SizeOfSlice int +var SizeOfString int +var SizeOfUint8 int +var SizeOfUint16 int +var SizeOfUint32 int +var SizeOfUint64 int diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/write.go b/backend/vendor/github.com/blevesearch/zapx/v11/write.go new file mode 100644 index 0000000000..cddaedd007 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/write.go @@ -0,0 +1,145 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "encoding/binary" + "io" + + "github.com/RoaringBitmap/roaring" +) + +// writes out the length of the roaring bitmap in bytes as varint +// then writes out the roaring bitmap itself +func writeRoaringWithLen(r *roaring.Bitmap, w io.Writer, + reuseBufVarint []byte) (int, error) { + buf, err := r.ToBytes() + if err != nil { + return 0, err + } + + var tw int + + // write out the length + n := binary.PutUvarint(reuseBufVarint, uint64(len(buf))) + nw, err := w.Write(reuseBufVarint[:n]) + tw += nw + if err != nil { + return tw, err + } + + // write out the roaring bytes + nw, err = w.Write(buf) + tw += nw + if err != nil { + return tw, err + } + + return tw, nil +} + +func persistFields(fieldsInv []string, w *CountHashWriter, dictLocs []uint64) (uint64, error) { + var rv uint64 + var fieldsOffsets []uint64 + + for fieldID, fieldName := range fieldsInv { + // record start of this field + fieldsOffsets = append(fieldsOffsets, uint64(w.Count())) + + // write out the dict location and field name length + _, err := writeUvarints(w, dictLocs[fieldID], uint64(len(fieldName))) + if err != nil { + return 0, err + } + + // write out the field name + _, err = w.Write([]byte(fieldName)) + if err != nil { + return 0, err + } + } + + // now write out the fields index + rv = uint64(w.Count()) + for fieldID := range fieldsInv { + err := binary.Write(w, binary.BigEndian, fieldsOffsets[fieldID]) + if err != nil { + return 0, err + } + } + + return rv, nil +} + +// FooterSize is the size of the footer record in bytes +// crc + ver + chunk + field offset + stored offset + num docs + docValueOffset +const FooterSize = 4 + 4 + 4 + 8 + 8 + 8 + 8 + +func persistFooter(numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset uint64, + chunkFactor uint32, crcBeforeFooter uint32, writerIn io.Writer) error { + w := NewCountHashWriter(writerIn) + w.crc = crcBeforeFooter + + // write out the number of docs + err := binary.Write(w, binary.BigEndian, numDocs) + if err != nil { + return err + } + // write out the stored field index location: + err = binary.Write(w, binary.BigEndian, storedIndexOffset) + if err != nil { + return err + } + // write out the field index location + err = binary.Write(w, binary.BigEndian, fieldsIndexOffset) + if err != nil { + return err + } + // write out the fieldDocValue location + err = binary.Write(w, binary.BigEndian, docValueOffset) + if err != nil { + return err + } + // write out 32-bit chunk factor + err = binary.Write(w, binary.BigEndian, chunkFactor) + if err != nil { + return err + } + // write out 32-bit version + err = binary.Write(w, binary.BigEndian, Version) + if err != nil { + return err + } + // write out CRC-32 of everything upto but not including this CRC + err = binary.Write(w, binary.BigEndian, w.crc) + if err != nil { + return err + } + return nil +} + +func writeUvarints(w io.Writer, vals ...uint64) (tw int, err error) { + buf := make([]byte, binary.MaxVarintLen64) + for _, val := range vals { + n := binary.PutUvarint(buf, val) + var nw int + nw, err = w.Write(buf[:n]) + tw += nw + if err != nil { + return tw, err + } + } + return tw, err +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v11/zap.md b/backend/vendor/github.com/blevesearch/zapx/v11/zap.md new file mode 100644 index 0000000000..d74dc548b8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v11/zap.md @@ -0,0 +1,177 @@ +# ZAP File Format + +## Legend + +### Sections + + |========| + | | section + |========| + +### Fixed-size fields + + |--------| |----| |--| |-| + | | uint64 | | uint32 | | uint16 | | uint8 + |--------| |----| |--| |-| + +### Varints + + |~~~~~~~~| + | | varint(up to uint64) + |~~~~~~~~| + +### Arbitrary-length fields + + |--------...---| + | | arbitrary-length field (string, vellum, roaring bitmap) + |--------...---| + +### Chunked data + + [--------] + [ ] + [--------] + +## Overview + +Footer section describes the configuration of particular ZAP file. The format of footer is version-dependent, so it is necessary to check `V` field before the parsing. + + |==================================================| + | Stored Fields | + |==================================================| + |-----> | Stored Fields Index | + | |==================================================| + | | Dictionaries + Postings + DocValues | + | |==================================================| + | |---> | DocValues Index | + | | |==================================================| + | | | Fields | + | | |==================================================| + | | |-> | Fields Index | + | | | |========|========|========|========|====|====|====| + | | | | D# | SF | F | FDV | CF | V | CC | (Footer) + | | | |========|====|===|====|===|====|===|====|====|====| + | | | | | | + |-+-+-----------------| | | + | |--------------------------| | + |-------------------------------------| + + D#. Number of Docs. + SF. Stored Fields Index Offset. + F. Field Index Offset. + FDV. Field DocValue Offset. + CF. Chunk Factor. + V. Version. + CC. CRC32. + +## Stored Fields + +Stored Fields Index is `D#` consecutive 64-bit unsigned integers - offsets, where relevant Stored Fields Data records are located. + + 0 [SF] [SF + D# * 8] + | Stored Fields | Stored Fields Index | + |================================|==================================| + | | | + | |--------------------| ||--------|--------|. . .|--------|| + | |-> | Stored Fields Data | || 0 | 1 | | D# - 1 || + | | |--------------------| ||--------|----|---|. . .|--------|| + | | | | | + |===|============================|==============|===================| + | | + |-------------------------------------------| + +Stored Fields Data is an arbitrary size record, which consists of metadata and [Snappy](https://github.com/golang/snappy)-compressed data. + + Stored Fields Data + |~~~~~~~~|~~~~~~~~|~~~~~~~~...~~~~~~~~|~~~~~~~~...~~~~~~~~| + | MDS | CDS | MD | CD | + |~~~~~~~~|~~~~~~~~|~~~~~~~~...~~~~~~~~|~~~~~~~~...~~~~~~~~| + + MDS. Metadata size. + CDS. Compressed data size. + MD. Metadata. + CD. Snappy-compressed data. + +## Fields + +Fields Index section located between addresses `F` and `len(file) - len(footer)` and consist of `uint64` values (`F1`, `F2`, ...) which are offsets to records in Fields section. We have `F# = (len(file) - len(footer) - F) / sizeof(uint64)` fields. + + + (...) [F] [F + F#] + | Fields | Fields Index. | + |================================|================================| + | | | + | |~~~~~~~~|~~~~~~~~|---...---|||--------|--------|...|--------|| + ||->| Dict | Length | Name ||| 0 | 1 | | F# - 1 || + || |~~~~~~~~|~~~~~~~~|---...---|||--------|----|---|...|--------|| + || | | | + ||===============================|==============|=================| + | | + |----------------------------------------------| + + +## Dictionaries + Postings + +Each of fields has its own dictionary, encoded in [Vellum](https://github.com/couchbase/vellum) format. Dictionary consists of pairs `(term, offset)`, where `offset` indicates the position of postings (list of documents) for this particular term. + + |================================================================|- Dictionaries + + | | Postings + + | | DocValues + | Freq/Norm (chunked) | + | [~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] | + | |->[ Freq | Norm (float32 under varint) ] | + | | [~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] | + | | | + | |------------------------------------------------------------| | + | Location Details (chunked) | | + | [~~~~~~|~~~~~|~~~~~~~|~~~~~|~~~~~~|~~~~~~~~|~~~~~] | | + | |->[ Size | Pos | Start | End | Arr# | ArrPos | ... ] | | + | | [~~~~~~|~~~~~|~~~~~~~|~~~~~|~~~~~~|~~~~~~~~|~~~~~] | | + | | | | + | |----------------------| | | + | Postings List | | | + | |~~~~~~~~|~~~~~|~~|~~~~~~~~|-----------...--| | | + | |->| F/N | LD | Length | ROARING BITMAP | | | + | | |~~~~~|~~|~~~~~~~~|~~~~~~~~|-----------...--| | | + | | |----------------------------------------------| | + | |--------------------------------------| | + | Dictionary | | + | |~~~~~~~~|--------------------------|-...-| | + | |->| Length | VELLUM DATA : (TERM -> OFFSET) | | + | | |~~~~~~~~|----------------------------...-| | + | | | + |======|=========================================================|- DocValues Index + | | | + |======|=========================================================|- Fields + | | | + | |~~~~|~~~|~~~~~~~~|---...---| | + | | Dict | Length | Name | | + | |~~~~~~~~|~~~~~~~~|---...---| | + | | + |================================================================| + +## DocValues + +DocValues Index is `F#` pairs of varints, one pair per field. Each pair of varints indicates start and end point of DocValues slice. + + |================================================================| + | |------...--| | + | |->| DocValues |<-| | + | | |------...--| | | + |==|=================|===========================================|- DocValues Index + ||~|~~~~~~~~~|~~~~~~~|~~| |~~~~~~~~~~~~~~|~~~~~~~~~~~~|| + || DV1 START | DV1 STOP | . . . . . | DV(F#) START | DV(F#) END || + ||~~~~~~~~~~~|~~~~~~~~~~| |~~~~~~~~~~~~~~|~~~~~~~~~~~~|| + |================================================================| + +DocValues is chunked Snappy-compressed values for each document and field. + + [~~~~~~~~~~~~~~~|~~~~~~|~~~~~~~~~|-...-|~~~~~~|~~~~~~~~~|--------------------...-] + [ Doc# in Chunk | Doc1 | Offset1 | ... | DocN | OffsetN | SNAPPY COMPRESSED DATA ] + [~~~~~~~~~~~~~~~|~~~~~~|~~~~~~~~~|-...-|~~~~~~|~~~~~~~~~|--------------------...-] + +Last 16 bytes are description of chunks. + + |~~~~~~~~~~~~...~|----------------|----------------| + | Chunk Sizes | Chunk Size Arr | Chunk# | + |~~~~~~~~~~~~...~|----------------|----------------| diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/.gitignore b/backend/vendor/github.com/blevesearch/zapx/v12/.gitignore new file mode 100644 index 0000000000..46d1cfad54 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/.gitignore @@ -0,0 +1,12 @@ +#* +*.sublime-* +*~ +.#* +.project +.settings +**/.idea/ +**/*.iml +.DS_Store +/cmd/zap/zap +*.test +tags diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/.golangci.yml b/backend/vendor/github.com/blevesearch/zapx/v12/.golangci.yml new file mode 100644 index 0000000000..1d55bfc00d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/.golangci.yml @@ -0,0 +1,28 @@ +linters: + # please, do not use `enable-all`: it's deprecated and will be removed soon. + # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint + disable-all: true + enable: + - bodyclose + - deadcode + - depguard + - dupl + - errcheck + - gofmt + - goimports + - goprintffuncname + - gosec + - gosimple + - govet + - ineffassign + - misspell + - nakedret + - nolintlint + - rowserrcheck + - staticcheck + - structcheck + - typecheck + - unused + - varcheck + - whitespace + diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/LICENSE b/backend/vendor/github.com/blevesearch/zapx/v12/LICENSE new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/README.md b/backend/vendor/github.com/blevesearch/zapx/v12/README.md new file mode 100644 index 0000000000..4cbf1a145b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/README.md @@ -0,0 +1,163 @@ +# zapx file format + +The zapx module is fork of [zap](https://github.com/blevesearch/zap) module which maintains file format compatibility, but removes dependency on bleve, and instead depends only on the indepenent interface modules: + +- [bleve_index_api](https://github.com/blevesearch/scorch_segment_api) +- [scorch_segment_api](https://github.com/blevesearch/scorch_segment_api) + +Advanced ZAP File Format Documentation is [here](zap.md). + +The file is written in the reverse order that we typically access data. This helps us write in one pass since later sections of the file require file offsets of things we've already written. + +Current usage: + +- mmap the entire file +- crc-32 bytes and version are in fixed position at end of the file +- reading remainder of footer could be version specific +- remainder of footer gives us: + - 3 important offsets (docValue , fields index and stored data index) + - 2 important values (number of docs and chunk factor) +- field data is processed once and memoized onto the heap so that we never have to go back to disk for it +- access to stored data by doc number means first navigating to the stored data index, then accessing a fixed position offset into that slice, which gives us the actual address of the data. the first bytes of that section tell us the size of data so that we know where it ends. +- access to all other indexed data follows the following pattern: + - first know the field name -> convert to id + - next navigate to term dictionary for that field + - some operations stop here and do dictionary ops + - next use dictionary to navigate to posting list for a specific term + - walk posting list + - if necessary, walk posting details as we go + - if location info is desired, consult location bitmap to see if it is there + +## stored fields section + +- for each document + - preparation phase: + - produce a slice of metadata bytes and data bytes + - produce these slices in field id order + - field value is appended to the data slice + - metadata slice is varint encoded with the following values for each field value + - field id (uint16) + - field type (byte) + - field value start offset in uncompressed data slice (uint64) + - field value length (uint64) + - field number of array positions (uint64) + - one additional value for each array position (uint64) + - compress the data slice using snappy + - file writing phase: + - remember the start offset for this document + - write out meta data length (varint uint64) + - write out compressed data length (varint uint64) + - write out the metadata bytes + - write out the compressed data bytes + +## stored fields idx + +- for each document + - write start offset (remembered from previous section) of stored data (big endian uint64) + +With this index and a known document number, we have direct access to all the stored field data. + +## posting details (freq/norm) section + +- for each posting list + - produce a slice containing multiple consecutive chunks (each chunk is varint stream) + - produce a slice remembering offsets of where each chunk starts + - preparation phase: + - for each hit in the posting list + - if this hit is in next chunk close out encoding of last chunk and record offset start of next + - encode term frequency (uint64) + - encode norm factor (float32) + - file writing phase: + - remember start position for this posting list details + - write out number of chunks that follow (varint uint64) + - write out length of each chunk (each a varint uint64) + - write out the byte slice containing all the chunk data + +If you know the doc number you're interested in, this format lets you jump to the correct chunk (docNum/chunkFactor) directly and then seek within that chunk until you find it. + +## posting details (location) section + +- for each posting list + - produce a slice containing multiple consecutive chunks (each chunk is varint stream) + - produce a slice remembering offsets of where each chunk starts + - preparation phase: + - for each hit in the posting list + - if this hit is in next chunk close out encoding of last chunk and record offset start of next + - encode field (uint16) + - encode field pos (uint64) + - encode field start (uint64) + - encode field end (uint64) + - encode number of array positions to follow (uint64) + - encode each array position (each uint64) + - file writing phase: + - remember start position for this posting list details + - write out number of chunks that follow (varint uint64) + - write out length of each chunk (each a varint uint64) + - write out the byte slice containing all the chunk data + +If you know the doc number you're interested in, this format lets you jump to the correct chunk (docNum/chunkFactor) directly and then seek within that chunk until you find it. + +## postings list section + +- for each posting list + - preparation phase: + - encode roaring bitmap posting list to bytes (so we know the length) + - file writing phase: + - remember the start position for this posting list + - write freq/norm details offset (remembered from previous, as varint uint64) + - write location details offset (remembered from previous, as varint uint64) + - write length of encoded roaring bitmap + - write the serialized roaring bitmap data + +## dictionary + +- for each field + - preparation phase: + - encode vellum FST with dictionary data pointing to file offset of posting list (remembered from previous) + - file writing phase: + - remember the start position of this persistDictionary + - write length of vellum data (varint uint64) + - write out vellum data + +## fields section + +- for each field + - file writing phase: + - remember start offset for each field + - write dictionary address (remembered from previous) (varint uint64) + - write length of field name (varint uint64) + - write field name bytes + +## fields idx + +- for each field + - file writing phase: + - write big endian uint64 of start offset for each field + +NOTE: currently we don't know or record the length of this fields index. Instead we rely on the fact that we know it immediately precedes a footer of known size. + +## fields DocValue + +- for each field + - preparation phase: + - produce a slice containing multiple consecutive chunks, where each chunk is composed of a meta section followed by compressed columnar field data + - produce a slice remembering the length of each chunk + - file writing phase: + - remember the start position of this first field DocValue offset in the footer + - write out number of chunks that follow (varint uint64) + - write out length of each chunk (each a varint uint64) + - write out the byte slice containing all the chunk data + +NOTE: currently the meta header inside each chunk gives clue to the location offsets and size of the data pertaining to a given docID and any +read operation leverage that meta information to extract the document specific data from the file. + +## footer + +- file writing phase + - write number of docs (big endian uint64) + - write stored field index location (big endian uint64) + - write field index location (big endian uint64) + - write field docValue location (big endian uint64) + - write out chunk factor (big endian uint32) + - write out version (big endian uint32) + - write out file CRC of everything preceding this (big endian uint32) diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/build.go b/backend/vendor/github.com/blevesearch/zapx/v12/build.go new file mode 100644 index 0000000000..de8265c140 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/build.go @@ -0,0 +1,186 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bufio" + "fmt" + "io" + "math" + "os" + + "github.com/blevesearch/vellum" +) + +const Version uint32 = 12 + +const Type string = "zap" + +const fieldNotUninverted = math.MaxUint64 + +func (sb *SegmentBase) Persist(path string) error { + return PersistSegmentBase(sb, path) +} + +// WriteTo is an implementation of io.WriterTo interface. +func (sb *SegmentBase) WriteTo(w io.Writer) (int64, error) { + if w == nil { + return 0, fmt.Errorf("invalid writer found") + } + + n, err := persistSegmentBaseToWriter(sb, w) + return int64(n), err +} + +// PersistSegmentBase persists SegmentBase in the zap file format. +func PersistSegmentBase(sb *SegmentBase, path string) error { + flag := os.O_RDWR | os.O_CREATE + + f, err := os.OpenFile(path, flag, 0600) + if err != nil { + return err + } + + cleanup := func() { + _ = f.Close() + _ = os.Remove(path) + } + + _, err = persistSegmentBaseToWriter(sb, f) + if err != nil { + cleanup() + return err + } + + err = f.Sync() + if err != nil { + cleanup() + return err + } + + err = f.Close() + if err != nil { + cleanup() + return err + } + + return err +} + +type bufWriter struct { + w *bufio.Writer + n int +} + +func (br *bufWriter) Write(in []byte) (int, error) { + n, err := br.w.Write(in) + br.n += n + return n, err +} + +func persistSegmentBaseToWriter(sb *SegmentBase, w io.Writer) (int, error) { + br := &bufWriter{w: bufio.NewWriter(w)} + + _, err := br.Write(sb.mem) + if err != nil { + return 0, err + } + + err = persistFooter(sb.numDocs, sb.storedIndexOffset, sb.fieldsIndexOffset, + sb.docValueOffset, sb.chunkMode, sb.memCRC, br) + if err != nil { + return 0, err + } + + err = br.w.Flush() + if err != nil { + return 0, err + } + + return br.n, nil +} + +func persistStoredFieldValues(fieldID int, + storedFieldValues [][]byte, stf []byte, spf [][]uint64, + curr int, metaEncode varintEncoder, data []byte) ( + int, []byte, error) { + for i := 0; i < len(storedFieldValues); i++ { + // encode field + _, err := metaEncode(uint64(fieldID)) + if err != nil { + return 0, nil, err + } + // encode type + _, err = metaEncode(uint64(stf[i])) + if err != nil { + return 0, nil, err + } + // encode start offset + _, err = metaEncode(uint64(curr)) + if err != nil { + return 0, nil, err + } + // end len + _, err = metaEncode(uint64(len(storedFieldValues[i]))) + if err != nil { + return 0, nil, err + } + // encode number of array pos + _, err = metaEncode(uint64(len(spf[i]))) + if err != nil { + return 0, nil, err + } + // encode all array positions + for _, pos := range spf[i] { + _, err = metaEncode(pos) + if err != nil { + return 0, nil, err + } + } + + data = append(data, storedFieldValues[i]...) + curr += len(storedFieldValues[i]) + } + + return curr, data, nil +} + +func InitSegmentBase(mem []byte, memCRC uint32, chunkMode uint32, + fieldsMap map[string]uint16, fieldsInv []string, numDocs uint64, + storedIndexOffset uint64, fieldsIndexOffset uint64, docValueOffset uint64, + dictLocs []uint64) (*SegmentBase, error) { + sb := &SegmentBase{ + mem: mem, + memCRC: memCRC, + chunkMode: chunkMode, + fieldsMap: fieldsMap, + fieldsInv: fieldsInv, + numDocs: numDocs, + storedIndexOffset: storedIndexOffset, + fieldsIndexOffset: fieldsIndexOffset, + docValueOffset: docValueOffset, + dictLocs: dictLocs, + fieldDvReaders: make(map[uint16]*docValueReader), + fieldFSTs: make(map[uint16]*vellum.FST), + } + sb.updateSize() + + err := sb.loadDvReaders() + if err != nil { + return nil, err + } + + return sb, nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/chunk.go b/backend/vendor/github.com/blevesearch/zapx/v12/chunk.go new file mode 100644 index 0000000000..fe9f398da6 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/chunk.go @@ -0,0 +1,54 @@ +// Copyright (c) 2019 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "fmt" +) + +// LegacyChunkMode was the original chunk mode (always chunk size 1024) +// this mode is still used for chunking doc values. +var LegacyChunkMode uint32 = 1024 + +// DefaultChunkMode is the most recent improvement to chunking and should +// be used by default. +var DefaultChunkMode uint32 = 1025 + +func getChunkSize(chunkMode uint32, cardinality uint64, maxDocs uint64) (uint64, error) { + switch { + // any chunkMode <= 1024 will always chunk with chunkSize=chunkMode + case chunkMode <= 1024: + // legacy chunk size + return uint64(chunkMode), nil + + case chunkMode == 1025: + // attempt at simple improvement + // theory - the point of chunking is to put a bound on the maximum number of + // calls to Next() needed to find a random document. ie, you should be able + // to do one jump to the correct chunk, and then walk through at most + // chunk-size items + // previously 1024 was chosen as the chunk size, but this is particularly + // wasteful for low cardinality terms. the observation is that if there + // are less than 1024 items, why not put them all in one chunk, + // this way you'll still achieve the same goal of visiting at most + // chunk-size items. + // no attempt is made to tweak any other case + if cardinality <= 1024 { + return maxDocs, nil + } + return 1024, nil + } + return 0, fmt.Errorf("unknown chunk mode %d", chunkMode) +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/contentcoder.go b/backend/vendor/github.com/blevesearch/zapx/v12/contentcoder.go new file mode 100644 index 0000000000..c145b5a113 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/contentcoder.go @@ -0,0 +1,243 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "io" + "reflect" + + "github.com/golang/snappy" +) + +var reflectStaticSizeMetaData int + +func init() { + var md MetaData + reflectStaticSizeMetaData = int(reflect.TypeOf(md).Size()) +} + +var termSeparator byte = 0xff +var termSeparatorSplitSlice = []byte{termSeparator} + +type chunkedContentCoder struct { + final []byte + chunkSize uint64 + currChunk uint64 + chunkLens []uint64 + + w io.Writer + progressiveWrite bool + + chunkMetaBuf bytes.Buffer + chunkBuf bytes.Buffer + + chunkMeta []MetaData + + compressed []byte // temp buf for snappy compression +} + +// MetaData represents the data information inside a +// chunk. +type MetaData struct { + DocNum uint64 // docNum of the data inside the chunk + DocDvOffset uint64 // offset of data inside the chunk for the given docid +} + +// newChunkedContentCoder returns a new chunk content coder which +// packs data into chunks based on the provided chunkSize +func newChunkedContentCoder(chunkSize uint64, maxDocNum uint64, + w io.Writer, progressiveWrite bool) *chunkedContentCoder { + total := maxDocNum/chunkSize + 1 + rv := &chunkedContentCoder{ + chunkSize: chunkSize, + chunkLens: make([]uint64, total), + chunkMeta: make([]MetaData, 0, total), + w: w, + progressiveWrite: progressiveWrite, + } + + return rv +} + +// Reset lets you reuse this chunked content coder. Buffers are reset +// and re used. You cannot change the chunk size. +func (c *chunkedContentCoder) Reset() { + c.currChunk = 0 + c.final = c.final[:0] + c.chunkBuf.Reset() + c.chunkMetaBuf.Reset() + for i := range c.chunkLens { + c.chunkLens[i] = 0 + } + c.chunkMeta = c.chunkMeta[:0] +} + +func (c *chunkedContentCoder) SetChunkSize(chunkSize uint64, maxDocNum uint64) { + total := int(maxDocNum/chunkSize + 1) + c.chunkSize = chunkSize + if cap(c.chunkLens) < total { + c.chunkLens = make([]uint64, total) + } else { + c.chunkLens = c.chunkLens[:total] + } + if cap(c.chunkMeta) < total { + c.chunkMeta = make([]MetaData, 0, total) + } +} + +// Close indicates you are done calling Add() this allows +// the final chunk to be encoded. +func (c *chunkedContentCoder) Close() error { + return c.flushContents() +} + +func (c *chunkedContentCoder) flushContents() error { + // flush the contents, with meta information at first + buf := make([]byte, binary.MaxVarintLen64) + n := binary.PutUvarint(buf, uint64(len(c.chunkMeta))) + _, err := c.chunkMetaBuf.Write(buf[:n]) + if err != nil { + return err + } + + // write out the metaData slice + for _, meta := range c.chunkMeta { + _, err := writeUvarints(&c.chunkMetaBuf, meta.DocNum, meta.DocDvOffset) + if err != nil { + return err + } + } + + // write the metadata to final data + metaData := c.chunkMetaBuf.Bytes() + c.final = append(c.final, c.chunkMetaBuf.Bytes()...) + // write the compressed data to the final data + c.compressed = snappy.Encode(c.compressed[:cap(c.compressed)], c.chunkBuf.Bytes()) + c.final = append(c.final, c.compressed...) + + c.chunkLens[c.currChunk] = uint64(len(c.compressed) + len(metaData)) + + if c.progressiveWrite { + _, err := c.w.Write(c.final) + if err != nil { + return err + } + c.final = c.final[:0] + } + + return nil +} + +// Add encodes the provided byte slice into the correct chunk for the provided +// doc num. You MUST call Add() with increasing docNums. +func (c *chunkedContentCoder) Add(docNum uint64, vals []byte) error { + chunk := docNum / c.chunkSize + if chunk != c.currChunk { + // flush out the previous chunk details + err := c.flushContents() + if err != nil { + return err + } + // clearing the chunk specific meta for next chunk + c.chunkBuf.Reset() + c.chunkMetaBuf.Reset() + c.chunkMeta = c.chunkMeta[:0] + c.currChunk = chunk + } + + // get the starting offset for this doc + dvOffset := c.chunkBuf.Len() + dvSize, err := c.chunkBuf.Write(vals) + if err != nil { + return err + } + + c.chunkMeta = append(c.chunkMeta, MetaData{ + DocNum: docNum, + DocDvOffset: uint64(dvOffset + dvSize), + }) + return nil +} + +// Write commits all the encoded chunked contents to the provided writer. +// +// | ..... data ..... | chunk offsets (varints) +// | position of chunk offsets (uint64) | number of offsets (uint64) | +// +func (c *chunkedContentCoder) Write() (int, error) { + var tw int + + if c.final != nil { + // write out the data section first + nw, err := c.w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + } + + chunkOffsetsStart := uint64(tw) + + if cap(c.final) < binary.MaxVarintLen64 { + c.final = make([]byte, binary.MaxVarintLen64) + } else { + c.final = c.final[0:binary.MaxVarintLen64] + } + chunkOffsets := modifyLengthsToEndOffsets(c.chunkLens) + // write out the chunk offsets + for _, chunkOffset := range chunkOffsets { + n := binary.PutUvarint(c.final, chunkOffset) + nw, err := c.w.Write(c.final[:n]) + tw += nw + if err != nil { + return tw, err + } + } + + chunkOffsetsLen := uint64(tw) - chunkOffsetsStart + + c.final = c.final[0:8] + // write out the length of chunk offsets + binary.BigEndian.PutUint64(c.final, chunkOffsetsLen) + nw, err := c.w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + + // write out the number of chunks + binary.BigEndian.PutUint64(c.final, uint64(len(c.chunkLens))) + nw, err = c.w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + + c.final = c.final[:0] + + return tw, nil +} + +// ReadDocValueBoundary elicits the start, end offsets from a +// metaData header slice +func ReadDocValueBoundary(chunk int, metaHeaders []MetaData) (uint64, uint64) { + var start uint64 + if chunk > 0 { + start = metaHeaders[chunk-1].DocDvOffset + } + return start, metaHeaders[chunk].DocDvOffset +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/count.go b/backend/vendor/github.com/blevesearch/zapx/v12/count.go new file mode 100644 index 0000000000..b6135359fb --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/count.go @@ -0,0 +1,61 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "hash/crc32" + "io" + + segment "github.com/blevesearch/scorch_segment_api/v2" +) + +// CountHashWriter is a wrapper around a Writer which counts the number of +// bytes which have been written and computes a crc32 hash +type CountHashWriter struct { + w io.Writer + crc uint32 + n int + s segment.StatsReporter +} + +// NewCountHashWriter returns a CountHashWriter which wraps the provided Writer +func NewCountHashWriter(w io.Writer) *CountHashWriter { + return &CountHashWriter{w: w} +} + +func NewCountHashWriterWithStatsReporter(w io.Writer, s segment.StatsReporter) *CountHashWriter { + return &CountHashWriter{w: w, s: s} +} + +// Write writes the provided bytes to the wrapped writer and counts the bytes +func (c *CountHashWriter) Write(b []byte) (int, error) { + n, err := c.w.Write(b) + c.crc = crc32.Update(c.crc, crc32.IEEETable, b[:n]) + c.n += n + if c.s != nil { + c.s.ReportBytesWritten(uint64(n)) + } + return n, err +} + +// Count returns the number of bytes written +func (c *CountHashWriter) Count() int { + return c.n +} + +// Sum32 returns the CRC-32 hash of the content written to this writer +func (c *CountHashWriter) Sum32() uint32 { + return c.crc +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/dict.go b/backend/vendor/github.com/blevesearch/zapx/v12/dict.go new file mode 100644 index 0000000000..e30bf2420d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/dict.go @@ -0,0 +1,158 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "fmt" + + "github.com/RoaringBitmap/roaring" + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" +) + +// Dictionary is the zap representation of the term dictionary +type Dictionary struct { + sb *SegmentBase + field string + fieldID uint16 + fst *vellum.FST + fstReader *vellum.Reader +} + +// represents an immutable, empty dictionary +var emptyDictionary = &Dictionary{} + +// PostingsList returns the postings list for the specified term +func (d *Dictionary) PostingsList(term []byte, except *roaring.Bitmap, + prealloc segment.PostingsList) (segment.PostingsList, error) { + var preallocPL *PostingsList + pl, ok := prealloc.(*PostingsList) + if ok && pl != nil { + preallocPL = pl + } + return d.postingsList(term, except, preallocPL) +} + +func (d *Dictionary) postingsList(term []byte, except *roaring.Bitmap, rv *PostingsList) (*PostingsList, error) { + if d.fstReader == nil { + if rv == nil || rv == emptyPostingsList { + return emptyPostingsList, nil + } + return d.postingsListInit(rv, except), nil + } + + postingsOffset, exists, err := d.fstReader.Get(term) + if err != nil { + return nil, fmt.Errorf("vellum err: %v", err) + } + if !exists { + if rv == nil || rv == emptyPostingsList { + return emptyPostingsList, nil + } + return d.postingsListInit(rv, except), nil + } + + return d.postingsListFromOffset(postingsOffset, except, rv) +} + +func (d *Dictionary) postingsListFromOffset(postingsOffset uint64, except *roaring.Bitmap, rv *PostingsList) (*PostingsList, error) { + rv = d.postingsListInit(rv, except) + + err := rv.read(postingsOffset, d) + if err != nil { + return nil, err + } + + return rv, nil +} + +func (d *Dictionary) postingsListInit(rv *PostingsList, except *roaring.Bitmap) *PostingsList { + if rv == nil || rv == emptyPostingsList { + rv = &PostingsList{} + } else { + postings := rv.postings + if postings != nil { + postings.Clear() + } + + *rv = PostingsList{} // clear the struct + + rv.postings = postings + } + rv.sb = d.sb + rv.except = except + return rv +} + +func (d *Dictionary) Contains(key []byte) (bool, error) { + if d.fst != nil { + return d.fst.Contains(key) + } + return false, nil +} + +// AutomatonIterator returns an iterator which only visits terms +// having the the vellum automaton and start/end key range +func (d *Dictionary) AutomatonIterator(a segment.Automaton, + startKeyInclusive, endKeyExclusive []byte) segment.DictionaryIterator { + if d.fst != nil { + rv := &DictionaryIterator{ + d: d, + } + + itr, err := d.fst.Search(a, startKeyInclusive, endKeyExclusive) + if err == nil { + rv.itr = itr + } else if err != vellum.ErrIteratorDone { + rv.err = err + } + + return rv + } + return emptyDictionaryIterator +} + +// DictionaryIterator is an iterator for term dictionary +type DictionaryIterator struct { + d *Dictionary + itr vellum.Iterator + err error + tmp PostingsList + entry index.DictEntry + omitCount bool +} + +var emptyDictionaryIterator = &DictionaryIterator{} + +// Next returns the next entry in the dictionary +func (i *DictionaryIterator) Next() (*index.DictEntry, error) { + if i.err != nil && i.err != vellum.ErrIteratorDone { + return nil, i.err + } else if i.itr == nil || i.err == vellum.ErrIteratorDone { + return nil, nil + } + term, postingsOffset := i.itr.Current() + i.entry.Term = string(term) + if !i.omitCount { + i.err = i.tmp.read(postingsOffset, i.d) + if i.err != nil { + return nil, i.err + } + i.entry.Count = i.tmp.Count() + } + i.err = i.itr.Next() + return &i.entry, nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/docvalues.go b/backend/vendor/github.com/blevesearch/zapx/v12/docvalues.go new file mode 100644 index 0000000000..a36485c870 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/docvalues.go @@ -0,0 +1,323 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "fmt" + "math" + "reflect" + "sort" + + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/golang/snappy" +) + +var reflectStaticSizedocValueReader int + +func init() { + var dvi docValueReader + reflectStaticSizedocValueReader = int(reflect.TypeOf(dvi).Size()) +} + +type docNumTermsVisitor func(docNum uint64, terms []byte) error + +type docVisitState struct { + dvrs map[uint16]*docValueReader + segment *SegmentBase +} + +// No-op implementations for DiskStatsReporter interface. +// Supported only in v15 +func (d *docVisitState) BytesRead() uint64 { + return 0 +} + +func (d *docVisitState) BytesWritten() uint64 { + return 0 +} + +func (d *docVisitState) ResetBytesRead(val uint64) {} + +type docValueReader struct { + field string + curChunkNum uint64 + chunkOffsets []uint64 + dvDataLoc uint64 + curChunkHeader []MetaData + curChunkData []byte // compressed data cache + uncompressed []byte // temp buf for snappy decompression +} + +func (di *docValueReader) size() int { + return reflectStaticSizedocValueReader + SizeOfPtr + + len(di.field) + + len(di.chunkOffsets)*SizeOfUint64 + + len(di.curChunkHeader)*reflectStaticSizeMetaData + + len(di.curChunkData) +} + +func (di *docValueReader) cloneInto(rv *docValueReader) *docValueReader { + if rv == nil { + rv = &docValueReader{} + } + + rv.field = di.field + rv.curChunkNum = math.MaxUint64 + rv.chunkOffsets = di.chunkOffsets // immutable, so it's sharable + rv.dvDataLoc = di.dvDataLoc + rv.curChunkHeader = rv.curChunkHeader[:0] + rv.curChunkData = nil + rv.uncompressed = rv.uncompressed[:0] + + return rv +} + +func (di *docValueReader) curChunkNumber() uint64 { + return di.curChunkNum +} + +func (s *SegmentBase) loadFieldDocValueReader(field string, + fieldDvLocStart, fieldDvLocEnd uint64) (*docValueReader, error) { + // get the docValue offset for the given fields + if fieldDvLocStart == fieldNotUninverted { + // no docValues found, nothing to do + return nil, nil + } + + // read the number of chunks, and chunk offsets position + var numChunks, chunkOffsetsPosition uint64 + + if fieldDvLocEnd-fieldDvLocStart > 16 { + numChunks = binary.BigEndian.Uint64(s.mem[fieldDvLocEnd-8 : fieldDvLocEnd]) + // read the length of chunk offsets + chunkOffsetsLen := binary.BigEndian.Uint64(s.mem[fieldDvLocEnd-16 : fieldDvLocEnd-8]) + // acquire position of chunk offsets + chunkOffsetsPosition = (fieldDvLocEnd - 16) - chunkOffsetsLen + } else { + return nil, fmt.Errorf("loadFieldDocValueReader: fieldDvLoc too small: %d-%d", fieldDvLocEnd, fieldDvLocStart) + } + + fdvIter := &docValueReader{ + curChunkNum: math.MaxUint64, + field: field, + chunkOffsets: make([]uint64, int(numChunks)), + } + + // read the chunk offsets + var offset uint64 + for i := 0; i < int(numChunks); i++ { + loc, read := binary.Uvarint(s.mem[chunkOffsetsPosition+offset : chunkOffsetsPosition+offset+binary.MaxVarintLen64]) + if read <= 0 { + return nil, fmt.Errorf("corrupted chunk offset during segment load") + } + fdvIter.chunkOffsets[i] = loc + offset += uint64(read) + } + + // set the data offset + fdvIter.dvDataLoc = fieldDvLocStart + + return fdvIter, nil +} + +func (di *docValueReader) loadDvChunk(chunkNumber uint64, s *SegmentBase) error { + // advance to the chunk where the docValues + // reside for the given docNum + destChunkDataLoc, curChunkEnd := di.dvDataLoc, di.dvDataLoc + start, end := readChunkBoundary(int(chunkNumber), di.chunkOffsets) + if start >= end { + di.curChunkHeader = di.curChunkHeader[:0] + di.curChunkData = nil + di.curChunkNum = chunkNumber + di.uncompressed = di.uncompressed[:0] + return nil + } + + destChunkDataLoc += start + curChunkEnd += end + + // read the number of docs reside in the chunk + numDocs, read := binary.Uvarint(s.mem[destChunkDataLoc : destChunkDataLoc+binary.MaxVarintLen64]) + if read <= 0 { + return fmt.Errorf("failed to read the chunk") + } + chunkMetaLoc := destChunkDataLoc + uint64(read) + + offset := uint64(0) + if cap(di.curChunkHeader) < int(numDocs) { + di.curChunkHeader = make([]MetaData, int(numDocs)) + } else { + di.curChunkHeader = di.curChunkHeader[:int(numDocs)] + } + for i := 0; i < int(numDocs); i++ { + di.curChunkHeader[i].DocNum, read = binary.Uvarint(s.mem[chunkMetaLoc+offset : chunkMetaLoc+offset+binary.MaxVarintLen64]) + offset += uint64(read) + di.curChunkHeader[i].DocDvOffset, read = binary.Uvarint(s.mem[chunkMetaLoc+offset : chunkMetaLoc+offset+binary.MaxVarintLen64]) + offset += uint64(read) + } + + compressedDataLoc := chunkMetaLoc + offset + dataLength := curChunkEnd - compressedDataLoc + di.curChunkData = s.mem[compressedDataLoc : compressedDataLoc+dataLength] + di.curChunkNum = chunkNumber + di.uncompressed = di.uncompressed[:0] + return nil +} + +func (di *docValueReader) iterateAllDocValues(s *SegmentBase, visitor docNumTermsVisitor) error { + for i := 0; i < len(di.chunkOffsets); i++ { + err := di.loadDvChunk(uint64(i), s) + if err != nil { + return err + } + if di.curChunkData == nil || len(di.curChunkHeader) == 0 { + continue + } + + // uncompress the already loaded data + uncompressed, err := snappy.Decode(di.uncompressed[:cap(di.uncompressed)], di.curChunkData) + if err != nil { + return err + } + di.uncompressed = uncompressed + + start := uint64(0) + for _, entry := range di.curChunkHeader { + err = visitor(entry.DocNum, uncompressed[start:entry.DocDvOffset]) + if err != nil { + return err + } + + start = entry.DocDvOffset + } + } + + return nil +} + +func (di *docValueReader) visitDocValues(docNum uint64, + visitor index.DocValueVisitor) error { + // binary search the term locations for the docNum + start, end := di.getDocValueLocs(docNum) + if start == math.MaxUint64 || end == math.MaxUint64 || start == end { + return nil + } + + var uncompressed []byte + var err error + // use the uncompressed copy if available + if len(di.uncompressed) > 0 { + uncompressed = di.uncompressed + } else { + // uncompress the already loaded data + uncompressed, err = snappy.Decode(di.uncompressed[:cap(di.uncompressed)], di.curChunkData) + if err != nil { + return err + } + di.uncompressed = uncompressed + } + + // pick the terms for the given docNum + uncompressed = uncompressed[start:end] + for { + i := bytes.Index(uncompressed, termSeparatorSplitSlice) + if i < 0 { + break + } + + visitor(di.field, uncompressed[0:i]) + uncompressed = uncompressed[i+1:] + } + + return nil +} + +func (di *docValueReader) getDocValueLocs(docNum uint64) (uint64, uint64) { + i := sort.Search(len(di.curChunkHeader), func(i int) bool { + return di.curChunkHeader[i].DocNum >= docNum + }) + if i < len(di.curChunkHeader) && di.curChunkHeader[i].DocNum == docNum { + return ReadDocValueBoundary(i, di.curChunkHeader) + } + return math.MaxUint64, math.MaxUint64 +} + +// VisitDocValues is an implementation of the +// DocValueVisitable interface +func (s *SegmentBase) VisitDocValues(localDocNum uint64, fields []string, + visitor index.DocValueVisitor, dvsIn segment.DocVisitState) ( + segment.DocVisitState, error) { + dvs, ok := dvsIn.(*docVisitState) + if !ok || dvs == nil { + dvs = &docVisitState{} + } else { + if dvs.segment != s { + dvs.segment = s + dvs.dvrs = nil + } + } + + var fieldIDPlus1 uint16 + if dvs.dvrs == nil { + dvs.dvrs = make(map[uint16]*docValueReader, len(fields)) + for _, field := range fields { + if fieldIDPlus1, ok = s.fieldsMap[field]; !ok { + continue + } + fieldID := fieldIDPlus1 - 1 + if dvIter, exists := s.fieldDvReaders[fieldID]; exists && + dvIter != nil { + dvs.dvrs[fieldID] = dvIter.cloneInto(dvs.dvrs[fieldID]) + } + } + } + + // find the chunkNumber where the docValues are stored + // NOTE: doc values continue to use legacy chunk mode + chunkFactor, err := getChunkSize(LegacyChunkMode, 0, 0) + if err != nil { + return nil, err + } + docInChunk := localDocNum / chunkFactor + var dvr *docValueReader + for _, field := range fields { + if fieldIDPlus1, ok = s.fieldsMap[field]; !ok { + continue + } + fieldID := fieldIDPlus1 - 1 + if dvr, ok = dvs.dvrs[fieldID]; ok && dvr != nil { + // check if the chunk is already loaded + if docInChunk != dvr.curChunkNumber() { + err := dvr.loadDvChunk(docInChunk, s) + if err != nil { + return dvs, err + } + } + + _ = dvr.visitDocValues(localDocNum, visitor) + } + } + return dvs, nil +} + +// VisitableDocValueFields returns the list of fields with +// persisted doc value terms ready to be visitable using the +// VisitDocumentFieldTerms method. +func (s *SegmentBase) VisitableDocValueFields() ([]string, error) { + return s.fieldDvNames, nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/enumerator.go b/backend/vendor/github.com/blevesearch/zapx/v12/enumerator.go new file mode 100644 index 0000000000..972a224165 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/enumerator.go @@ -0,0 +1,138 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + + "github.com/blevesearch/vellum" +) + +// enumerator provides an ordered traversal of multiple vellum +// iterators. Like JOIN of iterators, the enumerator produces a +// sequence of (key, iteratorIndex, value) tuples, sorted by key ASC, +// then iteratorIndex ASC, where the same key might be seen or +// repeated across multiple child iterators. +type enumerator struct { + itrs []vellum.Iterator + currKs [][]byte + currVs []uint64 + + lowK []byte + lowIdxs []int + lowCurr int +} + +// newEnumerator returns a new enumerator over the vellum Iterators +func newEnumerator(itrs []vellum.Iterator) (*enumerator, error) { + rv := &enumerator{ + itrs: itrs, + currKs: make([][]byte, len(itrs)), + currVs: make([]uint64, len(itrs)), + lowIdxs: make([]int, 0, len(itrs)), + } + for i, itr := range rv.itrs { + rv.currKs[i], rv.currVs[i] = itr.Current() + } + rv.updateMatches(false) + if rv.lowK == nil && len(rv.lowIdxs) == 0 { + return rv, vellum.ErrIteratorDone + } + return rv, nil +} + +// updateMatches maintains the low key matches based on the currKs +func (m *enumerator) updateMatches(skipEmptyKey bool) { + m.lowK = nil + m.lowIdxs = m.lowIdxs[:0] + m.lowCurr = 0 + + for i, key := range m.currKs { + if (key == nil && m.currVs[i] == 0) || // in case of empty iterator + (len(key) == 0 && skipEmptyKey) { // skip empty keys + continue + } + + cmp := bytes.Compare(key, m.lowK) + if cmp < 0 || len(m.lowIdxs) == 0 { + // reached a new low + m.lowK = key + m.lowIdxs = m.lowIdxs[:0] + m.lowIdxs = append(m.lowIdxs, i) + } else if cmp == 0 { + m.lowIdxs = append(m.lowIdxs, i) + } + } +} + +// Current returns the enumerator's current key, iterator-index, and +// value. If the enumerator is not pointing at a valid value (because +// Next returned an error previously), Current will return nil,0,0. +func (m *enumerator) Current() ([]byte, int, uint64) { + var i int + var v uint64 + if m.lowCurr < len(m.lowIdxs) { + i = m.lowIdxs[m.lowCurr] + v = m.currVs[i] + } + return m.lowK, i, v +} + +// GetLowIdxsAndValues will return all of the iterator indices +// which point to the current key, and their corresponding +// values. This can be used by advanced caller which may need +// to peek into these other sets of data before processing. +func (m *enumerator) GetLowIdxsAndValues() ([]int, []uint64) { + values := make([]uint64, 0, len(m.lowIdxs)) + for _, idx := range m.lowIdxs { + values = append(values, m.currVs[idx]) + } + return m.lowIdxs, values +} + +// Next advances the enumerator to the next key/iterator/value result, +// else vellum.ErrIteratorDone is returned. +func (m *enumerator) Next() error { + m.lowCurr += 1 + if m.lowCurr >= len(m.lowIdxs) { + // move all the current low iterators forwards + for _, vi := range m.lowIdxs { + err := m.itrs[vi].Next() + if err != nil && err != vellum.ErrIteratorDone { + return err + } + m.currKs[vi], m.currVs[vi] = m.itrs[vi].Current() + } + // can skip any empty keys encountered at this point + m.updateMatches(true) + } + if m.lowK == nil && len(m.lowIdxs) == 0 { + return vellum.ErrIteratorDone + } + return nil +} + +// Close all the underlying Iterators. The first error, if any, will +// be returned. +func (m *enumerator) Close() error { + var rv error + for _, itr := range m.itrs { + err := itr.Close() + if rv == nil { + rv = err + } + } + return rv +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/intDecoder.go b/backend/vendor/github.com/blevesearch/zapx/v12/intDecoder.go new file mode 100644 index 0000000000..e968093149 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/intDecoder.go @@ -0,0 +1,109 @@ +// Copyright (c) 2019 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "encoding/binary" + "fmt" +) + +type chunkedIntDecoder struct { + startOffset uint64 + dataStartOffset uint64 + chunkOffsets []uint64 + curChunkBytes []byte + data []byte + r *memUvarintReader +} + +func newChunkedIntDecoder(buf []byte, offset uint64) *chunkedIntDecoder { + rv := &chunkedIntDecoder{startOffset: offset, data: buf} + var n, numChunks uint64 + var read int + if offset == termNotEncoded { + numChunks = 0 + } else { + numChunks, read = binary.Uvarint(buf[offset+n : offset+n+binary.MaxVarintLen64]) + } + + n += uint64(read) + if cap(rv.chunkOffsets) >= int(numChunks) { + rv.chunkOffsets = rv.chunkOffsets[:int(numChunks)] + } else { + rv.chunkOffsets = make([]uint64, int(numChunks)) + } + for i := 0; i < int(numChunks); i++ { + rv.chunkOffsets[i], read = binary.Uvarint(buf[offset+n : offset+n+binary.MaxVarintLen64]) + n += uint64(read) + } + rv.dataStartOffset = offset + n + return rv +} + +func (d *chunkedIntDecoder) loadChunk(chunk int) error { + if d.startOffset == termNotEncoded { + d.r = newMemUvarintReader([]byte(nil)) + return nil + } + + if chunk >= len(d.chunkOffsets) { + return fmt.Errorf("tried to load freq chunk that doesn't exist %d/(%d)", + chunk, len(d.chunkOffsets)) + } + + end, start := d.dataStartOffset, d.dataStartOffset + s, e := readChunkBoundary(chunk, d.chunkOffsets) + start += s + end += e + d.curChunkBytes = d.data[start:end] + if d.r == nil { + d.r = newMemUvarintReader(d.curChunkBytes) + } else { + d.r.Reset(d.curChunkBytes) + } + + return nil +} + +func (d *chunkedIntDecoder) reset() { + d.startOffset = 0 + d.dataStartOffset = 0 + d.chunkOffsets = d.chunkOffsets[:0] + d.curChunkBytes = d.curChunkBytes[:0] + d.data = d.data[:0] + if d.r != nil { + d.r.Reset([]byte(nil)) + } +} + +func (d *chunkedIntDecoder) isNil() bool { + return d.curChunkBytes == nil +} + +func (d *chunkedIntDecoder) readUvarint() (uint64, error) { + return d.r.ReadUvarint() +} + +func (d *chunkedIntDecoder) SkipUvarint() { + d.r.SkipUvarint() +} + +func (d *chunkedIntDecoder) SkipBytes(count int) { + d.r.SkipBytes(count) +} + +func (d *chunkedIntDecoder) Len() int { + return d.r.Len() +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/intcoder.go b/backend/vendor/github.com/blevesearch/zapx/v12/intcoder.go new file mode 100644 index 0000000000..7682593e9f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/intcoder.go @@ -0,0 +1,203 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "io" + "math" +) + +const termNotEncoded = math.MaxUint64 + +type chunkedIntCoder struct { + final []byte + chunkSize uint64 + chunkBuf bytes.Buffer + chunkLens []uint64 + currChunk uint64 + + buf []byte +} + +// newChunkedIntCoder returns a new chunk int coder which packs data into +// chunks based on the provided chunkSize and supports up to the specified +// maxDocNum +func newChunkedIntCoder(chunkSize uint64, maxDocNum uint64) *chunkedIntCoder { + total := maxDocNum/chunkSize + 1 + rv := &chunkedIntCoder{ + chunkSize: chunkSize, + chunkLens: make([]uint64, total), + final: make([]byte, 0, 64), + } + + return rv +} + +// Reset lets you reuse this chunked int coder. buffers are reset and reused +// from previous use. you cannot change the chunk size or max doc num. +func (c *chunkedIntCoder) Reset() { + c.final = c.final[:0] + c.chunkBuf.Reset() + c.currChunk = 0 + for i := range c.chunkLens { + c.chunkLens[i] = 0 + } +} + +// SetChunkSize changes the chunk size. It is only valid to do so +// with a new chunkedIntCoder, or immediately after calling Reset() +func (c *chunkedIntCoder) SetChunkSize(chunkSize uint64, maxDocNum uint64) { + total := int(maxDocNum/chunkSize + 1) + c.chunkSize = chunkSize + if cap(c.chunkLens) < total { + c.chunkLens = make([]uint64, total) + } else { + c.chunkLens = c.chunkLens[:total] + } +} + +// Add encodes the provided integers into the correct chunk for the provided +// doc num. You MUST call Add() with increasing docNums. +func (c *chunkedIntCoder) Add(docNum uint64, vals ...uint64) error { + chunk := docNum / c.chunkSize + if chunk != c.currChunk { + // starting a new chunk + c.Close() + c.chunkBuf.Reset() + c.currChunk = chunk + } + + if len(c.buf) < binary.MaxVarintLen64 { + c.buf = make([]byte, binary.MaxVarintLen64) + } + + for _, val := range vals { + wb := binary.PutUvarint(c.buf, val) + _, err := c.chunkBuf.Write(c.buf[:wb]) + if err != nil { + return err + } + } + + return nil +} + +func (c *chunkedIntCoder) AddBytes(docNum uint64, buf []byte) error { + chunk := docNum / c.chunkSize + if chunk != c.currChunk { + // starting a new chunk + c.Close() + c.chunkBuf.Reset() + c.currChunk = chunk + } + + _, err := c.chunkBuf.Write(buf) + return err +} + +// Close indicates you are done calling Add() this allows the final chunk +// to be encoded. +func (c *chunkedIntCoder) Close() { + encodingBytes := c.chunkBuf.Bytes() + c.chunkLens[c.currChunk] = uint64(len(encodingBytes)) + c.final = append(c.final, encodingBytes...) + c.currChunk = uint64(cap(c.chunkLens)) // sentinel to detect double close +} + +// Write commits all the encoded chunked integers to the provided writer. +func (c *chunkedIntCoder) Write(w io.Writer) (int, error) { + bufNeeded := binary.MaxVarintLen64 * (1 + len(c.chunkLens)) + if len(c.buf) < bufNeeded { + c.buf = make([]byte, bufNeeded) + } + buf := c.buf + + // convert the chunk lengths into chunk offsets + chunkOffsets := modifyLengthsToEndOffsets(c.chunkLens) + + // write out the number of chunks & each chunk offsets + n := binary.PutUvarint(buf, uint64(len(chunkOffsets))) + for _, chunkOffset := range chunkOffsets { + n += binary.PutUvarint(buf[n:], chunkOffset) + } + + tw, err := w.Write(buf[:n]) + if err != nil { + return tw, err + } + + // write out the data + nw, err := w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + return tw, nil +} + +// writeAt commits all the encoded chunked integers to the provided writer +// and returns the starting offset, total bytes written and an error +func (c *chunkedIntCoder) writeAt(w io.Writer) (uint64, int, error) { + startOffset := uint64(termNotEncoded) + if len(c.final) <= 0 { + return startOffset, 0, nil + } + + if chw := w.(*CountHashWriter); chw != nil { + startOffset = uint64(chw.Count()) + } + + tw, err := c.Write(w) + return startOffset, tw, err +} + +func (c *chunkedIntCoder) FinalSize() int { + return len(c.final) +} + +// modifyLengthsToEndOffsets converts the chunk length array +// to a chunk offset array. The readChunkBoundary +// will figure out the start and end of every chunk from +// these offsets. Starting offset of i'th index is stored +// in i-1'th position except for 0'th index and ending offset +// is stored at i'th index position. +// For 0'th element, starting position is always zero. +// eg: +// Lens -> 5 5 5 5 => 5 10 15 20 +// Lens -> 0 5 0 5 => 0 5 5 10 +// Lens -> 0 0 0 5 => 0 0 0 5 +// Lens -> 5 0 0 0 => 5 5 5 5 +// Lens -> 0 5 0 0 => 0 5 5 5 +// Lens -> 0 0 5 0 => 0 0 5 5 +func modifyLengthsToEndOffsets(lengths []uint64) []uint64 { + var runningOffset uint64 + var index, i int + for i = 1; i <= len(lengths); i++ { + runningOffset += lengths[i-1] + lengths[index] = runningOffset + index++ + } + return lengths +} + +func readChunkBoundary(chunk int, offsets []uint64) (uint64, uint64) { + var start uint64 + if chunk > 0 { + start = offsets[chunk-1] + } + return start, offsets[chunk] +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/memuvarint.go b/backend/vendor/github.com/blevesearch/zapx/v12/memuvarint.go new file mode 100644 index 0000000000..48a57f9c85 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/memuvarint.go @@ -0,0 +1,103 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "fmt" +) + +type memUvarintReader struct { + C int // index of next byte to read from S + S []byte +} + +func newMemUvarintReader(s []byte) *memUvarintReader { + return &memUvarintReader{S: s} +} + +// Len returns the number of unread bytes. +func (r *memUvarintReader) Len() int { + n := len(r.S) - r.C + if n < 0 { + return 0 + } + return n +} + +// ReadUvarint reads an encoded uint64. The original code this was +// based on is at encoding/binary/ReadUvarint(). +func (r *memUvarintReader) ReadUvarint() (uint64, error) { + if r.C >= len(r.S) { + // nothing else to read + return 0, nil + } + + var x uint64 + var s uint + var C = r.C + var S = r.S + + for { + b := S[C] + C++ + + if b < 0x80 { + r.C = C + + // why 63? The original code had an 'i += 1' loop var and + // checked for i > 9 || i == 9 ...; but, we no longer + // check for the i var, but instead check here for s, + // which is incremented by 7. So, 7*9 == 63. + // + // why the "extra" >= check? The normal case is that s < + // 63, so we check this single >= guard first so that we + // hit the normal, nil-error return pathway sooner. + if s >= 63 && (s > 63 || b > 1) { + return 0, fmt.Errorf("memUvarintReader overflow") + } + + return x | uint64(b)<= len(r.S) { + return + } + + b := r.S[r.C] + r.C++ + + if b < 0x80 { + return + } + } +} + +// SkipBytes skips a count number of bytes. +func (r *memUvarintReader) SkipBytes(count int) { + r.C = r.C + count +} + +func (r *memUvarintReader) Reset(s []byte) { + r.C = 0 + r.S = s +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/merge.go b/backend/vendor/github.com/blevesearch/zapx/v12/merge.go new file mode 100644 index 0000000000..6a853a16a6 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/merge.go @@ -0,0 +1,843 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bufio" + "bytes" + "encoding/binary" + "fmt" + "math" + "os" + "sort" + + "github.com/RoaringBitmap/roaring" + seg "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" + "github.com/golang/snappy" +) + +var DefaultFileMergerBufferSize = 1024 * 1024 + +const docDropped = math.MaxUint64 // sentinel docNum to represent a deleted doc + +// Merge takes a slice of segments and bit masks describing which +// documents may be dropped, and creates a new segment containing the +// remaining data. This new segment is built at the specified path. +func (*ZapPlugin) Merge(segments []seg.Segment, drops []*roaring.Bitmap, path string, + closeCh chan struct{}, s seg.StatsReporter) ( + [][]uint64, uint64, error) { + segmentBases := make([]*SegmentBase, len(segments)) + for segmenti, segment := range segments { + switch segmentx := segment.(type) { + case *Segment: + segmentBases[segmenti] = &segmentx.SegmentBase + case *SegmentBase: + segmentBases[segmenti] = segmentx + default: + panic(fmt.Sprintf("oops, unexpected segment type: %T", segment)) + } + } + return mergeSegmentBases(segmentBases, drops, path, DefaultChunkMode, closeCh, s) +} + +func mergeSegmentBases(segmentBases []*SegmentBase, drops []*roaring.Bitmap, path string, + chunkMode uint32, closeCh chan struct{}, s seg.StatsReporter) ( + [][]uint64, uint64, error) { + flag := os.O_RDWR | os.O_CREATE + + f, err := os.OpenFile(path, flag, 0600) + if err != nil { + return nil, 0, err + } + + cleanup := func() { + _ = f.Close() + _ = os.Remove(path) + } + + // buffer the output + br := bufio.NewWriterSize(f, DefaultFileMergerBufferSize) + + // wrap it for counting (tracking offsets) + cr := NewCountHashWriterWithStatsReporter(br, s) + + newDocNums, numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset, _, _, _, err := + MergeToWriter(segmentBases, drops, chunkMode, cr, closeCh) + if err != nil { + cleanup() + return nil, 0, err + } + + err = persistFooter(numDocs, storedIndexOffset, fieldsIndexOffset, + docValueOffset, chunkMode, cr.Sum32(), cr) + if err != nil { + cleanup() + return nil, 0, err + } + + err = br.Flush() + if err != nil { + cleanup() + return nil, 0, err + } + + err = f.Sync() + if err != nil { + cleanup() + return nil, 0, err + } + + err = f.Close() + if err != nil { + cleanup() + return nil, 0, err + } + + return newDocNums, uint64(cr.Count()), nil +} + +func MergeToWriter(segments []*SegmentBase, drops []*roaring.Bitmap, + chunkMode uint32, cr *CountHashWriter, closeCh chan struct{}) ( + newDocNums [][]uint64, + numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset uint64, + dictLocs []uint64, fieldsInv []string, fieldsMap map[string]uint16, + err error) { + docValueOffset = uint64(fieldNotUninverted) + + var fieldsSame bool + fieldsSame, fieldsInv = mergeFields(segments) + fieldsMap = mapFields(fieldsInv) + + numDocs = computeNewDocCount(segments, drops) + + if isClosed(closeCh) { + return nil, 0, 0, 0, 0, nil, nil, nil, seg.ErrClosed + } + + if numDocs > 0 { + storedIndexOffset, newDocNums, err = mergeStoredAndRemap(segments, drops, + fieldsMap, fieldsInv, fieldsSame, numDocs, cr, closeCh) + if err != nil { + return nil, 0, 0, 0, 0, nil, nil, nil, err + } + + dictLocs, docValueOffset, err = persistMergedRest(segments, drops, + fieldsInv, fieldsMap, fieldsSame, + newDocNums, numDocs, chunkMode, cr, closeCh) + if err != nil { + return nil, 0, 0, 0, 0, nil, nil, nil, err + } + } else { + dictLocs = make([]uint64, len(fieldsInv)) + } + + fieldsIndexOffset, err = persistFields(fieldsInv, cr, dictLocs) + if err != nil { + return nil, 0, 0, 0, 0, nil, nil, nil, err + } + + return newDocNums, numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset, dictLocs, fieldsInv, fieldsMap, nil +} + +// mapFields takes the fieldsInv list and returns a map of fieldName +// to fieldID+1 +func mapFields(fields []string) map[string]uint16 { + rv := make(map[string]uint16, len(fields)) + for i, fieldName := range fields { + rv[fieldName] = uint16(i) + 1 + } + return rv +} + +// computeNewDocCount determines how many documents will be in the newly +// merged segment when obsoleted docs are dropped +func computeNewDocCount(segments []*SegmentBase, drops []*roaring.Bitmap) uint64 { + var newDocCount uint64 + for segI, segment := range segments { + newDocCount += segment.numDocs + if drops[segI] != nil { + newDocCount -= drops[segI].GetCardinality() + } + } + return newDocCount +} + +func persistMergedRest(segments []*SegmentBase, dropsIn []*roaring.Bitmap, + fieldsInv []string, fieldsMap map[string]uint16, fieldsSame bool, + newDocNumsIn [][]uint64, newSegDocCount uint64, chunkMode uint32, + w *CountHashWriter, closeCh chan struct{}) ([]uint64, uint64, error) { + var bufMaxVarintLen64 []byte = make([]byte, binary.MaxVarintLen64) + var bufLoc []uint64 + + var postings *PostingsList + var postItr *PostingsIterator + + rv := make([]uint64, len(fieldsInv)) + fieldDvLocsStart := make([]uint64, len(fieldsInv)) + fieldDvLocsEnd := make([]uint64, len(fieldsInv)) + + // these int coders are initialized with chunk size 1024 + // however this will be reset to the correct chunk size + // while processing each individual field-term section + tfEncoder := newChunkedIntCoder(1024, newSegDocCount-1) + locEncoder := newChunkedIntCoder(1024, newSegDocCount-1) + + var vellumBuf bytes.Buffer + newVellum, err := vellum.New(&vellumBuf, nil) + if err != nil { + return nil, 0, err + } + + newRoaring := roaring.NewBitmap() + + // for each field + for fieldID, fieldName := range fieldsInv { + // collect FST iterators from all active segments for this field + var newDocNums [][]uint64 + var drops []*roaring.Bitmap + var dicts []*Dictionary + var itrs []vellum.Iterator + + var segmentsInFocus []*SegmentBase + + for segmentI, segment := range segments { + // check for the closure in meantime + if isClosed(closeCh) { + return nil, 0, seg.ErrClosed + } + + dict, err2 := segment.dictionary(fieldName) + if err2 != nil { + return nil, 0, err2 + } + if dict != nil && dict.fst != nil { + itr, err2 := dict.fst.Iterator(nil, nil) + if err2 != nil && err2 != vellum.ErrIteratorDone { + return nil, 0, err2 + } + if itr != nil { + newDocNums = append(newDocNums, newDocNumsIn[segmentI]) + if dropsIn[segmentI] != nil && !dropsIn[segmentI].IsEmpty() { + drops = append(drops, dropsIn[segmentI]) + } else { + drops = append(drops, nil) + } + dicts = append(dicts, dict) + itrs = append(itrs, itr) + segmentsInFocus = append(segmentsInFocus, segment) + } + } + } + + var prevTerm []byte + + newRoaring.Clear() + + var lastDocNum, lastFreq, lastNorm uint64 + + // determines whether to use "1-hit" encoding optimization + // when a term appears in only 1 doc, with no loc info, + // has freq of 1, and the docNum fits into 31-bits + use1HitEncoding := func(termCardinality uint64) (bool, uint64, uint64) { + if termCardinality == uint64(1) && locEncoder.FinalSize() <= 0 { + docNum := uint64(newRoaring.Minimum()) + if under32Bits(docNum) && docNum == lastDocNum && lastFreq == 1 { + return true, docNum, lastNorm + } + } + return false, 0, 0 + } + + finishTerm := func(term []byte) error { + tfEncoder.Close() + locEncoder.Close() + + postingsOffset, err := writePostings(newRoaring, + tfEncoder, locEncoder, use1HitEncoding, w, bufMaxVarintLen64) + if err != nil { + return err + } + + if postingsOffset > 0 { + err = newVellum.Insert(term, postingsOffset) + if err != nil { + return err + } + } + + newRoaring.Clear() + + tfEncoder.Reset() + locEncoder.Reset() + + lastDocNum = 0 + lastFreq = 0 + lastNorm = 0 + + return nil + } + + enumerator, err := newEnumerator(itrs) + + for err == nil { + term, itrI, postingsOffset := enumerator.Current() + + if !bytes.Equal(prevTerm, term) { + // check for the closure in meantime + if isClosed(closeCh) { + return nil, 0, seg.ErrClosed + } + + // if the term changed, write out the info collected + // for the previous term + err = finishTerm(prevTerm) + if err != nil { + return nil, 0, err + } + } + if !bytes.Equal(prevTerm, term) || prevTerm == nil { + // compute cardinality of field-term in new seg + var newCard uint64 + lowItrIdxs, lowItrVals := enumerator.GetLowIdxsAndValues() + for i, idx := range lowItrIdxs { + pl, err := dicts[idx].postingsListFromOffset(lowItrVals[i], drops[idx], nil) + if err != nil { + return nil, 0, err + } + newCard += pl.Count() + } + // compute correct chunk size with this + chunkSize, err := getChunkSize(chunkMode, newCard, newSegDocCount) + if err != nil { + return nil, 0, err + } + // update encoders chunk + tfEncoder.SetChunkSize(chunkSize, newSegDocCount-1) + locEncoder.SetChunkSize(chunkSize, newSegDocCount-1) + } + + postings, err = dicts[itrI].postingsListFromOffset( + postingsOffset, drops[itrI], postings) + if err != nil { + return nil, 0, err + } + + postItr = postings.iterator(true, true, true, postItr) + + // can no longer optimize by copying, since chunk factor could have changed + lastDocNum, lastFreq, lastNorm, bufLoc, err = mergeTermFreqNormLocs( + fieldsMap, term, postItr, newDocNums[itrI], newRoaring, + tfEncoder, locEncoder, bufLoc) + + if err != nil { + return nil, 0, err + } + + prevTerm = prevTerm[:0] // copy to prevTerm in case Next() reuses term mem + prevTerm = append(prevTerm, term...) + + err = enumerator.Next() + } + if err != vellum.ErrIteratorDone { + return nil, 0, err + } + + err = finishTerm(prevTerm) + if err != nil { + return nil, 0, err + } + + dictOffset := uint64(w.Count()) + + err = newVellum.Close() + if err != nil { + return nil, 0, err + } + vellumData := vellumBuf.Bytes() + + // write out the length of the vellum data + n := binary.PutUvarint(bufMaxVarintLen64, uint64(len(vellumData))) + _, err = w.Write(bufMaxVarintLen64[:n]) + if err != nil { + return nil, 0, err + } + + // write this vellum to disk + _, err = w.Write(vellumData) + if err != nil { + return nil, 0, err + } + + rv[fieldID] = dictOffset + + // get the field doc value offset (start) + fieldDvLocsStart[fieldID] = uint64(w.Count()) + + // update the field doc values + // NOTE: doc values continue to use legacy chunk mode + chunkSize, err := getChunkSize(LegacyChunkMode, 0, 0) + if err != nil { + return nil, 0, err + } + fdvEncoder := newChunkedContentCoder(chunkSize, newSegDocCount-1, w, true) + + fdvReadersAvailable := false + var dvIterClone *docValueReader + for segmentI, segment := range segmentsInFocus { + // check for the closure in meantime + if isClosed(closeCh) { + return nil, 0, seg.ErrClosed + } + + fieldIDPlus1 := uint16(segment.fieldsMap[fieldName]) + if dvIter, exists := segment.fieldDvReaders[fieldIDPlus1-1]; exists && + dvIter != nil { + fdvReadersAvailable = true + dvIterClone = dvIter.cloneInto(dvIterClone) + err = dvIterClone.iterateAllDocValues(segment, func(docNum uint64, terms []byte) error { + if newDocNums[segmentI][docNum] == docDropped { + return nil + } + err := fdvEncoder.Add(newDocNums[segmentI][docNum], terms) + if err != nil { + return err + } + return nil + }) + if err != nil { + return nil, 0, err + } + } + } + + if fdvReadersAvailable { + err = fdvEncoder.Close() + if err != nil { + return nil, 0, err + } + + // persist the doc value details for this field + _, err = fdvEncoder.Write() + if err != nil { + return nil, 0, err + } + + // get the field doc value offset (end) + fieldDvLocsEnd[fieldID] = uint64(w.Count()) + } else { + fieldDvLocsStart[fieldID] = fieldNotUninverted + fieldDvLocsEnd[fieldID] = fieldNotUninverted + } + + // reset vellum buffer and vellum builder + vellumBuf.Reset() + err = newVellum.Reset(&vellumBuf) + if err != nil { + return nil, 0, err + } + } + + fieldDvLocsOffset := uint64(w.Count()) + + buf := bufMaxVarintLen64 + for i := 0; i < len(fieldDvLocsStart); i++ { + n := binary.PutUvarint(buf, fieldDvLocsStart[i]) + _, err := w.Write(buf[:n]) + if err != nil { + return nil, 0, err + } + n = binary.PutUvarint(buf, fieldDvLocsEnd[i]) + _, err = w.Write(buf[:n]) + if err != nil { + return nil, 0, err + } + } + + return rv, fieldDvLocsOffset, nil +} + +func mergeTermFreqNormLocs(fieldsMap map[string]uint16, term []byte, postItr *PostingsIterator, + newDocNums []uint64, newRoaring *roaring.Bitmap, + tfEncoder *chunkedIntCoder, locEncoder *chunkedIntCoder, bufLoc []uint64) ( + lastDocNum uint64, lastFreq uint64, lastNorm uint64, bufLocOut []uint64, err error) { + next, err := postItr.Next() + for next != nil && err == nil { + hitNewDocNum := newDocNums[next.Number()] + if hitNewDocNum == docDropped { + return 0, 0, 0, nil, fmt.Errorf("see hit with dropped docNum") + } + + newRoaring.Add(uint32(hitNewDocNum)) + + nextFreq := next.Frequency() + nextNorm := uint64(math.Float32bits(float32(next.Norm()))) + + locs := next.Locations() + + err = tfEncoder.Add(hitNewDocNum, + encodeFreqHasLocs(nextFreq, len(locs) > 0), nextNorm) + if err != nil { + return 0, 0, 0, nil, err + } + + if len(locs) > 0 { + numBytesLocs := 0 + for _, loc := range locs { + ap := loc.ArrayPositions() + numBytesLocs += totalUvarintBytes(uint64(fieldsMap[loc.Field()]-1), + loc.Pos(), loc.Start(), loc.End(), uint64(len(ap)), ap) + } + + err = locEncoder.Add(hitNewDocNum, uint64(numBytesLocs)) + if err != nil { + return 0, 0, 0, nil, err + } + + for _, loc := range locs { + ap := loc.ArrayPositions() + if cap(bufLoc) < 5+len(ap) { + bufLoc = make([]uint64, 0, 5+len(ap)) + } + args := bufLoc[0:5] + args[0] = uint64(fieldsMap[loc.Field()] - 1) + args[1] = loc.Pos() + args[2] = loc.Start() + args[3] = loc.End() + args[4] = uint64(len(ap)) + args = append(args, ap...) + err = locEncoder.Add(hitNewDocNum, args...) + if err != nil { + return 0, 0, 0, nil, err + } + } + } + + lastDocNum = hitNewDocNum + lastFreq = nextFreq + lastNorm = nextNorm + + next, err = postItr.Next() + } + + return lastDocNum, lastFreq, lastNorm, bufLoc, err +} + +func writePostings(postings *roaring.Bitmap, tfEncoder, locEncoder *chunkedIntCoder, + use1HitEncoding func(uint64) (bool, uint64, uint64), + w *CountHashWriter, bufMaxVarintLen64 []byte) ( + offset uint64, err error) { + termCardinality := postings.GetCardinality() + if termCardinality <= 0 { + return 0, nil + } + + if use1HitEncoding != nil { + encodeAs1Hit, docNum1Hit, normBits1Hit := use1HitEncoding(termCardinality) + if encodeAs1Hit { + return FSTValEncode1Hit(docNum1Hit, normBits1Hit), nil + } + } + + var tfOffset uint64 + tfOffset, _, err = tfEncoder.writeAt(w) + if err != nil { + return 0, err + } + + var locOffset uint64 + locOffset, _, err = locEncoder.writeAt(w) + if err != nil { + return 0, err + } + + postingsOffset := uint64(w.Count()) + + n := binary.PutUvarint(bufMaxVarintLen64, tfOffset) + _, err = w.Write(bufMaxVarintLen64[:n]) + if err != nil { + return 0, err + } + + n = binary.PutUvarint(bufMaxVarintLen64, locOffset) + _, err = w.Write(bufMaxVarintLen64[:n]) + if err != nil { + return 0, err + } + + _, err = writeRoaringWithLen(postings, w, bufMaxVarintLen64) + if err != nil { + return 0, err + } + + return postingsOffset, nil +} + +type varintEncoder func(uint64) (int, error) + +func mergeStoredAndRemap(segments []*SegmentBase, drops []*roaring.Bitmap, + fieldsMap map[string]uint16, fieldsInv []string, fieldsSame bool, newSegDocCount uint64, + w *CountHashWriter, closeCh chan struct{}) (uint64, [][]uint64, error) { + var rv [][]uint64 // The remapped or newDocNums for each segment. + + var newDocNum uint64 + + var curr int + var data, compressed []byte + var metaBuf bytes.Buffer + varBuf := make([]byte, binary.MaxVarintLen64) + metaEncode := func(val uint64) (int, error) { + wb := binary.PutUvarint(varBuf, val) + return metaBuf.Write(varBuf[:wb]) + } + + vals := make([][][]byte, len(fieldsInv)) + typs := make([][]byte, len(fieldsInv)) + poss := make([][][]uint64, len(fieldsInv)) + + var posBuf []uint64 + + docNumOffsets := make([]uint64, newSegDocCount) + + vdc := visitDocumentCtxPool.Get().(*visitDocumentCtx) + defer visitDocumentCtxPool.Put(vdc) + + // for each segment + for segI, segment := range segments { + // check for the closure in meantime + if isClosed(closeCh) { + return 0, nil, seg.ErrClosed + } + + segNewDocNums := make([]uint64, segment.numDocs) + + dropsI := drops[segI] + + // optimize when the field mapping is the same across all + // segments and there are no deletions, via byte-copying + // of stored docs bytes directly to the writer + if fieldsSame && (dropsI == nil || dropsI.GetCardinality() == 0) { + err := segment.copyStoredDocs(newDocNum, docNumOffsets, w) + if err != nil { + return 0, nil, err + } + + for i := uint64(0); i < segment.numDocs; i++ { + segNewDocNums[i] = newDocNum + newDocNum++ + } + rv = append(rv, segNewDocNums) + + continue + } + + // for each doc num + for docNum := uint64(0); docNum < segment.numDocs; docNum++ { + // TODO: roaring's API limits docNums to 32-bits? + if dropsI != nil && dropsI.Contains(uint32(docNum)) { + segNewDocNums[docNum] = docDropped + continue + } + + segNewDocNums[docNum] = newDocNum + + curr = 0 + metaBuf.Reset() + data = data[:0] + + posTemp := posBuf + + // collect all the data + for i := 0; i < len(fieldsInv); i++ { + vals[i] = vals[i][:0] + typs[i] = typs[i][:0] + poss[i] = poss[i][:0] + } + err := segment.visitStoredFields(vdc, docNum, func(field string, typ byte, value []byte, pos []uint64) bool { + fieldID := int(fieldsMap[field]) - 1 + vals[fieldID] = append(vals[fieldID], value) + typs[fieldID] = append(typs[fieldID], typ) + + // copy array positions to preserve them beyond the scope of this callback + var curPos []uint64 + if len(pos) > 0 { + if cap(posTemp) < len(pos) { + posBuf = make([]uint64, len(pos)*len(fieldsInv)) + posTemp = posBuf + } + curPos = posTemp[0:len(pos)] + copy(curPos, pos) + posTemp = posTemp[len(pos):] + } + poss[fieldID] = append(poss[fieldID], curPos) + + return true + }) + if err != nil { + return 0, nil, err + } + + // _id field special case optimizes ExternalID() lookups + idFieldVal := vals[uint16(0)][0] + _, err = metaEncode(uint64(len(idFieldVal))) + if err != nil { + return 0, nil, err + } + + // now walk the non-"_id" fields in order + for fieldID := 1; fieldID < len(fieldsInv); fieldID++ { + storedFieldValues := vals[fieldID] + + stf := typs[fieldID] + spf := poss[fieldID] + + var err2 error + curr, data, err2 = persistStoredFieldValues(fieldID, + storedFieldValues, stf, spf, curr, metaEncode, data) + if err2 != nil { + return 0, nil, err2 + } + } + + metaBytes := metaBuf.Bytes() + + compressed = snappy.Encode(compressed[:cap(compressed)], data) + + // record where we're about to start writing + docNumOffsets[newDocNum] = uint64(w.Count()) + + // write out the meta len and compressed data len + _, err = writeUvarints(w, + uint64(len(metaBytes)), + uint64(len(idFieldVal)+len(compressed))) + if err != nil { + return 0, nil, err + } + // now write the meta + _, err = w.Write(metaBytes) + if err != nil { + return 0, nil, err + } + // now write the _id field val (counted as part of the 'compressed' data) + _, err = w.Write(idFieldVal) + if err != nil { + return 0, nil, err + } + // now write the compressed data + _, err = w.Write(compressed) + if err != nil { + return 0, nil, err + } + + newDocNum++ + } + + rv = append(rv, segNewDocNums) + } + + // return value is the start of the stored index + storedIndexOffset := uint64(w.Count()) + + // now write out the stored doc index + for _, docNumOffset := range docNumOffsets { + err := binary.Write(w, binary.BigEndian, docNumOffset) + if err != nil { + return 0, nil, err + } + } + + return storedIndexOffset, rv, nil +} + +// copyStoredDocs writes out a segment's stored doc info, optimized by +// using a single Write() call for the entire set of bytes. The +// newDocNumOffsets is filled with the new offsets for each doc. +func (s *SegmentBase) copyStoredDocs(newDocNum uint64, newDocNumOffsets []uint64, + w *CountHashWriter) error { + if s.numDocs <= 0 { + return nil + } + + indexOffset0, storedOffset0, _, _, _ := + s.getDocStoredOffsets(0) // the segment's first doc + + indexOffsetN, storedOffsetN, readN, metaLenN, dataLenN := + s.getDocStoredOffsets(s.numDocs - 1) // the segment's last doc + + storedOffset0New := uint64(w.Count()) + + storedBytes := s.mem[storedOffset0 : storedOffsetN+readN+metaLenN+dataLenN] + _, err := w.Write(storedBytes) + if err != nil { + return err + } + + // remap the storedOffset's for the docs into new offsets relative + // to storedOffset0New, filling the given docNumOffsetsOut array + for indexOffset := indexOffset0; indexOffset <= indexOffsetN; indexOffset += 8 { + storedOffset := binary.BigEndian.Uint64(s.mem[indexOffset : indexOffset+8]) + storedOffsetNew := storedOffset - storedOffset0 + storedOffset0New + newDocNumOffsets[newDocNum] = storedOffsetNew + newDocNum += 1 + } + + return nil +} + +// mergeFields builds a unified list of fields used across all the +// input segments, and computes whether the fields are the same across +// segments (which depends on fields to be sorted in the same way +// across segments) +func mergeFields(segments []*SegmentBase) (bool, []string) { + fieldsSame := true + + var segment0Fields []string + if len(segments) > 0 { + segment0Fields = segments[0].Fields() + } + + fieldsExist := map[string]struct{}{} + for _, segment := range segments { + fields := segment.Fields() + for fieldi, field := range fields { + fieldsExist[field] = struct{}{} + if len(segment0Fields) != len(fields) || segment0Fields[fieldi] != field { + fieldsSame = false + } + } + } + + rv := make([]string, 0, len(fieldsExist)) + // ensure _id stays first + rv = append(rv, "_id") + for k := range fieldsExist { + if k != "_id" { + rv = append(rv, k) + } + } + + sort.Strings(rv[1:]) // leave _id as first + + return fieldsSame, rv +} + +func isClosed(closeCh chan struct{}) bool { + select { + case <-closeCh: + return true + default: + return false + } +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/new.go b/backend/vendor/github.com/blevesearch/zapx/v12/new.go new file mode 100644 index 0000000000..b4e0d03415 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/new.go @@ -0,0 +1,830 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "math" + "sort" + "sync" + + "github.com/RoaringBitmap/roaring" + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" + "github.com/golang/snappy" +) + +var NewSegmentBufferNumResultsBump int = 100 +var NewSegmentBufferNumResultsFactor float64 = 1.0 +var NewSegmentBufferAvgBytesPerDocFactor float64 = 1.0 + +// ValidateDocFields can be set by applications to perform additional checks +// on fields in a document being added to a new segment, by default it does +// nothing. +// This API is experimental and may be removed at any time. +var ValidateDocFields = func(field index.Field) error { + return nil +} + +// New creates an in-memory zap-encoded SegmentBase from a set of Documents +func (z *ZapPlugin) New(results []index.Document) ( + segment.Segment, uint64, error) { + return z.newWithChunkMode(results, DefaultChunkMode) +} + +func (*ZapPlugin) newWithChunkMode(results []index.Document, + chunkMode uint32) (segment.Segment, uint64, error) { + s := interimPool.Get().(*interim) + + var br bytes.Buffer + if s.lastNumDocs > 0 { + // use previous results to initialize the buf with an estimate + // size, but note that the interim instance comes from a + // global interimPool, so multiple scorch instances indexing + // different docs can lead to low quality estimates + estimateAvgBytesPerDoc := int(float64(s.lastOutSize/s.lastNumDocs) * + NewSegmentBufferNumResultsFactor) + estimateNumResults := int(float64(len(results)+NewSegmentBufferNumResultsBump) * + NewSegmentBufferAvgBytesPerDocFactor) + br.Grow(estimateAvgBytesPerDoc * estimateNumResults) + } + + s.results = results + s.chunkMode = chunkMode + s.w = NewCountHashWriter(&br) + + storedIndexOffset, fieldsIndexOffset, fdvIndexOffset, dictOffsets, + err := s.convert() + if err != nil { + return nil, uint64(0), err + } + + sb, err := InitSegmentBase(br.Bytes(), s.w.Sum32(), chunkMode, + s.FieldsMap, s.FieldsInv, uint64(len(results)), + storedIndexOffset, fieldsIndexOffset, fdvIndexOffset, dictOffsets) + + if err == nil && s.reset() == nil { + s.lastNumDocs = len(results) + s.lastOutSize = len(br.Bytes()) + interimPool.Put(s) + } + + return sb, uint64(len(br.Bytes())), err +} + +var interimPool = sync.Pool{New: func() interface{} { return &interim{} }} + +// interim holds temporary working data used while converting from +// analysis results to a zap-encoded segment +type interim struct { + results []index.Document + + chunkMode uint32 + + w *CountHashWriter + + // FieldsMap adds 1 to field id to avoid zero value issues + // name -> field id + 1 + FieldsMap map[string]uint16 + + // FieldsInv is the inverse of FieldsMap + // field id -> name + FieldsInv []string + + // Term dictionaries for each field + // field id -> term -> postings list id + 1 + Dicts []map[string]uint64 + + // Terms for each field, where terms are sorted ascending + // field id -> []term + DictKeys [][]string + + // Fields whose IncludeDocValues is true + // field id -> bool + IncludeDocValues []bool + + // postings id -> bitmap of docNums + Postings []*roaring.Bitmap + + // postings id -> freq/norm's, one for each docNum in postings + FreqNorms [][]interimFreqNorm + freqNormsBacking []interimFreqNorm + + // postings id -> locs, one for each freq + Locs [][]interimLoc + locsBacking []interimLoc + + numTermsPerPostingsList []int // key is postings list id + numLocsPerPostingsList []int // key is postings list id + + builder *vellum.Builder + builderBuf bytes.Buffer + + metaBuf bytes.Buffer + + tmp0 []byte + tmp1 []byte + + lastNumDocs int + lastOutSize int +} + +func (s *interim) reset() (err error) { + s.results = nil + s.chunkMode = 0 + s.w = nil + s.FieldsMap = nil + s.FieldsInv = nil + for i := range s.Dicts { + s.Dicts[i] = nil + } + s.Dicts = s.Dicts[:0] + for i := range s.DictKeys { + s.DictKeys[i] = s.DictKeys[i][:0] + } + s.DictKeys = s.DictKeys[:0] + for i := range s.IncludeDocValues { + s.IncludeDocValues[i] = false + } + s.IncludeDocValues = s.IncludeDocValues[:0] + for _, idn := range s.Postings { + idn.Clear() + } + s.Postings = s.Postings[:0] + s.FreqNorms = s.FreqNorms[:0] + for i := range s.freqNormsBacking { + s.freqNormsBacking[i] = interimFreqNorm{} + } + s.freqNormsBacking = s.freqNormsBacking[:0] + s.Locs = s.Locs[:0] + for i := range s.locsBacking { + s.locsBacking[i] = interimLoc{} + } + s.locsBacking = s.locsBacking[:0] + s.numTermsPerPostingsList = s.numTermsPerPostingsList[:0] + s.numLocsPerPostingsList = s.numLocsPerPostingsList[:0] + s.builderBuf.Reset() + if s.builder != nil { + err = s.builder.Reset(&s.builderBuf) + } + s.metaBuf.Reset() + s.tmp0 = s.tmp0[:0] + s.tmp1 = s.tmp1[:0] + s.lastNumDocs = 0 + s.lastOutSize = 0 + + return err +} + +func (s *interim) grabBuf(size int) []byte { + buf := s.tmp0 + if cap(buf) < size { + buf = make([]byte, size) + s.tmp0 = buf + } + return buf[0:size] +} + +type interimStoredField struct { + vals [][]byte + typs []byte + arrayposs [][]uint64 // array positions +} + +type interimFreqNorm struct { + freq uint64 + norm float32 + numLocs int +} + +type interimLoc struct { + fieldID uint16 + pos uint64 + start uint64 + end uint64 + arrayposs []uint64 +} + +func (s *interim) convert() (uint64, uint64, uint64, []uint64, error) { + s.FieldsMap = map[string]uint16{} + + s.getOrDefineField("_id") // _id field is fieldID 0 + + for _, result := range s.results { + result.VisitComposite(func(field index.CompositeField) { + s.getOrDefineField(field.Name()) + }) + result.VisitFields(func(field index.Field) { + s.getOrDefineField(field.Name()) + }) + } + + sort.Strings(s.FieldsInv[1:]) // keep _id as first field + + for fieldID, fieldName := range s.FieldsInv { + s.FieldsMap[fieldName] = uint16(fieldID + 1) + } + + if cap(s.IncludeDocValues) >= len(s.FieldsInv) { + s.IncludeDocValues = s.IncludeDocValues[:len(s.FieldsInv)] + } else { + s.IncludeDocValues = make([]bool, len(s.FieldsInv)) + } + + s.prepareDicts() + + for _, dict := range s.DictKeys { + sort.Strings(dict) + } + + s.processDocuments() + + storedIndexOffset, err := s.writeStoredFields() + if err != nil { + return 0, 0, 0, nil, err + } + + var fdvIndexOffset uint64 + var dictOffsets []uint64 + + if len(s.results) > 0 { + fdvIndexOffset, dictOffsets, err = s.writeDicts() + if err != nil { + return 0, 0, 0, nil, err + } + } else { + dictOffsets = make([]uint64, len(s.FieldsInv)) + } + + fieldsIndexOffset, err := persistFields(s.FieldsInv, s.w, dictOffsets) + if err != nil { + return 0, 0, 0, nil, err + } + + return storedIndexOffset, fieldsIndexOffset, fdvIndexOffset, dictOffsets, nil +} + +func (s *interim) getOrDefineField(fieldName string) int { + fieldIDPlus1, exists := s.FieldsMap[fieldName] + if !exists { + fieldIDPlus1 = uint16(len(s.FieldsInv) + 1) + s.FieldsMap[fieldName] = fieldIDPlus1 + s.FieldsInv = append(s.FieldsInv, fieldName) + + s.Dicts = append(s.Dicts, make(map[string]uint64)) + + n := len(s.DictKeys) + if n < cap(s.DictKeys) { + s.DictKeys = s.DictKeys[:n+1] + s.DictKeys[n] = s.DictKeys[n][:0] + } else { + s.DictKeys = append(s.DictKeys, []string(nil)) + } + } + + return int(fieldIDPlus1 - 1) +} + +// fill Dicts and DictKeys from analysis results +func (s *interim) prepareDicts() { + var pidNext int + + var totTFs int + var totLocs int + + visitField := func(field index.Field) { + fieldID := uint16(s.getOrDefineField(field.Name())) + + dict := s.Dicts[fieldID] + dictKeys := s.DictKeys[fieldID] + + tfs := field.AnalyzedTokenFrequencies() + for term, tf := range tfs { + pidPlus1, exists := dict[term] + if !exists { + pidNext++ + pidPlus1 = uint64(pidNext) + + dict[term] = pidPlus1 + dictKeys = append(dictKeys, term) + + s.numTermsPerPostingsList = append(s.numTermsPerPostingsList, 0) + s.numLocsPerPostingsList = append(s.numLocsPerPostingsList, 0) + } + + pid := pidPlus1 - 1 + + s.numTermsPerPostingsList[pid] += 1 + s.numLocsPerPostingsList[pid] += len(tf.Locations) + + totLocs += len(tf.Locations) + } + + totTFs += len(tfs) + + s.DictKeys[fieldID] = dictKeys + } + + for _, result := range s.results { + // walk each composite field + result.VisitComposite(func(field index.CompositeField) { + visitField(field) + }) + + // walk each field + result.VisitFields(visitField) + } + + numPostingsLists := pidNext + + if cap(s.Postings) >= numPostingsLists { + s.Postings = s.Postings[:numPostingsLists] + } else { + postings := make([]*roaring.Bitmap, numPostingsLists) + copy(postings, s.Postings[:cap(s.Postings)]) + for i := 0; i < numPostingsLists; i++ { + if postings[i] == nil { + postings[i] = roaring.New() + } + } + s.Postings = postings + } + + if cap(s.FreqNorms) >= numPostingsLists { + s.FreqNorms = s.FreqNorms[:numPostingsLists] + } else { + s.FreqNorms = make([][]interimFreqNorm, numPostingsLists) + } + + if cap(s.freqNormsBacking) >= totTFs { + s.freqNormsBacking = s.freqNormsBacking[:totTFs] + } else { + s.freqNormsBacking = make([]interimFreqNorm, totTFs) + } + + freqNormsBacking := s.freqNormsBacking + for pid, numTerms := range s.numTermsPerPostingsList { + s.FreqNorms[pid] = freqNormsBacking[0:0] + freqNormsBacking = freqNormsBacking[numTerms:] + } + + if cap(s.Locs) >= numPostingsLists { + s.Locs = s.Locs[:numPostingsLists] + } else { + s.Locs = make([][]interimLoc, numPostingsLists) + } + + if cap(s.locsBacking) >= totLocs { + s.locsBacking = s.locsBacking[:totLocs] + } else { + s.locsBacking = make([]interimLoc, totLocs) + } + + locsBacking := s.locsBacking + for pid, numLocs := range s.numLocsPerPostingsList { + s.Locs[pid] = locsBacking[0:0] + locsBacking = locsBacking[numLocs:] + } +} + +func (s *interim) processDocuments() { + numFields := len(s.FieldsInv) + reuseFieldLens := make([]int, numFields) + reuseFieldTFs := make([]index.TokenFrequencies, numFields) + + for docNum, result := range s.results { + for i := 0; i < numFields; i++ { // clear these for reuse + reuseFieldLens[i] = 0 + reuseFieldTFs[i] = nil + } + + s.processDocument(uint64(docNum), result, + reuseFieldLens, reuseFieldTFs) + } +} + +func (s *interim) processDocument(docNum uint64, + result index.Document, + fieldLens []int, fieldTFs []index.TokenFrequencies) { + visitField := func(field index.Field) { + fieldID := uint16(s.getOrDefineField(field.Name())) + fieldLens[fieldID] += field.AnalyzedLength() + + existingFreqs := fieldTFs[fieldID] + if existingFreqs != nil { + existingFreqs.MergeAll(field.Name(), field.AnalyzedTokenFrequencies()) + } else { + fieldTFs[fieldID] = field.AnalyzedTokenFrequencies() + } + } + + // walk each composite field + result.VisitComposite(func(field index.CompositeField) { + visitField(field) + }) + + // walk each field + result.VisitFields(visitField) + + // now that it's been rolled up into fieldTFs, walk that + for fieldID, tfs := range fieldTFs { + dict := s.Dicts[fieldID] + norm := float32(1.0 / math.Sqrt(float64(fieldLens[fieldID]))) + + for term, tf := range tfs { + pid := dict[term] - 1 + bs := s.Postings[pid] + bs.Add(uint32(docNum)) + + s.FreqNorms[pid] = append(s.FreqNorms[pid], + interimFreqNorm{ + freq: uint64(tf.Frequency()), + norm: norm, + numLocs: len(tf.Locations), + }) + + if len(tf.Locations) > 0 { + locs := s.Locs[pid] + + for _, loc := range tf.Locations { + var locf = uint16(fieldID) + if loc.Field != "" { + locf = uint16(s.getOrDefineField(loc.Field)) + } + var arrayposs []uint64 + if len(loc.ArrayPositions) > 0 { + arrayposs = loc.ArrayPositions + } + locs = append(locs, interimLoc{ + fieldID: locf, + pos: uint64(loc.Position), + start: uint64(loc.Start), + end: uint64(loc.End), + arrayposs: arrayposs, + }) + } + + s.Locs[pid] = locs + } + } + } +} + +func (s *interim) writeStoredFields() ( + storedIndexOffset uint64, err error) { + varBuf := make([]byte, binary.MaxVarintLen64) + metaEncode := func(val uint64) (int, error) { + wb := binary.PutUvarint(varBuf, val) + return s.metaBuf.Write(varBuf[:wb]) + } + + data, compressed := s.tmp0[:0], s.tmp1[:0] + defer func() { s.tmp0, s.tmp1 = data, compressed }() + + // keyed by docNum + docStoredOffsets := make([]uint64, len(s.results)) + + // keyed by fieldID, for the current doc in the loop + docStoredFields := map[uint16]interimStoredField{} + + for docNum, result := range s.results { + for fieldID := range docStoredFields { // reset for next doc + delete(docStoredFields, fieldID) + } + + var validationErr error + result.VisitFields(func(field index.Field) { + fieldID := uint16(s.getOrDefineField(field.Name())) + + if field.Options().IsStored() { + isf := docStoredFields[fieldID] + isf.vals = append(isf.vals, field.Value()) + isf.typs = append(isf.typs, field.EncodedFieldType()) + isf.arrayposs = append(isf.arrayposs, field.ArrayPositions()) + docStoredFields[fieldID] = isf + } + + if field.Options().IncludeDocValues() { + s.IncludeDocValues[fieldID] = true + } + + err := ValidateDocFields(field) + if err != nil && validationErr == nil { + validationErr = err + } + }) + if validationErr != nil { + return 0, validationErr + } + + var curr int + + s.metaBuf.Reset() + data = data[:0] + + // _id field special case optimizes ExternalID() lookups + idFieldVal := docStoredFields[uint16(0)].vals[0] + _, err = metaEncode(uint64(len(idFieldVal))) + if err != nil { + return 0, err + } + + // handle non-"_id" fields + for fieldID := 1; fieldID < len(s.FieldsInv); fieldID++ { + isf, exists := docStoredFields[uint16(fieldID)] + if exists { + curr, data, err = persistStoredFieldValues( + fieldID, isf.vals, isf.typs, isf.arrayposs, + curr, metaEncode, data) + if err != nil { + return 0, err + } + } + } + + metaBytes := s.metaBuf.Bytes() + + compressed = snappy.Encode(compressed[:cap(compressed)], data) + + docStoredOffsets[docNum] = uint64(s.w.Count()) + + _, err := writeUvarints(s.w, + uint64(len(metaBytes)), + uint64(len(idFieldVal)+len(compressed))) + if err != nil { + return 0, err + } + + _, err = s.w.Write(metaBytes) + if err != nil { + return 0, err + } + + _, err = s.w.Write(idFieldVal) + if err != nil { + return 0, err + } + + _, err = s.w.Write(compressed) + if err != nil { + return 0, err + } + } + + storedIndexOffset = uint64(s.w.Count()) + + for _, docStoredOffset := range docStoredOffsets { + err = binary.Write(s.w, binary.BigEndian, docStoredOffset) + if err != nil { + return 0, err + } + } + + return storedIndexOffset, nil +} + +func (s *interim) writeDicts() (fdvIndexOffset uint64, dictOffsets []uint64, err error) { + dictOffsets = make([]uint64, len(s.FieldsInv)) + + fdvOffsetsStart := make([]uint64, len(s.FieldsInv)) + fdvOffsetsEnd := make([]uint64, len(s.FieldsInv)) + + buf := s.grabBuf(binary.MaxVarintLen64) + + // these int coders are initialized with chunk size 1024 + // however this will be reset to the correct chunk size + // while processing each individual field-term section + tfEncoder := newChunkedIntCoder(1024, uint64(len(s.results)-1)) + locEncoder := newChunkedIntCoder(1024, uint64(len(s.results)-1)) + + var docTermMap [][]byte + + if s.builder == nil { + s.builder, err = vellum.New(&s.builderBuf, nil) + if err != nil { + return 0, nil, err + } + } + + for fieldID, terms := range s.DictKeys { + if cap(docTermMap) < len(s.results) { + docTermMap = make([][]byte, len(s.results)) + } else { + docTermMap = docTermMap[0:len(s.results)] + for docNum := range docTermMap { // reset the docTermMap + docTermMap[docNum] = docTermMap[docNum][:0] + } + } + + dict := s.Dicts[fieldID] + + for _, term := range terms { // terms are already sorted + pid := dict[term] - 1 + + postingsBS := s.Postings[pid] + + freqNorms := s.FreqNorms[pid] + freqNormOffset := 0 + + locs := s.Locs[pid] + locOffset := 0 + + chunkSize, err := getChunkSize(s.chunkMode, postingsBS.GetCardinality(), uint64(len(s.results))) + if err != nil { + return 0, nil, err + } + tfEncoder.SetChunkSize(chunkSize, uint64(len(s.results)-1)) + locEncoder.SetChunkSize(chunkSize, uint64(len(s.results)-1)) + + postingsItr := postingsBS.Iterator() + for postingsItr.HasNext() { + docNum := uint64(postingsItr.Next()) + + freqNorm := freqNorms[freqNormOffset] + + err = tfEncoder.Add(docNum, + encodeFreqHasLocs(freqNorm.freq, freqNorm.numLocs > 0), + uint64(math.Float32bits(freqNorm.norm))) + if err != nil { + return 0, nil, err + } + + if freqNorm.numLocs > 0 { + numBytesLocs := 0 + for _, loc := range locs[locOffset : locOffset+freqNorm.numLocs] { + numBytesLocs += totalUvarintBytes( + uint64(loc.fieldID), loc.pos, loc.start, loc.end, + uint64(len(loc.arrayposs)), loc.arrayposs) + } + + err = locEncoder.Add(docNum, uint64(numBytesLocs)) + if err != nil { + return 0, nil, err + } + + for _, loc := range locs[locOffset : locOffset+freqNorm.numLocs] { + err = locEncoder.Add(docNum, + uint64(loc.fieldID), loc.pos, loc.start, loc.end, + uint64(len(loc.arrayposs))) + if err != nil { + return 0, nil, err + } + + err = locEncoder.Add(docNum, loc.arrayposs...) + if err != nil { + return 0, nil, err + } + } + + locOffset += freqNorm.numLocs + } + + freqNormOffset++ + + docTermMap[docNum] = append( + append(docTermMap[docNum], term...), + termSeparator) + } + + tfEncoder.Close() + locEncoder.Close() + + postingsOffset, err := + writePostings(postingsBS, tfEncoder, locEncoder, nil, s.w, buf) + if err != nil { + return 0, nil, err + } + + if postingsOffset > uint64(0) { + err = s.builder.Insert([]byte(term), postingsOffset) + if err != nil { + return 0, nil, err + } + } + + tfEncoder.Reset() + locEncoder.Reset() + } + + err = s.builder.Close() + if err != nil { + return 0, nil, err + } + + // record where this dictionary starts + dictOffsets[fieldID] = uint64(s.w.Count()) + + vellumData := s.builderBuf.Bytes() + + // write out the length of the vellum data + n := binary.PutUvarint(buf, uint64(len(vellumData))) + _, err = s.w.Write(buf[:n]) + if err != nil { + return 0, nil, err + } + + // write this vellum to disk + _, err = s.w.Write(vellumData) + if err != nil { + return 0, nil, err + } + + // reset vellum for reuse + s.builderBuf.Reset() + + err = s.builder.Reset(&s.builderBuf) + if err != nil { + return 0, nil, err + } + + // write the field doc values + // NOTE: doc values continue to use legacy chunk mode + chunkSize, err := getChunkSize(LegacyChunkMode, 0, 0) + if err != nil { + return 0, nil, err + } + fdvEncoder := newChunkedContentCoder(chunkSize, uint64(len(s.results)-1), s.w, false) + if s.IncludeDocValues[fieldID] { + for docNum, docTerms := range docTermMap { + if len(docTerms) > 0 { + err = fdvEncoder.Add(uint64(docNum), docTerms) + if err != nil { + return 0, nil, err + } + } + } + err = fdvEncoder.Close() + if err != nil { + return 0, nil, err + } + + fdvOffsetsStart[fieldID] = uint64(s.w.Count()) + + _, err = fdvEncoder.Write() + if err != nil { + return 0, nil, err + } + + fdvOffsetsEnd[fieldID] = uint64(s.w.Count()) + + fdvEncoder.Reset() + } else { + fdvOffsetsStart[fieldID] = fieldNotUninverted + fdvOffsetsEnd[fieldID] = fieldNotUninverted + } + } + + fdvIndexOffset = uint64(s.w.Count()) + + for i := 0; i < len(fdvOffsetsStart); i++ { + n := binary.PutUvarint(buf, fdvOffsetsStart[i]) + _, err := s.w.Write(buf[:n]) + if err != nil { + return 0, nil, err + } + n = binary.PutUvarint(buf, fdvOffsetsEnd[i]) + _, err = s.w.Write(buf[:n]) + if err != nil { + return 0, nil, err + } + } + + return fdvIndexOffset, dictOffsets, nil +} + +// returns the total # of bytes needed to encode the given uint64's +// into binary.PutUVarint() encoding +func totalUvarintBytes(a, b, c, d, e uint64, more []uint64) (n int) { + n = numUvarintBytes(a) + n += numUvarintBytes(b) + n += numUvarintBytes(c) + n += numUvarintBytes(d) + n += numUvarintBytes(e) + for _, v := range more { + n += numUvarintBytes(v) + } + return n +} + +// returns # of bytes needed to encode x in binary.PutUvarint() encoding +func numUvarintBytes(x uint64) (n int) { + for x >= 0x80 { + x >>= 7 + n++ + } + return n + 1 +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/plugin.go b/backend/vendor/github.com/blevesearch/zapx/v12/plugin.go new file mode 100644 index 0000000000..f67297ec2f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/plugin.go @@ -0,0 +1,27 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +// ZapPlugin implements the Plugin interface of +// the blevesearch/scorch_segment_api pkg +type ZapPlugin struct{} + +func (*ZapPlugin) Type() string { + return Type +} + +func (*ZapPlugin) Version() uint32 { + return Version +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/posting.go b/backend/vendor/github.com/blevesearch/zapx/v12/posting.go new file mode 100644 index 0000000000..627a19b1d9 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/posting.go @@ -0,0 +1,837 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "encoding/binary" + "fmt" + "math" + "reflect" + + "github.com/RoaringBitmap/roaring" + segment "github.com/blevesearch/scorch_segment_api/v2" +) + +var reflectStaticSizePostingsList int +var reflectStaticSizePostingsIterator int +var reflectStaticSizePosting int +var reflectStaticSizeLocation int + +func init() { + var pl PostingsList + reflectStaticSizePostingsList = int(reflect.TypeOf(pl).Size()) + var pi PostingsIterator + reflectStaticSizePostingsIterator = int(reflect.TypeOf(pi).Size()) + var p Posting + reflectStaticSizePosting = int(reflect.TypeOf(p).Size()) + var l Location + reflectStaticSizeLocation = int(reflect.TypeOf(l).Size()) +} + +// FST or vellum value (uint64) encoding is determined by the top two +// highest-order or most significant bits... +// +// encoding : MSB +// name : 63 62 61...to...bit #0 (LSB) +// ----------+---+---+--------------------------------------------------- +// general : 0 | 0 | 62-bits of postingsOffset. +// ~ : 0 | 1 | reserved for future. +// 1-hit : 1 | 0 | 31-bits of positive float31 norm | 31-bits docNum. +// ~ : 1 | 1 | reserved for future. +// +// Encoding "general" is able to handle all cases, where the +// postingsOffset points to more information about the postings for +// the term. +// +// Encoding "1-hit" is used to optimize a commonly seen case when a +// term has only a single hit. For example, a term in the _id field +// will have only 1 hit. The "1-hit" encoding is used for a term +// in a field when... +// +// - term vector info is disabled for that field; +// - and, the term appears in only a single doc for that field; +// - and, the term's freq is exactly 1 in that single doc for that field; +// - and, the docNum must fit into 31-bits; +// +// Otherwise, the "general" encoding is used instead. +// +// In the "1-hit" encoding, the field in that single doc may have +// other terms, which is supported in the "1-hit" encoding by the +// positive float31 norm. + +const FSTValEncodingMask = uint64(0xc000000000000000) +const FSTValEncodingGeneral = uint64(0x0000000000000000) +const FSTValEncoding1Hit = uint64(0x8000000000000000) + +func FSTValEncode1Hit(docNum uint64, normBits uint64) uint64 { + return FSTValEncoding1Hit | ((mask31Bits & normBits) << 31) | (mask31Bits & docNum) +} + +func FSTValDecode1Hit(v uint64) (docNum uint64, normBits uint64) { + return (mask31Bits & v), (mask31Bits & (v >> 31)) +} + +const mask31Bits = uint64(0x000000007fffffff) + +func under32Bits(x uint64) bool { + return x <= mask31Bits +} + +const DocNum1HitFinished = math.MaxUint64 + +var NormBits1Hit = uint64(math.Float32bits(float32(1))) + +// PostingsList is an in-memory representation of a postings list +type PostingsList struct { + sb *SegmentBase + postingsOffset uint64 + freqOffset uint64 + locOffset uint64 + postings *roaring.Bitmap + except *roaring.Bitmap + + // when normBits1Hit != 0, then this postings list came from a + // 1-hit encoding, and only the docNum1Hit & normBits1Hit apply + docNum1Hit uint64 + normBits1Hit uint64 +} + +// Following methods are dummy implementations for the interface +// DiskStatsReporter (for backward compatibility). +// The working implementations are supported only in zap v15.x +// and not in the earlier versions of zap. +func (i *PostingsList) ResetBytesRead(uint64) {} + +func (i *PostingsList) BytesRead() uint64 { + return 0 +} + +func (i *PostingsList) incrementBytesRead(uint64) {} + +func (i *PostingsList) BytesWritten() uint64 { + return 0 +} + +// represents an immutable, empty postings list +var emptyPostingsList = &PostingsList{} + +func (p *PostingsList) Size() int { + sizeInBytes := reflectStaticSizePostingsList + SizeOfPtr + + if p.except != nil { + sizeInBytes += int(p.except.GetSizeInBytes()) + } + + return sizeInBytes +} + +func (p *PostingsList) OrInto(receiver *roaring.Bitmap) { + if p.normBits1Hit != 0 { + receiver.Add(uint32(p.docNum1Hit)) + return + } + + if p.postings != nil { + receiver.Or(p.postings) + } +} + +// Iterator returns an iterator for this postings list +func (p *PostingsList) Iterator(includeFreq, includeNorm, includeLocs bool, + prealloc segment.PostingsIterator) segment.PostingsIterator { + if p.normBits1Hit == 0 && p.postings == nil { + return emptyPostingsIterator + } + + var preallocPI *PostingsIterator + pi, ok := prealloc.(*PostingsIterator) + if ok && pi != nil { + preallocPI = pi + } + if preallocPI == emptyPostingsIterator { + preallocPI = nil + } + + return p.iterator(includeFreq, includeNorm, includeLocs, preallocPI) +} + +func (p *PostingsList) iterator(includeFreq, includeNorm, includeLocs bool, + rv *PostingsIterator) *PostingsIterator { + if rv == nil { + rv = &PostingsIterator{} + } else { + freqNormReader := rv.freqNormReader + if freqNormReader != nil { + freqNormReader.reset() + } + + locReader := rv.locReader + if locReader != nil { + locReader.reset() + } + + nextLocs := rv.nextLocs[:0] + nextSegmentLocs := rv.nextSegmentLocs[:0] + + buf := rv.buf + + *rv = PostingsIterator{} // clear the struct + + rv.freqNormReader = freqNormReader + rv.locReader = locReader + + rv.nextLocs = nextLocs + rv.nextSegmentLocs = nextSegmentLocs + + rv.buf = buf + } + + rv.postings = p + rv.includeFreqNorm = includeFreq || includeNorm || includeLocs + rv.includeLocs = includeLocs + + if p.normBits1Hit != 0 { + // "1-hit" encoding + rv.docNum1Hit = p.docNum1Hit + rv.normBits1Hit = p.normBits1Hit + + if p.except != nil && p.except.Contains(uint32(rv.docNum1Hit)) { + rv.docNum1Hit = DocNum1HitFinished + } + + return rv + } + + // "general" encoding, check if empty + if p.postings == nil { + return rv + } + + // initialize freq chunk reader + if rv.includeFreqNorm { + rv.freqNormReader = newChunkedIntDecoder(p.sb.mem, p.freqOffset) + } + + // initialize the loc chunk reader + if rv.includeLocs { + rv.locReader = newChunkedIntDecoder(p.sb.mem, p.locOffset) + } + + rv.all = p.postings.Iterator() + if p.except != nil { + rv.ActualBM = roaring.AndNot(p.postings, p.except) + rv.Actual = rv.ActualBM.Iterator() + } else { + rv.ActualBM = p.postings + rv.Actual = rv.all // Optimize to use same iterator for all & Actual. + } + + return rv +} + +// Count returns the number of items on this postings list +func (p *PostingsList) Count() uint64 { + var n, e uint64 + if p.normBits1Hit != 0 { + n = 1 + if p.except != nil && p.except.Contains(uint32(p.docNum1Hit)) { + e = 1 + } + } else if p.postings != nil { + n = p.postings.GetCardinality() + if p.except != nil { + e = p.postings.AndCardinality(p.except) + } + } + return n - e +} + +func (rv *PostingsList) read(postingsOffset uint64, d *Dictionary) error { + rv.postingsOffset = postingsOffset + + // handle "1-hit" encoding special case + if rv.postingsOffset&FSTValEncodingMask == FSTValEncoding1Hit { + return rv.init1Hit(postingsOffset) + } + + // read the location of the freq/norm details + var n uint64 + var read int + + rv.freqOffset, read = binary.Uvarint(d.sb.mem[postingsOffset+n : postingsOffset+binary.MaxVarintLen64]) + n += uint64(read) + + rv.locOffset, read = binary.Uvarint(d.sb.mem[postingsOffset+n : postingsOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + + var postingsLen uint64 + postingsLen, read = binary.Uvarint(d.sb.mem[postingsOffset+n : postingsOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + + roaringBytes := d.sb.mem[postingsOffset+n : postingsOffset+n+postingsLen] + + if rv.postings == nil { + rv.postings = roaring.NewBitmap() + } + _, err := rv.postings.FromBuffer(roaringBytes) + if err != nil { + return fmt.Errorf("error loading roaring bitmap: %v", err) + } + + return nil +} + +func (rv *PostingsList) init1Hit(fstVal uint64) error { + docNum, normBits := FSTValDecode1Hit(fstVal) + + rv.docNum1Hit = docNum + rv.normBits1Hit = normBits + + return nil +} + +// PostingsIterator provides a way to iterate through the postings list +type PostingsIterator struct { + postings *PostingsList + all roaring.IntPeekable + Actual roaring.IntPeekable + ActualBM *roaring.Bitmap + + currChunk uint32 + freqNormReader *chunkedIntDecoder + locReader *chunkedIntDecoder + + next Posting // reused across Next() calls + nextLocs []Location // reused across Next() calls + nextSegmentLocs []segment.Location // reused across Next() calls + + docNum1Hit uint64 + normBits1Hit uint64 + + buf []byte + + includeFreqNorm bool + includeLocs bool +} + +var emptyPostingsIterator = &PostingsIterator{} + +// Following methods are dummy implementations for the interface +// DiskStatsReporter (for backward compatibility). +// The working implementations are supported only in zap v15.x +// and not in the earlier versions of zap. +func (i *PostingsIterator) ResetBytesRead(uint64) {} + +func (i *PostingsIterator) BytesRead() uint64 { + return 0 +} + +func (i *PostingsIterator) incrementBytesRead(uint64) {} + +func (i *PostingsIterator) BytesWritten() uint64 { + return 0 +} + +func (i *PostingsIterator) Size() int { + sizeInBytes := reflectStaticSizePostingsIterator + SizeOfPtr + + i.next.Size() + // account for freqNormReader, locReader if we start using this. + for _, entry := range i.nextLocs { + sizeInBytes += entry.Size() + } + + return sizeInBytes +} + +func (i *PostingsIterator) loadChunk(chunk int) error { + if i.includeFreqNorm { + err := i.freqNormReader.loadChunk(chunk) + if err != nil { + return err + } + } + + if i.includeLocs { + err := i.locReader.loadChunk(chunk) + if err != nil { + return err + } + } + + i.currChunk = uint32(chunk) + return nil +} + +func (i *PostingsIterator) readFreqNormHasLocs() (uint64, uint64, bool, error) { + if i.normBits1Hit != 0 { + return 1, i.normBits1Hit, false, nil + } + + freqHasLocs, err := i.freqNormReader.readUvarint() + if err != nil { + return 0, 0, false, fmt.Errorf("error reading frequency: %v", err) + } + + freq, hasLocs := decodeFreqHasLocs(freqHasLocs) + + normBits, err := i.freqNormReader.readUvarint() + if err != nil { + return 0, 0, false, fmt.Errorf("error reading norm: %v", err) + } + + return freq, normBits, hasLocs, nil +} + +func (i *PostingsIterator) skipFreqNormReadHasLocs() (bool, error) { + if i.normBits1Hit != 0 { + return false, nil + } + + freqHasLocs, err := i.freqNormReader.readUvarint() + if err != nil { + return false, fmt.Errorf("error reading freqHasLocs: %v", err) + } + + i.freqNormReader.SkipUvarint() // Skip normBits. + + return freqHasLocs&0x01 != 0, nil // See decodeFreqHasLocs() / hasLocs. +} + +func encodeFreqHasLocs(freq uint64, hasLocs bool) uint64 { + rv := freq << 1 + if hasLocs { + rv = rv | 0x01 // 0'th LSB encodes whether there are locations + } + return rv +} + +func decodeFreqHasLocs(freqHasLocs uint64) (uint64, bool) { + freq := freqHasLocs >> 1 + hasLocs := freqHasLocs&0x01 != 0 + return freq, hasLocs +} + +// readLocation processes all the integers on the stream representing a single +// location. +func (i *PostingsIterator) readLocation(l *Location) error { + // read off field + fieldID, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location field: %v", err) + } + // read off pos + pos, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location pos: %v", err) + } + // read off start + start, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location start: %v", err) + } + // read off end + end, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location end: %v", err) + } + // read off num array pos + numArrayPos, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location num array pos: %v", err) + } + + l.field = i.postings.sb.fieldsInv[fieldID] + l.pos = pos + l.start = start + l.end = end + + if cap(l.ap) < int(numArrayPos) { + l.ap = make([]uint64, int(numArrayPos)) + } else { + l.ap = l.ap[:int(numArrayPos)] + } + + // read off array positions + for k := 0; k < int(numArrayPos); k++ { + ap, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading array position: %v", err) + } + + l.ap[k] = ap + } + + return nil +} + +// Next returns the next posting on the postings list, or nil at the end +func (i *PostingsIterator) Next() (segment.Posting, error) { + return i.nextAtOrAfter(0) +} + +// Advance returns the posting at the specified docNum or it is not present +// the next posting, or if the end is reached, nil +func (i *PostingsIterator) Advance(docNum uint64) (segment.Posting, error) { + return i.nextAtOrAfter(docNum) +} + +// Next returns the next posting on the postings list, or nil at the end +func (i *PostingsIterator) nextAtOrAfter(atOrAfter uint64) (segment.Posting, error) { + docNum, exists, err := i.nextDocNumAtOrAfter(atOrAfter) + if err != nil || !exists { + return nil, err + } + + i.next = Posting{} // clear the struct + rv := &i.next + rv.docNum = docNum + + if !i.includeFreqNorm { + return rv, nil + } + + var normBits uint64 + var hasLocs bool + + rv.freq, normBits, hasLocs, err = i.readFreqNormHasLocs() + if err != nil { + return nil, err + } + + rv.norm = math.Float32frombits(uint32(normBits)) + + if i.includeLocs && hasLocs { + // prepare locations into reused slices, where we assume + // rv.freq >= "number of locs", since in a composite field, + // some component fields might have their IncludeTermVector + // flags disabled while other component fields are enabled + if cap(i.nextLocs) >= int(rv.freq) { + i.nextLocs = i.nextLocs[0:rv.freq] + } else { + i.nextLocs = make([]Location, rv.freq, rv.freq*2) + } + if cap(i.nextSegmentLocs) < int(rv.freq) { + i.nextSegmentLocs = make([]segment.Location, rv.freq, rv.freq*2) + } + rv.locs = i.nextSegmentLocs[:0] + + numLocsBytes, err := i.locReader.readUvarint() + if err != nil { + return nil, fmt.Errorf("error reading location numLocsBytes: %v", err) + } + + j := 0 + startBytesRemaining := i.locReader.Len() // # bytes remaining in the locReader + for startBytesRemaining-i.locReader.Len() < int(numLocsBytes) { + err := i.readLocation(&i.nextLocs[j]) + if err != nil { + return nil, err + } + rv.locs = append(rv.locs, &i.nextLocs[j]) + j++ + } + } + + return rv, nil +} + +// nextDocNum returns the next docNum on the postings list, and also +// sets up the currChunk / loc related fields of the iterator. +func (i *PostingsIterator) nextDocNumAtOrAfter(atOrAfter uint64) (uint64, bool, error) { + if i.normBits1Hit != 0 { + if i.docNum1Hit == DocNum1HitFinished { + return 0, false, nil + } + if i.docNum1Hit < atOrAfter { + // advanced past our 1-hit + i.docNum1Hit = DocNum1HitFinished // consume our 1-hit docNum + return 0, false, nil + } + docNum := i.docNum1Hit + i.docNum1Hit = DocNum1HitFinished // consume our 1-hit docNum + return docNum, true, nil + } + + if i.Actual == nil || !i.Actual.HasNext() { + return 0, false, nil + } + + if i.postings == nil || i.postings == emptyPostingsList { + // couldn't find anything + return 0, false, nil + } + + if i.postings.postings == i.ActualBM { + return i.nextDocNumAtOrAfterClean(atOrAfter) + } + + i.Actual.AdvanceIfNeeded(uint32(atOrAfter)) + + if !i.Actual.HasNext() || !i.all.HasNext() { + // couldn't find anything + return 0, false, nil + } + + n := i.Actual.Next() + allN := i.all.Next() + + chunkSize, err := getChunkSize(i.postings.sb.chunkMode, i.postings.postings.GetCardinality(), i.postings.sb.numDocs) + if err != nil { + return 0, false, err + } + nChunk := n / uint32(chunkSize) + + // when allN becomes >= to here, then allN is in the same chunk as nChunk. + allNReachesNChunk := nChunk * uint32(chunkSize) + + // n is the next actual hit (excluding some postings), and + // allN is the next hit in the full postings, and + // if they don't match, move 'all' forwards until they do + for allN != n { + // we've reached same chunk, so move the freq/norm/loc decoders forward + if i.includeFreqNorm && allN >= allNReachesNChunk { + err := i.currChunkNext(nChunk) + if err != nil { + return 0, false, err + } + } + + if !i.all.HasNext() { + return 0, false, nil + } + + allN = i.all.Next() + } + + if i.includeFreqNorm && (i.currChunk != nChunk || i.freqNormReader.isNil()) { + err := i.loadChunk(int(nChunk)) + if err != nil { + return 0, false, fmt.Errorf("error loading chunk: %v", err) + } + } + + return uint64(n), true, nil +} + +// optimization when the postings list is "clean" (e.g., no updates & +// no deletions) where the all bitmap is the same as the actual bitmap +func (i *PostingsIterator) nextDocNumAtOrAfterClean( + atOrAfter uint64) (uint64, bool, error) { + if !i.includeFreqNorm { + i.Actual.AdvanceIfNeeded(uint32(atOrAfter)) + + if !i.Actual.HasNext() { + return 0, false, nil // couldn't find anything + } + + return uint64(i.Actual.Next()), true, nil + } + + chunkSize, err := getChunkSize(i.postings.sb.chunkMode, i.postings.postings.GetCardinality(), i.postings.sb.numDocs) + if err != nil { + return 0, false, err + } + + // freq-norm's needed, so maintain freq-norm chunk reader + sameChunkNexts := 0 // # of times we called Next() in the same chunk + n := i.Actual.Next() + nChunk := n / uint32(chunkSize) + + for uint64(n) < atOrAfter && i.Actual.HasNext() { + n = i.Actual.Next() + + nChunkPrev := nChunk + nChunk = n / uint32(chunkSize) + + if nChunk != nChunkPrev { + sameChunkNexts = 0 + } else { + sameChunkNexts += 1 + } + } + + if uint64(n) < atOrAfter { + // couldn't find anything + return 0, false, nil + } + + for j := 0; j < sameChunkNexts; j++ { + err := i.currChunkNext(nChunk) + if err != nil { + return 0, false, fmt.Errorf("error optimized currChunkNext: %v", err) + } + } + + if i.currChunk != nChunk || i.freqNormReader.isNil() { + err := i.loadChunk(int(nChunk)) + if err != nil { + return 0, false, fmt.Errorf("error loading chunk: %v", err) + } + } + + return uint64(n), true, nil +} + +func (i *PostingsIterator) currChunkNext(nChunk uint32) error { + if i.currChunk != nChunk || i.freqNormReader.isNil() { + err := i.loadChunk(int(nChunk)) + if err != nil { + return fmt.Errorf("error loading chunk: %v", err) + } + } + + // read off freq/offsets even though we don't care about them + hasLocs, err := i.skipFreqNormReadHasLocs() + if err != nil { + return err + } + + if i.includeLocs && hasLocs { + numLocsBytes, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location numLocsBytes: %v", err) + } + + // skip over all the location bytes + i.locReader.SkipBytes(int(numLocsBytes)) + } + + return nil +} + +// DocNum1Hit returns the docNum and true if this is "1-hit" optimized +// and the docNum is available. +func (p *PostingsIterator) DocNum1Hit() (uint64, bool) { + if p.normBits1Hit != 0 && p.docNum1Hit != DocNum1HitFinished { + return p.docNum1Hit, true + } + return 0, false +} + +// ActualBitmap returns the underlying actual bitmap +// which can be used up the stack for optimizations +func (p *PostingsIterator) ActualBitmap() *roaring.Bitmap { + return p.ActualBM +} + +// ReplaceActual replaces the ActualBM with the provided +// bitmap +func (p *PostingsIterator) ReplaceActual(abm *roaring.Bitmap) { + p.ActualBM = abm + p.Actual = abm.Iterator() +} + +// PostingsIteratorFromBitmap constructs a PostingsIterator given an +// "actual" bitmap. +func PostingsIteratorFromBitmap(bm *roaring.Bitmap, + includeFreqNorm, includeLocs bool) (segment.PostingsIterator, error) { + return &PostingsIterator{ + ActualBM: bm, + Actual: bm.Iterator(), + includeFreqNorm: includeFreqNorm, + includeLocs: includeLocs, + }, nil +} + +// PostingsIteratorFrom1Hit constructs a PostingsIterator given a +// 1-hit docNum. +func PostingsIteratorFrom1Hit(docNum1Hit uint64, + includeFreqNorm, includeLocs bool) (segment.PostingsIterator, error) { + return &PostingsIterator{ + docNum1Hit: docNum1Hit, + normBits1Hit: NormBits1Hit, + includeFreqNorm: includeFreqNorm, + includeLocs: includeLocs, + }, nil +} + +// Posting is a single entry in a postings list +type Posting struct { + docNum uint64 + freq uint64 + norm float32 + locs []segment.Location +} + +func (p *Posting) Size() int { + sizeInBytes := reflectStaticSizePosting + + for _, entry := range p.locs { + sizeInBytes += entry.Size() + } + + return sizeInBytes +} + +// Number returns the document number of this posting in this segment +func (p *Posting) Number() uint64 { + return p.docNum +} + +// Frequency returns the frequencies of occurrence of this term in this doc/field +func (p *Posting) Frequency() uint64 { + return p.freq +} + +// Norm returns the normalization factor for this posting +func (p *Posting) Norm() float64 { + return float64(p.norm) +} + +// Locations returns the location information for each occurrence +func (p *Posting) Locations() []segment.Location { + return p.locs +} + +// Location represents the location of a single occurrence +type Location struct { + field string + pos uint64 + start uint64 + end uint64 + ap []uint64 +} + +func (l *Location) Size() int { + return reflectStaticSizeLocation + + len(l.field) + + len(l.ap)*SizeOfUint64 +} + +// Field returns the name of the field (useful in composite fields to know +// which original field the value came from) +func (l *Location) Field() string { + return l.field +} + +// Start returns the start byte offset of this occurrence +func (l *Location) Start() uint64 { + return l.start +} + +// End returns the end byte offset of this occurrence +func (l *Location) End() uint64 { + return l.end +} + +// Pos returns the 1-based phrase position of this occurrence +func (l *Location) Pos() uint64 { + return l.pos +} + +// ArrayPositions returns the array position vector associated with this occurrence +func (l *Location) ArrayPositions() []uint64 { + return l.ap +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/read.go b/backend/vendor/github.com/blevesearch/zapx/v12/read.go new file mode 100644 index 0000000000..e47d4c6abd --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/read.go @@ -0,0 +1,43 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import "encoding/binary" + +func (s *SegmentBase) getDocStoredMetaAndCompressed(docNum uint64) ([]byte, []byte) { + _, storedOffset, n, metaLen, dataLen := s.getDocStoredOffsets(docNum) + + meta := s.mem[storedOffset+n : storedOffset+n+metaLen] + data := s.mem[storedOffset+n+metaLen : storedOffset+n+metaLen+dataLen] + + return meta, data +} + +func (s *SegmentBase) getDocStoredOffsets(docNum uint64) ( + uint64, uint64, uint64, uint64, uint64) { + indexOffset := s.storedIndexOffset + (8 * docNum) + + storedOffset := binary.BigEndian.Uint64(s.mem[indexOffset : indexOffset+8]) + + var n uint64 + + metaLen, read := binary.Uvarint(s.mem[storedOffset : storedOffset+binary.MaxVarintLen64]) + n += uint64(read) + + dataLen, read := binary.Uvarint(s.mem[storedOffset+n : storedOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + + return indexOffset, storedOffset, n, metaLen, dataLen +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/segment.go b/backend/vendor/github.com/blevesearch/zapx/v12/segment.go new file mode 100644 index 0000000000..1fbf78480f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/segment.go @@ -0,0 +1,600 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" + "os" + "sync" + "unsafe" + + "github.com/RoaringBitmap/roaring" + mmap "github.com/blevesearch/mmap-go" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" + "github.com/golang/snappy" +) + +var reflectStaticSizeSegmentBase int + +func init() { + var sb SegmentBase + reflectStaticSizeSegmentBase = int(unsafe.Sizeof(sb)) +} + +// Open returns a zap impl of a segment +func (*ZapPlugin) Open(path string) (segment.Segment, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + mm, err := mmap.Map(f, mmap.RDONLY, 0) + if err != nil { + // mmap failed, try to close the file + _ = f.Close() + return nil, err + } + + rv := &Segment{ + SegmentBase: SegmentBase{ + mem: mm[0 : len(mm)-FooterSize], + fieldsMap: make(map[string]uint16), + fieldDvReaders: make(map[uint16]*docValueReader), + fieldFSTs: make(map[uint16]*vellum.FST), + }, + f: f, + mm: mm, + path: path, + refs: 1, + } + rv.SegmentBase.updateSize() + + err = rv.loadConfig() + if err != nil { + _ = rv.Close() + return nil, err + } + + err = rv.loadFields() + if err != nil { + _ = rv.Close() + return nil, err + } + + err = rv.loadDvReaders() + if err != nil { + _ = rv.Close() + return nil, err + } + + return rv, nil +} + +// SegmentBase is a memory only, read-only implementation of the +// segment.Segment interface, using zap's data representation. +type SegmentBase struct { + mem []byte + memCRC uint32 + chunkMode uint32 + fieldsMap map[string]uint16 // fieldName -> fieldID+1 + fieldsInv []string // fieldID -> fieldName + numDocs uint64 + storedIndexOffset uint64 + fieldsIndexOffset uint64 + docValueOffset uint64 + dictLocs []uint64 + fieldDvReaders map[uint16]*docValueReader // naive chunk cache per field + fieldDvNames []string // field names cached in fieldDvReaders + size uint64 + + m sync.Mutex + fieldFSTs map[uint16]*vellum.FST +} + +func (sb *SegmentBase) Size() int { + return int(sb.size) +} + +func (sb *SegmentBase) updateSize() { + sizeInBytes := reflectStaticSizeSegmentBase + + cap(sb.mem) + + // fieldsMap + for k := range sb.fieldsMap { + sizeInBytes += (len(k) + SizeOfString) + SizeOfUint16 + } + + // fieldsInv, dictLocs + for _, entry := range sb.fieldsInv { + sizeInBytes += len(entry) + SizeOfString + } + sizeInBytes += len(sb.dictLocs) * SizeOfUint64 + + // fieldDvReaders + for _, v := range sb.fieldDvReaders { + sizeInBytes += SizeOfUint16 + SizeOfPtr + if v != nil { + sizeInBytes += v.size() + } + } + + sb.size = uint64(sizeInBytes) +} + +func (sb *SegmentBase) AddRef() {} +func (sb *SegmentBase) DecRef() (err error) { return nil } +func (sb *SegmentBase) Close() (err error) { return nil } + +// Segment implements a persisted segment.Segment interface, by +// embedding an mmap()'ed SegmentBase. +type Segment struct { + SegmentBase + + f *os.File + mm mmap.MMap + path string + version uint32 + crc uint32 + + m sync.Mutex // Protects the fields that follow. + refs int64 +} + +func (s *Segment) Size() int { + // 8 /* size of file pointer */ + // 4 /* size of version -> uint32 */ + // 4 /* size of crc -> uint32 */ + sizeOfUints := 16 + + sizeInBytes := (len(s.path) + SizeOfString) + sizeOfUints + + // mutex, refs -> int64 + sizeInBytes += 16 + + // do not include the mmap'ed part + return sizeInBytes + s.SegmentBase.Size() - cap(s.mem) +} + +func (s *Segment) AddRef() { + s.m.Lock() + s.refs++ + s.m.Unlock() +} + +func (s *Segment) DecRef() (err error) { + s.m.Lock() + s.refs-- + if s.refs == 0 { + err = s.closeActual() + } + s.m.Unlock() + return err +} + +func (s *Segment) loadConfig() error { + crcOffset := len(s.mm) - 4 + s.crc = binary.BigEndian.Uint32(s.mm[crcOffset : crcOffset+4]) + + verOffset := crcOffset - 4 + s.version = binary.BigEndian.Uint32(s.mm[verOffset : verOffset+4]) + if s.version != Version { + return fmt.Errorf("unsupported version %d", s.version) + } + + chunkOffset := verOffset - 4 + s.chunkMode = binary.BigEndian.Uint32(s.mm[chunkOffset : chunkOffset+4]) + + docValueOffset := chunkOffset - 8 + s.docValueOffset = binary.BigEndian.Uint64(s.mm[docValueOffset : docValueOffset+8]) + + fieldsIndexOffset := docValueOffset - 8 + s.fieldsIndexOffset = binary.BigEndian.Uint64(s.mm[fieldsIndexOffset : fieldsIndexOffset+8]) + + storedIndexOffset := fieldsIndexOffset - 8 + s.storedIndexOffset = binary.BigEndian.Uint64(s.mm[storedIndexOffset : storedIndexOffset+8]) + + numDocsOffset := storedIndexOffset - 8 + s.numDocs = binary.BigEndian.Uint64(s.mm[numDocsOffset : numDocsOffset+8]) + return nil +} + +// Following methods are dummy implementations for the interface +// DiskStatsReporter (for backward compatibility). +// The working implementations are supported only in zap v15.x +// and not in the earlier versions of zap. +func (s *Segment) ResetBytesRead(uint64) {} + +func (s *Segment) BytesRead() uint64 { + return 0 +} + +func (s *Segment) BytesWritten() uint64 { + return 0 +} + +func (s *Segment) incrementBytesRead(uint64) {} + +func (s *SegmentBase) BytesWritten() uint64 { + return 0 +} + +func (s *SegmentBase) setBytesWritten(uint64) {} + +func (s *SegmentBase) BytesRead() uint64 { + return 0 +} + +func (s *SegmentBase) ResetBytesRead(uint64) {} + +func (s *SegmentBase) incrementBytesRead(uint64) {} + +func (s *SegmentBase) loadFields() error { + // NOTE for now we assume the fields index immediately precedes + // the footer, and if this changes, need to adjust accordingly (or + // store explicit length), where s.mem was sliced from s.mm in Open(). + fieldsIndexEnd := uint64(len(s.mem)) + + // iterate through fields index + var fieldID uint64 + for s.fieldsIndexOffset+(8*fieldID) < fieldsIndexEnd { + addr := binary.BigEndian.Uint64(s.mem[s.fieldsIndexOffset+(8*fieldID) : s.fieldsIndexOffset+(8*fieldID)+8]) + + dictLoc, read := binary.Uvarint(s.mem[addr:fieldsIndexEnd]) + n := uint64(read) + s.dictLocs = append(s.dictLocs, dictLoc) + + var nameLen uint64 + nameLen, read = binary.Uvarint(s.mem[addr+n : fieldsIndexEnd]) + n += uint64(read) + + name := string(s.mem[addr+n : addr+n+nameLen]) + s.fieldsInv = append(s.fieldsInv, name) + s.fieldsMap[name] = uint16(fieldID + 1) + + fieldID++ + } + return nil +} + +// Dictionary returns the term dictionary for the specified field +func (s *SegmentBase) Dictionary(field string) (segment.TermDictionary, error) { + dict, err := s.dictionary(field) + if err == nil && dict == nil { + return emptyDictionary, nil + } + return dict, err +} + +func (sb *SegmentBase) dictionary(field string) (rv *Dictionary, err error) { + fieldIDPlus1 := sb.fieldsMap[field] + if fieldIDPlus1 > 0 { + rv = &Dictionary{ + sb: sb, + field: field, + fieldID: fieldIDPlus1 - 1, + } + + dictStart := sb.dictLocs[rv.fieldID] + if dictStart > 0 { + var ok bool + sb.m.Lock() + if rv.fst, ok = sb.fieldFSTs[rv.fieldID]; !ok { + // read the length of the vellum data + vellumLen, read := binary.Uvarint(sb.mem[dictStart : dictStart+binary.MaxVarintLen64]) + fstBytes := sb.mem[dictStart+uint64(read) : dictStart+uint64(read)+vellumLen] + rv.fst, err = vellum.Load(fstBytes) + if err != nil { + sb.m.Unlock() + return nil, fmt.Errorf("dictionary field %s vellum err: %v", field, err) + } + + sb.fieldFSTs[rv.fieldID] = rv.fst + } + + sb.m.Unlock() + rv.fstReader, err = rv.fst.Reader() + if err != nil { + return nil, fmt.Errorf("dictionary field %s vellum reader err: %v", field, err) + } + } + } + + return rv, nil +} + +// visitDocumentCtx holds data structures that are reusable across +// multiple VisitDocument() calls to avoid memory allocations +type visitDocumentCtx struct { + buf []byte + reader bytes.Reader + arrayPos []uint64 +} + +var visitDocumentCtxPool = sync.Pool{ + New: func() interface{} { + reuse := &visitDocumentCtx{} + return reuse + }, +} + +// VisitStoredFields invokes the StoredFieldValueVisitor for each stored field +// for the specified doc number +func (s *SegmentBase) VisitStoredFields(num uint64, visitor segment.StoredFieldValueVisitor) error { + vdc := visitDocumentCtxPool.Get().(*visitDocumentCtx) + defer visitDocumentCtxPool.Put(vdc) + return s.visitStoredFields(vdc, num, visitor) +} + +func (s *SegmentBase) visitStoredFields(vdc *visitDocumentCtx, num uint64, + visitor segment.StoredFieldValueVisitor) error { + // first make sure this is a valid number in this segment + if num < s.numDocs { + meta, compressed := s.getDocStoredMetaAndCompressed(num) + + vdc.reader.Reset(meta) + + // handle _id field special case + idFieldValLen, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + idFieldVal := compressed[:idFieldValLen] + + keepGoing := visitor("_id", byte('t'), idFieldVal, nil) + if !keepGoing { + visitDocumentCtxPool.Put(vdc) + return nil + } + + // handle non-"_id" fields + compressed = compressed[idFieldValLen:] + + uncompressed, err := snappy.Decode(vdc.buf[:cap(vdc.buf)], compressed) + if err != nil { + return err + } + + for keepGoing { + field, err := binary.ReadUvarint(&vdc.reader) + if err == io.EOF { + break + } + if err != nil { + return err + } + typ, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + offset, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + l, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + numap, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + var arrayPos []uint64 + if numap > 0 { + if cap(vdc.arrayPos) < int(numap) { + vdc.arrayPos = make([]uint64, numap) + } + arrayPos = vdc.arrayPos[:numap] + for i := 0; i < int(numap); i++ { + ap, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + arrayPos[i] = ap + } + } + + value := uncompressed[offset : offset+l] + keepGoing = visitor(s.fieldsInv[field], byte(typ), value, arrayPos) + } + + vdc.buf = uncompressed + } + return nil +} + +// DocID returns the value of the _id field for the given docNum +func (s *SegmentBase) DocID(num uint64) ([]byte, error) { + if num >= s.numDocs { + return nil, nil + } + + vdc := visitDocumentCtxPool.Get().(*visitDocumentCtx) + + meta, compressed := s.getDocStoredMetaAndCompressed(num) + + vdc.reader.Reset(meta) + + // handle _id field special case + idFieldValLen, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return nil, err + } + idFieldVal := compressed[:idFieldValLen] + + visitDocumentCtxPool.Put(vdc) + + return idFieldVal, nil +} + +// Count returns the number of documents in this segment. +func (s *SegmentBase) Count() uint64 { + return s.numDocs +} + +// DocNumbers returns a bitset corresponding to the doc numbers of all the +// provided _id strings +func (s *SegmentBase) DocNumbers(ids []string) (*roaring.Bitmap, error) { + rv := roaring.New() + + if len(s.fieldsMap) > 0 { + idDict, err := s.dictionary("_id") + if err != nil { + return nil, err + } + + postingsList := emptyPostingsList + + sMax, err := idDict.fst.GetMaxKey() + if err != nil { + return nil, err + } + sMaxStr := string(sMax) + filteredIds := make([]string, 0, len(ids)) + for _, id := range ids { + if id <= sMaxStr { + filteredIds = append(filteredIds, id) + } + } + + for _, id := range filteredIds { + postingsList, err = idDict.postingsList([]byte(id), nil, postingsList) + if err != nil { + return nil, err + } + postingsList.OrInto(rv) + } + } + + return rv, nil +} + +// Fields returns the field names used in this segment +func (s *SegmentBase) Fields() []string { + return s.fieldsInv +} + +// Path returns the path of this segment on disk +func (s *Segment) Path() string { + return s.path +} + +// Close releases all resources associated with this segment +func (s *Segment) Close() (err error) { + return s.DecRef() +} + +func (s *Segment) closeActual() (err error) { + if s.mm != nil { + err = s.mm.Unmap() + } + // try to close file even if unmap failed + if s.f != nil { + err2 := s.f.Close() + if err == nil { + // try to return first error + err = err2 + } + } + return +} + +// some helpers i started adding for the command-line utility + +// Data returns the underlying mmaped data slice +func (s *Segment) Data() []byte { + return s.mm +} + +// CRC returns the CRC value stored in the file footer +func (s *Segment) CRC() uint32 { + return s.crc +} + +// Version returns the file version in the file footer +func (s *Segment) Version() uint32 { + return s.version +} + +// ChunkFactor returns the chunk factor in the file footer +func (s *Segment) ChunkMode() uint32 { + return s.chunkMode +} + +// FieldsIndexOffset returns the fields index offset in the file footer +func (s *Segment) FieldsIndexOffset() uint64 { + return s.fieldsIndexOffset +} + +// StoredIndexOffset returns the stored value index offset in the file footer +func (s *Segment) StoredIndexOffset() uint64 { + return s.storedIndexOffset +} + +// DocValueOffset returns the docValue offset in the file footer +func (s *Segment) DocValueOffset() uint64 { + return s.docValueOffset +} + +// NumDocs returns the number of documents in the file footer +func (s *Segment) NumDocs() uint64 { + return s.numDocs +} + +// DictAddr is a helper function to compute the file offset where the +// dictionary is stored for the specified field. +func (s *Segment) DictAddr(field string) (uint64, error) { + fieldIDPlus1, ok := s.fieldsMap[field] + if !ok { + return 0, fmt.Errorf("no such field '%s'", field) + } + + return s.dictLocs[fieldIDPlus1-1], nil +} + +func (s *SegmentBase) loadDvReaders() error { + if s.docValueOffset == fieldNotUninverted || s.numDocs == 0 { + return nil + } + + var read uint64 + for fieldID, field := range s.fieldsInv { + var fieldLocStart, fieldLocEnd uint64 + var n int + fieldLocStart, n = binary.Uvarint(s.mem[s.docValueOffset+read : s.docValueOffset+read+binary.MaxVarintLen64]) + if n <= 0 { + return fmt.Errorf("loadDvReaders: failed to read the docvalue offset start for field %d", fieldID) + } + read += uint64(n) + fieldLocEnd, n = binary.Uvarint(s.mem[s.docValueOffset+read : s.docValueOffset+read+binary.MaxVarintLen64]) + if n <= 0 { + return fmt.Errorf("loadDvReaders: failed to read the docvalue offset end for field %d", fieldID) + } + read += uint64(n) + + fieldDvReader, err := s.loadFieldDocValueReader(field, fieldLocStart, fieldLocEnd) + if err != nil { + return err + } + if fieldDvReader != nil { + s.fieldDvReaders[uint16(fieldID)] = fieldDvReader + s.fieldDvNames = append(s.fieldDvNames, field) + } + } + + return nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/sizes.go b/backend/vendor/github.com/blevesearch/zapx/v12/sizes.go new file mode 100644 index 0000000000..34166ea330 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/sizes.go @@ -0,0 +1,59 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "reflect" +) + +func init() { + var b bool + SizeOfBool = int(reflect.TypeOf(b).Size()) + var f32 float32 + SizeOfFloat32 = int(reflect.TypeOf(f32).Size()) + var f64 float64 + SizeOfFloat64 = int(reflect.TypeOf(f64).Size()) + var i int + SizeOfInt = int(reflect.TypeOf(i).Size()) + var m map[int]int + SizeOfMap = int(reflect.TypeOf(m).Size()) + var ptr *int + SizeOfPtr = int(reflect.TypeOf(ptr).Size()) + var slice []int + SizeOfSlice = int(reflect.TypeOf(slice).Size()) + var str string + SizeOfString = int(reflect.TypeOf(str).Size()) + var u8 uint8 + SizeOfUint8 = int(reflect.TypeOf(u8).Size()) + var u16 uint16 + SizeOfUint16 = int(reflect.TypeOf(u16).Size()) + var u32 uint32 + SizeOfUint32 = int(reflect.TypeOf(u32).Size()) + var u64 uint64 + SizeOfUint64 = int(reflect.TypeOf(u64).Size()) +} + +var SizeOfBool int +var SizeOfFloat32 int +var SizeOfFloat64 int +var SizeOfInt int +var SizeOfMap int +var SizeOfPtr int +var SizeOfSlice int +var SizeOfString int +var SizeOfUint8 int +var SizeOfUint16 int +var SizeOfUint32 int +var SizeOfUint64 int diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/write.go b/backend/vendor/github.com/blevesearch/zapx/v12/write.go new file mode 100644 index 0000000000..77aefdbfc8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/write.go @@ -0,0 +1,145 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "encoding/binary" + "io" + + "github.com/RoaringBitmap/roaring" +) + +// writes out the length of the roaring bitmap in bytes as varint +// then writes out the roaring bitmap itself +func writeRoaringWithLen(r *roaring.Bitmap, w io.Writer, + reuseBufVarint []byte) (int, error) { + buf, err := r.ToBytes() + if err != nil { + return 0, err + } + + var tw int + + // write out the length + n := binary.PutUvarint(reuseBufVarint, uint64(len(buf))) + nw, err := w.Write(reuseBufVarint[:n]) + tw += nw + if err != nil { + return tw, err + } + + // write out the roaring bytes + nw, err = w.Write(buf) + tw += nw + if err != nil { + return tw, err + } + + return tw, nil +} + +func persistFields(fieldsInv []string, w *CountHashWriter, dictLocs []uint64) (uint64, error) { + var rv uint64 + var fieldsOffsets []uint64 + + for fieldID, fieldName := range fieldsInv { + // record start of this field + fieldsOffsets = append(fieldsOffsets, uint64(w.Count())) + + // write out the dict location and field name length + _, err := writeUvarints(w, dictLocs[fieldID], uint64(len(fieldName))) + if err != nil { + return 0, err + } + + // write out the field name + _, err = w.Write([]byte(fieldName)) + if err != nil { + return 0, err + } + } + + // now write out the fields index + rv = uint64(w.Count()) + for fieldID := range fieldsInv { + err := binary.Write(w, binary.BigEndian, fieldsOffsets[fieldID]) + if err != nil { + return 0, err + } + } + + return rv, nil +} + +// FooterSize is the size of the footer record in bytes +// crc + ver + chunk + field offset + stored offset + num docs + docValueOffset +const FooterSize = 4 + 4 + 4 + 8 + 8 + 8 + 8 + +func persistFooter(numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset uint64, + chunkMode uint32, crcBeforeFooter uint32, writerIn io.Writer) error { + w := NewCountHashWriter(writerIn) + w.crc = crcBeforeFooter + + // write out the number of docs + err := binary.Write(w, binary.BigEndian, numDocs) + if err != nil { + return err + } + // write out the stored field index location: + err = binary.Write(w, binary.BigEndian, storedIndexOffset) + if err != nil { + return err + } + // write out the field index location + err = binary.Write(w, binary.BigEndian, fieldsIndexOffset) + if err != nil { + return err + } + // write out the fieldDocValue location + err = binary.Write(w, binary.BigEndian, docValueOffset) + if err != nil { + return err + } + // write out 32-bit chunk factor + err = binary.Write(w, binary.BigEndian, chunkMode) + if err != nil { + return err + } + // write out 32-bit version + err = binary.Write(w, binary.BigEndian, Version) + if err != nil { + return err + } + // write out CRC-32 of everything upto but not including this CRC + err = binary.Write(w, binary.BigEndian, w.crc) + if err != nil { + return err + } + return nil +} + +func writeUvarints(w io.Writer, vals ...uint64) (tw int, err error) { + buf := make([]byte, binary.MaxVarintLen64) + for _, val := range vals { + n := binary.PutUvarint(buf, val) + var nw int + nw, err = w.Write(buf[:n]) + tw += nw + if err != nil { + return tw, err + } + } + return tw, err +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v12/zap.md b/backend/vendor/github.com/blevesearch/zapx/v12/zap.md new file mode 100644 index 0000000000..d74dc548b8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v12/zap.md @@ -0,0 +1,177 @@ +# ZAP File Format + +## Legend + +### Sections + + |========| + | | section + |========| + +### Fixed-size fields + + |--------| |----| |--| |-| + | | uint64 | | uint32 | | uint16 | | uint8 + |--------| |----| |--| |-| + +### Varints + + |~~~~~~~~| + | | varint(up to uint64) + |~~~~~~~~| + +### Arbitrary-length fields + + |--------...---| + | | arbitrary-length field (string, vellum, roaring bitmap) + |--------...---| + +### Chunked data + + [--------] + [ ] + [--------] + +## Overview + +Footer section describes the configuration of particular ZAP file. The format of footer is version-dependent, so it is necessary to check `V` field before the parsing. + + |==================================================| + | Stored Fields | + |==================================================| + |-----> | Stored Fields Index | + | |==================================================| + | | Dictionaries + Postings + DocValues | + | |==================================================| + | |---> | DocValues Index | + | | |==================================================| + | | | Fields | + | | |==================================================| + | | |-> | Fields Index | + | | | |========|========|========|========|====|====|====| + | | | | D# | SF | F | FDV | CF | V | CC | (Footer) + | | | |========|====|===|====|===|====|===|====|====|====| + | | | | | | + |-+-+-----------------| | | + | |--------------------------| | + |-------------------------------------| + + D#. Number of Docs. + SF. Stored Fields Index Offset. + F. Field Index Offset. + FDV. Field DocValue Offset. + CF. Chunk Factor. + V. Version. + CC. CRC32. + +## Stored Fields + +Stored Fields Index is `D#` consecutive 64-bit unsigned integers - offsets, where relevant Stored Fields Data records are located. + + 0 [SF] [SF + D# * 8] + | Stored Fields | Stored Fields Index | + |================================|==================================| + | | | + | |--------------------| ||--------|--------|. . .|--------|| + | |-> | Stored Fields Data | || 0 | 1 | | D# - 1 || + | | |--------------------| ||--------|----|---|. . .|--------|| + | | | | | + |===|============================|==============|===================| + | | + |-------------------------------------------| + +Stored Fields Data is an arbitrary size record, which consists of metadata and [Snappy](https://github.com/golang/snappy)-compressed data. + + Stored Fields Data + |~~~~~~~~|~~~~~~~~|~~~~~~~~...~~~~~~~~|~~~~~~~~...~~~~~~~~| + | MDS | CDS | MD | CD | + |~~~~~~~~|~~~~~~~~|~~~~~~~~...~~~~~~~~|~~~~~~~~...~~~~~~~~| + + MDS. Metadata size. + CDS. Compressed data size. + MD. Metadata. + CD. Snappy-compressed data. + +## Fields + +Fields Index section located between addresses `F` and `len(file) - len(footer)` and consist of `uint64` values (`F1`, `F2`, ...) which are offsets to records in Fields section. We have `F# = (len(file) - len(footer) - F) / sizeof(uint64)` fields. + + + (...) [F] [F + F#] + | Fields | Fields Index. | + |================================|================================| + | | | + | |~~~~~~~~|~~~~~~~~|---...---|||--------|--------|...|--------|| + ||->| Dict | Length | Name ||| 0 | 1 | | F# - 1 || + || |~~~~~~~~|~~~~~~~~|---...---|||--------|----|---|...|--------|| + || | | | + ||===============================|==============|=================| + | | + |----------------------------------------------| + + +## Dictionaries + Postings + +Each of fields has its own dictionary, encoded in [Vellum](https://github.com/couchbase/vellum) format. Dictionary consists of pairs `(term, offset)`, where `offset` indicates the position of postings (list of documents) for this particular term. + + |================================================================|- Dictionaries + + | | Postings + + | | DocValues + | Freq/Norm (chunked) | + | [~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] | + | |->[ Freq | Norm (float32 under varint) ] | + | | [~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] | + | | | + | |------------------------------------------------------------| | + | Location Details (chunked) | | + | [~~~~~~|~~~~~|~~~~~~~|~~~~~|~~~~~~|~~~~~~~~|~~~~~] | | + | |->[ Size | Pos | Start | End | Arr# | ArrPos | ... ] | | + | | [~~~~~~|~~~~~|~~~~~~~|~~~~~|~~~~~~|~~~~~~~~|~~~~~] | | + | | | | + | |----------------------| | | + | Postings List | | | + | |~~~~~~~~|~~~~~|~~|~~~~~~~~|-----------...--| | | + | |->| F/N | LD | Length | ROARING BITMAP | | | + | | |~~~~~|~~|~~~~~~~~|~~~~~~~~|-----------...--| | | + | | |----------------------------------------------| | + | |--------------------------------------| | + | Dictionary | | + | |~~~~~~~~|--------------------------|-...-| | + | |->| Length | VELLUM DATA : (TERM -> OFFSET) | | + | | |~~~~~~~~|----------------------------...-| | + | | | + |======|=========================================================|- DocValues Index + | | | + |======|=========================================================|- Fields + | | | + | |~~~~|~~~|~~~~~~~~|---...---| | + | | Dict | Length | Name | | + | |~~~~~~~~|~~~~~~~~|---...---| | + | | + |================================================================| + +## DocValues + +DocValues Index is `F#` pairs of varints, one pair per field. Each pair of varints indicates start and end point of DocValues slice. + + |================================================================| + | |------...--| | + | |->| DocValues |<-| | + | | |------...--| | | + |==|=================|===========================================|- DocValues Index + ||~|~~~~~~~~~|~~~~~~~|~~| |~~~~~~~~~~~~~~|~~~~~~~~~~~~|| + || DV1 START | DV1 STOP | . . . . . | DV(F#) START | DV(F#) END || + ||~~~~~~~~~~~|~~~~~~~~~~| |~~~~~~~~~~~~~~|~~~~~~~~~~~~|| + |================================================================| + +DocValues is chunked Snappy-compressed values for each document and field. + + [~~~~~~~~~~~~~~~|~~~~~~|~~~~~~~~~|-...-|~~~~~~|~~~~~~~~~|--------------------...-] + [ Doc# in Chunk | Doc1 | Offset1 | ... | DocN | OffsetN | SNAPPY COMPRESSED DATA ] + [~~~~~~~~~~~~~~~|~~~~~~|~~~~~~~~~|-...-|~~~~~~|~~~~~~~~~|--------------------...-] + +Last 16 bytes are description of chunks. + + |~~~~~~~~~~~~...~|----------------|----------------| + | Chunk Sizes | Chunk Size Arr | Chunk# | + |~~~~~~~~~~~~...~|----------------|----------------| diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/.gitignore b/backend/vendor/github.com/blevesearch/zapx/v13/.gitignore new file mode 100644 index 0000000000..46d1cfad54 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/.gitignore @@ -0,0 +1,12 @@ +#* +*.sublime-* +*~ +.#* +.project +.settings +**/.idea/ +**/*.iml +.DS_Store +/cmd/zap/zap +*.test +tags diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/.golangci.yml b/backend/vendor/github.com/blevesearch/zapx/v13/.golangci.yml new file mode 100644 index 0000000000..1d55bfc00d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/.golangci.yml @@ -0,0 +1,28 @@ +linters: + # please, do not use `enable-all`: it's deprecated and will be removed soon. + # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint + disable-all: true + enable: + - bodyclose + - deadcode + - depguard + - dupl + - errcheck + - gofmt + - goimports + - goprintffuncname + - gosec + - gosimple + - govet + - ineffassign + - misspell + - nakedret + - nolintlint + - rowserrcheck + - staticcheck + - structcheck + - typecheck + - unused + - varcheck + - whitespace + diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/LICENSE b/backend/vendor/github.com/blevesearch/zapx/v13/LICENSE new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/README.md b/backend/vendor/github.com/blevesearch/zapx/v13/README.md new file mode 100644 index 0000000000..4cbf1a145b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/README.md @@ -0,0 +1,163 @@ +# zapx file format + +The zapx module is fork of [zap](https://github.com/blevesearch/zap) module which maintains file format compatibility, but removes dependency on bleve, and instead depends only on the indepenent interface modules: + +- [bleve_index_api](https://github.com/blevesearch/scorch_segment_api) +- [scorch_segment_api](https://github.com/blevesearch/scorch_segment_api) + +Advanced ZAP File Format Documentation is [here](zap.md). + +The file is written in the reverse order that we typically access data. This helps us write in one pass since later sections of the file require file offsets of things we've already written. + +Current usage: + +- mmap the entire file +- crc-32 bytes and version are in fixed position at end of the file +- reading remainder of footer could be version specific +- remainder of footer gives us: + - 3 important offsets (docValue , fields index and stored data index) + - 2 important values (number of docs and chunk factor) +- field data is processed once and memoized onto the heap so that we never have to go back to disk for it +- access to stored data by doc number means first navigating to the stored data index, then accessing a fixed position offset into that slice, which gives us the actual address of the data. the first bytes of that section tell us the size of data so that we know where it ends. +- access to all other indexed data follows the following pattern: + - first know the field name -> convert to id + - next navigate to term dictionary for that field + - some operations stop here and do dictionary ops + - next use dictionary to navigate to posting list for a specific term + - walk posting list + - if necessary, walk posting details as we go + - if location info is desired, consult location bitmap to see if it is there + +## stored fields section + +- for each document + - preparation phase: + - produce a slice of metadata bytes and data bytes + - produce these slices in field id order + - field value is appended to the data slice + - metadata slice is varint encoded with the following values for each field value + - field id (uint16) + - field type (byte) + - field value start offset in uncompressed data slice (uint64) + - field value length (uint64) + - field number of array positions (uint64) + - one additional value for each array position (uint64) + - compress the data slice using snappy + - file writing phase: + - remember the start offset for this document + - write out meta data length (varint uint64) + - write out compressed data length (varint uint64) + - write out the metadata bytes + - write out the compressed data bytes + +## stored fields idx + +- for each document + - write start offset (remembered from previous section) of stored data (big endian uint64) + +With this index and a known document number, we have direct access to all the stored field data. + +## posting details (freq/norm) section + +- for each posting list + - produce a slice containing multiple consecutive chunks (each chunk is varint stream) + - produce a slice remembering offsets of where each chunk starts + - preparation phase: + - for each hit in the posting list + - if this hit is in next chunk close out encoding of last chunk and record offset start of next + - encode term frequency (uint64) + - encode norm factor (float32) + - file writing phase: + - remember start position for this posting list details + - write out number of chunks that follow (varint uint64) + - write out length of each chunk (each a varint uint64) + - write out the byte slice containing all the chunk data + +If you know the doc number you're interested in, this format lets you jump to the correct chunk (docNum/chunkFactor) directly and then seek within that chunk until you find it. + +## posting details (location) section + +- for each posting list + - produce a slice containing multiple consecutive chunks (each chunk is varint stream) + - produce a slice remembering offsets of where each chunk starts + - preparation phase: + - for each hit in the posting list + - if this hit is in next chunk close out encoding of last chunk and record offset start of next + - encode field (uint16) + - encode field pos (uint64) + - encode field start (uint64) + - encode field end (uint64) + - encode number of array positions to follow (uint64) + - encode each array position (each uint64) + - file writing phase: + - remember start position for this posting list details + - write out number of chunks that follow (varint uint64) + - write out length of each chunk (each a varint uint64) + - write out the byte slice containing all the chunk data + +If you know the doc number you're interested in, this format lets you jump to the correct chunk (docNum/chunkFactor) directly and then seek within that chunk until you find it. + +## postings list section + +- for each posting list + - preparation phase: + - encode roaring bitmap posting list to bytes (so we know the length) + - file writing phase: + - remember the start position for this posting list + - write freq/norm details offset (remembered from previous, as varint uint64) + - write location details offset (remembered from previous, as varint uint64) + - write length of encoded roaring bitmap + - write the serialized roaring bitmap data + +## dictionary + +- for each field + - preparation phase: + - encode vellum FST with dictionary data pointing to file offset of posting list (remembered from previous) + - file writing phase: + - remember the start position of this persistDictionary + - write length of vellum data (varint uint64) + - write out vellum data + +## fields section + +- for each field + - file writing phase: + - remember start offset for each field + - write dictionary address (remembered from previous) (varint uint64) + - write length of field name (varint uint64) + - write field name bytes + +## fields idx + +- for each field + - file writing phase: + - write big endian uint64 of start offset for each field + +NOTE: currently we don't know or record the length of this fields index. Instead we rely on the fact that we know it immediately precedes a footer of known size. + +## fields DocValue + +- for each field + - preparation phase: + - produce a slice containing multiple consecutive chunks, where each chunk is composed of a meta section followed by compressed columnar field data + - produce a slice remembering the length of each chunk + - file writing phase: + - remember the start position of this first field DocValue offset in the footer + - write out number of chunks that follow (varint uint64) + - write out length of each chunk (each a varint uint64) + - write out the byte slice containing all the chunk data + +NOTE: currently the meta header inside each chunk gives clue to the location offsets and size of the data pertaining to a given docID and any +read operation leverage that meta information to extract the document specific data from the file. + +## footer + +- file writing phase + - write number of docs (big endian uint64) + - write stored field index location (big endian uint64) + - write field index location (big endian uint64) + - write field docValue location (big endian uint64) + - write out chunk factor (big endian uint32) + - write out version (big endian uint32) + - write out file CRC of everything preceding this (big endian uint32) diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/build.go b/backend/vendor/github.com/blevesearch/zapx/v13/build.go new file mode 100644 index 0000000000..827e5c47e8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/build.go @@ -0,0 +1,186 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bufio" + "fmt" + "io" + "math" + "os" + + "github.com/blevesearch/vellum" +) + +const Version uint32 = 13 + +const Type string = "zap" + +const fieldNotUninverted = math.MaxUint64 + +func (sb *SegmentBase) Persist(path string) error { + return PersistSegmentBase(sb, path) +} + +// WriteTo is an implementation of io.WriterTo interface. +func (sb *SegmentBase) WriteTo(w io.Writer) (int64, error) { + if w == nil { + return 0, fmt.Errorf("invalid writer found") + } + + n, err := persistSegmentBaseToWriter(sb, w) + return int64(n), err +} + +// PersistSegmentBase persists SegmentBase in the zap file format. +func PersistSegmentBase(sb *SegmentBase, path string) error { + flag := os.O_RDWR | os.O_CREATE + + f, err := os.OpenFile(path, flag, 0600) + if err != nil { + return err + } + + cleanup := func() { + _ = f.Close() + _ = os.Remove(path) + } + + _, err = persistSegmentBaseToWriter(sb, f) + if err != nil { + cleanup() + return err + } + + err = f.Sync() + if err != nil { + cleanup() + return err + } + + err = f.Close() + if err != nil { + cleanup() + return err + } + + return err +} + +type bufWriter struct { + w *bufio.Writer + n int +} + +func (br *bufWriter) Write(in []byte) (int, error) { + n, err := br.w.Write(in) + br.n += n + return n, err +} + +func persistSegmentBaseToWriter(sb *SegmentBase, w io.Writer) (int, error) { + br := &bufWriter{w: bufio.NewWriter(w)} + + _, err := br.Write(sb.mem) + if err != nil { + return 0, err + } + + err = persistFooter(sb.numDocs, sb.storedIndexOffset, sb.fieldsIndexOffset, + sb.docValueOffset, sb.chunkMode, sb.memCRC, br) + if err != nil { + return 0, err + } + + err = br.w.Flush() + if err != nil { + return 0, err + } + + return br.n, nil +} + +func persistStoredFieldValues(fieldID int, + storedFieldValues [][]byte, stf []byte, spf [][]uint64, + curr int, metaEncode varintEncoder, data []byte) ( + int, []byte, error) { + for i := 0; i < len(storedFieldValues); i++ { + // encode field + _, err := metaEncode(uint64(fieldID)) + if err != nil { + return 0, nil, err + } + // encode type + _, err = metaEncode(uint64(stf[i])) + if err != nil { + return 0, nil, err + } + // encode start offset + _, err = metaEncode(uint64(curr)) + if err != nil { + return 0, nil, err + } + // end len + _, err = metaEncode(uint64(len(storedFieldValues[i]))) + if err != nil { + return 0, nil, err + } + // encode number of array pos + _, err = metaEncode(uint64(len(spf[i]))) + if err != nil { + return 0, nil, err + } + // encode all array positions + for _, pos := range spf[i] { + _, err = metaEncode(pos) + if err != nil { + return 0, nil, err + } + } + + data = append(data, storedFieldValues[i]...) + curr += len(storedFieldValues[i]) + } + + return curr, data, nil +} + +func InitSegmentBase(mem []byte, memCRC uint32, chunkMode uint32, + fieldsMap map[string]uint16, fieldsInv []string, numDocs uint64, + storedIndexOffset uint64, fieldsIndexOffset uint64, docValueOffset uint64, + dictLocs []uint64) (*SegmentBase, error) { + sb := &SegmentBase{ + mem: mem, + memCRC: memCRC, + chunkMode: chunkMode, + fieldsMap: fieldsMap, + fieldsInv: fieldsInv, + numDocs: numDocs, + storedIndexOffset: storedIndexOffset, + fieldsIndexOffset: fieldsIndexOffset, + docValueOffset: docValueOffset, + dictLocs: dictLocs, + fieldDvReaders: make(map[uint16]*docValueReader), + fieldFSTs: make(map[uint16]*vellum.FST), + } + sb.updateSize() + + err := sb.loadDvReaders() + if err != nil { + return nil, err + } + + return sb, nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/chunk.go b/backend/vendor/github.com/blevesearch/zapx/v13/chunk.go new file mode 100644 index 0000000000..fe9f398da6 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/chunk.go @@ -0,0 +1,54 @@ +// Copyright (c) 2019 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "fmt" +) + +// LegacyChunkMode was the original chunk mode (always chunk size 1024) +// this mode is still used for chunking doc values. +var LegacyChunkMode uint32 = 1024 + +// DefaultChunkMode is the most recent improvement to chunking and should +// be used by default. +var DefaultChunkMode uint32 = 1025 + +func getChunkSize(chunkMode uint32, cardinality uint64, maxDocs uint64) (uint64, error) { + switch { + // any chunkMode <= 1024 will always chunk with chunkSize=chunkMode + case chunkMode <= 1024: + // legacy chunk size + return uint64(chunkMode), nil + + case chunkMode == 1025: + // attempt at simple improvement + // theory - the point of chunking is to put a bound on the maximum number of + // calls to Next() needed to find a random document. ie, you should be able + // to do one jump to the correct chunk, and then walk through at most + // chunk-size items + // previously 1024 was chosen as the chunk size, but this is particularly + // wasteful for low cardinality terms. the observation is that if there + // are less than 1024 items, why not put them all in one chunk, + // this way you'll still achieve the same goal of visiting at most + // chunk-size items. + // no attempt is made to tweak any other case + if cardinality <= 1024 { + return maxDocs, nil + } + return 1024, nil + } + return 0, fmt.Errorf("unknown chunk mode %d", chunkMode) +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/contentcoder.go b/backend/vendor/github.com/blevesearch/zapx/v13/contentcoder.go new file mode 100644 index 0000000000..c145b5a113 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/contentcoder.go @@ -0,0 +1,243 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "io" + "reflect" + + "github.com/golang/snappy" +) + +var reflectStaticSizeMetaData int + +func init() { + var md MetaData + reflectStaticSizeMetaData = int(reflect.TypeOf(md).Size()) +} + +var termSeparator byte = 0xff +var termSeparatorSplitSlice = []byte{termSeparator} + +type chunkedContentCoder struct { + final []byte + chunkSize uint64 + currChunk uint64 + chunkLens []uint64 + + w io.Writer + progressiveWrite bool + + chunkMetaBuf bytes.Buffer + chunkBuf bytes.Buffer + + chunkMeta []MetaData + + compressed []byte // temp buf for snappy compression +} + +// MetaData represents the data information inside a +// chunk. +type MetaData struct { + DocNum uint64 // docNum of the data inside the chunk + DocDvOffset uint64 // offset of data inside the chunk for the given docid +} + +// newChunkedContentCoder returns a new chunk content coder which +// packs data into chunks based on the provided chunkSize +func newChunkedContentCoder(chunkSize uint64, maxDocNum uint64, + w io.Writer, progressiveWrite bool) *chunkedContentCoder { + total := maxDocNum/chunkSize + 1 + rv := &chunkedContentCoder{ + chunkSize: chunkSize, + chunkLens: make([]uint64, total), + chunkMeta: make([]MetaData, 0, total), + w: w, + progressiveWrite: progressiveWrite, + } + + return rv +} + +// Reset lets you reuse this chunked content coder. Buffers are reset +// and re used. You cannot change the chunk size. +func (c *chunkedContentCoder) Reset() { + c.currChunk = 0 + c.final = c.final[:0] + c.chunkBuf.Reset() + c.chunkMetaBuf.Reset() + for i := range c.chunkLens { + c.chunkLens[i] = 0 + } + c.chunkMeta = c.chunkMeta[:0] +} + +func (c *chunkedContentCoder) SetChunkSize(chunkSize uint64, maxDocNum uint64) { + total := int(maxDocNum/chunkSize + 1) + c.chunkSize = chunkSize + if cap(c.chunkLens) < total { + c.chunkLens = make([]uint64, total) + } else { + c.chunkLens = c.chunkLens[:total] + } + if cap(c.chunkMeta) < total { + c.chunkMeta = make([]MetaData, 0, total) + } +} + +// Close indicates you are done calling Add() this allows +// the final chunk to be encoded. +func (c *chunkedContentCoder) Close() error { + return c.flushContents() +} + +func (c *chunkedContentCoder) flushContents() error { + // flush the contents, with meta information at first + buf := make([]byte, binary.MaxVarintLen64) + n := binary.PutUvarint(buf, uint64(len(c.chunkMeta))) + _, err := c.chunkMetaBuf.Write(buf[:n]) + if err != nil { + return err + } + + // write out the metaData slice + for _, meta := range c.chunkMeta { + _, err := writeUvarints(&c.chunkMetaBuf, meta.DocNum, meta.DocDvOffset) + if err != nil { + return err + } + } + + // write the metadata to final data + metaData := c.chunkMetaBuf.Bytes() + c.final = append(c.final, c.chunkMetaBuf.Bytes()...) + // write the compressed data to the final data + c.compressed = snappy.Encode(c.compressed[:cap(c.compressed)], c.chunkBuf.Bytes()) + c.final = append(c.final, c.compressed...) + + c.chunkLens[c.currChunk] = uint64(len(c.compressed) + len(metaData)) + + if c.progressiveWrite { + _, err := c.w.Write(c.final) + if err != nil { + return err + } + c.final = c.final[:0] + } + + return nil +} + +// Add encodes the provided byte slice into the correct chunk for the provided +// doc num. You MUST call Add() with increasing docNums. +func (c *chunkedContentCoder) Add(docNum uint64, vals []byte) error { + chunk := docNum / c.chunkSize + if chunk != c.currChunk { + // flush out the previous chunk details + err := c.flushContents() + if err != nil { + return err + } + // clearing the chunk specific meta for next chunk + c.chunkBuf.Reset() + c.chunkMetaBuf.Reset() + c.chunkMeta = c.chunkMeta[:0] + c.currChunk = chunk + } + + // get the starting offset for this doc + dvOffset := c.chunkBuf.Len() + dvSize, err := c.chunkBuf.Write(vals) + if err != nil { + return err + } + + c.chunkMeta = append(c.chunkMeta, MetaData{ + DocNum: docNum, + DocDvOffset: uint64(dvOffset + dvSize), + }) + return nil +} + +// Write commits all the encoded chunked contents to the provided writer. +// +// | ..... data ..... | chunk offsets (varints) +// | position of chunk offsets (uint64) | number of offsets (uint64) | +// +func (c *chunkedContentCoder) Write() (int, error) { + var tw int + + if c.final != nil { + // write out the data section first + nw, err := c.w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + } + + chunkOffsetsStart := uint64(tw) + + if cap(c.final) < binary.MaxVarintLen64 { + c.final = make([]byte, binary.MaxVarintLen64) + } else { + c.final = c.final[0:binary.MaxVarintLen64] + } + chunkOffsets := modifyLengthsToEndOffsets(c.chunkLens) + // write out the chunk offsets + for _, chunkOffset := range chunkOffsets { + n := binary.PutUvarint(c.final, chunkOffset) + nw, err := c.w.Write(c.final[:n]) + tw += nw + if err != nil { + return tw, err + } + } + + chunkOffsetsLen := uint64(tw) - chunkOffsetsStart + + c.final = c.final[0:8] + // write out the length of chunk offsets + binary.BigEndian.PutUint64(c.final, chunkOffsetsLen) + nw, err := c.w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + + // write out the number of chunks + binary.BigEndian.PutUint64(c.final, uint64(len(c.chunkLens))) + nw, err = c.w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + + c.final = c.final[:0] + + return tw, nil +} + +// ReadDocValueBoundary elicits the start, end offsets from a +// metaData header slice +func ReadDocValueBoundary(chunk int, metaHeaders []MetaData) (uint64, uint64) { + var start uint64 + if chunk > 0 { + start = metaHeaders[chunk-1].DocDvOffset + } + return start, metaHeaders[chunk].DocDvOffset +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/count.go b/backend/vendor/github.com/blevesearch/zapx/v13/count.go new file mode 100644 index 0000000000..b6135359fb --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/count.go @@ -0,0 +1,61 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "hash/crc32" + "io" + + segment "github.com/blevesearch/scorch_segment_api/v2" +) + +// CountHashWriter is a wrapper around a Writer which counts the number of +// bytes which have been written and computes a crc32 hash +type CountHashWriter struct { + w io.Writer + crc uint32 + n int + s segment.StatsReporter +} + +// NewCountHashWriter returns a CountHashWriter which wraps the provided Writer +func NewCountHashWriter(w io.Writer) *CountHashWriter { + return &CountHashWriter{w: w} +} + +func NewCountHashWriterWithStatsReporter(w io.Writer, s segment.StatsReporter) *CountHashWriter { + return &CountHashWriter{w: w, s: s} +} + +// Write writes the provided bytes to the wrapped writer and counts the bytes +func (c *CountHashWriter) Write(b []byte) (int, error) { + n, err := c.w.Write(b) + c.crc = crc32.Update(c.crc, crc32.IEEETable, b[:n]) + c.n += n + if c.s != nil { + c.s.ReportBytesWritten(uint64(n)) + } + return n, err +} + +// Count returns the number of bytes written +func (c *CountHashWriter) Count() int { + return c.n +} + +// Sum32 returns the CRC-32 hash of the content written to this writer +func (c *CountHashWriter) Sum32() uint32 { + return c.crc +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/dict.go b/backend/vendor/github.com/blevesearch/zapx/v13/dict.go new file mode 100644 index 0000000000..e30bf2420d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/dict.go @@ -0,0 +1,158 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "fmt" + + "github.com/RoaringBitmap/roaring" + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" +) + +// Dictionary is the zap representation of the term dictionary +type Dictionary struct { + sb *SegmentBase + field string + fieldID uint16 + fst *vellum.FST + fstReader *vellum.Reader +} + +// represents an immutable, empty dictionary +var emptyDictionary = &Dictionary{} + +// PostingsList returns the postings list for the specified term +func (d *Dictionary) PostingsList(term []byte, except *roaring.Bitmap, + prealloc segment.PostingsList) (segment.PostingsList, error) { + var preallocPL *PostingsList + pl, ok := prealloc.(*PostingsList) + if ok && pl != nil { + preallocPL = pl + } + return d.postingsList(term, except, preallocPL) +} + +func (d *Dictionary) postingsList(term []byte, except *roaring.Bitmap, rv *PostingsList) (*PostingsList, error) { + if d.fstReader == nil { + if rv == nil || rv == emptyPostingsList { + return emptyPostingsList, nil + } + return d.postingsListInit(rv, except), nil + } + + postingsOffset, exists, err := d.fstReader.Get(term) + if err != nil { + return nil, fmt.Errorf("vellum err: %v", err) + } + if !exists { + if rv == nil || rv == emptyPostingsList { + return emptyPostingsList, nil + } + return d.postingsListInit(rv, except), nil + } + + return d.postingsListFromOffset(postingsOffset, except, rv) +} + +func (d *Dictionary) postingsListFromOffset(postingsOffset uint64, except *roaring.Bitmap, rv *PostingsList) (*PostingsList, error) { + rv = d.postingsListInit(rv, except) + + err := rv.read(postingsOffset, d) + if err != nil { + return nil, err + } + + return rv, nil +} + +func (d *Dictionary) postingsListInit(rv *PostingsList, except *roaring.Bitmap) *PostingsList { + if rv == nil || rv == emptyPostingsList { + rv = &PostingsList{} + } else { + postings := rv.postings + if postings != nil { + postings.Clear() + } + + *rv = PostingsList{} // clear the struct + + rv.postings = postings + } + rv.sb = d.sb + rv.except = except + return rv +} + +func (d *Dictionary) Contains(key []byte) (bool, error) { + if d.fst != nil { + return d.fst.Contains(key) + } + return false, nil +} + +// AutomatonIterator returns an iterator which only visits terms +// having the the vellum automaton and start/end key range +func (d *Dictionary) AutomatonIterator(a segment.Automaton, + startKeyInclusive, endKeyExclusive []byte) segment.DictionaryIterator { + if d.fst != nil { + rv := &DictionaryIterator{ + d: d, + } + + itr, err := d.fst.Search(a, startKeyInclusive, endKeyExclusive) + if err == nil { + rv.itr = itr + } else if err != vellum.ErrIteratorDone { + rv.err = err + } + + return rv + } + return emptyDictionaryIterator +} + +// DictionaryIterator is an iterator for term dictionary +type DictionaryIterator struct { + d *Dictionary + itr vellum.Iterator + err error + tmp PostingsList + entry index.DictEntry + omitCount bool +} + +var emptyDictionaryIterator = &DictionaryIterator{} + +// Next returns the next entry in the dictionary +func (i *DictionaryIterator) Next() (*index.DictEntry, error) { + if i.err != nil && i.err != vellum.ErrIteratorDone { + return nil, i.err + } else if i.itr == nil || i.err == vellum.ErrIteratorDone { + return nil, nil + } + term, postingsOffset := i.itr.Current() + i.entry.Term = string(term) + if !i.omitCount { + i.err = i.tmp.read(postingsOffset, i.d) + if i.err != nil { + return nil, i.err + } + i.entry.Count = i.tmp.Count() + } + i.err = i.itr.Next() + return &i.entry, nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/docvalues.go b/backend/vendor/github.com/blevesearch/zapx/v13/docvalues.go new file mode 100644 index 0000000000..a36485c870 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/docvalues.go @@ -0,0 +1,323 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "fmt" + "math" + "reflect" + "sort" + + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/golang/snappy" +) + +var reflectStaticSizedocValueReader int + +func init() { + var dvi docValueReader + reflectStaticSizedocValueReader = int(reflect.TypeOf(dvi).Size()) +} + +type docNumTermsVisitor func(docNum uint64, terms []byte) error + +type docVisitState struct { + dvrs map[uint16]*docValueReader + segment *SegmentBase +} + +// No-op implementations for DiskStatsReporter interface. +// Supported only in v15 +func (d *docVisitState) BytesRead() uint64 { + return 0 +} + +func (d *docVisitState) BytesWritten() uint64 { + return 0 +} + +func (d *docVisitState) ResetBytesRead(val uint64) {} + +type docValueReader struct { + field string + curChunkNum uint64 + chunkOffsets []uint64 + dvDataLoc uint64 + curChunkHeader []MetaData + curChunkData []byte // compressed data cache + uncompressed []byte // temp buf for snappy decompression +} + +func (di *docValueReader) size() int { + return reflectStaticSizedocValueReader + SizeOfPtr + + len(di.field) + + len(di.chunkOffsets)*SizeOfUint64 + + len(di.curChunkHeader)*reflectStaticSizeMetaData + + len(di.curChunkData) +} + +func (di *docValueReader) cloneInto(rv *docValueReader) *docValueReader { + if rv == nil { + rv = &docValueReader{} + } + + rv.field = di.field + rv.curChunkNum = math.MaxUint64 + rv.chunkOffsets = di.chunkOffsets // immutable, so it's sharable + rv.dvDataLoc = di.dvDataLoc + rv.curChunkHeader = rv.curChunkHeader[:0] + rv.curChunkData = nil + rv.uncompressed = rv.uncompressed[:0] + + return rv +} + +func (di *docValueReader) curChunkNumber() uint64 { + return di.curChunkNum +} + +func (s *SegmentBase) loadFieldDocValueReader(field string, + fieldDvLocStart, fieldDvLocEnd uint64) (*docValueReader, error) { + // get the docValue offset for the given fields + if fieldDvLocStart == fieldNotUninverted { + // no docValues found, nothing to do + return nil, nil + } + + // read the number of chunks, and chunk offsets position + var numChunks, chunkOffsetsPosition uint64 + + if fieldDvLocEnd-fieldDvLocStart > 16 { + numChunks = binary.BigEndian.Uint64(s.mem[fieldDvLocEnd-8 : fieldDvLocEnd]) + // read the length of chunk offsets + chunkOffsetsLen := binary.BigEndian.Uint64(s.mem[fieldDvLocEnd-16 : fieldDvLocEnd-8]) + // acquire position of chunk offsets + chunkOffsetsPosition = (fieldDvLocEnd - 16) - chunkOffsetsLen + } else { + return nil, fmt.Errorf("loadFieldDocValueReader: fieldDvLoc too small: %d-%d", fieldDvLocEnd, fieldDvLocStart) + } + + fdvIter := &docValueReader{ + curChunkNum: math.MaxUint64, + field: field, + chunkOffsets: make([]uint64, int(numChunks)), + } + + // read the chunk offsets + var offset uint64 + for i := 0; i < int(numChunks); i++ { + loc, read := binary.Uvarint(s.mem[chunkOffsetsPosition+offset : chunkOffsetsPosition+offset+binary.MaxVarintLen64]) + if read <= 0 { + return nil, fmt.Errorf("corrupted chunk offset during segment load") + } + fdvIter.chunkOffsets[i] = loc + offset += uint64(read) + } + + // set the data offset + fdvIter.dvDataLoc = fieldDvLocStart + + return fdvIter, nil +} + +func (di *docValueReader) loadDvChunk(chunkNumber uint64, s *SegmentBase) error { + // advance to the chunk where the docValues + // reside for the given docNum + destChunkDataLoc, curChunkEnd := di.dvDataLoc, di.dvDataLoc + start, end := readChunkBoundary(int(chunkNumber), di.chunkOffsets) + if start >= end { + di.curChunkHeader = di.curChunkHeader[:0] + di.curChunkData = nil + di.curChunkNum = chunkNumber + di.uncompressed = di.uncompressed[:0] + return nil + } + + destChunkDataLoc += start + curChunkEnd += end + + // read the number of docs reside in the chunk + numDocs, read := binary.Uvarint(s.mem[destChunkDataLoc : destChunkDataLoc+binary.MaxVarintLen64]) + if read <= 0 { + return fmt.Errorf("failed to read the chunk") + } + chunkMetaLoc := destChunkDataLoc + uint64(read) + + offset := uint64(0) + if cap(di.curChunkHeader) < int(numDocs) { + di.curChunkHeader = make([]MetaData, int(numDocs)) + } else { + di.curChunkHeader = di.curChunkHeader[:int(numDocs)] + } + for i := 0; i < int(numDocs); i++ { + di.curChunkHeader[i].DocNum, read = binary.Uvarint(s.mem[chunkMetaLoc+offset : chunkMetaLoc+offset+binary.MaxVarintLen64]) + offset += uint64(read) + di.curChunkHeader[i].DocDvOffset, read = binary.Uvarint(s.mem[chunkMetaLoc+offset : chunkMetaLoc+offset+binary.MaxVarintLen64]) + offset += uint64(read) + } + + compressedDataLoc := chunkMetaLoc + offset + dataLength := curChunkEnd - compressedDataLoc + di.curChunkData = s.mem[compressedDataLoc : compressedDataLoc+dataLength] + di.curChunkNum = chunkNumber + di.uncompressed = di.uncompressed[:0] + return nil +} + +func (di *docValueReader) iterateAllDocValues(s *SegmentBase, visitor docNumTermsVisitor) error { + for i := 0; i < len(di.chunkOffsets); i++ { + err := di.loadDvChunk(uint64(i), s) + if err != nil { + return err + } + if di.curChunkData == nil || len(di.curChunkHeader) == 0 { + continue + } + + // uncompress the already loaded data + uncompressed, err := snappy.Decode(di.uncompressed[:cap(di.uncompressed)], di.curChunkData) + if err != nil { + return err + } + di.uncompressed = uncompressed + + start := uint64(0) + for _, entry := range di.curChunkHeader { + err = visitor(entry.DocNum, uncompressed[start:entry.DocDvOffset]) + if err != nil { + return err + } + + start = entry.DocDvOffset + } + } + + return nil +} + +func (di *docValueReader) visitDocValues(docNum uint64, + visitor index.DocValueVisitor) error { + // binary search the term locations for the docNum + start, end := di.getDocValueLocs(docNum) + if start == math.MaxUint64 || end == math.MaxUint64 || start == end { + return nil + } + + var uncompressed []byte + var err error + // use the uncompressed copy if available + if len(di.uncompressed) > 0 { + uncompressed = di.uncompressed + } else { + // uncompress the already loaded data + uncompressed, err = snappy.Decode(di.uncompressed[:cap(di.uncompressed)], di.curChunkData) + if err != nil { + return err + } + di.uncompressed = uncompressed + } + + // pick the terms for the given docNum + uncompressed = uncompressed[start:end] + for { + i := bytes.Index(uncompressed, termSeparatorSplitSlice) + if i < 0 { + break + } + + visitor(di.field, uncompressed[0:i]) + uncompressed = uncompressed[i+1:] + } + + return nil +} + +func (di *docValueReader) getDocValueLocs(docNum uint64) (uint64, uint64) { + i := sort.Search(len(di.curChunkHeader), func(i int) bool { + return di.curChunkHeader[i].DocNum >= docNum + }) + if i < len(di.curChunkHeader) && di.curChunkHeader[i].DocNum == docNum { + return ReadDocValueBoundary(i, di.curChunkHeader) + } + return math.MaxUint64, math.MaxUint64 +} + +// VisitDocValues is an implementation of the +// DocValueVisitable interface +func (s *SegmentBase) VisitDocValues(localDocNum uint64, fields []string, + visitor index.DocValueVisitor, dvsIn segment.DocVisitState) ( + segment.DocVisitState, error) { + dvs, ok := dvsIn.(*docVisitState) + if !ok || dvs == nil { + dvs = &docVisitState{} + } else { + if dvs.segment != s { + dvs.segment = s + dvs.dvrs = nil + } + } + + var fieldIDPlus1 uint16 + if dvs.dvrs == nil { + dvs.dvrs = make(map[uint16]*docValueReader, len(fields)) + for _, field := range fields { + if fieldIDPlus1, ok = s.fieldsMap[field]; !ok { + continue + } + fieldID := fieldIDPlus1 - 1 + if dvIter, exists := s.fieldDvReaders[fieldID]; exists && + dvIter != nil { + dvs.dvrs[fieldID] = dvIter.cloneInto(dvs.dvrs[fieldID]) + } + } + } + + // find the chunkNumber where the docValues are stored + // NOTE: doc values continue to use legacy chunk mode + chunkFactor, err := getChunkSize(LegacyChunkMode, 0, 0) + if err != nil { + return nil, err + } + docInChunk := localDocNum / chunkFactor + var dvr *docValueReader + for _, field := range fields { + if fieldIDPlus1, ok = s.fieldsMap[field]; !ok { + continue + } + fieldID := fieldIDPlus1 - 1 + if dvr, ok = dvs.dvrs[fieldID]; ok && dvr != nil { + // check if the chunk is already loaded + if docInChunk != dvr.curChunkNumber() { + err := dvr.loadDvChunk(docInChunk, s) + if err != nil { + return dvs, err + } + } + + _ = dvr.visitDocValues(localDocNum, visitor) + } + } + return dvs, nil +} + +// VisitableDocValueFields returns the list of fields with +// persisted doc value terms ready to be visitable using the +// VisitDocumentFieldTerms method. +func (s *SegmentBase) VisitableDocValueFields() ([]string, error) { + return s.fieldDvNames, nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/enumerator.go b/backend/vendor/github.com/blevesearch/zapx/v13/enumerator.go new file mode 100644 index 0000000000..972a224165 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/enumerator.go @@ -0,0 +1,138 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + + "github.com/blevesearch/vellum" +) + +// enumerator provides an ordered traversal of multiple vellum +// iterators. Like JOIN of iterators, the enumerator produces a +// sequence of (key, iteratorIndex, value) tuples, sorted by key ASC, +// then iteratorIndex ASC, where the same key might be seen or +// repeated across multiple child iterators. +type enumerator struct { + itrs []vellum.Iterator + currKs [][]byte + currVs []uint64 + + lowK []byte + lowIdxs []int + lowCurr int +} + +// newEnumerator returns a new enumerator over the vellum Iterators +func newEnumerator(itrs []vellum.Iterator) (*enumerator, error) { + rv := &enumerator{ + itrs: itrs, + currKs: make([][]byte, len(itrs)), + currVs: make([]uint64, len(itrs)), + lowIdxs: make([]int, 0, len(itrs)), + } + for i, itr := range rv.itrs { + rv.currKs[i], rv.currVs[i] = itr.Current() + } + rv.updateMatches(false) + if rv.lowK == nil && len(rv.lowIdxs) == 0 { + return rv, vellum.ErrIteratorDone + } + return rv, nil +} + +// updateMatches maintains the low key matches based on the currKs +func (m *enumerator) updateMatches(skipEmptyKey bool) { + m.lowK = nil + m.lowIdxs = m.lowIdxs[:0] + m.lowCurr = 0 + + for i, key := range m.currKs { + if (key == nil && m.currVs[i] == 0) || // in case of empty iterator + (len(key) == 0 && skipEmptyKey) { // skip empty keys + continue + } + + cmp := bytes.Compare(key, m.lowK) + if cmp < 0 || len(m.lowIdxs) == 0 { + // reached a new low + m.lowK = key + m.lowIdxs = m.lowIdxs[:0] + m.lowIdxs = append(m.lowIdxs, i) + } else if cmp == 0 { + m.lowIdxs = append(m.lowIdxs, i) + } + } +} + +// Current returns the enumerator's current key, iterator-index, and +// value. If the enumerator is not pointing at a valid value (because +// Next returned an error previously), Current will return nil,0,0. +func (m *enumerator) Current() ([]byte, int, uint64) { + var i int + var v uint64 + if m.lowCurr < len(m.lowIdxs) { + i = m.lowIdxs[m.lowCurr] + v = m.currVs[i] + } + return m.lowK, i, v +} + +// GetLowIdxsAndValues will return all of the iterator indices +// which point to the current key, and their corresponding +// values. This can be used by advanced caller which may need +// to peek into these other sets of data before processing. +func (m *enumerator) GetLowIdxsAndValues() ([]int, []uint64) { + values := make([]uint64, 0, len(m.lowIdxs)) + for _, idx := range m.lowIdxs { + values = append(values, m.currVs[idx]) + } + return m.lowIdxs, values +} + +// Next advances the enumerator to the next key/iterator/value result, +// else vellum.ErrIteratorDone is returned. +func (m *enumerator) Next() error { + m.lowCurr += 1 + if m.lowCurr >= len(m.lowIdxs) { + // move all the current low iterators forwards + for _, vi := range m.lowIdxs { + err := m.itrs[vi].Next() + if err != nil && err != vellum.ErrIteratorDone { + return err + } + m.currKs[vi], m.currVs[vi] = m.itrs[vi].Current() + } + // can skip any empty keys encountered at this point + m.updateMatches(true) + } + if m.lowK == nil && len(m.lowIdxs) == 0 { + return vellum.ErrIteratorDone + } + return nil +} + +// Close all the underlying Iterators. The first error, if any, will +// be returned. +func (m *enumerator) Close() error { + var rv error + for _, itr := range m.itrs { + err := itr.Close() + if rv == nil { + rv = err + } + } + return rv +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/intDecoder.go b/backend/vendor/github.com/blevesearch/zapx/v13/intDecoder.go new file mode 100644 index 0000000000..e968093149 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/intDecoder.go @@ -0,0 +1,109 @@ +// Copyright (c) 2019 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "encoding/binary" + "fmt" +) + +type chunkedIntDecoder struct { + startOffset uint64 + dataStartOffset uint64 + chunkOffsets []uint64 + curChunkBytes []byte + data []byte + r *memUvarintReader +} + +func newChunkedIntDecoder(buf []byte, offset uint64) *chunkedIntDecoder { + rv := &chunkedIntDecoder{startOffset: offset, data: buf} + var n, numChunks uint64 + var read int + if offset == termNotEncoded { + numChunks = 0 + } else { + numChunks, read = binary.Uvarint(buf[offset+n : offset+n+binary.MaxVarintLen64]) + } + + n += uint64(read) + if cap(rv.chunkOffsets) >= int(numChunks) { + rv.chunkOffsets = rv.chunkOffsets[:int(numChunks)] + } else { + rv.chunkOffsets = make([]uint64, int(numChunks)) + } + for i := 0; i < int(numChunks); i++ { + rv.chunkOffsets[i], read = binary.Uvarint(buf[offset+n : offset+n+binary.MaxVarintLen64]) + n += uint64(read) + } + rv.dataStartOffset = offset + n + return rv +} + +func (d *chunkedIntDecoder) loadChunk(chunk int) error { + if d.startOffset == termNotEncoded { + d.r = newMemUvarintReader([]byte(nil)) + return nil + } + + if chunk >= len(d.chunkOffsets) { + return fmt.Errorf("tried to load freq chunk that doesn't exist %d/(%d)", + chunk, len(d.chunkOffsets)) + } + + end, start := d.dataStartOffset, d.dataStartOffset + s, e := readChunkBoundary(chunk, d.chunkOffsets) + start += s + end += e + d.curChunkBytes = d.data[start:end] + if d.r == nil { + d.r = newMemUvarintReader(d.curChunkBytes) + } else { + d.r.Reset(d.curChunkBytes) + } + + return nil +} + +func (d *chunkedIntDecoder) reset() { + d.startOffset = 0 + d.dataStartOffset = 0 + d.chunkOffsets = d.chunkOffsets[:0] + d.curChunkBytes = d.curChunkBytes[:0] + d.data = d.data[:0] + if d.r != nil { + d.r.Reset([]byte(nil)) + } +} + +func (d *chunkedIntDecoder) isNil() bool { + return d.curChunkBytes == nil +} + +func (d *chunkedIntDecoder) readUvarint() (uint64, error) { + return d.r.ReadUvarint() +} + +func (d *chunkedIntDecoder) SkipUvarint() { + d.r.SkipUvarint() +} + +func (d *chunkedIntDecoder) SkipBytes(count int) { + d.r.SkipBytes(count) +} + +func (d *chunkedIntDecoder) Len() int { + return d.r.Len() +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/intcoder.go b/backend/vendor/github.com/blevesearch/zapx/v13/intcoder.go new file mode 100644 index 0000000000..c3c488fb74 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/intcoder.go @@ -0,0 +1,206 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "io" +) + +// We can safely use 0 to represent termNotEncoded since 0 +// could never be a valid address for term location information. +// (stored field index is always non-empty and earlier in the +// file) +const termNotEncoded = 0 + +type chunkedIntCoder struct { + final []byte + chunkSize uint64 + chunkBuf bytes.Buffer + chunkLens []uint64 + currChunk uint64 + + buf []byte +} + +// newChunkedIntCoder returns a new chunk int coder which packs data into +// chunks based on the provided chunkSize and supports up to the specified +// maxDocNum +func newChunkedIntCoder(chunkSize uint64, maxDocNum uint64) *chunkedIntCoder { + total := maxDocNum/chunkSize + 1 + rv := &chunkedIntCoder{ + chunkSize: chunkSize, + chunkLens: make([]uint64, total), + final: make([]byte, 0, 64), + } + + return rv +} + +// Reset lets you reuse this chunked int coder. buffers are reset and reused +// from previous use. you cannot change the chunk size or max doc num. +func (c *chunkedIntCoder) Reset() { + c.final = c.final[:0] + c.chunkBuf.Reset() + c.currChunk = 0 + for i := range c.chunkLens { + c.chunkLens[i] = 0 + } +} + +// SetChunkSize changes the chunk size. It is only valid to do so +// with a new chunkedIntCoder, or immediately after calling Reset() +func (c *chunkedIntCoder) SetChunkSize(chunkSize uint64, maxDocNum uint64) { + total := int(maxDocNum/chunkSize + 1) + c.chunkSize = chunkSize + if cap(c.chunkLens) < total { + c.chunkLens = make([]uint64, total) + } else { + c.chunkLens = c.chunkLens[:total] + } +} + +// Add encodes the provided integers into the correct chunk for the provided +// doc num. You MUST call Add() with increasing docNums. +func (c *chunkedIntCoder) Add(docNum uint64, vals ...uint64) error { + chunk := docNum / c.chunkSize + if chunk != c.currChunk { + // starting a new chunk + c.Close() + c.chunkBuf.Reset() + c.currChunk = chunk + } + + if len(c.buf) < binary.MaxVarintLen64 { + c.buf = make([]byte, binary.MaxVarintLen64) + } + + for _, val := range vals { + wb := binary.PutUvarint(c.buf, val) + _, err := c.chunkBuf.Write(c.buf[:wb]) + if err != nil { + return err + } + } + + return nil +} + +func (c *chunkedIntCoder) AddBytes(docNum uint64, buf []byte) error { + chunk := docNum / c.chunkSize + if chunk != c.currChunk { + // starting a new chunk + c.Close() + c.chunkBuf.Reset() + c.currChunk = chunk + } + + _, err := c.chunkBuf.Write(buf) + return err +} + +// Close indicates you are done calling Add() this allows the final chunk +// to be encoded. +func (c *chunkedIntCoder) Close() { + encodingBytes := c.chunkBuf.Bytes() + c.chunkLens[c.currChunk] = uint64(len(encodingBytes)) + c.final = append(c.final, encodingBytes...) + c.currChunk = uint64(cap(c.chunkLens)) // sentinel to detect double close +} + +// Write commits all the encoded chunked integers to the provided writer. +func (c *chunkedIntCoder) Write(w io.Writer) (int, error) { + bufNeeded := binary.MaxVarintLen64 * (1 + len(c.chunkLens)) + if len(c.buf) < bufNeeded { + c.buf = make([]byte, bufNeeded) + } + buf := c.buf + + // convert the chunk lengths into chunk offsets + chunkOffsets := modifyLengthsToEndOffsets(c.chunkLens) + + // write out the number of chunks & each chunk offsets + n := binary.PutUvarint(buf, uint64(len(chunkOffsets))) + for _, chunkOffset := range chunkOffsets { + n += binary.PutUvarint(buf[n:], chunkOffset) + } + + tw, err := w.Write(buf[:n]) + if err != nil { + return tw, err + } + + // write out the data + nw, err := w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + return tw, nil +} + +// writeAt commits all the encoded chunked integers to the provided writer +// and returns the starting offset, total bytes written and an error +func (c *chunkedIntCoder) writeAt(w io.Writer) (uint64, int, error) { + startOffset := uint64(termNotEncoded) + if len(c.final) <= 0 { + return startOffset, 0, nil + } + + if chw := w.(*CountHashWriter); chw != nil { + startOffset = uint64(chw.Count()) + } + + tw, err := c.Write(w) + return startOffset, tw, err +} + +func (c *chunkedIntCoder) FinalSize() int { + return len(c.final) +} + +// modifyLengthsToEndOffsets converts the chunk length array +// to a chunk offset array. The readChunkBoundary +// will figure out the start and end of every chunk from +// these offsets. Starting offset of i'th index is stored +// in i-1'th position except for 0'th index and ending offset +// is stored at i'th index position. +// For 0'th element, starting position is always zero. +// eg: +// Lens -> 5 5 5 5 => 5 10 15 20 +// Lens -> 0 5 0 5 => 0 5 5 10 +// Lens -> 0 0 0 5 => 0 0 0 5 +// Lens -> 5 0 0 0 => 5 5 5 5 +// Lens -> 0 5 0 0 => 0 5 5 5 +// Lens -> 0 0 5 0 => 0 0 5 5 +func modifyLengthsToEndOffsets(lengths []uint64) []uint64 { + var runningOffset uint64 + var index, i int + for i = 1; i <= len(lengths); i++ { + runningOffset += lengths[i-1] + lengths[index] = runningOffset + index++ + } + return lengths +} + +func readChunkBoundary(chunk int, offsets []uint64) (uint64, uint64) { + var start uint64 + if chunk > 0 { + start = offsets[chunk-1] + } + return start, offsets[chunk] +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/memuvarint.go b/backend/vendor/github.com/blevesearch/zapx/v13/memuvarint.go new file mode 100644 index 0000000000..48a57f9c85 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/memuvarint.go @@ -0,0 +1,103 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "fmt" +) + +type memUvarintReader struct { + C int // index of next byte to read from S + S []byte +} + +func newMemUvarintReader(s []byte) *memUvarintReader { + return &memUvarintReader{S: s} +} + +// Len returns the number of unread bytes. +func (r *memUvarintReader) Len() int { + n := len(r.S) - r.C + if n < 0 { + return 0 + } + return n +} + +// ReadUvarint reads an encoded uint64. The original code this was +// based on is at encoding/binary/ReadUvarint(). +func (r *memUvarintReader) ReadUvarint() (uint64, error) { + if r.C >= len(r.S) { + // nothing else to read + return 0, nil + } + + var x uint64 + var s uint + var C = r.C + var S = r.S + + for { + b := S[C] + C++ + + if b < 0x80 { + r.C = C + + // why 63? The original code had an 'i += 1' loop var and + // checked for i > 9 || i == 9 ...; but, we no longer + // check for the i var, but instead check here for s, + // which is incremented by 7. So, 7*9 == 63. + // + // why the "extra" >= check? The normal case is that s < + // 63, so we check this single >= guard first so that we + // hit the normal, nil-error return pathway sooner. + if s >= 63 && (s > 63 || b > 1) { + return 0, fmt.Errorf("memUvarintReader overflow") + } + + return x | uint64(b)<= len(r.S) { + return + } + + b := r.S[r.C] + r.C++ + + if b < 0x80 { + return + } + } +} + +// SkipBytes skips a count number of bytes. +func (r *memUvarintReader) SkipBytes(count int) { + r.C = r.C + count +} + +func (r *memUvarintReader) Reset(s []byte) { + r.C = 0 + r.S = s +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/merge.go b/backend/vendor/github.com/blevesearch/zapx/v13/merge.go new file mode 100644 index 0000000000..6a853a16a6 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/merge.go @@ -0,0 +1,843 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bufio" + "bytes" + "encoding/binary" + "fmt" + "math" + "os" + "sort" + + "github.com/RoaringBitmap/roaring" + seg "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" + "github.com/golang/snappy" +) + +var DefaultFileMergerBufferSize = 1024 * 1024 + +const docDropped = math.MaxUint64 // sentinel docNum to represent a deleted doc + +// Merge takes a slice of segments and bit masks describing which +// documents may be dropped, and creates a new segment containing the +// remaining data. This new segment is built at the specified path. +func (*ZapPlugin) Merge(segments []seg.Segment, drops []*roaring.Bitmap, path string, + closeCh chan struct{}, s seg.StatsReporter) ( + [][]uint64, uint64, error) { + segmentBases := make([]*SegmentBase, len(segments)) + for segmenti, segment := range segments { + switch segmentx := segment.(type) { + case *Segment: + segmentBases[segmenti] = &segmentx.SegmentBase + case *SegmentBase: + segmentBases[segmenti] = segmentx + default: + panic(fmt.Sprintf("oops, unexpected segment type: %T", segment)) + } + } + return mergeSegmentBases(segmentBases, drops, path, DefaultChunkMode, closeCh, s) +} + +func mergeSegmentBases(segmentBases []*SegmentBase, drops []*roaring.Bitmap, path string, + chunkMode uint32, closeCh chan struct{}, s seg.StatsReporter) ( + [][]uint64, uint64, error) { + flag := os.O_RDWR | os.O_CREATE + + f, err := os.OpenFile(path, flag, 0600) + if err != nil { + return nil, 0, err + } + + cleanup := func() { + _ = f.Close() + _ = os.Remove(path) + } + + // buffer the output + br := bufio.NewWriterSize(f, DefaultFileMergerBufferSize) + + // wrap it for counting (tracking offsets) + cr := NewCountHashWriterWithStatsReporter(br, s) + + newDocNums, numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset, _, _, _, err := + MergeToWriter(segmentBases, drops, chunkMode, cr, closeCh) + if err != nil { + cleanup() + return nil, 0, err + } + + err = persistFooter(numDocs, storedIndexOffset, fieldsIndexOffset, + docValueOffset, chunkMode, cr.Sum32(), cr) + if err != nil { + cleanup() + return nil, 0, err + } + + err = br.Flush() + if err != nil { + cleanup() + return nil, 0, err + } + + err = f.Sync() + if err != nil { + cleanup() + return nil, 0, err + } + + err = f.Close() + if err != nil { + cleanup() + return nil, 0, err + } + + return newDocNums, uint64(cr.Count()), nil +} + +func MergeToWriter(segments []*SegmentBase, drops []*roaring.Bitmap, + chunkMode uint32, cr *CountHashWriter, closeCh chan struct{}) ( + newDocNums [][]uint64, + numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset uint64, + dictLocs []uint64, fieldsInv []string, fieldsMap map[string]uint16, + err error) { + docValueOffset = uint64(fieldNotUninverted) + + var fieldsSame bool + fieldsSame, fieldsInv = mergeFields(segments) + fieldsMap = mapFields(fieldsInv) + + numDocs = computeNewDocCount(segments, drops) + + if isClosed(closeCh) { + return nil, 0, 0, 0, 0, nil, nil, nil, seg.ErrClosed + } + + if numDocs > 0 { + storedIndexOffset, newDocNums, err = mergeStoredAndRemap(segments, drops, + fieldsMap, fieldsInv, fieldsSame, numDocs, cr, closeCh) + if err != nil { + return nil, 0, 0, 0, 0, nil, nil, nil, err + } + + dictLocs, docValueOffset, err = persistMergedRest(segments, drops, + fieldsInv, fieldsMap, fieldsSame, + newDocNums, numDocs, chunkMode, cr, closeCh) + if err != nil { + return nil, 0, 0, 0, 0, nil, nil, nil, err + } + } else { + dictLocs = make([]uint64, len(fieldsInv)) + } + + fieldsIndexOffset, err = persistFields(fieldsInv, cr, dictLocs) + if err != nil { + return nil, 0, 0, 0, 0, nil, nil, nil, err + } + + return newDocNums, numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset, dictLocs, fieldsInv, fieldsMap, nil +} + +// mapFields takes the fieldsInv list and returns a map of fieldName +// to fieldID+1 +func mapFields(fields []string) map[string]uint16 { + rv := make(map[string]uint16, len(fields)) + for i, fieldName := range fields { + rv[fieldName] = uint16(i) + 1 + } + return rv +} + +// computeNewDocCount determines how many documents will be in the newly +// merged segment when obsoleted docs are dropped +func computeNewDocCount(segments []*SegmentBase, drops []*roaring.Bitmap) uint64 { + var newDocCount uint64 + for segI, segment := range segments { + newDocCount += segment.numDocs + if drops[segI] != nil { + newDocCount -= drops[segI].GetCardinality() + } + } + return newDocCount +} + +func persistMergedRest(segments []*SegmentBase, dropsIn []*roaring.Bitmap, + fieldsInv []string, fieldsMap map[string]uint16, fieldsSame bool, + newDocNumsIn [][]uint64, newSegDocCount uint64, chunkMode uint32, + w *CountHashWriter, closeCh chan struct{}) ([]uint64, uint64, error) { + var bufMaxVarintLen64 []byte = make([]byte, binary.MaxVarintLen64) + var bufLoc []uint64 + + var postings *PostingsList + var postItr *PostingsIterator + + rv := make([]uint64, len(fieldsInv)) + fieldDvLocsStart := make([]uint64, len(fieldsInv)) + fieldDvLocsEnd := make([]uint64, len(fieldsInv)) + + // these int coders are initialized with chunk size 1024 + // however this will be reset to the correct chunk size + // while processing each individual field-term section + tfEncoder := newChunkedIntCoder(1024, newSegDocCount-1) + locEncoder := newChunkedIntCoder(1024, newSegDocCount-1) + + var vellumBuf bytes.Buffer + newVellum, err := vellum.New(&vellumBuf, nil) + if err != nil { + return nil, 0, err + } + + newRoaring := roaring.NewBitmap() + + // for each field + for fieldID, fieldName := range fieldsInv { + // collect FST iterators from all active segments for this field + var newDocNums [][]uint64 + var drops []*roaring.Bitmap + var dicts []*Dictionary + var itrs []vellum.Iterator + + var segmentsInFocus []*SegmentBase + + for segmentI, segment := range segments { + // check for the closure in meantime + if isClosed(closeCh) { + return nil, 0, seg.ErrClosed + } + + dict, err2 := segment.dictionary(fieldName) + if err2 != nil { + return nil, 0, err2 + } + if dict != nil && dict.fst != nil { + itr, err2 := dict.fst.Iterator(nil, nil) + if err2 != nil && err2 != vellum.ErrIteratorDone { + return nil, 0, err2 + } + if itr != nil { + newDocNums = append(newDocNums, newDocNumsIn[segmentI]) + if dropsIn[segmentI] != nil && !dropsIn[segmentI].IsEmpty() { + drops = append(drops, dropsIn[segmentI]) + } else { + drops = append(drops, nil) + } + dicts = append(dicts, dict) + itrs = append(itrs, itr) + segmentsInFocus = append(segmentsInFocus, segment) + } + } + } + + var prevTerm []byte + + newRoaring.Clear() + + var lastDocNum, lastFreq, lastNorm uint64 + + // determines whether to use "1-hit" encoding optimization + // when a term appears in only 1 doc, with no loc info, + // has freq of 1, and the docNum fits into 31-bits + use1HitEncoding := func(termCardinality uint64) (bool, uint64, uint64) { + if termCardinality == uint64(1) && locEncoder.FinalSize() <= 0 { + docNum := uint64(newRoaring.Minimum()) + if under32Bits(docNum) && docNum == lastDocNum && lastFreq == 1 { + return true, docNum, lastNorm + } + } + return false, 0, 0 + } + + finishTerm := func(term []byte) error { + tfEncoder.Close() + locEncoder.Close() + + postingsOffset, err := writePostings(newRoaring, + tfEncoder, locEncoder, use1HitEncoding, w, bufMaxVarintLen64) + if err != nil { + return err + } + + if postingsOffset > 0 { + err = newVellum.Insert(term, postingsOffset) + if err != nil { + return err + } + } + + newRoaring.Clear() + + tfEncoder.Reset() + locEncoder.Reset() + + lastDocNum = 0 + lastFreq = 0 + lastNorm = 0 + + return nil + } + + enumerator, err := newEnumerator(itrs) + + for err == nil { + term, itrI, postingsOffset := enumerator.Current() + + if !bytes.Equal(prevTerm, term) { + // check for the closure in meantime + if isClosed(closeCh) { + return nil, 0, seg.ErrClosed + } + + // if the term changed, write out the info collected + // for the previous term + err = finishTerm(prevTerm) + if err != nil { + return nil, 0, err + } + } + if !bytes.Equal(prevTerm, term) || prevTerm == nil { + // compute cardinality of field-term in new seg + var newCard uint64 + lowItrIdxs, lowItrVals := enumerator.GetLowIdxsAndValues() + for i, idx := range lowItrIdxs { + pl, err := dicts[idx].postingsListFromOffset(lowItrVals[i], drops[idx], nil) + if err != nil { + return nil, 0, err + } + newCard += pl.Count() + } + // compute correct chunk size with this + chunkSize, err := getChunkSize(chunkMode, newCard, newSegDocCount) + if err != nil { + return nil, 0, err + } + // update encoders chunk + tfEncoder.SetChunkSize(chunkSize, newSegDocCount-1) + locEncoder.SetChunkSize(chunkSize, newSegDocCount-1) + } + + postings, err = dicts[itrI].postingsListFromOffset( + postingsOffset, drops[itrI], postings) + if err != nil { + return nil, 0, err + } + + postItr = postings.iterator(true, true, true, postItr) + + // can no longer optimize by copying, since chunk factor could have changed + lastDocNum, lastFreq, lastNorm, bufLoc, err = mergeTermFreqNormLocs( + fieldsMap, term, postItr, newDocNums[itrI], newRoaring, + tfEncoder, locEncoder, bufLoc) + + if err != nil { + return nil, 0, err + } + + prevTerm = prevTerm[:0] // copy to prevTerm in case Next() reuses term mem + prevTerm = append(prevTerm, term...) + + err = enumerator.Next() + } + if err != vellum.ErrIteratorDone { + return nil, 0, err + } + + err = finishTerm(prevTerm) + if err != nil { + return nil, 0, err + } + + dictOffset := uint64(w.Count()) + + err = newVellum.Close() + if err != nil { + return nil, 0, err + } + vellumData := vellumBuf.Bytes() + + // write out the length of the vellum data + n := binary.PutUvarint(bufMaxVarintLen64, uint64(len(vellumData))) + _, err = w.Write(bufMaxVarintLen64[:n]) + if err != nil { + return nil, 0, err + } + + // write this vellum to disk + _, err = w.Write(vellumData) + if err != nil { + return nil, 0, err + } + + rv[fieldID] = dictOffset + + // get the field doc value offset (start) + fieldDvLocsStart[fieldID] = uint64(w.Count()) + + // update the field doc values + // NOTE: doc values continue to use legacy chunk mode + chunkSize, err := getChunkSize(LegacyChunkMode, 0, 0) + if err != nil { + return nil, 0, err + } + fdvEncoder := newChunkedContentCoder(chunkSize, newSegDocCount-1, w, true) + + fdvReadersAvailable := false + var dvIterClone *docValueReader + for segmentI, segment := range segmentsInFocus { + // check for the closure in meantime + if isClosed(closeCh) { + return nil, 0, seg.ErrClosed + } + + fieldIDPlus1 := uint16(segment.fieldsMap[fieldName]) + if dvIter, exists := segment.fieldDvReaders[fieldIDPlus1-1]; exists && + dvIter != nil { + fdvReadersAvailable = true + dvIterClone = dvIter.cloneInto(dvIterClone) + err = dvIterClone.iterateAllDocValues(segment, func(docNum uint64, terms []byte) error { + if newDocNums[segmentI][docNum] == docDropped { + return nil + } + err := fdvEncoder.Add(newDocNums[segmentI][docNum], terms) + if err != nil { + return err + } + return nil + }) + if err != nil { + return nil, 0, err + } + } + } + + if fdvReadersAvailable { + err = fdvEncoder.Close() + if err != nil { + return nil, 0, err + } + + // persist the doc value details for this field + _, err = fdvEncoder.Write() + if err != nil { + return nil, 0, err + } + + // get the field doc value offset (end) + fieldDvLocsEnd[fieldID] = uint64(w.Count()) + } else { + fieldDvLocsStart[fieldID] = fieldNotUninverted + fieldDvLocsEnd[fieldID] = fieldNotUninverted + } + + // reset vellum buffer and vellum builder + vellumBuf.Reset() + err = newVellum.Reset(&vellumBuf) + if err != nil { + return nil, 0, err + } + } + + fieldDvLocsOffset := uint64(w.Count()) + + buf := bufMaxVarintLen64 + for i := 0; i < len(fieldDvLocsStart); i++ { + n := binary.PutUvarint(buf, fieldDvLocsStart[i]) + _, err := w.Write(buf[:n]) + if err != nil { + return nil, 0, err + } + n = binary.PutUvarint(buf, fieldDvLocsEnd[i]) + _, err = w.Write(buf[:n]) + if err != nil { + return nil, 0, err + } + } + + return rv, fieldDvLocsOffset, nil +} + +func mergeTermFreqNormLocs(fieldsMap map[string]uint16, term []byte, postItr *PostingsIterator, + newDocNums []uint64, newRoaring *roaring.Bitmap, + tfEncoder *chunkedIntCoder, locEncoder *chunkedIntCoder, bufLoc []uint64) ( + lastDocNum uint64, lastFreq uint64, lastNorm uint64, bufLocOut []uint64, err error) { + next, err := postItr.Next() + for next != nil && err == nil { + hitNewDocNum := newDocNums[next.Number()] + if hitNewDocNum == docDropped { + return 0, 0, 0, nil, fmt.Errorf("see hit with dropped docNum") + } + + newRoaring.Add(uint32(hitNewDocNum)) + + nextFreq := next.Frequency() + nextNorm := uint64(math.Float32bits(float32(next.Norm()))) + + locs := next.Locations() + + err = tfEncoder.Add(hitNewDocNum, + encodeFreqHasLocs(nextFreq, len(locs) > 0), nextNorm) + if err != nil { + return 0, 0, 0, nil, err + } + + if len(locs) > 0 { + numBytesLocs := 0 + for _, loc := range locs { + ap := loc.ArrayPositions() + numBytesLocs += totalUvarintBytes(uint64(fieldsMap[loc.Field()]-1), + loc.Pos(), loc.Start(), loc.End(), uint64(len(ap)), ap) + } + + err = locEncoder.Add(hitNewDocNum, uint64(numBytesLocs)) + if err != nil { + return 0, 0, 0, nil, err + } + + for _, loc := range locs { + ap := loc.ArrayPositions() + if cap(bufLoc) < 5+len(ap) { + bufLoc = make([]uint64, 0, 5+len(ap)) + } + args := bufLoc[0:5] + args[0] = uint64(fieldsMap[loc.Field()] - 1) + args[1] = loc.Pos() + args[2] = loc.Start() + args[3] = loc.End() + args[4] = uint64(len(ap)) + args = append(args, ap...) + err = locEncoder.Add(hitNewDocNum, args...) + if err != nil { + return 0, 0, 0, nil, err + } + } + } + + lastDocNum = hitNewDocNum + lastFreq = nextFreq + lastNorm = nextNorm + + next, err = postItr.Next() + } + + return lastDocNum, lastFreq, lastNorm, bufLoc, err +} + +func writePostings(postings *roaring.Bitmap, tfEncoder, locEncoder *chunkedIntCoder, + use1HitEncoding func(uint64) (bool, uint64, uint64), + w *CountHashWriter, bufMaxVarintLen64 []byte) ( + offset uint64, err error) { + termCardinality := postings.GetCardinality() + if termCardinality <= 0 { + return 0, nil + } + + if use1HitEncoding != nil { + encodeAs1Hit, docNum1Hit, normBits1Hit := use1HitEncoding(termCardinality) + if encodeAs1Hit { + return FSTValEncode1Hit(docNum1Hit, normBits1Hit), nil + } + } + + var tfOffset uint64 + tfOffset, _, err = tfEncoder.writeAt(w) + if err != nil { + return 0, err + } + + var locOffset uint64 + locOffset, _, err = locEncoder.writeAt(w) + if err != nil { + return 0, err + } + + postingsOffset := uint64(w.Count()) + + n := binary.PutUvarint(bufMaxVarintLen64, tfOffset) + _, err = w.Write(bufMaxVarintLen64[:n]) + if err != nil { + return 0, err + } + + n = binary.PutUvarint(bufMaxVarintLen64, locOffset) + _, err = w.Write(bufMaxVarintLen64[:n]) + if err != nil { + return 0, err + } + + _, err = writeRoaringWithLen(postings, w, bufMaxVarintLen64) + if err != nil { + return 0, err + } + + return postingsOffset, nil +} + +type varintEncoder func(uint64) (int, error) + +func mergeStoredAndRemap(segments []*SegmentBase, drops []*roaring.Bitmap, + fieldsMap map[string]uint16, fieldsInv []string, fieldsSame bool, newSegDocCount uint64, + w *CountHashWriter, closeCh chan struct{}) (uint64, [][]uint64, error) { + var rv [][]uint64 // The remapped or newDocNums for each segment. + + var newDocNum uint64 + + var curr int + var data, compressed []byte + var metaBuf bytes.Buffer + varBuf := make([]byte, binary.MaxVarintLen64) + metaEncode := func(val uint64) (int, error) { + wb := binary.PutUvarint(varBuf, val) + return metaBuf.Write(varBuf[:wb]) + } + + vals := make([][][]byte, len(fieldsInv)) + typs := make([][]byte, len(fieldsInv)) + poss := make([][][]uint64, len(fieldsInv)) + + var posBuf []uint64 + + docNumOffsets := make([]uint64, newSegDocCount) + + vdc := visitDocumentCtxPool.Get().(*visitDocumentCtx) + defer visitDocumentCtxPool.Put(vdc) + + // for each segment + for segI, segment := range segments { + // check for the closure in meantime + if isClosed(closeCh) { + return 0, nil, seg.ErrClosed + } + + segNewDocNums := make([]uint64, segment.numDocs) + + dropsI := drops[segI] + + // optimize when the field mapping is the same across all + // segments and there are no deletions, via byte-copying + // of stored docs bytes directly to the writer + if fieldsSame && (dropsI == nil || dropsI.GetCardinality() == 0) { + err := segment.copyStoredDocs(newDocNum, docNumOffsets, w) + if err != nil { + return 0, nil, err + } + + for i := uint64(0); i < segment.numDocs; i++ { + segNewDocNums[i] = newDocNum + newDocNum++ + } + rv = append(rv, segNewDocNums) + + continue + } + + // for each doc num + for docNum := uint64(0); docNum < segment.numDocs; docNum++ { + // TODO: roaring's API limits docNums to 32-bits? + if dropsI != nil && dropsI.Contains(uint32(docNum)) { + segNewDocNums[docNum] = docDropped + continue + } + + segNewDocNums[docNum] = newDocNum + + curr = 0 + metaBuf.Reset() + data = data[:0] + + posTemp := posBuf + + // collect all the data + for i := 0; i < len(fieldsInv); i++ { + vals[i] = vals[i][:0] + typs[i] = typs[i][:0] + poss[i] = poss[i][:0] + } + err := segment.visitStoredFields(vdc, docNum, func(field string, typ byte, value []byte, pos []uint64) bool { + fieldID := int(fieldsMap[field]) - 1 + vals[fieldID] = append(vals[fieldID], value) + typs[fieldID] = append(typs[fieldID], typ) + + // copy array positions to preserve them beyond the scope of this callback + var curPos []uint64 + if len(pos) > 0 { + if cap(posTemp) < len(pos) { + posBuf = make([]uint64, len(pos)*len(fieldsInv)) + posTemp = posBuf + } + curPos = posTemp[0:len(pos)] + copy(curPos, pos) + posTemp = posTemp[len(pos):] + } + poss[fieldID] = append(poss[fieldID], curPos) + + return true + }) + if err != nil { + return 0, nil, err + } + + // _id field special case optimizes ExternalID() lookups + idFieldVal := vals[uint16(0)][0] + _, err = metaEncode(uint64(len(idFieldVal))) + if err != nil { + return 0, nil, err + } + + // now walk the non-"_id" fields in order + for fieldID := 1; fieldID < len(fieldsInv); fieldID++ { + storedFieldValues := vals[fieldID] + + stf := typs[fieldID] + spf := poss[fieldID] + + var err2 error + curr, data, err2 = persistStoredFieldValues(fieldID, + storedFieldValues, stf, spf, curr, metaEncode, data) + if err2 != nil { + return 0, nil, err2 + } + } + + metaBytes := metaBuf.Bytes() + + compressed = snappy.Encode(compressed[:cap(compressed)], data) + + // record where we're about to start writing + docNumOffsets[newDocNum] = uint64(w.Count()) + + // write out the meta len and compressed data len + _, err = writeUvarints(w, + uint64(len(metaBytes)), + uint64(len(idFieldVal)+len(compressed))) + if err != nil { + return 0, nil, err + } + // now write the meta + _, err = w.Write(metaBytes) + if err != nil { + return 0, nil, err + } + // now write the _id field val (counted as part of the 'compressed' data) + _, err = w.Write(idFieldVal) + if err != nil { + return 0, nil, err + } + // now write the compressed data + _, err = w.Write(compressed) + if err != nil { + return 0, nil, err + } + + newDocNum++ + } + + rv = append(rv, segNewDocNums) + } + + // return value is the start of the stored index + storedIndexOffset := uint64(w.Count()) + + // now write out the stored doc index + for _, docNumOffset := range docNumOffsets { + err := binary.Write(w, binary.BigEndian, docNumOffset) + if err != nil { + return 0, nil, err + } + } + + return storedIndexOffset, rv, nil +} + +// copyStoredDocs writes out a segment's stored doc info, optimized by +// using a single Write() call for the entire set of bytes. The +// newDocNumOffsets is filled with the new offsets for each doc. +func (s *SegmentBase) copyStoredDocs(newDocNum uint64, newDocNumOffsets []uint64, + w *CountHashWriter) error { + if s.numDocs <= 0 { + return nil + } + + indexOffset0, storedOffset0, _, _, _ := + s.getDocStoredOffsets(0) // the segment's first doc + + indexOffsetN, storedOffsetN, readN, metaLenN, dataLenN := + s.getDocStoredOffsets(s.numDocs - 1) // the segment's last doc + + storedOffset0New := uint64(w.Count()) + + storedBytes := s.mem[storedOffset0 : storedOffsetN+readN+metaLenN+dataLenN] + _, err := w.Write(storedBytes) + if err != nil { + return err + } + + // remap the storedOffset's for the docs into new offsets relative + // to storedOffset0New, filling the given docNumOffsetsOut array + for indexOffset := indexOffset0; indexOffset <= indexOffsetN; indexOffset += 8 { + storedOffset := binary.BigEndian.Uint64(s.mem[indexOffset : indexOffset+8]) + storedOffsetNew := storedOffset - storedOffset0 + storedOffset0New + newDocNumOffsets[newDocNum] = storedOffsetNew + newDocNum += 1 + } + + return nil +} + +// mergeFields builds a unified list of fields used across all the +// input segments, and computes whether the fields are the same across +// segments (which depends on fields to be sorted in the same way +// across segments) +func mergeFields(segments []*SegmentBase) (bool, []string) { + fieldsSame := true + + var segment0Fields []string + if len(segments) > 0 { + segment0Fields = segments[0].Fields() + } + + fieldsExist := map[string]struct{}{} + for _, segment := range segments { + fields := segment.Fields() + for fieldi, field := range fields { + fieldsExist[field] = struct{}{} + if len(segment0Fields) != len(fields) || segment0Fields[fieldi] != field { + fieldsSame = false + } + } + } + + rv := make([]string, 0, len(fieldsExist)) + // ensure _id stays first + rv = append(rv, "_id") + for k := range fieldsExist { + if k != "_id" { + rv = append(rv, k) + } + } + + sort.Strings(rv[1:]) // leave _id as first + + return fieldsSame, rv +} + +func isClosed(closeCh chan struct{}) bool { + select { + case <-closeCh: + return true + default: + return false + } +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/new.go b/backend/vendor/github.com/blevesearch/zapx/v13/new.go new file mode 100644 index 0000000000..b4e0d03415 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/new.go @@ -0,0 +1,830 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "math" + "sort" + "sync" + + "github.com/RoaringBitmap/roaring" + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" + "github.com/golang/snappy" +) + +var NewSegmentBufferNumResultsBump int = 100 +var NewSegmentBufferNumResultsFactor float64 = 1.0 +var NewSegmentBufferAvgBytesPerDocFactor float64 = 1.0 + +// ValidateDocFields can be set by applications to perform additional checks +// on fields in a document being added to a new segment, by default it does +// nothing. +// This API is experimental and may be removed at any time. +var ValidateDocFields = func(field index.Field) error { + return nil +} + +// New creates an in-memory zap-encoded SegmentBase from a set of Documents +func (z *ZapPlugin) New(results []index.Document) ( + segment.Segment, uint64, error) { + return z.newWithChunkMode(results, DefaultChunkMode) +} + +func (*ZapPlugin) newWithChunkMode(results []index.Document, + chunkMode uint32) (segment.Segment, uint64, error) { + s := interimPool.Get().(*interim) + + var br bytes.Buffer + if s.lastNumDocs > 0 { + // use previous results to initialize the buf with an estimate + // size, but note that the interim instance comes from a + // global interimPool, so multiple scorch instances indexing + // different docs can lead to low quality estimates + estimateAvgBytesPerDoc := int(float64(s.lastOutSize/s.lastNumDocs) * + NewSegmentBufferNumResultsFactor) + estimateNumResults := int(float64(len(results)+NewSegmentBufferNumResultsBump) * + NewSegmentBufferAvgBytesPerDocFactor) + br.Grow(estimateAvgBytesPerDoc * estimateNumResults) + } + + s.results = results + s.chunkMode = chunkMode + s.w = NewCountHashWriter(&br) + + storedIndexOffset, fieldsIndexOffset, fdvIndexOffset, dictOffsets, + err := s.convert() + if err != nil { + return nil, uint64(0), err + } + + sb, err := InitSegmentBase(br.Bytes(), s.w.Sum32(), chunkMode, + s.FieldsMap, s.FieldsInv, uint64(len(results)), + storedIndexOffset, fieldsIndexOffset, fdvIndexOffset, dictOffsets) + + if err == nil && s.reset() == nil { + s.lastNumDocs = len(results) + s.lastOutSize = len(br.Bytes()) + interimPool.Put(s) + } + + return sb, uint64(len(br.Bytes())), err +} + +var interimPool = sync.Pool{New: func() interface{} { return &interim{} }} + +// interim holds temporary working data used while converting from +// analysis results to a zap-encoded segment +type interim struct { + results []index.Document + + chunkMode uint32 + + w *CountHashWriter + + // FieldsMap adds 1 to field id to avoid zero value issues + // name -> field id + 1 + FieldsMap map[string]uint16 + + // FieldsInv is the inverse of FieldsMap + // field id -> name + FieldsInv []string + + // Term dictionaries for each field + // field id -> term -> postings list id + 1 + Dicts []map[string]uint64 + + // Terms for each field, where terms are sorted ascending + // field id -> []term + DictKeys [][]string + + // Fields whose IncludeDocValues is true + // field id -> bool + IncludeDocValues []bool + + // postings id -> bitmap of docNums + Postings []*roaring.Bitmap + + // postings id -> freq/norm's, one for each docNum in postings + FreqNorms [][]interimFreqNorm + freqNormsBacking []interimFreqNorm + + // postings id -> locs, one for each freq + Locs [][]interimLoc + locsBacking []interimLoc + + numTermsPerPostingsList []int // key is postings list id + numLocsPerPostingsList []int // key is postings list id + + builder *vellum.Builder + builderBuf bytes.Buffer + + metaBuf bytes.Buffer + + tmp0 []byte + tmp1 []byte + + lastNumDocs int + lastOutSize int +} + +func (s *interim) reset() (err error) { + s.results = nil + s.chunkMode = 0 + s.w = nil + s.FieldsMap = nil + s.FieldsInv = nil + for i := range s.Dicts { + s.Dicts[i] = nil + } + s.Dicts = s.Dicts[:0] + for i := range s.DictKeys { + s.DictKeys[i] = s.DictKeys[i][:0] + } + s.DictKeys = s.DictKeys[:0] + for i := range s.IncludeDocValues { + s.IncludeDocValues[i] = false + } + s.IncludeDocValues = s.IncludeDocValues[:0] + for _, idn := range s.Postings { + idn.Clear() + } + s.Postings = s.Postings[:0] + s.FreqNorms = s.FreqNorms[:0] + for i := range s.freqNormsBacking { + s.freqNormsBacking[i] = interimFreqNorm{} + } + s.freqNormsBacking = s.freqNormsBacking[:0] + s.Locs = s.Locs[:0] + for i := range s.locsBacking { + s.locsBacking[i] = interimLoc{} + } + s.locsBacking = s.locsBacking[:0] + s.numTermsPerPostingsList = s.numTermsPerPostingsList[:0] + s.numLocsPerPostingsList = s.numLocsPerPostingsList[:0] + s.builderBuf.Reset() + if s.builder != nil { + err = s.builder.Reset(&s.builderBuf) + } + s.metaBuf.Reset() + s.tmp0 = s.tmp0[:0] + s.tmp1 = s.tmp1[:0] + s.lastNumDocs = 0 + s.lastOutSize = 0 + + return err +} + +func (s *interim) grabBuf(size int) []byte { + buf := s.tmp0 + if cap(buf) < size { + buf = make([]byte, size) + s.tmp0 = buf + } + return buf[0:size] +} + +type interimStoredField struct { + vals [][]byte + typs []byte + arrayposs [][]uint64 // array positions +} + +type interimFreqNorm struct { + freq uint64 + norm float32 + numLocs int +} + +type interimLoc struct { + fieldID uint16 + pos uint64 + start uint64 + end uint64 + arrayposs []uint64 +} + +func (s *interim) convert() (uint64, uint64, uint64, []uint64, error) { + s.FieldsMap = map[string]uint16{} + + s.getOrDefineField("_id") // _id field is fieldID 0 + + for _, result := range s.results { + result.VisitComposite(func(field index.CompositeField) { + s.getOrDefineField(field.Name()) + }) + result.VisitFields(func(field index.Field) { + s.getOrDefineField(field.Name()) + }) + } + + sort.Strings(s.FieldsInv[1:]) // keep _id as first field + + for fieldID, fieldName := range s.FieldsInv { + s.FieldsMap[fieldName] = uint16(fieldID + 1) + } + + if cap(s.IncludeDocValues) >= len(s.FieldsInv) { + s.IncludeDocValues = s.IncludeDocValues[:len(s.FieldsInv)] + } else { + s.IncludeDocValues = make([]bool, len(s.FieldsInv)) + } + + s.prepareDicts() + + for _, dict := range s.DictKeys { + sort.Strings(dict) + } + + s.processDocuments() + + storedIndexOffset, err := s.writeStoredFields() + if err != nil { + return 0, 0, 0, nil, err + } + + var fdvIndexOffset uint64 + var dictOffsets []uint64 + + if len(s.results) > 0 { + fdvIndexOffset, dictOffsets, err = s.writeDicts() + if err != nil { + return 0, 0, 0, nil, err + } + } else { + dictOffsets = make([]uint64, len(s.FieldsInv)) + } + + fieldsIndexOffset, err := persistFields(s.FieldsInv, s.w, dictOffsets) + if err != nil { + return 0, 0, 0, nil, err + } + + return storedIndexOffset, fieldsIndexOffset, fdvIndexOffset, dictOffsets, nil +} + +func (s *interim) getOrDefineField(fieldName string) int { + fieldIDPlus1, exists := s.FieldsMap[fieldName] + if !exists { + fieldIDPlus1 = uint16(len(s.FieldsInv) + 1) + s.FieldsMap[fieldName] = fieldIDPlus1 + s.FieldsInv = append(s.FieldsInv, fieldName) + + s.Dicts = append(s.Dicts, make(map[string]uint64)) + + n := len(s.DictKeys) + if n < cap(s.DictKeys) { + s.DictKeys = s.DictKeys[:n+1] + s.DictKeys[n] = s.DictKeys[n][:0] + } else { + s.DictKeys = append(s.DictKeys, []string(nil)) + } + } + + return int(fieldIDPlus1 - 1) +} + +// fill Dicts and DictKeys from analysis results +func (s *interim) prepareDicts() { + var pidNext int + + var totTFs int + var totLocs int + + visitField := func(field index.Field) { + fieldID := uint16(s.getOrDefineField(field.Name())) + + dict := s.Dicts[fieldID] + dictKeys := s.DictKeys[fieldID] + + tfs := field.AnalyzedTokenFrequencies() + for term, tf := range tfs { + pidPlus1, exists := dict[term] + if !exists { + pidNext++ + pidPlus1 = uint64(pidNext) + + dict[term] = pidPlus1 + dictKeys = append(dictKeys, term) + + s.numTermsPerPostingsList = append(s.numTermsPerPostingsList, 0) + s.numLocsPerPostingsList = append(s.numLocsPerPostingsList, 0) + } + + pid := pidPlus1 - 1 + + s.numTermsPerPostingsList[pid] += 1 + s.numLocsPerPostingsList[pid] += len(tf.Locations) + + totLocs += len(tf.Locations) + } + + totTFs += len(tfs) + + s.DictKeys[fieldID] = dictKeys + } + + for _, result := range s.results { + // walk each composite field + result.VisitComposite(func(field index.CompositeField) { + visitField(field) + }) + + // walk each field + result.VisitFields(visitField) + } + + numPostingsLists := pidNext + + if cap(s.Postings) >= numPostingsLists { + s.Postings = s.Postings[:numPostingsLists] + } else { + postings := make([]*roaring.Bitmap, numPostingsLists) + copy(postings, s.Postings[:cap(s.Postings)]) + for i := 0; i < numPostingsLists; i++ { + if postings[i] == nil { + postings[i] = roaring.New() + } + } + s.Postings = postings + } + + if cap(s.FreqNorms) >= numPostingsLists { + s.FreqNorms = s.FreqNorms[:numPostingsLists] + } else { + s.FreqNorms = make([][]interimFreqNorm, numPostingsLists) + } + + if cap(s.freqNormsBacking) >= totTFs { + s.freqNormsBacking = s.freqNormsBacking[:totTFs] + } else { + s.freqNormsBacking = make([]interimFreqNorm, totTFs) + } + + freqNormsBacking := s.freqNormsBacking + for pid, numTerms := range s.numTermsPerPostingsList { + s.FreqNorms[pid] = freqNormsBacking[0:0] + freqNormsBacking = freqNormsBacking[numTerms:] + } + + if cap(s.Locs) >= numPostingsLists { + s.Locs = s.Locs[:numPostingsLists] + } else { + s.Locs = make([][]interimLoc, numPostingsLists) + } + + if cap(s.locsBacking) >= totLocs { + s.locsBacking = s.locsBacking[:totLocs] + } else { + s.locsBacking = make([]interimLoc, totLocs) + } + + locsBacking := s.locsBacking + for pid, numLocs := range s.numLocsPerPostingsList { + s.Locs[pid] = locsBacking[0:0] + locsBacking = locsBacking[numLocs:] + } +} + +func (s *interim) processDocuments() { + numFields := len(s.FieldsInv) + reuseFieldLens := make([]int, numFields) + reuseFieldTFs := make([]index.TokenFrequencies, numFields) + + for docNum, result := range s.results { + for i := 0; i < numFields; i++ { // clear these for reuse + reuseFieldLens[i] = 0 + reuseFieldTFs[i] = nil + } + + s.processDocument(uint64(docNum), result, + reuseFieldLens, reuseFieldTFs) + } +} + +func (s *interim) processDocument(docNum uint64, + result index.Document, + fieldLens []int, fieldTFs []index.TokenFrequencies) { + visitField := func(field index.Field) { + fieldID := uint16(s.getOrDefineField(field.Name())) + fieldLens[fieldID] += field.AnalyzedLength() + + existingFreqs := fieldTFs[fieldID] + if existingFreqs != nil { + existingFreqs.MergeAll(field.Name(), field.AnalyzedTokenFrequencies()) + } else { + fieldTFs[fieldID] = field.AnalyzedTokenFrequencies() + } + } + + // walk each composite field + result.VisitComposite(func(field index.CompositeField) { + visitField(field) + }) + + // walk each field + result.VisitFields(visitField) + + // now that it's been rolled up into fieldTFs, walk that + for fieldID, tfs := range fieldTFs { + dict := s.Dicts[fieldID] + norm := float32(1.0 / math.Sqrt(float64(fieldLens[fieldID]))) + + for term, tf := range tfs { + pid := dict[term] - 1 + bs := s.Postings[pid] + bs.Add(uint32(docNum)) + + s.FreqNorms[pid] = append(s.FreqNorms[pid], + interimFreqNorm{ + freq: uint64(tf.Frequency()), + norm: norm, + numLocs: len(tf.Locations), + }) + + if len(tf.Locations) > 0 { + locs := s.Locs[pid] + + for _, loc := range tf.Locations { + var locf = uint16(fieldID) + if loc.Field != "" { + locf = uint16(s.getOrDefineField(loc.Field)) + } + var arrayposs []uint64 + if len(loc.ArrayPositions) > 0 { + arrayposs = loc.ArrayPositions + } + locs = append(locs, interimLoc{ + fieldID: locf, + pos: uint64(loc.Position), + start: uint64(loc.Start), + end: uint64(loc.End), + arrayposs: arrayposs, + }) + } + + s.Locs[pid] = locs + } + } + } +} + +func (s *interim) writeStoredFields() ( + storedIndexOffset uint64, err error) { + varBuf := make([]byte, binary.MaxVarintLen64) + metaEncode := func(val uint64) (int, error) { + wb := binary.PutUvarint(varBuf, val) + return s.metaBuf.Write(varBuf[:wb]) + } + + data, compressed := s.tmp0[:0], s.tmp1[:0] + defer func() { s.tmp0, s.tmp1 = data, compressed }() + + // keyed by docNum + docStoredOffsets := make([]uint64, len(s.results)) + + // keyed by fieldID, for the current doc in the loop + docStoredFields := map[uint16]interimStoredField{} + + for docNum, result := range s.results { + for fieldID := range docStoredFields { // reset for next doc + delete(docStoredFields, fieldID) + } + + var validationErr error + result.VisitFields(func(field index.Field) { + fieldID := uint16(s.getOrDefineField(field.Name())) + + if field.Options().IsStored() { + isf := docStoredFields[fieldID] + isf.vals = append(isf.vals, field.Value()) + isf.typs = append(isf.typs, field.EncodedFieldType()) + isf.arrayposs = append(isf.arrayposs, field.ArrayPositions()) + docStoredFields[fieldID] = isf + } + + if field.Options().IncludeDocValues() { + s.IncludeDocValues[fieldID] = true + } + + err := ValidateDocFields(field) + if err != nil && validationErr == nil { + validationErr = err + } + }) + if validationErr != nil { + return 0, validationErr + } + + var curr int + + s.metaBuf.Reset() + data = data[:0] + + // _id field special case optimizes ExternalID() lookups + idFieldVal := docStoredFields[uint16(0)].vals[0] + _, err = metaEncode(uint64(len(idFieldVal))) + if err != nil { + return 0, err + } + + // handle non-"_id" fields + for fieldID := 1; fieldID < len(s.FieldsInv); fieldID++ { + isf, exists := docStoredFields[uint16(fieldID)] + if exists { + curr, data, err = persistStoredFieldValues( + fieldID, isf.vals, isf.typs, isf.arrayposs, + curr, metaEncode, data) + if err != nil { + return 0, err + } + } + } + + metaBytes := s.metaBuf.Bytes() + + compressed = snappy.Encode(compressed[:cap(compressed)], data) + + docStoredOffsets[docNum] = uint64(s.w.Count()) + + _, err := writeUvarints(s.w, + uint64(len(metaBytes)), + uint64(len(idFieldVal)+len(compressed))) + if err != nil { + return 0, err + } + + _, err = s.w.Write(metaBytes) + if err != nil { + return 0, err + } + + _, err = s.w.Write(idFieldVal) + if err != nil { + return 0, err + } + + _, err = s.w.Write(compressed) + if err != nil { + return 0, err + } + } + + storedIndexOffset = uint64(s.w.Count()) + + for _, docStoredOffset := range docStoredOffsets { + err = binary.Write(s.w, binary.BigEndian, docStoredOffset) + if err != nil { + return 0, err + } + } + + return storedIndexOffset, nil +} + +func (s *interim) writeDicts() (fdvIndexOffset uint64, dictOffsets []uint64, err error) { + dictOffsets = make([]uint64, len(s.FieldsInv)) + + fdvOffsetsStart := make([]uint64, len(s.FieldsInv)) + fdvOffsetsEnd := make([]uint64, len(s.FieldsInv)) + + buf := s.grabBuf(binary.MaxVarintLen64) + + // these int coders are initialized with chunk size 1024 + // however this will be reset to the correct chunk size + // while processing each individual field-term section + tfEncoder := newChunkedIntCoder(1024, uint64(len(s.results)-1)) + locEncoder := newChunkedIntCoder(1024, uint64(len(s.results)-1)) + + var docTermMap [][]byte + + if s.builder == nil { + s.builder, err = vellum.New(&s.builderBuf, nil) + if err != nil { + return 0, nil, err + } + } + + for fieldID, terms := range s.DictKeys { + if cap(docTermMap) < len(s.results) { + docTermMap = make([][]byte, len(s.results)) + } else { + docTermMap = docTermMap[0:len(s.results)] + for docNum := range docTermMap { // reset the docTermMap + docTermMap[docNum] = docTermMap[docNum][:0] + } + } + + dict := s.Dicts[fieldID] + + for _, term := range terms { // terms are already sorted + pid := dict[term] - 1 + + postingsBS := s.Postings[pid] + + freqNorms := s.FreqNorms[pid] + freqNormOffset := 0 + + locs := s.Locs[pid] + locOffset := 0 + + chunkSize, err := getChunkSize(s.chunkMode, postingsBS.GetCardinality(), uint64(len(s.results))) + if err != nil { + return 0, nil, err + } + tfEncoder.SetChunkSize(chunkSize, uint64(len(s.results)-1)) + locEncoder.SetChunkSize(chunkSize, uint64(len(s.results)-1)) + + postingsItr := postingsBS.Iterator() + for postingsItr.HasNext() { + docNum := uint64(postingsItr.Next()) + + freqNorm := freqNorms[freqNormOffset] + + err = tfEncoder.Add(docNum, + encodeFreqHasLocs(freqNorm.freq, freqNorm.numLocs > 0), + uint64(math.Float32bits(freqNorm.norm))) + if err != nil { + return 0, nil, err + } + + if freqNorm.numLocs > 0 { + numBytesLocs := 0 + for _, loc := range locs[locOffset : locOffset+freqNorm.numLocs] { + numBytesLocs += totalUvarintBytes( + uint64(loc.fieldID), loc.pos, loc.start, loc.end, + uint64(len(loc.arrayposs)), loc.arrayposs) + } + + err = locEncoder.Add(docNum, uint64(numBytesLocs)) + if err != nil { + return 0, nil, err + } + + for _, loc := range locs[locOffset : locOffset+freqNorm.numLocs] { + err = locEncoder.Add(docNum, + uint64(loc.fieldID), loc.pos, loc.start, loc.end, + uint64(len(loc.arrayposs))) + if err != nil { + return 0, nil, err + } + + err = locEncoder.Add(docNum, loc.arrayposs...) + if err != nil { + return 0, nil, err + } + } + + locOffset += freqNorm.numLocs + } + + freqNormOffset++ + + docTermMap[docNum] = append( + append(docTermMap[docNum], term...), + termSeparator) + } + + tfEncoder.Close() + locEncoder.Close() + + postingsOffset, err := + writePostings(postingsBS, tfEncoder, locEncoder, nil, s.w, buf) + if err != nil { + return 0, nil, err + } + + if postingsOffset > uint64(0) { + err = s.builder.Insert([]byte(term), postingsOffset) + if err != nil { + return 0, nil, err + } + } + + tfEncoder.Reset() + locEncoder.Reset() + } + + err = s.builder.Close() + if err != nil { + return 0, nil, err + } + + // record where this dictionary starts + dictOffsets[fieldID] = uint64(s.w.Count()) + + vellumData := s.builderBuf.Bytes() + + // write out the length of the vellum data + n := binary.PutUvarint(buf, uint64(len(vellumData))) + _, err = s.w.Write(buf[:n]) + if err != nil { + return 0, nil, err + } + + // write this vellum to disk + _, err = s.w.Write(vellumData) + if err != nil { + return 0, nil, err + } + + // reset vellum for reuse + s.builderBuf.Reset() + + err = s.builder.Reset(&s.builderBuf) + if err != nil { + return 0, nil, err + } + + // write the field doc values + // NOTE: doc values continue to use legacy chunk mode + chunkSize, err := getChunkSize(LegacyChunkMode, 0, 0) + if err != nil { + return 0, nil, err + } + fdvEncoder := newChunkedContentCoder(chunkSize, uint64(len(s.results)-1), s.w, false) + if s.IncludeDocValues[fieldID] { + for docNum, docTerms := range docTermMap { + if len(docTerms) > 0 { + err = fdvEncoder.Add(uint64(docNum), docTerms) + if err != nil { + return 0, nil, err + } + } + } + err = fdvEncoder.Close() + if err != nil { + return 0, nil, err + } + + fdvOffsetsStart[fieldID] = uint64(s.w.Count()) + + _, err = fdvEncoder.Write() + if err != nil { + return 0, nil, err + } + + fdvOffsetsEnd[fieldID] = uint64(s.w.Count()) + + fdvEncoder.Reset() + } else { + fdvOffsetsStart[fieldID] = fieldNotUninverted + fdvOffsetsEnd[fieldID] = fieldNotUninverted + } + } + + fdvIndexOffset = uint64(s.w.Count()) + + for i := 0; i < len(fdvOffsetsStart); i++ { + n := binary.PutUvarint(buf, fdvOffsetsStart[i]) + _, err := s.w.Write(buf[:n]) + if err != nil { + return 0, nil, err + } + n = binary.PutUvarint(buf, fdvOffsetsEnd[i]) + _, err = s.w.Write(buf[:n]) + if err != nil { + return 0, nil, err + } + } + + return fdvIndexOffset, dictOffsets, nil +} + +// returns the total # of bytes needed to encode the given uint64's +// into binary.PutUVarint() encoding +func totalUvarintBytes(a, b, c, d, e uint64, more []uint64) (n int) { + n = numUvarintBytes(a) + n += numUvarintBytes(b) + n += numUvarintBytes(c) + n += numUvarintBytes(d) + n += numUvarintBytes(e) + for _, v := range more { + n += numUvarintBytes(v) + } + return n +} + +// returns # of bytes needed to encode x in binary.PutUvarint() encoding +func numUvarintBytes(x uint64) (n int) { + for x >= 0x80 { + x >>= 7 + n++ + } + return n + 1 +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/plugin.go b/backend/vendor/github.com/blevesearch/zapx/v13/plugin.go new file mode 100644 index 0000000000..f67297ec2f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/plugin.go @@ -0,0 +1,27 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +// ZapPlugin implements the Plugin interface of +// the blevesearch/scorch_segment_api pkg +type ZapPlugin struct{} + +func (*ZapPlugin) Type() string { + return Type +} + +func (*ZapPlugin) Version() uint32 { + return Version +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/posting.go b/backend/vendor/github.com/blevesearch/zapx/v13/posting.go new file mode 100644 index 0000000000..1ba133d6e0 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/posting.go @@ -0,0 +1,837 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "encoding/binary" + "fmt" + "math" + "reflect" + + "github.com/RoaringBitmap/roaring" + segment "github.com/blevesearch/scorch_segment_api/v2" +) + +var reflectStaticSizePostingsList int +var reflectStaticSizePostingsIterator int +var reflectStaticSizePosting int +var reflectStaticSizeLocation int + +func init() { + var pl PostingsList + reflectStaticSizePostingsList = int(reflect.TypeOf(pl).Size()) + var pi PostingsIterator + reflectStaticSizePostingsIterator = int(reflect.TypeOf(pi).Size()) + var p Posting + reflectStaticSizePosting = int(reflect.TypeOf(p).Size()) + var l Location + reflectStaticSizeLocation = int(reflect.TypeOf(l).Size()) +} + +// FST or vellum value (uint64) encoding is determined by the top two +// highest-order or most significant bits... +// +// encoding : MSB +// name : 63 62 61...to...bit #0 (LSB) +// ----------+---+---+--------------------------------------------------- +// general : 0 | 0 | 62-bits of postingsOffset. +// ~ : 0 | 1 | reserved for future. +// 1-hit : 1 | 0 | 31-bits of positive float31 norm | 31-bits docNum. +// ~ : 1 | 1 | reserved for future. +// +// Encoding "general" is able to handle all cases, where the +// postingsOffset points to more information about the postings for +// the term. +// +// Encoding "1-hit" is used to optimize a commonly seen case when a +// term has only a single hit. For example, a term in the _id field +// will have only 1 hit. The "1-hit" encoding is used for a term +// in a field when... +// +// - term vector info is disabled for that field; +// - and, the term appears in only a single doc for that field; +// - and, the term's freq is exactly 1 in that single doc for that field; +// - and, the docNum must fit into 31-bits; +// +// Otherwise, the "general" encoding is used instead. +// +// In the "1-hit" encoding, the field in that single doc may have +// other terms, which is supported in the "1-hit" encoding by the +// positive float31 norm. + +const FSTValEncodingMask = uint64(0xc000000000000000) +const FSTValEncodingGeneral = uint64(0x0000000000000000) +const FSTValEncoding1Hit = uint64(0x8000000000000000) + +func FSTValEncode1Hit(docNum uint64, normBits uint64) uint64 { + return FSTValEncoding1Hit | ((mask31Bits & normBits) << 31) | (mask31Bits & docNum) +} + +func FSTValDecode1Hit(v uint64) (docNum uint64, normBits uint64) { + return (mask31Bits & v), (mask31Bits & (v >> 31)) +} + +const mask31Bits = uint64(0x000000007fffffff) + +func under32Bits(x uint64) bool { + return x <= mask31Bits +} + +const DocNum1HitFinished = math.MaxUint64 + +var NormBits1Hit = uint64(math.Float32bits(float32(1))) + +// PostingsList is an in-memory representation of a postings list +type PostingsList struct { + sb *SegmentBase + postingsOffset uint64 + freqOffset uint64 + locOffset uint64 + postings *roaring.Bitmap + except *roaring.Bitmap + + // when normBits1Hit != 0, then this postings list came from a + // 1-hit encoding, and only the docNum1Hit & normBits1Hit apply + docNum1Hit uint64 + normBits1Hit uint64 +} + +// represents an immutable, empty postings list +var emptyPostingsList = &PostingsList{} + +// Following methods are dummy implementations for the interface +// DiskStatsReporter (for backward compatibility). +// The working implementations are supported only in zap v15.x +// and not in the earlier versions of zap. +func (i *PostingsList) ResetBytesRead(uint64) {} + +func (i *PostingsList) BytesRead() uint64 { + return 0 +} + +func (i *PostingsList) incrementBytesRead(uint64) {} + +func (i *PostingsList) BytesWritten() uint64 { + return 0 +} + +func (p *PostingsList) Size() int { + sizeInBytes := reflectStaticSizePostingsList + SizeOfPtr + + if p.except != nil { + sizeInBytes += int(p.except.GetSizeInBytes()) + } + + return sizeInBytes +} + +func (p *PostingsList) OrInto(receiver *roaring.Bitmap) { + if p.normBits1Hit != 0 { + receiver.Add(uint32(p.docNum1Hit)) + return + } + + if p.postings != nil { + receiver.Or(p.postings) + } +} + +// Iterator returns an iterator for this postings list +func (p *PostingsList) Iterator(includeFreq, includeNorm, includeLocs bool, + prealloc segment.PostingsIterator) segment.PostingsIterator { + if p.normBits1Hit == 0 && p.postings == nil { + return emptyPostingsIterator + } + + var preallocPI *PostingsIterator + pi, ok := prealloc.(*PostingsIterator) + if ok && pi != nil { + preallocPI = pi + } + if preallocPI == emptyPostingsIterator { + preallocPI = nil + } + + return p.iterator(includeFreq, includeNorm, includeLocs, preallocPI) +} + +func (p *PostingsList) iterator(includeFreq, includeNorm, includeLocs bool, + rv *PostingsIterator) *PostingsIterator { + if rv == nil { + rv = &PostingsIterator{} + } else { + freqNormReader := rv.freqNormReader + if freqNormReader != nil { + freqNormReader.reset() + } + + locReader := rv.locReader + if locReader != nil { + locReader.reset() + } + + nextLocs := rv.nextLocs[:0] + nextSegmentLocs := rv.nextSegmentLocs[:0] + + buf := rv.buf + + *rv = PostingsIterator{} // clear the struct + + rv.freqNormReader = freqNormReader + rv.locReader = locReader + + rv.nextLocs = nextLocs + rv.nextSegmentLocs = nextSegmentLocs + + rv.buf = buf + } + + rv.postings = p + rv.includeFreqNorm = includeFreq || includeNorm || includeLocs + rv.includeLocs = includeLocs + + if p.normBits1Hit != 0 { + // "1-hit" encoding + rv.docNum1Hit = p.docNum1Hit + rv.normBits1Hit = p.normBits1Hit + + if p.except != nil && p.except.Contains(uint32(rv.docNum1Hit)) { + rv.docNum1Hit = DocNum1HitFinished + } + + return rv + } + + // "general" encoding, check if empty + if p.postings == nil { + return rv + } + + // initialize freq chunk reader + if rv.includeFreqNorm { + rv.freqNormReader = newChunkedIntDecoder(p.sb.mem, p.freqOffset) + } + + // initialize the loc chunk reader + if rv.includeLocs { + rv.locReader = newChunkedIntDecoder(p.sb.mem, p.locOffset) + } + + rv.all = p.postings.Iterator() + if p.except != nil { + rv.ActualBM = roaring.AndNot(p.postings, p.except) + rv.Actual = rv.ActualBM.Iterator() + } else { + rv.ActualBM = p.postings + rv.Actual = rv.all // Optimize to use same iterator for all & Actual. + } + + return rv +} + +// Count returns the number of items on this postings list +func (p *PostingsList) Count() uint64 { + var n, e uint64 + if p.normBits1Hit != 0 { + n = 1 + if p.except != nil && p.except.Contains(uint32(p.docNum1Hit)) { + e = 1 + } + } else if p.postings != nil { + n = p.postings.GetCardinality() + if p.except != nil { + e = p.postings.AndCardinality(p.except) + } + } + return n - e +} + +func (rv *PostingsList) read(postingsOffset uint64, d *Dictionary) error { + rv.postingsOffset = postingsOffset + + // handle "1-hit" encoding special case + if rv.postingsOffset&FSTValEncodingMask == FSTValEncoding1Hit { + return rv.init1Hit(postingsOffset) + } + + // read the location of the freq/norm details + var n uint64 + var read int + + rv.freqOffset, read = binary.Uvarint(d.sb.mem[postingsOffset+n : postingsOffset+binary.MaxVarintLen64]) + n += uint64(read) + + rv.locOffset, read = binary.Uvarint(d.sb.mem[postingsOffset+n : postingsOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + + var postingsLen uint64 + postingsLen, read = binary.Uvarint(d.sb.mem[postingsOffset+n : postingsOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + + roaringBytes := d.sb.mem[postingsOffset+n : postingsOffset+n+postingsLen] + + if rv.postings == nil { + rv.postings = roaring.NewBitmap() + } + _, err := rv.postings.FromBuffer(roaringBytes) + if err != nil { + return fmt.Errorf("error loading roaring bitmap: %v", err) + } + + return nil +} + +func (rv *PostingsList) init1Hit(fstVal uint64) error { + docNum, normBits := FSTValDecode1Hit(fstVal) + + rv.docNum1Hit = docNum + rv.normBits1Hit = normBits + + return nil +} + +// PostingsIterator provides a way to iterate through the postings list +type PostingsIterator struct { + postings *PostingsList + all roaring.IntPeekable + Actual roaring.IntPeekable + ActualBM *roaring.Bitmap + + currChunk uint32 + freqNormReader *chunkedIntDecoder + locReader *chunkedIntDecoder + + next Posting // reused across Next() calls + nextLocs []Location // reused across Next() calls + nextSegmentLocs []segment.Location // reused across Next() calls + + docNum1Hit uint64 + normBits1Hit uint64 + + buf []byte + + includeFreqNorm bool + includeLocs bool +} + +var emptyPostingsIterator = &PostingsIterator{} + +// Following methods are dummy implementations for the interface +// DiskStatsReporter (for backward compatibility). +// The working implementations are supported only in zap v15.x +// and not in the earlier versions of zap. +func (i *PostingsIterator) ResetBytesRead(uint64) {} + +func (i *PostingsIterator) BytesRead() uint64 { + return 0 +} + +func (i *PostingsIterator) incrementBytesRead(uint64) {} + +func (i *PostingsIterator) BytesWritten() uint64 { + return 0 +} + +func (i *PostingsIterator) Size() int { + sizeInBytes := reflectStaticSizePostingsIterator + SizeOfPtr + + i.next.Size() + // account for freqNormReader, locReader if we start using this. + for _, entry := range i.nextLocs { + sizeInBytes += entry.Size() + } + + return sizeInBytes +} + +func (i *PostingsIterator) loadChunk(chunk int) error { + if i.includeFreqNorm { + err := i.freqNormReader.loadChunk(chunk) + if err != nil { + return err + } + } + + if i.includeLocs { + err := i.locReader.loadChunk(chunk) + if err != nil { + return err + } + } + + i.currChunk = uint32(chunk) + return nil +} + +func (i *PostingsIterator) readFreqNormHasLocs() (uint64, uint64, bool, error) { + if i.normBits1Hit != 0 { + return 1, i.normBits1Hit, false, nil + } + + freqHasLocs, err := i.freqNormReader.readUvarint() + if err != nil { + return 0, 0, false, fmt.Errorf("error reading frequency: %v", err) + } + + freq, hasLocs := decodeFreqHasLocs(freqHasLocs) + + normBits, err := i.freqNormReader.readUvarint() + if err != nil { + return 0, 0, false, fmt.Errorf("error reading norm: %v", err) + } + + return freq, normBits, hasLocs, nil +} + +func (i *PostingsIterator) skipFreqNormReadHasLocs() (bool, error) { + if i.normBits1Hit != 0 { + return false, nil + } + + freqHasLocs, err := i.freqNormReader.readUvarint() + if err != nil { + return false, fmt.Errorf("error reading freqHasLocs: %v", err) + } + + i.freqNormReader.SkipUvarint() // Skip normBits. + + return freqHasLocs&0x01 != 0, nil // See decodeFreqHasLocs() / hasLocs. +} + +func encodeFreqHasLocs(freq uint64, hasLocs bool) uint64 { + rv := freq << 1 + if hasLocs { + rv = rv | 0x01 // 0'th LSB encodes whether there are locations + } + return rv +} + +func decodeFreqHasLocs(freqHasLocs uint64) (uint64, bool) { + freq := freqHasLocs >> 1 + hasLocs := freqHasLocs&0x01 != 0 + return freq, hasLocs +} + +// readLocation processes all the integers on the stream representing a single +// location. +func (i *PostingsIterator) readLocation(l *Location) error { + // read off field + fieldID, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location field: %v", err) + } + // read off pos + pos, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location pos: %v", err) + } + // read off start + start, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location start: %v", err) + } + // read off end + end, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location end: %v", err) + } + // read off num array pos + numArrayPos, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location num array pos: %v", err) + } + + l.field = i.postings.sb.fieldsInv[fieldID] + l.pos = pos + l.start = start + l.end = end + + if cap(l.ap) < int(numArrayPos) { + l.ap = make([]uint64, int(numArrayPos)) + } else { + l.ap = l.ap[:int(numArrayPos)] + } + + // read off array positions + for k := 0; k < int(numArrayPos); k++ { + ap, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading array position: %v", err) + } + + l.ap[k] = ap + } + + return nil +} + +// Next returns the next posting on the postings list, or nil at the end +func (i *PostingsIterator) Next() (segment.Posting, error) { + return i.nextAtOrAfter(0) +} + +// Advance returns the posting at the specified docNum or it is not present +// the next posting, or if the end is reached, nil +func (i *PostingsIterator) Advance(docNum uint64) (segment.Posting, error) { + return i.nextAtOrAfter(docNum) +} + +// Next returns the next posting on the postings list, or nil at the end +func (i *PostingsIterator) nextAtOrAfter(atOrAfter uint64) (segment.Posting, error) { + docNum, exists, err := i.nextDocNumAtOrAfter(atOrAfter) + if err != nil || !exists { + return nil, err + } + + i.next = Posting{} // clear the struct + rv := &i.next + rv.docNum = docNum + + if !i.includeFreqNorm { + return rv, nil + } + + var normBits uint64 + var hasLocs bool + + rv.freq, normBits, hasLocs, err = i.readFreqNormHasLocs() + if err != nil { + return nil, err + } + + rv.norm = math.Float32frombits(uint32(normBits)) + + if i.includeLocs && hasLocs { + // prepare locations into reused slices, where we assume + // rv.freq >= "number of locs", since in a composite field, + // some component fields might have their IncludeTermVector + // flags disabled while other component fields are enabled + if cap(i.nextLocs) >= int(rv.freq) { + i.nextLocs = i.nextLocs[0:rv.freq] + } else { + i.nextLocs = make([]Location, rv.freq, rv.freq*2) + } + if cap(i.nextSegmentLocs) < int(rv.freq) { + i.nextSegmentLocs = make([]segment.Location, rv.freq, rv.freq*2) + } + rv.locs = i.nextSegmentLocs[:0] + + numLocsBytes, err := i.locReader.readUvarint() + if err != nil { + return nil, fmt.Errorf("error reading location numLocsBytes: %v", err) + } + + j := 0 + startBytesRemaining := i.locReader.Len() // # bytes remaining in the locReader + for startBytesRemaining-i.locReader.Len() < int(numLocsBytes) { + err := i.readLocation(&i.nextLocs[j]) + if err != nil { + return nil, err + } + rv.locs = append(rv.locs, &i.nextLocs[j]) + j++ + } + } + + return rv, nil +} + +// nextDocNum returns the next docNum on the postings list, and also +// sets up the currChunk / loc related fields of the iterator. +func (i *PostingsIterator) nextDocNumAtOrAfter(atOrAfter uint64) (uint64, bool, error) { + if i.normBits1Hit != 0 { + if i.docNum1Hit == DocNum1HitFinished { + return 0, false, nil + } + if i.docNum1Hit < atOrAfter { + // advanced past our 1-hit + i.docNum1Hit = DocNum1HitFinished // consume our 1-hit docNum + return 0, false, nil + } + docNum := i.docNum1Hit + i.docNum1Hit = DocNum1HitFinished // consume our 1-hit docNum + return docNum, true, nil + } + + if i.Actual == nil || !i.Actual.HasNext() { + return 0, false, nil + } + + if i.postings == nil || i.postings == emptyPostingsList { + // couldn't find anything + return 0, false, nil + } + + if i.postings.postings == i.ActualBM { + return i.nextDocNumAtOrAfterClean(atOrAfter) + } + + i.Actual.AdvanceIfNeeded(uint32(atOrAfter)) + + if !i.Actual.HasNext() || !i.all.HasNext() { + // couldn't find anything + return 0, false, nil + } + + n := i.Actual.Next() + allN := i.all.Next() + + chunkSize, err := getChunkSize(i.postings.sb.chunkMode, i.postings.postings.GetCardinality(), i.postings.sb.numDocs) + if err != nil { + return 0, false, err + } + nChunk := n / uint32(chunkSize) + + // when allN becomes >= to here, then allN is in the same chunk as nChunk. + allNReachesNChunk := nChunk * uint32(chunkSize) + + // n is the next actual hit (excluding some postings), and + // allN is the next hit in the full postings, and + // if they don't match, move 'all' forwards until they do + for allN != n { + // we've reached same chunk, so move the freq/norm/loc decoders forward + if i.includeFreqNorm && allN >= allNReachesNChunk { + err := i.currChunkNext(nChunk) + if err != nil { + return 0, false, err + } + } + + if !i.all.HasNext() { + return 0, false, nil + } + + allN = i.all.Next() + } + + if i.includeFreqNorm && (i.currChunk != nChunk || i.freqNormReader.isNil()) { + err := i.loadChunk(int(nChunk)) + if err != nil { + return 0, false, fmt.Errorf("error loading chunk: %v", err) + } + } + + return uint64(n), true, nil +} + +// optimization when the postings list is "clean" (e.g., no updates & +// no deletions) where the all bitmap is the same as the actual bitmap +func (i *PostingsIterator) nextDocNumAtOrAfterClean( + atOrAfter uint64) (uint64, bool, error) { + if !i.includeFreqNorm { + i.Actual.AdvanceIfNeeded(uint32(atOrAfter)) + + if !i.Actual.HasNext() { + return 0, false, nil // couldn't find anything + } + + return uint64(i.Actual.Next()), true, nil + } + + chunkSize, err := getChunkSize(i.postings.sb.chunkMode, i.postings.postings.GetCardinality(), i.postings.sb.numDocs) + if err != nil { + return 0, false, err + } + + // freq-norm's needed, so maintain freq-norm chunk reader + sameChunkNexts := 0 // # of times we called Next() in the same chunk + n := i.Actual.Next() + nChunk := n / uint32(chunkSize) + + for uint64(n) < atOrAfter && i.Actual.HasNext() { + n = i.Actual.Next() + + nChunkPrev := nChunk + nChunk = n / uint32(chunkSize) + + if nChunk != nChunkPrev { + sameChunkNexts = 0 + } else { + sameChunkNexts += 1 + } + } + + if uint64(n) < atOrAfter { + // couldn't find anything + return 0, false, nil + } + + for j := 0; j < sameChunkNexts; j++ { + err := i.currChunkNext(nChunk) + if err != nil { + return 0, false, fmt.Errorf("error optimized currChunkNext: %v", err) + } + } + + if i.currChunk != nChunk || i.freqNormReader.isNil() { + err := i.loadChunk(int(nChunk)) + if err != nil { + return 0, false, fmt.Errorf("error loading chunk: %v", err) + } + } + + return uint64(n), true, nil +} + +func (i *PostingsIterator) currChunkNext(nChunk uint32) error { + if i.currChunk != nChunk || i.freqNormReader.isNil() { + err := i.loadChunk(int(nChunk)) + if err != nil { + return fmt.Errorf("error loading chunk: %v", err) + } + } + + // read off freq/offsets even though we don't care about them + hasLocs, err := i.skipFreqNormReadHasLocs() + if err != nil { + return err + } + + if i.includeLocs && hasLocs { + numLocsBytes, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location numLocsBytes: %v", err) + } + + // skip over all the location bytes + i.locReader.SkipBytes(int(numLocsBytes)) + } + + return nil +} + +// DocNum1Hit returns the docNum and true if this is "1-hit" optimized +// and the docNum is available. +func (p *PostingsIterator) DocNum1Hit() (uint64, bool) { + if p.normBits1Hit != 0 && p.docNum1Hit != DocNum1HitFinished { + return p.docNum1Hit, true + } + return 0, false +} + +// ActualBitmap returns the underlying actual bitmap +// which can be used up the stack for optimizations +func (p *PostingsIterator) ActualBitmap() *roaring.Bitmap { + return p.ActualBM +} + +// ReplaceActual replaces the ActualBM with the provided +// bitmap +func (p *PostingsIterator) ReplaceActual(abm *roaring.Bitmap) { + p.ActualBM = abm + p.Actual = abm.Iterator() +} + +// PostingsIteratorFromBitmap constructs a PostingsIterator given an +// "actual" bitmap. +func PostingsIteratorFromBitmap(bm *roaring.Bitmap, + includeFreqNorm, includeLocs bool) (segment.PostingsIterator, error) { + return &PostingsIterator{ + ActualBM: bm, + Actual: bm.Iterator(), + includeFreqNorm: includeFreqNorm, + includeLocs: includeLocs, + }, nil +} + +// PostingsIteratorFrom1Hit constructs a PostingsIterator given a +// 1-hit docNum. +func PostingsIteratorFrom1Hit(docNum1Hit uint64, + includeFreqNorm, includeLocs bool) (segment.PostingsIterator, error) { + return &PostingsIterator{ + docNum1Hit: docNum1Hit, + normBits1Hit: NormBits1Hit, + includeFreqNorm: includeFreqNorm, + includeLocs: includeLocs, + }, nil +} + +// Posting is a single entry in a postings list +type Posting struct { + docNum uint64 + freq uint64 + norm float32 + locs []segment.Location +} + +func (p *Posting) Size() int { + sizeInBytes := reflectStaticSizePosting + + for _, entry := range p.locs { + sizeInBytes += entry.Size() + } + + return sizeInBytes +} + +// Number returns the document number of this posting in this segment +func (p *Posting) Number() uint64 { + return p.docNum +} + +// Frequency returns the frequencies of occurrence of this term in this doc/field +func (p *Posting) Frequency() uint64 { + return p.freq +} + +// Norm returns the normalization factor for this posting +func (p *Posting) Norm() float64 { + return float64(p.norm) +} + +// Locations returns the location information for each occurrence +func (p *Posting) Locations() []segment.Location { + return p.locs +} + +// Location represents the location of a single occurrence +type Location struct { + field string + pos uint64 + start uint64 + end uint64 + ap []uint64 +} + +func (l *Location) Size() int { + return reflectStaticSizeLocation + + len(l.field) + + len(l.ap)*SizeOfUint64 +} + +// Field returns the name of the field (useful in composite fields to know +// which original field the value came from) +func (l *Location) Field() string { + return l.field +} + +// Start returns the start byte offset of this occurrence +func (l *Location) Start() uint64 { + return l.start +} + +// End returns the end byte offset of this occurrence +func (l *Location) End() uint64 { + return l.end +} + +// Pos returns the 1-based phrase position of this occurrence +func (l *Location) Pos() uint64 { + return l.pos +} + +// ArrayPositions returns the array position vector associated with this occurrence +func (l *Location) ArrayPositions() []uint64 { + return l.ap +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/read.go b/backend/vendor/github.com/blevesearch/zapx/v13/read.go new file mode 100644 index 0000000000..e47d4c6abd --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/read.go @@ -0,0 +1,43 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import "encoding/binary" + +func (s *SegmentBase) getDocStoredMetaAndCompressed(docNum uint64) ([]byte, []byte) { + _, storedOffset, n, metaLen, dataLen := s.getDocStoredOffsets(docNum) + + meta := s.mem[storedOffset+n : storedOffset+n+metaLen] + data := s.mem[storedOffset+n+metaLen : storedOffset+n+metaLen+dataLen] + + return meta, data +} + +func (s *SegmentBase) getDocStoredOffsets(docNum uint64) ( + uint64, uint64, uint64, uint64, uint64) { + indexOffset := s.storedIndexOffset + (8 * docNum) + + storedOffset := binary.BigEndian.Uint64(s.mem[indexOffset : indexOffset+8]) + + var n uint64 + + metaLen, read := binary.Uvarint(s.mem[storedOffset : storedOffset+binary.MaxVarintLen64]) + n += uint64(read) + + dataLen, read := binary.Uvarint(s.mem[storedOffset+n : storedOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + + return indexOffset, storedOffset, n, metaLen, dataLen +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/segment.go b/backend/vendor/github.com/blevesearch/zapx/v13/segment.go new file mode 100644 index 0000000000..1fbf78480f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/segment.go @@ -0,0 +1,600 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" + "os" + "sync" + "unsafe" + + "github.com/RoaringBitmap/roaring" + mmap "github.com/blevesearch/mmap-go" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" + "github.com/golang/snappy" +) + +var reflectStaticSizeSegmentBase int + +func init() { + var sb SegmentBase + reflectStaticSizeSegmentBase = int(unsafe.Sizeof(sb)) +} + +// Open returns a zap impl of a segment +func (*ZapPlugin) Open(path string) (segment.Segment, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + mm, err := mmap.Map(f, mmap.RDONLY, 0) + if err != nil { + // mmap failed, try to close the file + _ = f.Close() + return nil, err + } + + rv := &Segment{ + SegmentBase: SegmentBase{ + mem: mm[0 : len(mm)-FooterSize], + fieldsMap: make(map[string]uint16), + fieldDvReaders: make(map[uint16]*docValueReader), + fieldFSTs: make(map[uint16]*vellum.FST), + }, + f: f, + mm: mm, + path: path, + refs: 1, + } + rv.SegmentBase.updateSize() + + err = rv.loadConfig() + if err != nil { + _ = rv.Close() + return nil, err + } + + err = rv.loadFields() + if err != nil { + _ = rv.Close() + return nil, err + } + + err = rv.loadDvReaders() + if err != nil { + _ = rv.Close() + return nil, err + } + + return rv, nil +} + +// SegmentBase is a memory only, read-only implementation of the +// segment.Segment interface, using zap's data representation. +type SegmentBase struct { + mem []byte + memCRC uint32 + chunkMode uint32 + fieldsMap map[string]uint16 // fieldName -> fieldID+1 + fieldsInv []string // fieldID -> fieldName + numDocs uint64 + storedIndexOffset uint64 + fieldsIndexOffset uint64 + docValueOffset uint64 + dictLocs []uint64 + fieldDvReaders map[uint16]*docValueReader // naive chunk cache per field + fieldDvNames []string // field names cached in fieldDvReaders + size uint64 + + m sync.Mutex + fieldFSTs map[uint16]*vellum.FST +} + +func (sb *SegmentBase) Size() int { + return int(sb.size) +} + +func (sb *SegmentBase) updateSize() { + sizeInBytes := reflectStaticSizeSegmentBase + + cap(sb.mem) + + // fieldsMap + for k := range sb.fieldsMap { + sizeInBytes += (len(k) + SizeOfString) + SizeOfUint16 + } + + // fieldsInv, dictLocs + for _, entry := range sb.fieldsInv { + sizeInBytes += len(entry) + SizeOfString + } + sizeInBytes += len(sb.dictLocs) * SizeOfUint64 + + // fieldDvReaders + for _, v := range sb.fieldDvReaders { + sizeInBytes += SizeOfUint16 + SizeOfPtr + if v != nil { + sizeInBytes += v.size() + } + } + + sb.size = uint64(sizeInBytes) +} + +func (sb *SegmentBase) AddRef() {} +func (sb *SegmentBase) DecRef() (err error) { return nil } +func (sb *SegmentBase) Close() (err error) { return nil } + +// Segment implements a persisted segment.Segment interface, by +// embedding an mmap()'ed SegmentBase. +type Segment struct { + SegmentBase + + f *os.File + mm mmap.MMap + path string + version uint32 + crc uint32 + + m sync.Mutex // Protects the fields that follow. + refs int64 +} + +func (s *Segment) Size() int { + // 8 /* size of file pointer */ + // 4 /* size of version -> uint32 */ + // 4 /* size of crc -> uint32 */ + sizeOfUints := 16 + + sizeInBytes := (len(s.path) + SizeOfString) + sizeOfUints + + // mutex, refs -> int64 + sizeInBytes += 16 + + // do not include the mmap'ed part + return sizeInBytes + s.SegmentBase.Size() - cap(s.mem) +} + +func (s *Segment) AddRef() { + s.m.Lock() + s.refs++ + s.m.Unlock() +} + +func (s *Segment) DecRef() (err error) { + s.m.Lock() + s.refs-- + if s.refs == 0 { + err = s.closeActual() + } + s.m.Unlock() + return err +} + +func (s *Segment) loadConfig() error { + crcOffset := len(s.mm) - 4 + s.crc = binary.BigEndian.Uint32(s.mm[crcOffset : crcOffset+4]) + + verOffset := crcOffset - 4 + s.version = binary.BigEndian.Uint32(s.mm[verOffset : verOffset+4]) + if s.version != Version { + return fmt.Errorf("unsupported version %d", s.version) + } + + chunkOffset := verOffset - 4 + s.chunkMode = binary.BigEndian.Uint32(s.mm[chunkOffset : chunkOffset+4]) + + docValueOffset := chunkOffset - 8 + s.docValueOffset = binary.BigEndian.Uint64(s.mm[docValueOffset : docValueOffset+8]) + + fieldsIndexOffset := docValueOffset - 8 + s.fieldsIndexOffset = binary.BigEndian.Uint64(s.mm[fieldsIndexOffset : fieldsIndexOffset+8]) + + storedIndexOffset := fieldsIndexOffset - 8 + s.storedIndexOffset = binary.BigEndian.Uint64(s.mm[storedIndexOffset : storedIndexOffset+8]) + + numDocsOffset := storedIndexOffset - 8 + s.numDocs = binary.BigEndian.Uint64(s.mm[numDocsOffset : numDocsOffset+8]) + return nil +} + +// Following methods are dummy implementations for the interface +// DiskStatsReporter (for backward compatibility). +// The working implementations are supported only in zap v15.x +// and not in the earlier versions of zap. +func (s *Segment) ResetBytesRead(uint64) {} + +func (s *Segment) BytesRead() uint64 { + return 0 +} + +func (s *Segment) BytesWritten() uint64 { + return 0 +} + +func (s *Segment) incrementBytesRead(uint64) {} + +func (s *SegmentBase) BytesWritten() uint64 { + return 0 +} + +func (s *SegmentBase) setBytesWritten(uint64) {} + +func (s *SegmentBase) BytesRead() uint64 { + return 0 +} + +func (s *SegmentBase) ResetBytesRead(uint64) {} + +func (s *SegmentBase) incrementBytesRead(uint64) {} + +func (s *SegmentBase) loadFields() error { + // NOTE for now we assume the fields index immediately precedes + // the footer, and if this changes, need to adjust accordingly (or + // store explicit length), where s.mem was sliced from s.mm in Open(). + fieldsIndexEnd := uint64(len(s.mem)) + + // iterate through fields index + var fieldID uint64 + for s.fieldsIndexOffset+(8*fieldID) < fieldsIndexEnd { + addr := binary.BigEndian.Uint64(s.mem[s.fieldsIndexOffset+(8*fieldID) : s.fieldsIndexOffset+(8*fieldID)+8]) + + dictLoc, read := binary.Uvarint(s.mem[addr:fieldsIndexEnd]) + n := uint64(read) + s.dictLocs = append(s.dictLocs, dictLoc) + + var nameLen uint64 + nameLen, read = binary.Uvarint(s.mem[addr+n : fieldsIndexEnd]) + n += uint64(read) + + name := string(s.mem[addr+n : addr+n+nameLen]) + s.fieldsInv = append(s.fieldsInv, name) + s.fieldsMap[name] = uint16(fieldID + 1) + + fieldID++ + } + return nil +} + +// Dictionary returns the term dictionary for the specified field +func (s *SegmentBase) Dictionary(field string) (segment.TermDictionary, error) { + dict, err := s.dictionary(field) + if err == nil && dict == nil { + return emptyDictionary, nil + } + return dict, err +} + +func (sb *SegmentBase) dictionary(field string) (rv *Dictionary, err error) { + fieldIDPlus1 := sb.fieldsMap[field] + if fieldIDPlus1 > 0 { + rv = &Dictionary{ + sb: sb, + field: field, + fieldID: fieldIDPlus1 - 1, + } + + dictStart := sb.dictLocs[rv.fieldID] + if dictStart > 0 { + var ok bool + sb.m.Lock() + if rv.fst, ok = sb.fieldFSTs[rv.fieldID]; !ok { + // read the length of the vellum data + vellumLen, read := binary.Uvarint(sb.mem[dictStart : dictStart+binary.MaxVarintLen64]) + fstBytes := sb.mem[dictStart+uint64(read) : dictStart+uint64(read)+vellumLen] + rv.fst, err = vellum.Load(fstBytes) + if err != nil { + sb.m.Unlock() + return nil, fmt.Errorf("dictionary field %s vellum err: %v", field, err) + } + + sb.fieldFSTs[rv.fieldID] = rv.fst + } + + sb.m.Unlock() + rv.fstReader, err = rv.fst.Reader() + if err != nil { + return nil, fmt.Errorf("dictionary field %s vellum reader err: %v", field, err) + } + } + } + + return rv, nil +} + +// visitDocumentCtx holds data structures that are reusable across +// multiple VisitDocument() calls to avoid memory allocations +type visitDocumentCtx struct { + buf []byte + reader bytes.Reader + arrayPos []uint64 +} + +var visitDocumentCtxPool = sync.Pool{ + New: func() interface{} { + reuse := &visitDocumentCtx{} + return reuse + }, +} + +// VisitStoredFields invokes the StoredFieldValueVisitor for each stored field +// for the specified doc number +func (s *SegmentBase) VisitStoredFields(num uint64, visitor segment.StoredFieldValueVisitor) error { + vdc := visitDocumentCtxPool.Get().(*visitDocumentCtx) + defer visitDocumentCtxPool.Put(vdc) + return s.visitStoredFields(vdc, num, visitor) +} + +func (s *SegmentBase) visitStoredFields(vdc *visitDocumentCtx, num uint64, + visitor segment.StoredFieldValueVisitor) error { + // first make sure this is a valid number in this segment + if num < s.numDocs { + meta, compressed := s.getDocStoredMetaAndCompressed(num) + + vdc.reader.Reset(meta) + + // handle _id field special case + idFieldValLen, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + idFieldVal := compressed[:idFieldValLen] + + keepGoing := visitor("_id", byte('t'), idFieldVal, nil) + if !keepGoing { + visitDocumentCtxPool.Put(vdc) + return nil + } + + // handle non-"_id" fields + compressed = compressed[idFieldValLen:] + + uncompressed, err := snappy.Decode(vdc.buf[:cap(vdc.buf)], compressed) + if err != nil { + return err + } + + for keepGoing { + field, err := binary.ReadUvarint(&vdc.reader) + if err == io.EOF { + break + } + if err != nil { + return err + } + typ, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + offset, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + l, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + numap, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + var arrayPos []uint64 + if numap > 0 { + if cap(vdc.arrayPos) < int(numap) { + vdc.arrayPos = make([]uint64, numap) + } + arrayPos = vdc.arrayPos[:numap] + for i := 0; i < int(numap); i++ { + ap, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + arrayPos[i] = ap + } + } + + value := uncompressed[offset : offset+l] + keepGoing = visitor(s.fieldsInv[field], byte(typ), value, arrayPos) + } + + vdc.buf = uncompressed + } + return nil +} + +// DocID returns the value of the _id field for the given docNum +func (s *SegmentBase) DocID(num uint64) ([]byte, error) { + if num >= s.numDocs { + return nil, nil + } + + vdc := visitDocumentCtxPool.Get().(*visitDocumentCtx) + + meta, compressed := s.getDocStoredMetaAndCompressed(num) + + vdc.reader.Reset(meta) + + // handle _id field special case + idFieldValLen, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return nil, err + } + idFieldVal := compressed[:idFieldValLen] + + visitDocumentCtxPool.Put(vdc) + + return idFieldVal, nil +} + +// Count returns the number of documents in this segment. +func (s *SegmentBase) Count() uint64 { + return s.numDocs +} + +// DocNumbers returns a bitset corresponding to the doc numbers of all the +// provided _id strings +func (s *SegmentBase) DocNumbers(ids []string) (*roaring.Bitmap, error) { + rv := roaring.New() + + if len(s.fieldsMap) > 0 { + idDict, err := s.dictionary("_id") + if err != nil { + return nil, err + } + + postingsList := emptyPostingsList + + sMax, err := idDict.fst.GetMaxKey() + if err != nil { + return nil, err + } + sMaxStr := string(sMax) + filteredIds := make([]string, 0, len(ids)) + for _, id := range ids { + if id <= sMaxStr { + filteredIds = append(filteredIds, id) + } + } + + for _, id := range filteredIds { + postingsList, err = idDict.postingsList([]byte(id), nil, postingsList) + if err != nil { + return nil, err + } + postingsList.OrInto(rv) + } + } + + return rv, nil +} + +// Fields returns the field names used in this segment +func (s *SegmentBase) Fields() []string { + return s.fieldsInv +} + +// Path returns the path of this segment on disk +func (s *Segment) Path() string { + return s.path +} + +// Close releases all resources associated with this segment +func (s *Segment) Close() (err error) { + return s.DecRef() +} + +func (s *Segment) closeActual() (err error) { + if s.mm != nil { + err = s.mm.Unmap() + } + // try to close file even if unmap failed + if s.f != nil { + err2 := s.f.Close() + if err == nil { + // try to return first error + err = err2 + } + } + return +} + +// some helpers i started adding for the command-line utility + +// Data returns the underlying mmaped data slice +func (s *Segment) Data() []byte { + return s.mm +} + +// CRC returns the CRC value stored in the file footer +func (s *Segment) CRC() uint32 { + return s.crc +} + +// Version returns the file version in the file footer +func (s *Segment) Version() uint32 { + return s.version +} + +// ChunkFactor returns the chunk factor in the file footer +func (s *Segment) ChunkMode() uint32 { + return s.chunkMode +} + +// FieldsIndexOffset returns the fields index offset in the file footer +func (s *Segment) FieldsIndexOffset() uint64 { + return s.fieldsIndexOffset +} + +// StoredIndexOffset returns the stored value index offset in the file footer +func (s *Segment) StoredIndexOffset() uint64 { + return s.storedIndexOffset +} + +// DocValueOffset returns the docValue offset in the file footer +func (s *Segment) DocValueOffset() uint64 { + return s.docValueOffset +} + +// NumDocs returns the number of documents in the file footer +func (s *Segment) NumDocs() uint64 { + return s.numDocs +} + +// DictAddr is a helper function to compute the file offset where the +// dictionary is stored for the specified field. +func (s *Segment) DictAddr(field string) (uint64, error) { + fieldIDPlus1, ok := s.fieldsMap[field] + if !ok { + return 0, fmt.Errorf("no such field '%s'", field) + } + + return s.dictLocs[fieldIDPlus1-1], nil +} + +func (s *SegmentBase) loadDvReaders() error { + if s.docValueOffset == fieldNotUninverted || s.numDocs == 0 { + return nil + } + + var read uint64 + for fieldID, field := range s.fieldsInv { + var fieldLocStart, fieldLocEnd uint64 + var n int + fieldLocStart, n = binary.Uvarint(s.mem[s.docValueOffset+read : s.docValueOffset+read+binary.MaxVarintLen64]) + if n <= 0 { + return fmt.Errorf("loadDvReaders: failed to read the docvalue offset start for field %d", fieldID) + } + read += uint64(n) + fieldLocEnd, n = binary.Uvarint(s.mem[s.docValueOffset+read : s.docValueOffset+read+binary.MaxVarintLen64]) + if n <= 0 { + return fmt.Errorf("loadDvReaders: failed to read the docvalue offset end for field %d", fieldID) + } + read += uint64(n) + + fieldDvReader, err := s.loadFieldDocValueReader(field, fieldLocStart, fieldLocEnd) + if err != nil { + return err + } + if fieldDvReader != nil { + s.fieldDvReaders[uint16(fieldID)] = fieldDvReader + s.fieldDvNames = append(s.fieldDvNames, field) + } + } + + return nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/sizes.go b/backend/vendor/github.com/blevesearch/zapx/v13/sizes.go new file mode 100644 index 0000000000..34166ea330 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/sizes.go @@ -0,0 +1,59 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "reflect" +) + +func init() { + var b bool + SizeOfBool = int(reflect.TypeOf(b).Size()) + var f32 float32 + SizeOfFloat32 = int(reflect.TypeOf(f32).Size()) + var f64 float64 + SizeOfFloat64 = int(reflect.TypeOf(f64).Size()) + var i int + SizeOfInt = int(reflect.TypeOf(i).Size()) + var m map[int]int + SizeOfMap = int(reflect.TypeOf(m).Size()) + var ptr *int + SizeOfPtr = int(reflect.TypeOf(ptr).Size()) + var slice []int + SizeOfSlice = int(reflect.TypeOf(slice).Size()) + var str string + SizeOfString = int(reflect.TypeOf(str).Size()) + var u8 uint8 + SizeOfUint8 = int(reflect.TypeOf(u8).Size()) + var u16 uint16 + SizeOfUint16 = int(reflect.TypeOf(u16).Size()) + var u32 uint32 + SizeOfUint32 = int(reflect.TypeOf(u32).Size()) + var u64 uint64 + SizeOfUint64 = int(reflect.TypeOf(u64).Size()) +} + +var SizeOfBool int +var SizeOfFloat32 int +var SizeOfFloat64 int +var SizeOfInt int +var SizeOfMap int +var SizeOfPtr int +var SizeOfSlice int +var SizeOfString int +var SizeOfUint8 int +var SizeOfUint16 int +var SizeOfUint32 int +var SizeOfUint64 int diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/write.go b/backend/vendor/github.com/blevesearch/zapx/v13/write.go new file mode 100644 index 0000000000..77aefdbfc8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/write.go @@ -0,0 +1,145 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "encoding/binary" + "io" + + "github.com/RoaringBitmap/roaring" +) + +// writes out the length of the roaring bitmap in bytes as varint +// then writes out the roaring bitmap itself +func writeRoaringWithLen(r *roaring.Bitmap, w io.Writer, + reuseBufVarint []byte) (int, error) { + buf, err := r.ToBytes() + if err != nil { + return 0, err + } + + var tw int + + // write out the length + n := binary.PutUvarint(reuseBufVarint, uint64(len(buf))) + nw, err := w.Write(reuseBufVarint[:n]) + tw += nw + if err != nil { + return tw, err + } + + // write out the roaring bytes + nw, err = w.Write(buf) + tw += nw + if err != nil { + return tw, err + } + + return tw, nil +} + +func persistFields(fieldsInv []string, w *CountHashWriter, dictLocs []uint64) (uint64, error) { + var rv uint64 + var fieldsOffsets []uint64 + + for fieldID, fieldName := range fieldsInv { + // record start of this field + fieldsOffsets = append(fieldsOffsets, uint64(w.Count())) + + // write out the dict location and field name length + _, err := writeUvarints(w, dictLocs[fieldID], uint64(len(fieldName))) + if err != nil { + return 0, err + } + + // write out the field name + _, err = w.Write([]byte(fieldName)) + if err != nil { + return 0, err + } + } + + // now write out the fields index + rv = uint64(w.Count()) + for fieldID := range fieldsInv { + err := binary.Write(w, binary.BigEndian, fieldsOffsets[fieldID]) + if err != nil { + return 0, err + } + } + + return rv, nil +} + +// FooterSize is the size of the footer record in bytes +// crc + ver + chunk + field offset + stored offset + num docs + docValueOffset +const FooterSize = 4 + 4 + 4 + 8 + 8 + 8 + 8 + +func persistFooter(numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset uint64, + chunkMode uint32, crcBeforeFooter uint32, writerIn io.Writer) error { + w := NewCountHashWriter(writerIn) + w.crc = crcBeforeFooter + + // write out the number of docs + err := binary.Write(w, binary.BigEndian, numDocs) + if err != nil { + return err + } + // write out the stored field index location: + err = binary.Write(w, binary.BigEndian, storedIndexOffset) + if err != nil { + return err + } + // write out the field index location + err = binary.Write(w, binary.BigEndian, fieldsIndexOffset) + if err != nil { + return err + } + // write out the fieldDocValue location + err = binary.Write(w, binary.BigEndian, docValueOffset) + if err != nil { + return err + } + // write out 32-bit chunk factor + err = binary.Write(w, binary.BigEndian, chunkMode) + if err != nil { + return err + } + // write out 32-bit version + err = binary.Write(w, binary.BigEndian, Version) + if err != nil { + return err + } + // write out CRC-32 of everything upto but not including this CRC + err = binary.Write(w, binary.BigEndian, w.crc) + if err != nil { + return err + } + return nil +} + +func writeUvarints(w io.Writer, vals ...uint64) (tw int, err error) { + buf := make([]byte, binary.MaxVarintLen64) + for _, val := range vals { + n := binary.PutUvarint(buf, val) + var nw int + nw, err = w.Write(buf[:n]) + tw += nw + if err != nil { + return tw, err + } + } + return tw, err +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v13/zap.md b/backend/vendor/github.com/blevesearch/zapx/v13/zap.md new file mode 100644 index 0000000000..d74dc548b8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v13/zap.md @@ -0,0 +1,177 @@ +# ZAP File Format + +## Legend + +### Sections + + |========| + | | section + |========| + +### Fixed-size fields + + |--------| |----| |--| |-| + | | uint64 | | uint32 | | uint16 | | uint8 + |--------| |----| |--| |-| + +### Varints + + |~~~~~~~~| + | | varint(up to uint64) + |~~~~~~~~| + +### Arbitrary-length fields + + |--------...---| + | | arbitrary-length field (string, vellum, roaring bitmap) + |--------...---| + +### Chunked data + + [--------] + [ ] + [--------] + +## Overview + +Footer section describes the configuration of particular ZAP file. The format of footer is version-dependent, so it is necessary to check `V` field before the parsing. + + |==================================================| + | Stored Fields | + |==================================================| + |-----> | Stored Fields Index | + | |==================================================| + | | Dictionaries + Postings + DocValues | + | |==================================================| + | |---> | DocValues Index | + | | |==================================================| + | | | Fields | + | | |==================================================| + | | |-> | Fields Index | + | | | |========|========|========|========|====|====|====| + | | | | D# | SF | F | FDV | CF | V | CC | (Footer) + | | | |========|====|===|====|===|====|===|====|====|====| + | | | | | | + |-+-+-----------------| | | + | |--------------------------| | + |-------------------------------------| + + D#. Number of Docs. + SF. Stored Fields Index Offset. + F. Field Index Offset. + FDV. Field DocValue Offset. + CF. Chunk Factor. + V. Version. + CC. CRC32. + +## Stored Fields + +Stored Fields Index is `D#` consecutive 64-bit unsigned integers - offsets, where relevant Stored Fields Data records are located. + + 0 [SF] [SF + D# * 8] + | Stored Fields | Stored Fields Index | + |================================|==================================| + | | | + | |--------------------| ||--------|--------|. . .|--------|| + | |-> | Stored Fields Data | || 0 | 1 | | D# - 1 || + | | |--------------------| ||--------|----|---|. . .|--------|| + | | | | | + |===|============================|==============|===================| + | | + |-------------------------------------------| + +Stored Fields Data is an arbitrary size record, which consists of metadata and [Snappy](https://github.com/golang/snappy)-compressed data. + + Stored Fields Data + |~~~~~~~~|~~~~~~~~|~~~~~~~~...~~~~~~~~|~~~~~~~~...~~~~~~~~| + | MDS | CDS | MD | CD | + |~~~~~~~~|~~~~~~~~|~~~~~~~~...~~~~~~~~|~~~~~~~~...~~~~~~~~| + + MDS. Metadata size. + CDS. Compressed data size. + MD. Metadata. + CD. Snappy-compressed data. + +## Fields + +Fields Index section located between addresses `F` and `len(file) - len(footer)` and consist of `uint64` values (`F1`, `F2`, ...) which are offsets to records in Fields section. We have `F# = (len(file) - len(footer) - F) / sizeof(uint64)` fields. + + + (...) [F] [F + F#] + | Fields | Fields Index. | + |================================|================================| + | | | + | |~~~~~~~~|~~~~~~~~|---...---|||--------|--------|...|--------|| + ||->| Dict | Length | Name ||| 0 | 1 | | F# - 1 || + || |~~~~~~~~|~~~~~~~~|---...---|||--------|----|---|...|--------|| + || | | | + ||===============================|==============|=================| + | | + |----------------------------------------------| + + +## Dictionaries + Postings + +Each of fields has its own dictionary, encoded in [Vellum](https://github.com/couchbase/vellum) format. Dictionary consists of pairs `(term, offset)`, where `offset` indicates the position of postings (list of documents) for this particular term. + + |================================================================|- Dictionaries + + | | Postings + + | | DocValues + | Freq/Norm (chunked) | + | [~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] | + | |->[ Freq | Norm (float32 under varint) ] | + | | [~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] | + | | | + | |------------------------------------------------------------| | + | Location Details (chunked) | | + | [~~~~~~|~~~~~|~~~~~~~|~~~~~|~~~~~~|~~~~~~~~|~~~~~] | | + | |->[ Size | Pos | Start | End | Arr# | ArrPos | ... ] | | + | | [~~~~~~|~~~~~|~~~~~~~|~~~~~|~~~~~~|~~~~~~~~|~~~~~] | | + | | | | + | |----------------------| | | + | Postings List | | | + | |~~~~~~~~|~~~~~|~~|~~~~~~~~|-----------...--| | | + | |->| F/N | LD | Length | ROARING BITMAP | | | + | | |~~~~~|~~|~~~~~~~~|~~~~~~~~|-----------...--| | | + | | |----------------------------------------------| | + | |--------------------------------------| | + | Dictionary | | + | |~~~~~~~~|--------------------------|-...-| | + | |->| Length | VELLUM DATA : (TERM -> OFFSET) | | + | | |~~~~~~~~|----------------------------...-| | + | | | + |======|=========================================================|- DocValues Index + | | | + |======|=========================================================|- Fields + | | | + | |~~~~|~~~|~~~~~~~~|---...---| | + | | Dict | Length | Name | | + | |~~~~~~~~|~~~~~~~~|---...---| | + | | + |================================================================| + +## DocValues + +DocValues Index is `F#` pairs of varints, one pair per field. Each pair of varints indicates start and end point of DocValues slice. + + |================================================================| + | |------...--| | + | |->| DocValues |<-| | + | | |------...--| | | + |==|=================|===========================================|- DocValues Index + ||~|~~~~~~~~~|~~~~~~~|~~| |~~~~~~~~~~~~~~|~~~~~~~~~~~~|| + || DV1 START | DV1 STOP | . . . . . | DV(F#) START | DV(F#) END || + ||~~~~~~~~~~~|~~~~~~~~~~| |~~~~~~~~~~~~~~|~~~~~~~~~~~~|| + |================================================================| + +DocValues is chunked Snappy-compressed values for each document and field. + + [~~~~~~~~~~~~~~~|~~~~~~|~~~~~~~~~|-...-|~~~~~~|~~~~~~~~~|--------------------...-] + [ Doc# in Chunk | Doc1 | Offset1 | ... | DocN | OffsetN | SNAPPY COMPRESSED DATA ] + [~~~~~~~~~~~~~~~|~~~~~~|~~~~~~~~~|-...-|~~~~~~|~~~~~~~~~|--------------------...-] + +Last 16 bytes are description of chunks. + + |~~~~~~~~~~~~...~|----------------|----------------| + | Chunk Sizes | Chunk Size Arr | Chunk# | + |~~~~~~~~~~~~...~|----------------|----------------| diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/.gitignore b/backend/vendor/github.com/blevesearch/zapx/v14/.gitignore new file mode 100644 index 0000000000..46d1cfad54 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/.gitignore @@ -0,0 +1,12 @@ +#* +*.sublime-* +*~ +.#* +.project +.settings +**/.idea/ +**/*.iml +.DS_Store +/cmd/zap/zap +*.test +tags diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/.golangci.yml b/backend/vendor/github.com/blevesearch/zapx/v14/.golangci.yml new file mode 100644 index 0000000000..1d55bfc00d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/.golangci.yml @@ -0,0 +1,28 @@ +linters: + # please, do not use `enable-all`: it's deprecated and will be removed soon. + # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint + disable-all: true + enable: + - bodyclose + - deadcode + - depguard + - dupl + - errcheck + - gofmt + - goimports + - goprintffuncname + - gosec + - gosimple + - govet + - ineffassign + - misspell + - nakedret + - nolintlint + - rowserrcheck + - staticcheck + - structcheck + - typecheck + - unused + - varcheck + - whitespace + diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/LICENSE b/backend/vendor/github.com/blevesearch/zapx/v14/LICENSE new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/README.md b/backend/vendor/github.com/blevesearch/zapx/v14/README.md new file mode 100644 index 0000000000..4cbf1a145b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/README.md @@ -0,0 +1,163 @@ +# zapx file format + +The zapx module is fork of [zap](https://github.com/blevesearch/zap) module which maintains file format compatibility, but removes dependency on bleve, and instead depends only on the indepenent interface modules: + +- [bleve_index_api](https://github.com/blevesearch/scorch_segment_api) +- [scorch_segment_api](https://github.com/blevesearch/scorch_segment_api) + +Advanced ZAP File Format Documentation is [here](zap.md). + +The file is written in the reverse order that we typically access data. This helps us write in one pass since later sections of the file require file offsets of things we've already written. + +Current usage: + +- mmap the entire file +- crc-32 bytes and version are in fixed position at end of the file +- reading remainder of footer could be version specific +- remainder of footer gives us: + - 3 important offsets (docValue , fields index and stored data index) + - 2 important values (number of docs and chunk factor) +- field data is processed once and memoized onto the heap so that we never have to go back to disk for it +- access to stored data by doc number means first navigating to the stored data index, then accessing a fixed position offset into that slice, which gives us the actual address of the data. the first bytes of that section tell us the size of data so that we know where it ends. +- access to all other indexed data follows the following pattern: + - first know the field name -> convert to id + - next navigate to term dictionary for that field + - some operations stop here and do dictionary ops + - next use dictionary to navigate to posting list for a specific term + - walk posting list + - if necessary, walk posting details as we go + - if location info is desired, consult location bitmap to see if it is there + +## stored fields section + +- for each document + - preparation phase: + - produce a slice of metadata bytes and data bytes + - produce these slices in field id order + - field value is appended to the data slice + - metadata slice is varint encoded with the following values for each field value + - field id (uint16) + - field type (byte) + - field value start offset in uncompressed data slice (uint64) + - field value length (uint64) + - field number of array positions (uint64) + - one additional value for each array position (uint64) + - compress the data slice using snappy + - file writing phase: + - remember the start offset for this document + - write out meta data length (varint uint64) + - write out compressed data length (varint uint64) + - write out the metadata bytes + - write out the compressed data bytes + +## stored fields idx + +- for each document + - write start offset (remembered from previous section) of stored data (big endian uint64) + +With this index and a known document number, we have direct access to all the stored field data. + +## posting details (freq/norm) section + +- for each posting list + - produce a slice containing multiple consecutive chunks (each chunk is varint stream) + - produce a slice remembering offsets of where each chunk starts + - preparation phase: + - for each hit in the posting list + - if this hit is in next chunk close out encoding of last chunk and record offset start of next + - encode term frequency (uint64) + - encode norm factor (float32) + - file writing phase: + - remember start position for this posting list details + - write out number of chunks that follow (varint uint64) + - write out length of each chunk (each a varint uint64) + - write out the byte slice containing all the chunk data + +If you know the doc number you're interested in, this format lets you jump to the correct chunk (docNum/chunkFactor) directly and then seek within that chunk until you find it. + +## posting details (location) section + +- for each posting list + - produce a slice containing multiple consecutive chunks (each chunk is varint stream) + - produce a slice remembering offsets of where each chunk starts + - preparation phase: + - for each hit in the posting list + - if this hit is in next chunk close out encoding of last chunk and record offset start of next + - encode field (uint16) + - encode field pos (uint64) + - encode field start (uint64) + - encode field end (uint64) + - encode number of array positions to follow (uint64) + - encode each array position (each uint64) + - file writing phase: + - remember start position for this posting list details + - write out number of chunks that follow (varint uint64) + - write out length of each chunk (each a varint uint64) + - write out the byte slice containing all the chunk data + +If you know the doc number you're interested in, this format lets you jump to the correct chunk (docNum/chunkFactor) directly and then seek within that chunk until you find it. + +## postings list section + +- for each posting list + - preparation phase: + - encode roaring bitmap posting list to bytes (so we know the length) + - file writing phase: + - remember the start position for this posting list + - write freq/norm details offset (remembered from previous, as varint uint64) + - write location details offset (remembered from previous, as varint uint64) + - write length of encoded roaring bitmap + - write the serialized roaring bitmap data + +## dictionary + +- for each field + - preparation phase: + - encode vellum FST with dictionary data pointing to file offset of posting list (remembered from previous) + - file writing phase: + - remember the start position of this persistDictionary + - write length of vellum data (varint uint64) + - write out vellum data + +## fields section + +- for each field + - file writing phase: + - remember start offset for each field + - write dictionary address (remembered from previous) (varint uint64) + - write length of field name (varint uint64) + - write field name bytes + +## fields idx + +- for each field + - file writing phase: + - write big endian uint64 of start offset for each field + +NOTE: currently we don't know or record the length of this fields index. Instead we rely on the fact that we know it immediately precedes a footer of known size. + +## fields DocValue + +- for each field + - preparation phase: + - produce a slice containing multiple consecutive chunks, where each chunk is composed of a meta section followed by compressed columnar field data + - produce a slice remembering the length of each chunk + - file writing phase: + - remember the start position of this first field DocValue offset in the footer + - write out number of chunks that follow (varint uint64) + - write out length of each chunk (each a varint uint64) + - write out the byte slice containing all the chunk data + +NOTE: currently the meta header inside each chunk gives clue to the location offsets and size of the data pertaining to a given docID and any +read operation leverage that meta information to extract the document specific data from the file. + +## footer + +- file writing phase + - write number of docs (big endian uint64) + - write stored field index location (big endian uint64) + - write field index location (big endian uint64) + - write field docValue location (big endian uint64) + - write out chunk factor (big endian uint32) + - write out version (big endian uint32) + - write out file CRC of everything preceding this (big endian uint32) diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/build.go b/backend/vendor/github.com/blevesearch/zapx/v14/build.go new file mode 100644 index 0000000000..b36878abbb --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/build.go @@ -0,0 +1,186 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bufio" + "fmt" + "io" + "math" + "os" + + "github.com/blevesearch/vellum" +) + +const Version uint32 = 14 + +const Type string = "zap" + +const fieldNotUninverted = math.MaxUint64 + +func (sb *SegmentBase) Persist(path string) error { + return PersistSegmentBase(sb, path) +} + +// WriteTo is an implementation of io.WriterTo interface. +func (sb *SegmentBase) WriteTo(w io.Writer) (int64, error) { + if w == nil { + return 0, fmt.Errorf("invalid writer found") + } + + n, err := persistSegmentBaseToWriter(sb, w) + return int64(n), err +} + +// PersistSegmentBase persists SegmentBase in the zap file format. +func PersistSegmentBase(sb *SegmentBase, path string) error { + flag := os.O_RDWR | os.O_CREATE + + f, err := os.OpenFile(path, flag, 0600) + if err != nil { + return err + } + + cleanup := func() { + _ = f.Close() + _ = os.Remove(path) + } + + _, err = persistSegmentBaseToWriter(sb, f) + if err != nil { + cleanup() + return err + } + + err = f.Sync() + if err != nil { + cleanup() + return err + } + + err = f.Close() + if err != nil { + cleanup() + return err + } + + return err +} + +type bufWriter struct { + w *bufio.Writer + n int +} + +func (br *bufWriter) Write(in []byte) (int, error) { + n, err := br.w.Write(in) + br.n += n + return n, err +} + +func persistSegmentBaseToWriter(sb *SegmentBase, w io.Writer) (int, error) { + br := &bufWriter{w: bufio.NewWriter(w)} + + _, err := br.Write(sb.mem) + if err != nil { + return 0, err + } + + err = persistFooter(sb.numDocs, sb.storedIndexOffset, sb.fieldsIndexOffset, + sb.docValueOffset, sb.chunkMode, sb.memCRC, br) + if err != nil { + return 0, err + } + + err = br.w.Flush() + if err != nil { + return 0, err + } + + return br.n, nil +} + +func persistStoredFieldValues(fieldID int, + storedFieldValues [][]byte, stf []byte, spf [][]uint64, + curr int, metaEncode varintEncoder, data []byte) ( + int, []byte, error) { + for i := 0; i < len(storedFieldValues); i++ { + // encode field + _, err := metaEncode(uint64(fieldID)) + if err != nil { + return 0, nil, err + } + // encode type + _, err = metaEncode(uint64(stf[i])) + if err != nil { + return 0, nil, err + } + // encode start offset + _, err = metaEncode(uint64(curr)) + if err != nil { + return 0, nil, err + } + // end len + _, err = metaEncode(uint64(len(storedFieldValues[i]))) + if err != nil { + return 0, nil, err + } + // encode number of array pos + _, err = metaEncode(uint64(len(spf[i]))) + if err != nil { + return 0, nil, err + } + // encode all array positions + for _, pos := range spf[i] { + _, err = metaEncode(pos) + if err != nil { + return 0, nil, err + } + } + + data = append(data, storedFieldValues[i]...) + curr += len(storedFieldValues[i]) + } + + return curr, data, nil +} + +func InitSegmentBase(mem []byte, memCRC uint32, chunkMode uint32, + fieldsMap map[string]uint16, fieldsInv []string, numDocs uint64, + storedIndexOffset uint64, fieldsIndexOffset uint64, docValueOffset uint64, + dictLocs []uint64) (*SegmentBase, error) { + sb := &SegmentBase{ + mem: mem, + memCRC: memCRC, + chunkMode: chunkMode, + fieldsMap: fieldsMap, + fieldsInv: fieldsInv, + numDocs: numDocs, + storedIndexOffset: storedIndexOffset, + fieldsIndexOffset: fieldsIndexOffset, + docValueOffset: docValueOffset, + dictLocs: dictLocs, + fieldDvReaders: make(map[uint16]*docValueReader), + fieldFSTs: make(map[uint16]*vellum.FST), + } + sb.updateSize() + + err := sb.loadDvReaders() + if err != nil { + return nil, err + } + + return sb, nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/chunk.go b/backend/vendor/github.com/blevesearch/zapx/v14/chunk.go new file mode 100644 index 0000000000..4307d0ed29 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/chunk.go @@ -0,0 +1,67 @@ +// Copyright (c) 2019 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "fmt" +) + +// LegacyChunkMode was the original chunk mode (always chunk size 1024) +// this mode is still used for chunking doc values. +var LegacyChunkMode uint32 = 1024 + +// DefaultChunkMode is the most recent improvement to chunking and should +// be used by default. +var DefaultChunkMode uint32 = 1026 + +func getChunkSize(chunkMode uint32, cardinality uint64, maxDocs uint64) (uint64, error) { + switch { + // any chunkMode <= 1024 will always chunk with chunkSize=chunkMode + case chunkMode <= 1024: + // legacy chunk size + return uint64(chunkMode), nil + + case chunkMode == 1025: + // attempt at simple improvement + // theory - the point of chunking is to put a bound on the maximum number of + // calls to Next() needed to find a random document. ie, you should be able + // to do one jump to the correct chunk, and then walk through at most + // chunk-size items + // previously 1024 was chosen as the chunk size, but this is particularly + // wasteful for low cardinality terms. the observation is that if there + // are less than 1024 items, why not put them all in one chunk, + // this way you'll still achieve the same goal of visiting at most + // chunk-size items. + // no attempt is made to tweak any other case + if cardinality <= 1024 { + return maxDocs, nil + } + return 1024, nil + + case chunkMode == 1026: + // improve upon the ideas tested in chunkMode 1025 + // the observation that the fewest number of dense chunks is the most + // desirable layout, given the built-in assumptions of chunking + // (that we want to put an upper-bound on the number of items you must + // walk over without skipping, currently tuned to 1024) + // + // 1. compute the number of chunks needed (max 1024/chunk) + // 2. convert to chunkSize, dividing into maxDocs + numChunks := (cardinality / 1024) + 1 + chunkSize := maxDocs / numChunks + return chunkSize, nil + } + return 0, fmt.Errorf("unknown chunk mode %d", chunkMode) +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/contentcoder.go b/backend/vendor/github.com/blevesearch/zapx/v14/contentcoder.go new file mode 100644 index 0000000000..c145b5a113 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/contentcoder.go @@ -0,0 +1,243 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "io" + "reflect" + + "github.com/golang/snappy" +) + +var reflectStaticSizeMetaData int + +func init() { + var md MetaData + reflectStaticSizeMetaData = int(reflect.TypeOf(md).Size()) +} + +var termSeparator byte = 0xff +var termSeparatorSplitSlice = []byte{termSeparator} + +type chunkedContentCoder struct { + final []byte + chunkSize uint64 + currChunk uint64 + chunkLens []uint64 + + w io.Writer + progressiveWrite bool + + chunkMetaBuf bytes.Buffer + chunkBuf bytes.Buffer + + chunkMeta []MetaData + + compressed []byte // temp buf for snappy compression +} + +// MetaData represents the data information inside a +// chunk. +type MetaData struct { + DocNum uint64 // docNum of the data inside the chunk + DocDvOffset uint64 // offset of data inside the chunk for the given docid +} + +// newChunkedContentCoder returns a new chunk content coder which +// packs data into chunks based on the provided chunkSize +func newChunkedContentCoder(chunkSize uint64, maxDocNum uint64, + w io.Writer, progressiveWrite bool) *chunkedContentCoder { + total := maxDocNum/chunkSize + 1 + rv := &chunkedContentCoder{ + chunkSize: chunkSize, + chunkLens: make([]uint64, total), + chunkMeta: make([]MetaData, 0, total), + w: w, + progressiveWrite: progressiveWrite, + } + + return rv +} + +// Reset lets you reuse this chunked content coder. Buffers are reset +// and re used. You cannot change the chunk size. +func (c *chunkedContentCoder) Reset() { + c.currChunk = 0 + c.final = c.final[:0] + c.chunkBuf.Reset() + c.chunkMetaBuf.Reset() + for i := range c.chunkLens { + c.chunkLens[i] = 0 + } + c.chunkMeta = c.chunkMeta[:0] +} + +func (c *chunkedContentCoder) SetChunkSize(chunkSize uint64, maxDocNum uint64) { + total := int(maxDocNum/chunkSize + 1) + c.chunkSize = chunkSize + if cap(c.chunkLens) < total { + c.chunkLens = make([]uint64, total) + } else { + c.chunkLens = c.chunkLens[:total] + } + if cap(c.chunkMeta) < total { + c.chunkMeta = make([]MetaData, 0, total) + } +} + +// Close indicates you are done calling Add() this allows +// the final chunk to be encoded. +func (c *chunkedContentCoder) Close() error { + return c.flushContents() +} + +func (c *chunkedContentCoder) flushContents() error { + // flush the contents, with meta information at first + buf := make([]byte, binary.MaxVarintLen64) + n := binary.PutUvarint(buf, uint64(len(c.chunkMeta))) + _, err := c.chunkMetaBuf.Write(buf[:n]) + if err != nil { + return err + } + + // write out the metaData slice + for _, meta := range c.chunkMeta { + _, err := writeUvarints(&c.chunkMetaBuf, meta.DocNum, meta.DocDvOffset) + if err != nil { + return err + } + } + + // write the metadata to final data + metaData := c.chunkMetaBuf.Bytes() + c.final = append(c.final, c.chunkMetaBuf.Bytes()...) + // write the compressed data to the final data + c.compressed = snappy.Encode(c.compressed[:cap(c.compressed)], c.chunkBuf.Bytes()) + c.final = append(c.final, c.compressed...) + + c.chunkLens[c.currChunk] = uint64(len(c.compressed) + len(metaData)) + + if c.progressiveWrite { + _, err := c.w.Write(c.final) + if err != nil { + return err + } + c.final = c.final[:0] + } + + return nil +} + +// Add encodes the provided byte slice into the correct chunk for the provided +// doc num. You MUST call Add() with increasing docNums. +func (c *chunkedContentCoder) Add(docNum uint64, vals []byte) error { + chunk := docNum / c.chunkSize + if chunk != c.currChunk { + // flush out the previous chunk details + err := c.flushContents() + if err != nil { + return err + } + // clearing the chunk specific meta for next chunk + c.chunkBuf.Reset() + c.chunkMetaBuf.Reset() + c.chunkMeta = c.chunkMeta[:0] + c.currChunk = chunk + } + + // get the starting offset for this doc + dvOffset := c.chunkBuf.Len() + dvSize, err := c.chunkBuf.Write(vals) + if err != nil { + return err + } + + c.chunkMeta = append(c.chunkMeta, MetaData{ + DocNum: docNum, + DocDvOffset: uint64(dvOffset + dvSize), + }) + return nil +} + +// Write commits all the encoded chunked contents to the provided writer. +// +// | ..... data ..... | chunk offsets (varints) +// | position of chunk offsets (uint64) | number of offsets (uint64) | +// +func (c *chunkedContentCoder) Write() (int, error) { + var tw int + + if c.final != nil { + // write out the data section first + nw, err := c.w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + } + + chunkOffsetsStart := uint64(tw) + + if cap(c.final) < binary.MaxVarintLen64 { + c.final = make([]byte, binary.MaxVarintLen64) + } else { + c.final = c.final[0:binary.MaxVarintLen64] + } + chunkOffsets := modifyLengthsToEndOffsets(c.chunkLens) + // write out the chunk offsets + for _, chunkOffset := range chunkOffsets { + n := binary.PutUvarint(c.final, chunkOffset) + nw, err := c.w.Write(c.final[:n]) + tw += nw + if err != nil { + return tw, err + } + } + + chunkOffsetsLen := uint64(tw) - chunkOffsetsStart + + c.final = c.final[0:8] + // write out the length of chunk offsets + binary.BigEndian.PutUint64(c.final, chunkOffsetsLen) + nw, err := c.w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + + // write out the number of chunks + binary.BigEndian.PutUint64(c.final, uint64(len(c.chunkLens))) + nw, err = c.w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + + c.final = c.final[:0] + + return tw, nil +} + +// ReadDocValueBoundary elicits the start, end offsets from a +// metaData header slice +func ReadDocValueBoundary(chunk int, metaHeaders []MetaData) (uint64, uint64) { + var start uint64 + if chunk > 0 { + start = metaHeaders[chunk-1].DocDvOffset + } + return start, metaHeaders[chunk].DocDvOffset +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/count.go b/backend/vendor/github.com/blevesearch/zapx/v14/count.go new file mode 100644 index 0000000000..b6135359fb --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/count.go @@ -0,0 +1,61 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "hash/crc32" + "io" + + segment "github.com/blevesearch/scorch_segment_api/v2" +) + +// CountHashWriter is a wrapper around a Writer which counts the number of +// bytes which have been written and computes a crc32 hash +type CountHashWriter struct { + w io.Writer + crc uint32 + n int + s segment.StatsReporter +} + +// NewCountHashWriter returns a CountHashWriter which wraps the provided Writer +func NewCountHashWriter(w io.Writer) *CountHashWriter { + return &CountHashWriter{w: w} +} + +func NewCountHashWriterWithStatsReporter(w io.Writer, s segment.StatsReporter) *CountHashWriter { + return &CountHashWriter{w: w, s: s} +} + +// Write writes the provided bytes to the wrapped writer and counts the bytes +func (c *CountHashWriter) Write(b []byte) (int, error) { + n, err := c.w.Write(b) + c.crc = crc32.Update(c.crc, crc32.IEEETable, b[:n]) + c.n += n + if c.s != nil { + c.s.ReportBytesWritten(uint64(n)) + } + return n, err +} + +// Count returns the number of bytes written +func (c *CountHashWriter) Count() int { + return c.n +} + +// Sum32 returns the CRC-32 hash of the content written to this writer +func (c *CountHashWriter) Sum32() uint32 { + return c.crc +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/dict.go b/backend/vendor/github.com/blevesearch/zapx/v14/dict.go new file mode 100644 index 0000000000..e30bf2420d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/dict.go @@ -0,0 +1,158 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "fmt" + + "github.com/RoaringBitmap/roaring" + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" +) + +// Dictionary is the zap representation of the term dictionary +type Dictionary struct { + sb *SegmentBase + field string + fieldID uint16 + fst *vellum.FST + fstReader *vellum.Reader +} + +// represents an immutable, empty dictionary +var emptyDictionary = &Dictionary{} + +// PostingsList returns the postings list for the specified term +func (d *Dictionary) PostingsList(term []byte, except *roaring.Bitmap, + prealloc segment.PostingsList) (segment.PostingsList, error) { + var preallocPL *PostingsList + pl, ok := prealloc.(*PostingsList) + if ok && pl != nil { + preallocPL = pl + } + return d.postingsList(term, except, preallocPL) +} + +func (d *Dictionary) postingsList(term []byte, except *roaring.Bitmap, rv *PostingsList) (*PostingsList, error) { + if d.fstReader == nil { + if rv == nil || rv == emptyPostingsList { + return emptyPostingsList, nil + } + return d.postingsListInit(rv, except), nil + } + + postingsOffset, exists, err := d.fstReader.Get(term) + if err != nil { + return nil, fmt.Errorf("vellum err: %v", err) + } + if !exists { + if rv == nil || rv == emptyPostingsList { + return emptyPostingsList, nil + } + return d.postingsListInit(rv, except), nil + } + + return d.postingsListFromOffset(postingsOffset, except, rv) +} + +func (d *Dictionary) postingsListFromOffset(postingsOffset uint64, except *roaring.Bitmap, rv *PostingsList) (*PostingsList, error) { + rv = d.postingsListInit(rv, except) + + err := rv.read(postingsOffset, d) + if err != nil { + return nil, err + } + + return rv, nil +} + +func (d *Dictionary) postingsListInit(rv *PostingsList, except *roaring.Bitmap) *PostingsList { + if rv == nil || rv == emptyPostingsList { + rv = &PostingsList{} + } else { + postings := rv.postings + if postings != nil { + postings.Clear() + } + + *rv = PostingsList{} // clear the struct + + rv.postings = postings + } + rv.sb = d.sb + rv.except = except + return rv +} + +func (d *Dictionary) Contains(key []byte) (bool, error) { + if d.fst != nil { + return d.fst.Contains(key) + } + return false, nil +} + +// AutomatonIterator returns an iterator which only visits terms +// having the the vellum automaton and start/end key range +func (d *Dictionary) AutomatonIterator(a segment.Automaton, + startKeyInclusive, endKeyExclusive []byte) segment.DictionaryIterator { + if d.fst != nil { + rv := &DictionaryIterator{ + d: d, + } + + itr, err := d.fst.Search(a, startKeyInclusive, endKeyExclusive) + if err == nil { + rv.itr = itr + } else if err != vellum.ErrIteratorDone { + rv.err = err + } + + return rv + } + return emptyDictionaryIterator +} + +// DictionaryIterator is an iterator for term dictionary +type DictionaryIterator struct { + d *Dictionary + itr vellum.Iterator + err error + tmp PostingsList + entry index.DictEntry + omitCount bool +} + +var emptyDictionaryIterator = &DictionaryIterator{} + +// Next returns the next entry in the dictionary +func (i *DictionaryIterator) Next() (*index.DictEntry, error) { + if i.err != nil && i.err != vellum.ErrIteratorDone { + return nil, i.err + } else if i.itr == nil || i.err == vellum.ErrIteratorDone { + return nil, nil + } + term, postingsOffset := i.itr.Current() + i.entry.Term = string(term) + if !i.omitCount { + i.err = i.tmp.read(postingsOffset, i.d) + if i.err != nil { + return nil, i.err + } + i.entry.Count = i.tmp.Count() + } + i.err = i.itr.Next() + return &i.entry, nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/docvalues.go b/backend/vendor/github.com/blevesearch/zapx/v14/docvalues.go new file mode 100644 index 0000000000..a36485c870 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/docvalues.go @@ -0,0 +1,323 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "fmt" + "math" + "reflect" + "sort" + + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/golang/snappy" +) + +var reflectStaticSizedocValueReader int + +func init() { + var dvi docValueReader + reflectStaticSizedocValueReader = int(reflect.TypeOf(dvi).Size()) +} + +type docNumTermsVisitor func(docNum uint64, terms []byte) error + +type docVisitState struct { + dvrs map[uint16]*docValueReader + segment *SegmentBase +} + +// No-op implementations for DiskStatsReporter interface. +// Supported only in v15 +func (d *docVisitState) BytesRead() uint64 { + return 0 +} + +func (d *docVisitState) BytesWritten() uint64 { + return 0 +} + +func (d *docVisitState) ResetBytesRead(val uint64) {} + +type docValueReader struct { + field string + curChunkNum uint64 + chunkOffsets []uint64 + dvDataLoc uint64 + curChunkHeader []MetaData + curChunkData []byte // compressed data cache + uncompressed []byte // temp buf for snappy decompression +} + +func (di *docValueReader) size() int { + return reflectStaticSizedocValueReader + SizeOfPtr + + len(di.field) + + len(di.chunkOffsets)*SizeOfUint64 + + len(di.curChunkHeader)*reflectStaticSizeMetaData + + len(di.curChunkData) +} + +func (di *docValueReader) cloneInto(rv *docValueReader) *docValueReader { + if rv == nil { + rv = &docValueReader{} + } + + rv.field = di.field + rv.curChunkNum = math.MaxUint64 + rv.chunkOffsets = di.chunkOffsets // immutable, so it's sharable + rv.dvDataLoc = di.dvDataLoc + rv.curChunkHeader = rv.curChunkHeader[:0] + rv.curChunkData = nil + rv.uncompressed = rv.uncompressed[:0] + + return rv +} + +func (di *docValueReader) curChunkNumber() uint64 { + return di.curChunkNum +} + +func (s *SegmentBase) loadFieldDocValueReader(field string, + fieldDvLocStart, fieldDvLocEnd uint64) (*docValueReader, error) { + // get the docValue offset for the given fields + if fieldDvLocStart == fieldNotUninverted { + // no docValues found, nothing to do + return nil, nil + } + + // read the number of chunks, and chunk offsets position + var numChunks, chunkOffsetsPosition uint64 + + if fieldDvLocEnd-fieldDvLocStart > 16 { + numChunks = binary.BigEndian.Uint64(s.mem[fieldDvLocEnd-8 : fieldDvLocEnd]) + // read the length of chunk offsets + chunkOffsetsLen := binary.BigEndian.Uint64(s.mem[fieldDvLocEnd-16 : fieldDvLocEnd-8]) + // acquire position of chunk offsets + chunkOffsetsPosition = (fieldDvLocEnd - 16) - chunkOffsetsLen + } else { + return nil, fmt.Errorf("loadFieldDocValueReader: fieldDvLoc too small: %d-%d", fieldDvLocEnd, fieldDvLocStart) + } + + fdvIter := &docValueReader{ + curChunkNum: math.MaxUint64, + field: field, + chunkOffsets: make([]uint64, int(numChunks)), + } + + // read the chunk offsets + var offset uint64 + for i := 0; i < int(numChunks); i++ { + loc, read := binary.Uvarint(s.mem[chunkOffsetsPosition+offset : chunkOffsetsPosition+offset+binary.MaxVarintLen64]) + if read <= 0 { + return nil, fmt.Errorf("corrupted chunk offset during segment load") + } + fdvIter.chunkOffsets[i] = loc + offset += uint64(read) + } + + // set the data offset + fdvIter.dvDataLoc = fieldDvLocStart + + return fdvIter, nil +} + +func (di *docValueReader) loadDvChunk(chunkNumber uint64, s *SegmentBase) error { + // advance to the chunk where the docValues + // reside for the given docNum + destChunkDataLoc, curChunkEnd := di.dvDataLoc, di.dvDataLoc + start, end := readChunkBoundary(int(chunkNumber), di.chunkOffsets) + if start >= end { + di.curChunkHeader = di.curChunkHeader[:0] + di.curChunkData = nil + di.curChunkNum = chunkNumber + di.uncompressed = di.uncompressed[:0] + return nil + } + + destChunkDataLoc += start + curChunkEnd += end + + // read the number of docs reside in the chunk + numDocs, read := binary.Uvarint(s.mem[destChunkDataLoc : destChunkDataLoc+binary.MaxVarintLen64]) + if read <= 0 { + return fmt.Errorf("failed to read the chunk") + } + chunkMetaLoc := destChunkDataLoc + uint64(read) + + offset := uint64(0) + if cap(di.curChunkHeader) < int(numDocs) { + di.curChunkHeader = make([]MetaData, int(numDocs)) + } else { + di.curChunkHeader = di.curChunkHeader[:int(numDocs)] + } + for i := 0; i < int(numDocs); i++ { + di.curChunkHeader[i].DocNum, read = binary.Uvarint(s.mem[chunkMetaLoc+offset : chunkMetaLoc+offset+binary.MaxVarintLen64]) + offset += uint64(read) + di.curChunkHeader[i].DocDvOffset, read = binary.Uvarint(s.mem[chunkMetaLoc+offset : chunkMetaLoc+offset+binary.MaxVarintLen64]) + offset += uint64(read) + } + + compressedDataLoc := chunkMetaLoc + offset + dataLength := curChunkEnd - compressedDataLoc + di.curChunkData = s.mem[compressedDataLoc : compressedDataLoc+dataLength] + di.curChunkNum = chunkNumber + di.uncompressed = di.uncompressed[:0] + return nil +} + +func (di *docValueReader) iterateAllDocValues(s *SegmentBase, visitor docNumTermsVisitor) error { + for i := 0; i < len(di.chunkOffsets); i++ { + err := di.loadDvChunk(uint64(i), s) + if err != nil { + return err + } + if di.curChunkData == nil || len(di.curChunkHeader) == 0 { + continue + } + + // uncompress the already loaded data + uncompressed, err := snappy.Decode(di.uncompressed[:cap(di.uncompressed)], di.curChunkData) + if err != nil { + return err + } + di.uncompressed = uncompressed + + start := uint64(0) + for _, entry := range di.curChunkHeader { + err = visitor(entry.DocNum, uncompressed[start:entry.DocDvOffset]) + if err != nil { + return err + } + + start = entry.DocDvOffset + } + } + + return nil +} + +func (di *docValueReader) visitDocValues(docNum uint64, + visitor index.DocValueVisitor) error { + // binary search the term locations for the docNum + start, end := di.getDocValueLocs(docNum) + if start == math.MaxUint64 || end == math.MaxUint64 || start == end { + return nil + } + + var uncompressed []byte + var err error + // use the uncompressed copy if available + if len(di.uncompressed) > 0 { + uncompressed = di.uncompressed + } else { + // uncompress the already loaded data + uncompressed, err = snappy.Decode(di.uncompressed[:cap(di.uncompressed)], di.curChunkData) + if err != nil { + return err + } + di.uncompressed = uncompressed + } + + // pick the terms for the given docNum + uncompressed = uncompressed[start:end] + for { + i := bytes.Index(uncompressed, termSeparatorSplitSlice) + if i < 0 { + break + } + + visitor(di.field, uncompressed[0:i]) + uncompressed = uncompressed[i+1:] + } + + return nil +} + +func (di *docValueReader) getDocValueLocs(docNum uint64) (uint64, uint64) { + i := sort.Search(len(di.curChunkHeader), func(i int) bool { + return di.curChunkHeader[i].DocNum >= docNum + }) + if i < len(di.curChunkHeader) && di.curChunkHeader[i].DocNum == docNum { + return ReadDocValueBoundary(i, di.curChunkHeader) + } + return math.MaxUint64, math.MaxUint64 +} + +// VisitDocValues is an implementation of the +// DocValueVisitable interface +func (s *SegmentBase) VisitDocValues(localDocNum uint64, fields []string, + visitor index.DocValueVisitor, dvsIn segment.DocVisitState) ( + segment.DocVisitState, error) { + dvs, ok := dvsIn.(*docVisitState) + if !ok || dvs == nil { + dvs = &docVisitState{} + } else { + if dvs.segment != s { + dvs.segment = s + dvs.dvrs = nil + } + } + + var fieldIDPlus1 uint16 + if dvs.dvrs == nil { + dvs.dvrs = make(map[uint16]*docValueReader, len(fields)) + for _, field := range fields { + if fieldIDPlus1, ok = s.fieldsMap[field]; !ok { + continue + } + fieldID := fieldIDPlus1 - 1 + if dvIter, exists := s.fieldDvReaders[fieldID]; exists && + dvIter != nil { + dvs.dvrs[fieldID] = dvIter.cloneInto(dvs.dvrs[fieldID]) + } + } + } + + // find the chunkNumber where the docValues are stored + // NOTE: doc values continue to use legacy chunk mode + chunkFactor, err := getChunkSize(LegacyChunkMode, 0, 0) + if err != nil { + return nil, err + } + docInChunk := localDocNum / chunkFactor + var dvr *docValueReader + for _, field := range fields { + if fieldIDPlus1, ok = s.fieldsMap[field]; !ok { + continue + } + fieldID := fieldIDPlus1 - 1 + if dvr, ok = dvs.dvrs[fieldID]; ok && dvr != nil { + // check if the chunk is already loaded + if docInChunk != dvr.curChunkNumber() { + err := dvr.loadDvChunk(docInChunk, s) + if err != nil { + return dvs, err + } + } + + _ = dvr.visitDocValues(localDocNum, visitor) + } + } + return dvs, nil +} + +// VisitableDocValueFields returns the list of fields with +// persisted doc value terms ready to be visitable using the +// VisitDocumentFieldTerms method. +func (s *SegmentBase) VisitableDocValueFields() ([]string, error) { + return s.fieldDvNames, nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/enumerator.go b/backend/vendor/github.com/blevesearch/zapx/v14/enumerator.go new file mode 100644 index 0000000000..972a224165 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/enumerator.go @@ -0,0 +1,138 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + + "github.com/blevesearch/vellum" +) + +// enumerator provides an ordered traversal of multiple vellum +// iterators. Like JOIN of iterators, the enumerator produces a +// sequence of (key, iteratorIndex, value) tuples, sorted by key ASC, +// then iteratorIndex ASC, where the same key might be seen or +// repeated across multiple child iterators. +type enumerator struct { + itrs []vellum.Iterator + currKs [][]byte + currVs []uint64 + + lowK []byte + lowIdxs []int + lowCurr int +} + +// newEnumerator returns a new enumerator over the vellum Iterators +func newEnumerator(itrs []vellum.Iterator) (*enumerator, error) { + rv := &enumerator{ + itrs: itrs, + currKs: make([][]byte, len(itrs)), + currVs: make([]uint64, len(itrs)), + lowIdxs: make([]int, 0, len(itrs)), + } + for i, itr := range rv.itrs { + rv.currKs[i], rv.currVs[i] = itr.Current() + } + rv.updateMatches(false) + if rv.lowK == nil && len(rv.lowIdxs) == 0 { + return rv, vellum.ErrIteratorDone + } + return rv, nil +} + +// updateMatches maintains the low key matches based on the currKs +func (m *enumerator) updateMatches(skipEmptyKey bool) { + m.lowK = nil + m.lowIdxs = m.lowIdxs[:0] + m.lowCurr = 0 + + for i, key := range m.currKs { + if (key == nil && m.currVs[i] == 0) || // in case of empty iterator + (len(key) == 0 && skipEmptyKey) { // skip empty keys + continue + } + + cmp := bytes.Compare(key, m.lowK) + if cmp < 0 || len(m.lowIdxs) == 0 { + // reached a new low + m.lowK = key + m.lowIdxs = m.lowIdxs[:0] + m.lowIdxs = append(m.lowIdxs, i) + } else if cmp == 0 { + m.lowIdxs = append(m.lowIdxs, i) + } + } +} + +// Current returns the enumerator's current key, iterator-index, and +// value. If the enumerator is not pointing at a valid value (because +// Next returned an error previously), Current will return nil,0,0. +func (m *enumerator) Current() ([]byte, int, uint64) { + var i int + var v uint64 + if m.lowCurr < len(m.lowIdxs) { + i = m.lowIdxs[m.lowCurr] + v = m.currVs[i] + } + return m.lowK, i, v +} + +// GetLowIdxsAndValues will return all of the iterator indices +// which point to the current key, and their corresponding +// values. This can be used by advanced caller which may need +// to peek into these other sets of data before processing. +func (m *enumerator) GetLowIdxsAndValues() ([]int, []uint64) { + values := make([]uint64, 0, len(m.lowIdxs)) + for _, idx := range m.lowIdxs { + values = append(values, m.currVs[idx]) + } + return m.lowIdxs, values +} + +// Next advances the enumerator to the next key/iterator/value result, +// else vellum.ErrIteratorDone is returned. +func (m *enumerator) Next() error { + m.lowCurr += 1 + if m.lowCurr >= len(m.lowIdxs) { + // move all the current low iterators forwards + for _, vi := range m.lowIdxs { + err := m.itrs[vi].Next() + if err != nil && err != vellum.ErrIteratorDone { + return err + } + m.currKs[vi], m.currVs[vi] = m.itrs[vi].Current() + } + // can skip any empty keys encountered at this point + m.updateMatches(true) + } + if m.lowK == nil && len(m.lowIdxs) == 0 { + return vellum.ErrIteratorDone + } + return nil +} + +// Close all the underlying Iterators. The first error, if any, will +// be returned. +func (m *enumerator) Close() error { + var rv error + for _, itr := range m.itrs { + err := itr.Close() + if rv == nil { + rv = err + } + } + return rv +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/intDecoder.go b/backend/vendor/github.com/blevesearch/zapx/v14/intDecoder.go new file mode 100644 index 0000000000..1b839e1c62 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/intDecoder.go @@ -0,0 +1,116 @@ +// Copyright (c) 2019 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "encoding/binary" + "fmt" +) + +type chunkedIntDecoder struct { + startOffset uint64 + dataStartOffset uint64 + chunkOffsets []uint64 + curChunkBytes []byte + data []byte + r *memUvarintReader +} + +// newChunkedIntDecoder expects an optional or reset chunkedIntDecoder for better reuse. +func newChunkedIntDecoder(buf []byte, offset uint64, rv *chunkedIntDecoder) *chunkedIntDecoder { + if rv == nil { + rv = &chunkedIntDecoder{startOffset: offset, data: buf} + } else { + rv.startOffset = offset + rv.data = buf + } + + var n, numChunks uint64 + var read int + if offset == termNotEncoded { + numChunks = 0 + } else { + numChunks, read = binary.Uvarint(buf[offset+n : offset+n+binary.MaxVarintLen64]) + } + + n += uint64(read) + if cap(rv.chunkOffsets) >= int(numChunks) { + rv.chunkOffsets = rv.chunkOffsets[:int(numChunks)] + } else { + rv.chunkOffsets = make([]uint64, int(numChunks)) + } + for i := 0; i < int(numChunks); i++ { + rv.chunkOffsets[i], read = binary.Uvarint(buf[offset+n : offset+n+binary.MaxVarintLen64]) + n += uint64(read) + } + rv.dataStartOffset = offset + n + return rv +} + +func (d *chunkedIntDecoder) loadChunk(chunk int) error { + if d.startOffset == termNotEncoded { + d.r = newMemUvarintReader([]byte(nil)) + return nil + } + + if chunk >= len(d.chunkOffsets) { + return fmt.Errorf("tried to load freq chunk that doesn't exist %d/(%d)", + chunk, len(d.chunkOffsets)) + } + + end, start := d.dataStartOffset, d.dataStartOffset + s, e := readChunkBoundary(chunk, d.chunkOffsets) + start += s + end += e + d.curChunkBytes = d.data[start:end] + if d.r == nil { + d.r = newMemUvarintReader(d.curChunkBytes) + } else { + d.r.Reset(d.curChunkBytes) + } + + return nil +} + +func (d *chunkedIntDecoder) reset() { + d.startOffset = 0 + d.dataStartOffset = 0 + d.chunkOffsets = d.chunkOffsets[:0] + d.curChunkBytes = d.curChunkBytes[:0] + d.data = d.data[:0] + if d.r != nil { + d.r.Reset([]byte(nil)) + } +} + +func (d *chunkedIntDecoder) isNil() bool { + return d.curChunkBytes == nil || len(d.curChunkBytes) == 0 +} + +func (d *chunkedIntDecoder) readUvarint() (uint64, error) { + return d.r.ReadUvarint() +} + +func (d *chunkedIntDecoder) SkipUvarint() { + d.r.SkipUvarint() +} + +func (d *chunkedIntDecoder) SkipBytes(count int) { + d.r.SkipBytes(count) +} + +func (d *chunkedIntDecoder) Len() int { + return d.r.Len() +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/intcoder.go b/backend/vendor/github.com/blevesearch/zapx/v14/intcoder.go new file mode 100644 index 0000000000..c3c488fb74 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/intcoder.go @@ -0,0 +1,206 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "io" +) + +// We can safely use 0 to represent termNotEncoded since 0 +// could never be a valid address for term location information. +// (stored field index is always non-empty and earlier in the +// file) +const termNotEncoded = 0 + +type chunkedIntCoder struct { + final []byte + chunkSize uint64 + chunkBuf bytes.Buffer + chunkLens []uint64 + currChunk uint64 + + buf []byte +} + +// newChunkedIntCoder returns a new chunk int coder which packs data into +// chunks based on the provided chunkSize and supports up to the specified +// maxDocNum +func newChunkedIntCoder(chunkSize uint64, maxDocNum uint64) *chunkedIntCoder { + total := maxDocNum/chunkSize + 1 + rv := &chunkedIntCoder{ + chunkSize: chunkSize, + chunkLens: make([]uint64, total), + final: make([]byte, 0, 64), + } + + return rv +} + +// Reset lets you reuse this chunked int coder. buffers are reset and reused +// from previous use. you cannot change the chunk size or max doc num. +func (c *chunkedIntCoder) Reset() { + c.final = c.final[:0] + c.chunkBuf.Reset() + c.currChunk = 0 + for i := range c.chunkLens { + c.chunkLens[i] = 0 + } +} + +// SetChunkSize changes the chunk size. It is only valid to do so +// with a new chunkedIntCoder, or immediately after calling Reset() +func (c *chunkedIntCoder) SetChunkSize(chunkSize uint64, maxDocNum uint64) { + total := int(maxDocNum/chunkSize + 1) + c.chunkSize = chunkSize + if cap(c.chunkLens) < total { + c.chunkLens = make([]uint64, total) + } else { + c.chunkLens = c.chunkLens[:total] + } +} + +// Add encodes the provided integers into the correct chunk for the provided +// doc num. You MUST call Add() with increasing docNums. +func (c *chunkedIntCoder) Add(docNum uint64, vals ...uint64) error { + chunk := docNum / c.chunkSize + if chunk != c.currChunk { + // starting a new chunk + c.Close() + c.chunkBuf.Reset() + c.currChunk = chunk + } + + if len(c.buf) < binary.MaxVarintLen64 { + c.buf = make([]byte, binary.MaxVarintLen64) + } + + for _, val := range vals { + wb := binary.PutUvarint(c.buf, val) + _, err := c.chunkBuf.Write(c.buf[:wb]) + if err != nil { + return err + } + } + + return nil +} + +func (c *chunkedIntCoder) AddBytes(docNum uint64, buf []byte) error { + chunk := docNum / c.chunkSize + if chunk != c.currChunk { + // starting a new chunk + c.Close() + c.chunkBuf.Reset() + c.currChunk = chunk + } + + _, err := c.chunkBuf.Write(buf) + return err +} + +// Close indicates you are done calling Add() this allows the final chunk +// to be encoded. +func (c *chunkedIntCoder) Close() { + encodingBytes := c.chunkBuf.Bytes() + c.chunkLens[c.currChunk] = uint64(len(encodingBytes)) + c.final = append(c.final, encodingBytes...) + c.currChunk = uint64(cap(c.chunkLens)) // sentinel to detect double close +} + +// Write commits all the encoded chunked integers to the provided writer. +func (c *chunkedIntCoder) Write(w io.Writer) (int, error) { + bufNeeded := binary.MaxVarintLen64 * (1 + len(c.chunkLens)) + if len(c.buf) < bufNeeded { + c.buf = make([]byte, bufNeeded) + } + buf := c.buf + + // convert the chunk lengths into chunk offsets + chunkOffsets := modifyLengthsToEndOffsets(c.chunkLens) + + // write out the number of chunks & each chunk offsets + n := binary.PutUvarint(buf, uint64(len(chunkOffsets))) + for _, chunkOffset := range chunkOffsets { + n += binary.PutUvarint(buf[n:], chunkOffset) + } + + tw, err := w.Write(buf[:n]) + if err != nil { + return tw, err + } + + // write out the data + nw, err := w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + return tw, nil +} + +// writeAt commits all the encoded chunked integers to the provided writer +// and returns the starting offset, total bytes written and an error +func (c *chunkedIntCoder) writeAt(w io.Writer) (uint64, int, error) { + startOffset := uint64(termNotEncoded) + if len(c.final) <= 0 { + return startOffset, 0, nil + } + + if chw := w.(*CountHashWriter); chw != nil { + startOffset = uint64(chw.Count()) + } + + tw, err := c.Write(w) + return startOffset, tw, err +} + +func (c *chunkedIntCoder) FinalSize() int { + return len(c.final) +} + +// modifyLengthsToEndOffsets converts the chunk length array +// to a chunk offset array. The readChunkBoundary +// will figure out the start and end of every chunk from +// these offsets. Starting offset of i'th index is stored +// in i-1'th position except for 0'th index and ending offset +// is stored at i'th index position. +// For 0'th element, starting position is always zero. +// eg: +// Lens -> 5 5 5 5 => 5 10 15 20 +// Lens -> 0 5 0 5 => 0 5 5 10 +// Lens -> 0 0 0 5 => 0 0 0 5 +// Lens -> 5 0 0 0 => 5 5 5 5 +// Lens -> 0 5 0 0 => 0 5 5 5 +// Lens -> 0 0 5 0 => 0 0 5 5 +func modifyLengthsToEndOffsets(lengths []uint64) []uint64 { + var runningOffset uint64 + var index, i int + for i = 1; i <= len(lengths); i++ { + runningOffset += lengths[i-1] + lengths[index] = runningOffset + index++ + } + return lengths +} + +func readChunkBoundary(chunk int, offsets []uint64) (uint64, uint64) { + var start uint64 + if chunk > 0 { + start = offsets[chunk-1] + } + return start, offsets[chunk] +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/memuvarint.go b/backend/vendor/github.com/blevesearch/zapx/v14/memuvarint.go new file mode 100644 index 0000000000..48a57f9c85 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/memuvarint.go @@ -0,0 +1,103 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "fmt" +) + +type memUvarintReader struct { + C int // index of next byte to read from S + S []byte +} + +func newMemUvarintReader(s []byte) *memUvarintReader { + return &memUvarintReader{S: s} +} + +// Len returns the number of unread bytes. +func (r *memUvarintReader) Len() int { + n := len(r.S) - r.C + if n < 0 { + return 0 + } + return n +} + +// ReadUvarint reads an encoded uint64. The original code this was +// based on is at encoding/binary/ReadUvarint(). +func (r *memUvarintReader) ReadUvarint() (uint64, error) { + if r.C >= len(r.S) { + // nothing else to read + return 0, nil + } + + var x uint64 + var s uint + var C = r.C + var S = r.S + + for { + b := S[C] + C++ + + if b < 0x80 { + r.C = C + + // why 63? The original code had an 'i += 1' loop var and + // checked for i > 9 || i == 9 ...; but, we no longer + // check for the i var, but instead check here for s, + // which is incremented by 7. So, 7*9 == 63. + // + // why the "extra" >= check? The normal case is that s < + // 63, so we check this single >= guard first so that we + // hit the normal, nil-error return pathway sooner. + if s >= 63 && (s > 63 || b > 1) { + return 0, fmt.Errorf("memUvarintReader overflow") + } + + return x | uint64(b)<= len(r.S) { + return + } + + b := r.S[r.C] + r.C++ + + if b < 0x80 { + return + } + } +} + +// SkipBytes skips a count number of bytes. +func (r *memUvarintReader) SkipBytes(count int) { + r.C = r.C + count +} + +func (r *memUvarintReader) Reset(s []byte) { + r.C = 0 + r.S = s +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/merge.go b/backend/vendor/github.com/blevesearch/zapx/v14/merge.go new file mode 100644 index 0000000000..6a853a16a6 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/merge.go @@ -0,0 +1,843 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bufio" + "bytes" + "encoding/binary" + "fmt" + "math" + "os" + "sort" + + "github.com/RoaringBitmap/roaring" + seg "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" + "github.com/golang/snappy" +) + +var DefaultFileMergerBufferSize = 1024 * 1024 + +const docDropped = math.MaxUint64 // sentinel docNum to represent a deleted doc + +// Merge takes a slice of segments and bit masks describing which +// documents may be dropped, and creates a new segment containing the +// remaining data. This new segment is built at the specified path. +func (*ZapPlugin) Merge(segments []seg.Segment, drops []*roaring.Bitmap, path string, + closeCh chan struct{}, s seg.StatsReporter) ( + [][]uint64, uint64, error) { + segmentBases := make([]*SegmentBase, len(segments)) + for segmenti, segment := range segments { + switch segmentx := segment.(type) { + case *Segment: + segmentBases[segmenti] = &segmentx.SegmentBase + case *SegmentBase: + segmentBases[segmenti] = segmentx + default: + panic(fmt.Sprintf("oops, unexpected segment type: %T", segment)) + } + } + return mergeSegmentBases(segmentBases, drops, path, DefaultChunkMode, closeCh, s) +} + +func mergeSegmentBases(segmentBases []*SegmentBase, drops []*roaring.Bitmap, path string, + chunkMode uint32, closeCh chan struct{}, s seg.StatsReporter) ( + [][]uint64, uint64, error) { + flag := os.O_RDWR | os.O_CREATE + + f, err := os.OpenFile(path, flag, 0600) + if err != nil { + return nil, 0, err + } + + cleanup := func() { + _ = f.Close() + _ = os.Remove(path) + } + + // buffer the output + br := bufio.NewWriterSize(f, DefaultFileMergerBufferSize) + + // wrap it for counting (tracking offsets) + cr := NewCountHashWriterWithStatsReporter(br, s) + + newDocNums, numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset, _, _, _, err := + MergeToWriter(segmentBases, drops, chunkMode, cr, closeCh) + if err != nil { + cleanup() + return nil, 0, err + } + + err = persistFooter(numDocs, storedIndexOffset, fieldsIndexOffset, + docValueOffset, chunkMode, cr.Sum32(), cr) + if err != nil { + cleanup() + return nil, 0, err + } + + err = br.Flush() + if err != nil { + cleanup() + return nil, 0, err + } + + err = f.Sync() + if err != nil { + cleanup() + return nil, 0, err + } + + err = f.Close() + if err != nil { + cleanup() + return nil, 0, err + } + + return newDocNums, uint64(cr.Count()), nil +} + +func MergeToWriter(segments []*SegmentBase, drops []*roaring.Bitmap, + chunkMode uint32, cr *CountHashWriter, closeCh chan struct{}) ( + newDocNums [][]uint64, + numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset uint64, + dictLocs []uint64, fieldsInv []string, fieldsMap map[string]uint16, + err error) { + docValueOffset = uint64(fieldNotUninverted) + + var fieldsSame bool + fieldsSame, fieldsInv = mergeFields(segments) + fieldsMap = mapFields(fieldsInv) + + numDocs = computeNewDocCount(segments, drops) + + if isClosed(closeCh) { + return nil, 0, 0, 0, 0, nil, nil, nil, seg.ErrClosed + } + + if numDocs > 0 { + storedIndexOffset, newDocNums, err = mergeStoredAndRemap(segments, drops, + fieldsMap, fieldsInv, fieldsSame, numDocs, cr, closeCh) + if err != nil { + return nil, 0, 0, 0, 0, nil, nil, nil, err + } + + dictLocs, docValueOffset, err = persistMergedRest(segments, drops, + fieldsInv, fieldsMap, fieldsSame, + newDocNums, numDocs, chunkMode, cr, closeCh) + if err != nil { + return nil, 0, 0, 0, 0, nil, nil, nil, err + } + } else { + dictLocs = make([]uint64, len(fieldsInv)) + } + + fieldsIndexOffset, err = persistFields(fieldsInv, cr, dictLocs) + if err != nil { + return nil, 0, 0, 0, 0, nil, nil, nil, err + } + + return newDocNums, numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset, dictLocs, fieldsInv, fieldsMap, nil +} + +// mapFields takes the fieldsInv list and returns a map of fieldName +// to fieldID+1 +func mapFields(fields []string) map[string]uint16 { + rv := make(map[string]uint16, len(fields)) + for i, fieldName := range fields { + rv[fieldName] = uint16(i) + 1 + } + return rv +} + +// computeNewDocCount determines how many documents will be in the newly +// merged segment when obsoleted docs are dropped +func computeNewDocCount(segments []*SegmentBase, drops []*roaring.Bitmap) uint64 { + var newDocCount uint64 + for segI, segment := range segments { + newDocCount += segment.numDocs + if drops[segI] != nil { + newDocCount -= drops[segI].GetCardinality() + } + } + return newDocCount +} + +func persistMergedRest(segments []*SegmentBase, dropsIn []*roaring.Bitmap, + fieldsInv []string, fieldsMap map[string]uint16, fieldsSame bool, + newDocNumsIn [][]uint64, newSegDocCount uint64, chunkMode uint32, + w *CountHashWriter, closeCh chan struct{}) ([]uint64, uint64, error) { + var bufMaxVarintLen64 []byte = make([]byte, binary.MaxVarintLen64) + var bufLoc []uint64 + + var postings *PostingsList + var postItr *PostingsIterator + + rv := make([]uint64, len(fieldsInv)) + fieldDvLocsStart := make([]uint64, len(fieldsInv)) + fieldDvLocsEnd := make([]uint64, len(fieldsInv)) + + // these int coders are initialized with chunk size 1024 + // however this will be reset to the correct chunk size + // while processing each individual field-term section + tfEncoder := newChunkedIntCoder(1024, newSegDocCount-1) + locEncoder := newChunkedIntCoder(1024, newSegDocCount-1) + + var vellumBuf bytes.Buffer + newVellum, err := vellum.New(&vellumBuf, nil) + if err != nil { + return nil, 0, err + } + + newRoaring := roaring.NewBitmap() + + // for each field + for fieldID, fieldName := range fieldsInv { + // collect FST iterators from all active segments for this field + var newDocNums [][]uint64 + var drops []*roaring.Bitmap + var dicts []*Dictionary + var itrs []vellum.Iterator + + var segmentsInFocus []*SegmentBase + + for segmentI, segment := range segments { + // check for the closure in meantime + if isClosed(closeCh) { + return nil, 0, seg.ErrClosed + } + + dict, err2 := segment.dictionary(fieldName) + if err2 != nil { + return nil, 0, err2 + } + if dict != nil && dict.fst != nil { + itr, err2 := dict.fst.Iterator(nil, nil) + if err2 != nil && err2 != vellum.ErrIteratorDone { + return nil, 0, err2 + } + if itr != nil { + newDocNums = append(newDocNums, newDocNumsIn[segmentI]) + if dropsIn[segmentI] != nil && !dropsIn[segmentI].IsEmpty() { + drops = append(drops, dropsIn[segmentI]) + } else { + drops = append(drops, nil) + } + dicts = append(dicts, dict) + itrs = append(itrs, itr) + segmentsInFocus = append(segmentsInFocus, segment) + } + } + } + + var prevTerm []byte + + newRoaring.Clear() + + var lastDocNum, lastFreq, lastNorm uint64 + + // determines whether to use "1-hit" encoding optimization + // when a term appears in only 1 doc, with no loc info, + // has freq of 1, and the docNum fits into 31-bits + use1HitEncoding := func(termCardinality uint64) (bool, uint64, uint64) { + if termCardinality == uint64(1) && locEncoder.FinalSize() <= 0 { + docNum := uint64(newRoaring.Minimum()) + if under32Bits(docNum) && docNum == lastDocNum && lastFreq == 1 { + return true, docNum, lastNorm + } + } + return false, 0, 0 + } + + finishTerm := func(term []byte) error { + tfEncoder.Close() + locEncoder.Close() + + postingsOffset, err := writePostings(newRoaring, + tfEncoder, locEncoder, use1HitEncoding, w, bufMaxVarintLen64) + if err != nil { + return err + } + + if postingsOffset > 0 { + err = newVellum.Insert(term, postingsOffset) + if err != nil { + return err + } + } + + newRoaring.Clear() + + tfEncoder.Reset() + locEncoder.Reset() + + lastDocNum = 0 + lastFreq = 0 + lastNorm = 0 + + return nil + } + + enumerator, err := newEnumerator(itrs) + + for err == nil { + term, itrI, postingsOffset := enumerator.Current() + + if !bytes.Equal(prevTerm, term) { + // check for the closure in meantime + if isClosed(closeCh) { + return nil, 0, seg.ErrClosed + } + + // if the term changed, write out the info collected + // for the previous term + err = finishTerm(prevTerm) + if err != nil { + return nil, 0, err + } + } + if !bytes.Equal(prevTerm, term) || prevTerm == nil { + // compute cardinality of field-term in new seg + var newCard uint64 + lowItrIdxs, lowItrVals := enumerator.GetLowIdxsAndValues() + for i, idx := range lowItrIdxs { + pl, err := dicts[idx].postingsListFromOffset(lowItrVals[i], drops[idx], nil) + if err != nil { + return nil, 0, err + } + newCard += pl.Count() + } + // compute correct chunk size with this + chunkSize, err := getChunkSize(chunkMode, newCard, newSegDocCount) + if err != nil { + return nil, 0, err + } + // update encoders chunk + tfEncoder.SetChunkSize(chunkSize, newSegDocCount-1) + locEncoder.SetChunkSize(chunkSize, newSegDocCount-1) + } + + postings, err = dicts[itrI].postingsListFromOffset( + postingsOffset, drops[itrI], postings) + if err != nil { + return nil, 0, err + } + + postItr = postings.iterator(true, true, true, postItr) + + // can no longer optimize by copying, since chunk factor could have changed + lastDocNum, lastFreq, lastNorm, bufLoc, err = mergeTermFreqNormLocs( + fieldsMap, term, postItr, newDocNums[itrI], newRoaring, + tfEncoder, locEncoder, bufLoc) + + if err != nil { + return nil, 0, err + } + + prevTerm = prevTerm[:0] // copy to prevTerm in case Next() reuses term mem + prevTerm = append(prevTerm, term...) + + err = enumerator.Next() + } + if err != vellum.ErrIteratorDone { + return nil, 0, err + } + + err = finishTerm(prevTerm) + if err != nil { + return nil, 0, err + } + + dictOffset := uint64(w.Count()) + + err = newVellum.Close() + if err != nil { + return nil, 0, err + } + vellumData := vellumBuf.Bytes() + + // write out the length of the vellum data + n := binary.PutUvarint(bufMaxVarintLen64, uint64(len(vellumData))) + _, err = w.Write(bufMaxVarintLen64[:n]) + if err != nil { + return nil, 0, err + } + + // write this vellum to disk + _, err = w.Write(vellumData) + if err != nil { + return nil, 0, err + } + + rv[fieldID] = dictOffset + + // get the field doc value offset (start) + fieldDvLocsStart[fieldID] = uint64(w.Count()) + + // update the field doc values + // NOTE: doc values continue to use legacy chunk mode + chunkSize, err := getChunkSize(LegacyChunkMode, 0, 0) + if err != nil { + return nil, 0, err + } + fdvEncoder := newChunkedContentCoder(chunkSize, newSegDocCount-1, w, true) + + fdvReadersAvailable := false + var dvIterClone *docValueReader + for segmentI, segment := range segmentsInFocus { + // check for the closure in meantime + if isClosed(closeCh) { + return nil, 0, seg.ErrClosed + } + + fieldIDPlus1 := uint16(segment.fieldsMap[fieldName]) + if dvIter, exists := segment.fieldDvReaders[fieldIDPlus1-1]; exists && + dvIter != nil { + fdvReadersAvailable = true + dvIterClone = dvIter.cloneInto(dvIterClone) + err = dvIterClone.iterateAllDocValues(segment, func(docNum uint64, terms []byte) error { + if newDocNums[segmentI][docNum] == docDropped { + return nil + } + err := fdvEncoder.Add(newDocNums[segmentI][docNum], terms) + if err != nil { + return err + } + return nil + }) + if err != nil { + return nil, 0, err + } + } + } + + if fdvReadersAvailable { + err = fdvEncoder.Close() + if err != nil { + return nil, 0, err + } + + // persist the doc value details for this field + _, err = fdvEncoder.Write() + if err != nil { + return nil, 0, err + } + + // get the field doc value offset (end) + fieldDvLocsEnd[fieldID] = uint64(w.Count()) + } else { + fieldDvLocsStart[fieldID] = fieldNotUninverted + fieldDvLocsEnd[fieldID] = fieldNotUninverted + } + + // reset vellum buffer and vellum builder + vellumBuf.Reset() + err = newVellum.Reset(&vellumBuf) + if err != nil { + return nil, 0, err + } + } + + fieldDvLocsOffset := uint64(w.Count()) + + buf := bufMaxVarintLen64 + for i := 0; i < len(fieldDvLocsStart); i++ { + n := binary.PutUvarint(buf, fieldDvLocsStart[i]) + _, err := w.Write(buf[:n]) + if err != nil { + return nil, 0, err + } + n = binary.PutUvarint(buf, fieldDvLocsEnd[i]) + _, err = w.Write(buf[:n]) + if err != nil { + return nil, 0, err + } + } + + return rv, fieldDvLocsOffset, nil +} + +func mergeTermFreqNormLocs(fieldsMap map[string]uint16, term []byte, postItr *PostingsIterator, + newDocNums []uint64, newRoaring *roaring.Bitmap, + tfEncoder *chunkedIntCoder, locEncoder *chunkedIntCoder, bufLoc []uint64) ( + lastDocNum uint64, lastFreq uint64, lastNorm uint64, bufLocOut []uint64, err error) { + next, err := postItr.Next() + for next != nil && err == nil { + hitNewDocNum := newDocNums[next.Number()] + if hitNewDocNum == docDropped { + return 0, 0, 0, nil, fmt.Errorf("see hit with dropped docNum") + } + + newRoaring.Add(uint32(hitNewDocNum)) + + nextFreq := next.Frequency() + nextNorm := uint64(math.Float32bits(float32(next.Norm()))) + + locs := next.Locations() + + err = tfEncoder.Add(hitNewDocNum, + encodeFreqHasLocs(nextFreq, len(locs) > 0), nextNorm) + if err != nil { + return 0, 0, 0, nil, err + } + + if len(locs) > 0 { + numBytesLocs := 0 + for _, loc := range locs { + ap := loc.ArrayPositions() + numBytesLocs += totalUvarintBytes(uint64(fieldsMap[loc.Field()]-1), + loc.Pos(), loc.Start(), loc.End(), uint64(len(ap)), ap) + } + + err = locEncoder.Add(hitNewDocNum, uint64(numBytesLocs)) + if err != nil { + return 0, 0, 0, nil, err + } + + for _, loc := range locs { + ap := loc.ArrayPositions() + if cap(bufLoc) < 5+len(ap) { + bufLoc = make([]uint64, 0, 5+len(ap)) + } + args := bufLoc[0:5] + args[0] = uint64(fieldsMap[loc.Field()] - 1) + args[1] = loc.Pos() + args[2] = loc.Start() + args[3] = loc.End() + args[4] = uint64(len(ap)) + args = append(args, ap...) + err = locEncoder.Add(hitNewDocNum, args...) + if err != nil { + return 0, 0, 0, nil, err + } + } + } + + lastDocNum = hitNewDocNum + lastFreq = nextFreq + lastNorm = nextNorm + + next, err = postItr.Next() + } + + return lastDocNum, lastFreq, lastNorm, bufLoc, err +} + +func writePostings(postings *roaring.Bitmap, tfEncoder, locEncoder *chunkedIntCoder, + use1HitEncoding func(uint64) (bool, uint64, uint64), + w *CountHashWriter, bufMaxVarintLen64 []byte) ( + offset uint64, err error) { + termCardinality := postings.GetCardinality() + if termCardinality <= 0 { + return 0, nil + } + + if use1HitEncoding != nil { + encodeAs1Hit, docNum1Hit, normBits1Hit := use1HitEncoding(termCardinality) + if encodeAs1Hit { + return FSTValEncode1Hit(docNum1Hit, normBits1Hit), nil + } + } + + var tfOffset uint64 + tfOffset, _, err = tfEncoder.writeAt(w) + if err != nil { + return 0, err + } + + var locOffset uint64 + locOffset, _, err = locEncoder.writeAt(w) + if err != nil { + return 0, err + } + + postingsOffset := uint64(w.Count()) + + n := binary.PutUvarint(bufMaxVarintLen64, tfOffset) + _, err = w.Write(bufMaxVarintLen64[:n]) + if err != nil { + return 0, err + } + + n = binary.PutUvarint(bufMaxVarintLen64, locOffset) + _, err = w.Write(bufMaxVarintLen64[:n]) + if err != nil { + return 0, err + } + + _, err = writeRoaringWithLen(postings, w, bufMaxVarintLen64) + if err != nil { + return 0, err + } + + return postingsOffset, nil +} + +type varintEncoder func(uint64) (int, error) + +func mergeStoredAndRemap(segments []*SegmentBase, drops []*roaring.Bitmap, + fieldsMap map[string]uint16, fieldsInv []string, fieldsSame bool, newSegDocCount uint64, + w *CountHashWriter, closeCh chan struct{}) (uint64, [][]uint64, error) { + var rv [][]uint64 // The remapped or newDocNums for each segment. + + var newDocNum uint64 + + var curr int + var data, compressed []byte + var metaBuf bytes.Buffer + varBuf := make([]byte, binary.MaxVarintLen64) + metaEncode := func(val uint64) (int, error) { + wb := binary.PutUvarint(varBuf, val) + return metaBuf.Write(varBuf[:wb]) + } + + vals := make([][][]byte, len(fieldsInv)) + typs := make([][]byte, len(fieldsInv)) + poss := make([][][]uint64, len(fieldsInv)) + + var posBuf []uint64 + + docNumOffsets := make([]uint64, newSegDocCount) + + vdc := visitDocumentCtxPool.Get().(*visitDocumentCtx) + defer visitDocumentCtxPool.Put(vdc) + + // for each segment + for segI, segment := range segments { + // check for the closure in meantime + if isClosed(closeCh) { + return 0, nil, seg.ErrClosed + } + + segNewDocNums := make([]uint64, segment.numDocs) + + dropsI := drops[segI] + + // optimize when the field mapping is the same across all + // segments and there are no deletions, via byte-copying + // of stored docs bytes directly to the writer + if fieldsSame && (dropsI == nil || dropsI.GetCardinality() == 0) { + err := segment.copyStoredDocs(newDocNum, docNumOffsets, w) + if err != nil { + return 0, nil, err + } + + for i := uint64(0); i < segment.numDocs; i++ { + segNewDocNums[i] = newDocNum + newDocNum++ + } + rv = append(rv, segNewDocNums) + + continue + } + + // for each doc num + for docNum := uint64(0); docNum < segment.numDocs; docNum++ { + // TODO: roaring's API limits docNums to 32-bits? + if dropsI != nil && dropsI.Contains(uint32(docNum)) { + segNewDocNums[docNum] = docDropped + continue + } + + segNewDocNums[docNum] = newDocNum + + curr = 0 + metaBuf.Reset() + data = data[:0] + + posTemp := posBuf + + // collect all the data + for i := 0; i < len(fieldsInv); i++ { + vals[i] = vals[i][:0] + typs[i] = typs[i][:0] + poss[i] = poss[i][:0] + } + err := segment.visitStoredFields(vdc, docNum, func(field string, typ byte, value []byte, pos []uint64) bool { + fieldID := int(fieldsMap[field]) - 1 + vals[fieldID] = append(vals[fieldID], value) + typs[fieldID] = append(typs[fieldID], typ) + + // copy array positions to preserve them beyond the scope of this callback + var curPos []uint64 + if len(pos) > 0 { + if cap(posTemp) < len(pos) { + posBuf = make([]uint64, len(pos)*len(fieldsInv)) + posTemp = posBuf + } + curPos = posTemp[0:len(pos)] + copy(curPos, pos) + posTemp = posTemp[len(pos):] + } + poss[fieldID] = append(poss[fieldID], curPos) + + return true + }) + if err != nil { + return 0, nil, err + } + + // _id field special case optimizes ExternalID() lookups + idFieldVal := vals[uint16(0)][0] + _, err = metaEncode(uint64(len(idFieldVal))) + if err != nil { + return 0, nil, err + } + + // now walk the non-"_id" fields in order + for fieldID := 1; fieldID < len(fieldsInv); fieldID++ { + storedFieldValues := vals[fieldID] + + stf := typs[fieldID] + spf := poss[fieldID] + + var err2 error + curr, data, err2 = persistStoredFieldValues(fieldID, + storedFieldValues, stf, spf, curr, metaEncode, data) + if err2 != nil { + return 0, nil, err2 + } + } + + metaBytes := metaBuf.Bytes() + + compressed = snappy.Encode(compressed[:cap(compressed)], data) + + // record where we're about to start writing + docNumOffsets[newDocNum] = uint64(w.Count()) + + // write out the meta len and compressed data len + _, err = writeUvarints(w, + uint64(len(metaBytes)), + uint64(len(idFieldVal)+len(compressed))) + if err != nil { + return 0, nil, err + } + // now write the meta + _, err = w.Write(metaBytes) + if err != nil { + return 0, nil, err + } + // now write the _id field val (counted as part of the 'compressed' data) + _, err = w.Write(idFieldVal) + if err != nil { + return 0, nil, err + } + // now write the compressed data + _, err = w.Write(compressed) + if err != nil { + return 0, nil, err + } + + newDocNum++ + } + + rv = append(rv, segNewDocNums) + } + + // return value is the start of the stored index + storedIndexOffset := uint64(w.Count()) + + // now write out the stored doc index + for _, docNumOffset := range docNumOffsets { + err := binary.Write(w, binary.BigEndian, docNumOffset) + if err != nil { + return 0, nil, err + } + } + + return storedIndexOffset, rv, nil +} + +// copyStoredDocs writes out a segment's stored doc info, optimized by +// using a single Write() call for the entire set of bytes. The +// newDocNumOffsets is filled with the new offsets for each doc. +func (s *SegmentBase) copyStoredDocs(newDocNum uint64, newDocNumOffsets []uint64, + w *CountHashWriter) error { + if s.numDocs <= 0 { + return nil + } + + indexOffset0, storedOffset0, _, _, _ := + s.getDocStoredOffsets(0) // the segment's first doc + + indexOffsetN, storedOffsetN, readN, metaLenN, dataLenN := + s.getDocStoredOffsets(s.numDocs - 1) // the segment's last doc + + storedOffset0New := uint64(w.Count()) + + storedBytes := s.mem[storedOffset0 : storedOffsetN+readN+metaLenN+dataLenN] + _, err := w.Write(storedBytes) + if err != nil { + return err + } + + // remap the storedOffset's for the docs into new offsets relative + // to storedOffset0New, filling the given docNumOffsetsOut array + for indexOffset := indexOffset0; indexOffset <= indexOffsetN; indexOffset += 8 { + storedOffset := binary.BigEndian.Uint64(s.mem[indexOffset : indexOffset+8]) + storedOffsetNew := storedOffset - storedOffset0 + storedOffset0New + newDocNumOffsets[newDocNum] = storedOffsetNew + newDocNum += 1 + } + + return nil +} + +// mergeFields builds a unified list of fields used across all the +// input segments, and computes whether the fields are the same across +// segments (which depends on fields to be sorted in the same way +// across segments) +func mergeFields(segments []*SegmentBase) (bool, []string) { + fieldsSame := true + + var segment0Fields []string + if len(segments) > 0 { + segment0Fields = segments[0].Fields() + } + + fieldsExist := map[string]struct{}{} + for _, segment := range segments { + fields := segment.Fields() + for fieldi, field := range fields { + fieldsExist[field] = struct{}{} + if len(segment0Fields) != len(fields) || segment0Fields[fieldi] != field { + fieldsSame = false + } + } + } + + rv := make([]string, 0, len(fieldsExist)) + // ensure _id stays first + rv = append(rv, "_id") + for k := range fieldsExist { + if k != "_id" { + rv = append(rv, k) + } + } + + sort.Strings(rv[1:]) // leave _id as first + + return fieldsSame, rv +} + +func isClosed(closeCh chan struct{}) bool { + select { + case <-closeCh: + return true + default: + return false + } +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/new.go b/backend/vendor/github.com/blevesearch/zapx/v14/new.go new file mode 100644 index 0000000000..b4e0d03415 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/new.go @@ -0,0 +1,830 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "math" + "sort" + "sync" + + "github.com/RoaringBitmap/roaring" + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" + "github.com/golang/snappy" +) + +var NewSegmentBufferNumResultsBump int = 100 +var NewSegmentBufferNumResultsFactor float64 = 1.0 +var NewSegmentBufferAvgBytesPerDocFactor float64 = 1.0 + +// ValidateDocFields can be set by applications to perform additional checks +// on fields in a document being added to a new segment, by default it does +// nothing. +// This API is experimental and may be removed at any time. +var ValidateDocFields = func(field index.Field) error { + return nil +} + +// New creates an in-memory zap-encoded SegmentBase from a set of Documents +func (z *ZapPlugin) New(results []index.Document) ( + segment.Segment, uint64, error) { + return z.newWithChunkMode(results, DefaultChunkMode) +} + +func (*ZapPlugin) newWithChunkMode(results []index.Document, + chunkMode uint32) (segment.Segment, uint64, error) { + s := interimPool.Get().(*interim) + + var br bytes.Buffer + if s.lastNumDocs > 0 { + // use previous results to initialize the buf with an estimate + // size, but note that the interim instance comes from a + // global interimPool, so multiple scorch instances indexing + // different docs can lead to low quality estimates + estimateAvgBytesPerDoc := int(float64(s.lastOutSize/s.lastNumDocs) * + NewSegmentBufferNumResultsFactor) + estimateNumResults := int(float64(len(results)+NewSegmentBufferNumResultsBump) * + NewSegmentBufferAvgBytesPerDocFactor) + br.Grow(estimateAvgBytesPerDoc * estimateNumResults) + } + + s.results = results + s.chunkMode = chunkMode + s.w = NewCountHashWriter(&br) + + storedIndexOffset, fieldsIndexOffset, fdvIndexOffset, dictOffsets, + err := s.convert() + if err != nil { + return nil, uint64(0), err + } + + sb, err := InitSegmentBase(br.Bytes(), s.w.Sum32(), chunkMode, + s.FieldsMap, s.FieldsInv, uint64(len(results)), + storedIndexOffset, fieldsIndexOffset, fdvIndexOffset, dictOffsets) + + if err == nil && s.reset() == nil { + s.lastNumDocs = len(results) + s.lastOutSize = len(br.Bytes()) + interimPool.Put(s) + } + + return sb, uint64(len(br.Bytes())), err +} + +var interimPool = sync.Pool{New: func() interface{} { return &interim{} }} + +// interim holds temporary working data used while converting from +// analysis results to a zap-encoded segment +type interim struct { + results []index.Document + + chunkMode uint32 + + w *CountHashWriter + + // FieldsMap adds 1 to field id to avoid zero value issues + // name -> field id + 1 + FieldsMap map[string]uint16 + + // FieldsInv is the inverse of FieldsMap + // field id -> name + FieldsInv []string + + // Term dictionaries for each field + // field id -> term -> postings list id + 1 + Dicts []map[string]uint64 + + // Terms for each field, where terms are sorted ascending + // field id -> []term + DictKeys [][]string + + // Fields whose IncludeDocValues is true + // field id -> bool + IncludeDocValues []bool + + // postings id -> bitmap of docNums + Postings []*roaring.Bitmap + + // postings id -> freq/norm's, one for each docNum in postings + FreqNorms [][]interimFreqNorm + freqNormsBacking []interimFreqNorm + + // postings id -> locs, one for each freq + Locs [][]interimLoc + locsBacking []interimLoc + + numTermsPerPostingsList []int // key is postings list id + numLocsPerPostingsList []int // key is postings list id + + builder *vellum.Builder + builderBuf bytes.Buffer + + metaBuf bytes.Buffer + + tmp0 []byte + tmp1 []byte + + lastNumDocs int + lastOutSize int +} + +func (s *interim) reset() (err error) { + s.results = nil + s.chunkMode = 0 + s.w = nil + s.FieldsMap = nil + s.FieldsInv = nil + for i := range s.Dicts { + s.Dicts[i] = nil + } + s.Dicts = s.Dicts[:0] + for i := range s.DictKeys { + s.DictKeys[i] = s.DictKeys[i][:0] + } + s.DictKeys = s.DictKeys[:0] + for i := range s.IncludeDocValues { + s.IncludeDocValues[i] = false + } + s.IncludeDocValues = s.IncludeDocValues[:0] + for _, idn := range s.Postings { + idn.Clear() + } + s.Postings = s.Postings[:0] + s.FreqNorms = s.FreqNorms[:0] + for i := range s.freqNormsBacking { + s.freqNormsBacking[i] = interimFreqNorm{} + } + s.freqNormsBacking = s.freqNormsBacking[:0] + s.Locs = s.Locs[:0] + for i := range s.locsBacking { + s.locsBacking[i] = interimLoc{} + } + s.locsBacking = s.locsBacking[:0] + s.numTermsPerPostingsList = s.numTermsPerPostingsList[:0] + s.numLocsPerPostingsList = s.numLocsPerPostingsList[:0] + s.builderBuf.Reset() + if s.builder != nil { + err = s.builder.Reset(&s.builderBuf) + } + s.metaBuf.Reset() + s.tmp0 = s.tmp0[:0] + s.tmp1 = s.tmp1[:0] + s.lastNumDocs = 0 + s.lastOutSize = 0 + + return err +} + +func (s *interim) grabBuf(size int) []byte { + buf := s.tmp0 + if cap(buf) < size { + buf = make([]byte, size) + s.tmp0 = buf + } + return buf[0:size] +} + +type interimStoredField struct { + vals [][]byte + typs []byte + arrayposs [][]uint64 // array positions +} + +type interimFreqNorm struct { + freq uint64 + norm float32 + numLocs int +} + +type interimLoc struct { + fieldID uint16 + pos uint64 + start uint64 + end uint64 + arrayposs []uint64 +} + +func (s *interim) convert() (uint64, uint64, uint64, []uint64, error) { + s.FieldsMap = map[string]uint16{} + + s.getOrDefineField("_id") // _id field is fieldID 0 + + for _, result := range s.results { + result.VisitComposite(func(field index.CompositeField) { + s.getOrDefineField(field.Name()) + }) + result.VisitFields(func(field index.Field) { + s.getOrDefineField(field.Name()) + }) + } + + sort.Strings(s.FieldsInv[1:]) // keep _id as first field + + for fieldID, fieldName := range s.FieldsInv { + s.FieldsMap[fieldName] = uint16(fieldID + 1) + } + + if cap(s.IncludeDocValues) >= len(s.FieldsInv) { + s.IncludeDocValues = s.IncludeDocValues[:len(s.FieldsInv)] + } else { + s.IncludeDocValues = make([]bool, len(s.FieldsInv)) + } + + s.prepareDicts() + + for _, dict := range s.DictKeys { + sort.Strings(dict) + } + + s.processDocuments() + + storedIndexOffset, err := s.writeStoredFields() + if err != nil { + return 0, 0, 0, nil, err + } + + var fdvIndexOffset uint64 + var dictOffsets []uint64 + + if len(s.results) > 0 { + fdvIndexOffset, dictOffsets, err = s.writeDicts() + if err != nil { + return 0, 0, 0, nil, err + } + } else { + dictOffsets = make([]uint64, len(s.FieldsInv)) + } + + fieldsIndexOffset, err := persistFields(s.FieldsInv, s.w, dictOffsets) + if err != nil { + return 0, 0, 0, nil, err + } + + return storedIndexOffset, fieldsIndexOffset, fdvIndexOffset, dictOffsets, nil +} + +func (s *interim) getOrDefineField(fieldName string) int { + fieldIDPlus1, exists := s.FieldsMap[fieldName] + if !exists { + fieldIDPlus1 = uint16(len(s.FieldsInv) + 1) + s.FieldsMap[fieldName] = fieldIDPlus1 + s.FieldsInv = append(s.FieldsInv, fieldName) + + s.Dicts = append(s.Dicts, make(map[string]uint64)) + + n := len(s.DictKeys) + if n < cap(s.DictKeys) { + s.DictKeys = s.DictKeys[:n+1] + s.DictKeys[n] = s.DictKeys[n][:0] + } else { + s.DictKeys = append(s.DictKeys, []string(nil)) + } + } + + return int(fieldIDPlus1 - 1) +} + +// fill Dicts and DictKeys from analysis results +func (s *interim) prepareDicts() { + var pidNext int + + var totTFs int + var totLocs int + + visitField := func(field index.Field) { + fieldID := uint16(s.getOrDefineField(field.Name())) + + dict := s.Dicts[fieldID] + dictKeys := s.DictKeys[fieldID] + + tfs := field.AnalyzedTokenFrequencies() + for term, tf := range tfs { + pidPlus1, exists := dict[term] + if !exists { + pidNext++ + pidPlus1 = uint64(pidNext) + + dict[term] = pidPlus1 + dictKeys = append(dictKeys, term) + + s.numTermsPerPostingsList = append(s.numTermsPerPostingsList, 0) + s.numLocsPerPostingsList = append(s.numLocsPerPostingsList, 0) + } + + pid := pidPlus1 - 1 + + s.numTermsPerPostingsList[pid] += 1 + s.numLocsPerPostingsList[pid] += len(tf.Locations) + + totLocs += len(tf.Locations) + } + + totTFs += len(tfs) + + s.DictKeys[fieldID] = dictKeys + } + + for _, result := range s.results { + // walk each composite field + result.VisitComposite(func(field index.CompositeField) { + visitField(field) + }) + + // walk each field + result.VisitFields(visitField) + } + + numPostingsLists := pidNext + + if cap(s.Postings) >= numPostingsLists { + s.Postings = s.Postings[:numPostingsLists] + } else { + postings := make([]*roaring.Bitmap, numPostingsLists) + copy(postings, s.Postings[:cap(s.Postings)]) + for i := 0; i < numPostingsLists; i++ { + if postings[i] == nil { + postings[i] = roaring.New() + } + } + s.Postings = postings + } + + if cap(s.FreqNorms) >= numPostingsLists { + s.FreqNorms = s.FreqNorms[:numPostingsLists] + } else { + s.FreqNorms = make([][]interimFreqNorm, numPostingsLists) + } + + if cap(s.freqNormsBacking) >= totTFs { + s.freqNormsBacking = s.freqNormsBacking[:totTFs] + } else { + s.freqNormsBacking = make([]interimFreqNorm, totTFs) + } + + freqNormsBacking := s.freqNormsBacking + for pid, numTerms := range s.numTermsPerPostingsList { + s.FreqNorms[pid] = freqNormsBacking[0:0] + freqNormsBacking = freqNormsBacking[numTerms:] + } + + if cap(s.Locs) >= numPostingsLists { + s.Locs = s.Locs[:numPostingsLists] + } else { + s.Locs = make([][]interimLoc, numPostingsLists) + } + + if cap(s.locsBacking) >= totLocs { + s.locsBacking = s.locsBacking[:totLocs] + } else { + s.locsBacking = make([]interimLoc, totLocs) + } + + locsBacking := s.locsBacking + for pid, numLocs := range s.numLocsPerPostingsList { + s.Locs[pid] = locsBacking[0:0] + locsBacking = locsBacking[numLocs:] + } +} + +func (s *interim) processDocuments() { + numFields := len(s.FieldsInv) + reuseFieldLens := make([]int, numFields) + reuseFieldTFs := make([]index.TokenFrequencies, numFields) + + for docNum, result := range s.results { + for i := 0; i < numFields; i++ { // clear these for reuse + reuseFieldLens[i] = 0 + reuseFieldTFs[i] = nil + } + + s.processDocument(uint64(docNum), result, + reuseFieldLens, reuseFieldTFs) + } +} + +func (s *interim) processDocument(docNum uint64, + result index.Document, + fieldLens []int, fieldTFs []index.TokenFrequencies) { + visitField := func(field index.Field) { + fieldID := uint16(s.getOrDefineField(field.Name())) + fieldLens[fieldID] += field.AnalyzedLength() + + existingFreqs := fieldTFs[fieldID] + if existingFreqs != nil { + existingFreqs.MergeAll(field.Name(), field.AnalyzedTokenFrequencies()) + } else { + fieldTFs[fieldID] = field.AnalyzedTokenFrequencies() + } + } + + // walk each composite field + result.VisitComposite(func(field index.CompositeField) { + visitField(field) + }) + + // walk each field + result.VisitFields(visitField) + + // now that it's been rolled up into fieldTFs, walk that + for fieldID, tfs := range fieldTFs { + dict := s.Dicts[fieldID] + norm := float32(1.0 / math.Sqrt(float64(fieldLens[fieldID]))) + + for term, tf := range tfs { + pid := dict[term] - 1 + bs := s.Postings[pid] + bs.Add(uint32(docNum)) + + s.FreqNorms[pid] = append(s.FreqNorms[pid], + interimFreqNorm{ + freq: uint64(tf.Frequency()), + norm: norm, + numLocs: len(tf.Locations), + }) + + if len(tf.Locations) > 0 { + locs := s.Locs[pid] + + for _, loc := range tf.Locations { + var locf = uint16(fieldID) + if loc.Field != "" { + locf = uint16(s.getOrDefineField(loc.Field)) + } + var arrayposs []uint64 + if len(loc.ArrayPositions) > 0 { + arrayposs = loc.ArrayPositions + } + locs = append(locs, interimLoc{ + fieldID: locf, + pos: uint64(loc.Position), + start: uint64(loc.Start), + end: uint64(loc.End), + arrayposs: arrayposs, + }) + } + + s.Locs[pid] = locs + } + } + } +} + +func (s *interim) writeStoredFields() ( + storedIndexOffset uint64, err error) { + varBuf := make([]byte, binary.MaxVarintLen64) + metaEncode := func(val uint64) (int, error) { + wb := binary.PutUvarint(varBuf, val) + return s.metaBuf.Write(varBuf[:wb]) + } + + data, compressed := s.tmp0[:0], s.tmp1[:0] + defer func() { s.tmp0, s.tmp1 = data, compressed }() + + // keyed by docNum + docStoredOffsets := make([]uint64, len(s.results)) + + // keyed by fieldID, for the current doc in the loop + docStoredFields := map[uint16]interimStoredField{} + + for docNum, result := range s.results { + for fieldID := range docStoredFields { // reset for next doc + delete(docStoredFields, fieldID) + } + + var validationErr error + result.VisitFields(func(field index.Field) { + fieldID := uint16(s.getOrDefineField(field.Name())) + + if field.Options().IsStored() { + isf := docStoredFields[fieldID] + isf.vals = append(isf.vals, field.Value()) + isf.typs = append(isf.typs, field.EncodedFieldType()) + isf.arrayposs = append(isf.arrayposs, field.ArrayPositions()) + docStoredFields[fieldID] = isf + } + + if field.Options().IncludeDocValues() { + s.IncludeDocValues[fieldID] = true + } + + err := ValidateDocFields(field) + if err != nil && validationErr == nil { + validationErr = err + } + }) + if validationErr != nil { + return 0, validationErr + } + + var curr int + + s.metaBuf.Reset() + data = data[:0] + + // _id field special case optimizes ExternalID() lookups + idFieldVal := docStoredFields[uint16(0)].vals[0] + _, err = metaEncode(uint64(len(idFieldVal))) + if err != nil { + return 0, err + } + + // handle non-"_id" fields + for fieldID := 1; fieldID < len(s.FieldsInv); fieldID++ { + isf, exists := docStoredFields[uint16(fieldID)] + if exists { + curr, data, err = persistStoredFieldValues( + fieldID, isf.vals, isf.typs, isf.arrayposs, + curr, metaEncode, data) + if err != nil { + return 0, err + } + } + } + + metaBytes := s.metaBuf.Bytes() + + compressed = snappy.Encode(compressed[:cap(compressed)], data) + + docStoredOffsets[docNum] = uint64(s.w.Count()) + + _, err := writeUvarints(s.w, + uint64(len(metaBytes)), + uint64(len(idFieldVal)+len(compressed))) + if err != nil { + return 0, err + } + + _, err = s.w.Write(metaBytes) + if err != nil { + return 0, err + } + + _, err = s.w.Write(idFieldVal) + if err != nil { + return 0, err + } + + _, err = s.w.Write(compressed) + if err != nil { + return 0, err + } + } + + storedIndexOffset = uint64(s.w.Count()) + + for _, docStoredOffset := range docStoredOffsets { + err = binary.Write(s.w, binary.BigEndian, docStoredOffset) + if err != nil { + return 0, err + } + } + + return storedIndexOffset, nil +} + +func (s *interim) writeDicts() (fdvIndexOffset uint64, dictOffsets []uint64, err error) { + dictOffsets = make([]uint64, len(s.FieldsInv)) + + fdvOffsetsStart := make([]uint64, len(s.FieldsInv)) + fdvOffsetsEnd := make([]uint64, len(s.FieldsInv)) + + buf := s.grabBuf(binary.MaxVarintLen64) + + // these int coders are initialized with chunk size 1024 + // however this will be reset to the correct chunk size + // while processing each individual field-term section + tfEncoder := newChunkedIntCoder(1024, uint64(len(s.results)-1)) + locEncoder := newChunkedIntCoder(1024, uint64(len(s.results)-1)) + + var docTermMap [][]byte + + if s.builder == nil { + s.builder, err = vellum.New(&s.builderBuf, nil) + if err != nil { + return 0, nil, err + } + } + + for fieldID, terms := range s.DictKeys { + if cap(docTermMap) < len(s.results) { + docTermMap = make([][]byte, len(s.results)) + } else { + docTermMap = docTermMap[0:len(s.results)] + for docNum := range docTermMap { // reset the docTermMap + docTermMap[docNum] = docTermMap[docNum][:0] + } + } + + dict := s.Dicts[fieldID] + + for _, term := range terms { // terms are already sorted + pid := dict[term] - 1 + + postingsBS := s.Postings[pid] + + freqNorms := s.FreqNorms[pid] + freqNormOffset := 0 + + locs := s.Locs[pid] + locOffset := 0 + + chunkSize, err := getChunkSize(s.chunkMode, postingsBS.GetCardinality(), uint64(len(s.results))) + if err != nil { + return 0, nil, err + } + tfEncoder.SetChunkSize(chunkSize, uint64(len(s.results)-1)) + locEncoder.SetChunkSize(chunkSize, uint64(len(s.results)-1)) + + postingsItr := postingsBS.Iterator() + for postingsItr.HasNext() { + docNum := uint64(postingsItr.Next()) + + freqNorm := freqNorms[freqNormOffset] + + err = tfEncoder.Add(docNum, + encodeFreqHasLocs(freqNorm.freq, freqNorm.numLocs > 0), + uint64(math.Float32bits(freqNorm.norm))) + if err != nil { + return 0, nil, err + } + + if freqNorm.numLocs > 0 { + numBytesLocs := 0 + for _, loc := range locs[locOffset : locOffset+freqNorm.numLocs] { + numBytesLocs += totalUvarintBytes( + uint64(loc.fieldID), loc.pos, loc.start, loc.end, + uint64(len(loc.arrayposs)), loc.arrayposs) + } + + err = locEncoder.Add(docNum, uint64(numBytesLocs)) + if err != nil { + return 0, nil, err + } + + for _, loc := range locs[locOffset : locOffset+freqNorm.numLocs] { + err = locEncoder.Add(docNum, + uint64(loc.fieldID), loc.pos, loc.start, loc.end, + uint64(len(loc.arrayposs))) + if err != nil { + return 0, nil, err + } + + err = locEncoder.Add(docNum, loc.arrayposs...) + if err != nil { + return 0, nil, err + } + } + + locOffset += freqNorm.numLocs + } + + freqNormOffset++ + + docTermMap[docNum] = append( + append(docTermMap[docNum], term...), + termSeparator) + } + + tfEncoder.Close() + locEncoder.Close() + + postingsOffset, err := + writePostings(postingsBS, tfEncoder, locEncoder, nil, s.w, buf) + if err != nil { + return 0, nil, err + } + + if postingsOffset > uint64(0) { + err = s.builder.Insert([]byte(term), postingsOffset) + if err != nil { + return 0, nil, err + } + } + + tfEncoder.Reset() + locEncoder.Reset() + } + + err = s.builder.Close() + if err != nil { + return 0, nil, err + } + + // record where this dictionary starts + dictOffsets[fieldID] = uint64(s.w.Count()) + + vellumData := s.builderBuf.Bytes() + + // write out the length of the vellum data + n := binary.PutUvarint(buf, uint64(len(vellumData))) + _, err = s.w.Write(buf[:n]) + if err != nil { + return 0, nil, err + } + + // write this vellum to disk + _, err = s.w.Write(vellumData) + if err != nil { + return 0, nil, err + } + + // reset vellum for reuse + s.builderBuf.Reset() + + err = s.builder.Reset(&s.builderBuf) + if err != nil { + return 0, nil, err + } + + // write the field doc values + // NOTE: doc values continue to use legacy chunk mode + chunkSize, err := getChunkSize(LegacyChunkMode, 0, 0) + if err != nil { + return 0, nil, err + } + fdvEncoder := newChunkedContentCoder(chunkSize, uint64(len(s.results)-1), s.w, false) + if s.IncludeDocValues[fieldID] { + for docNum, docTerms := range docTermMap { + if len(docTerms) > 0 { + err = fdvEncoder.Add(uint64(docNum), docTerms) + if err != nil { + return 0, nil, err + } + } + } + err = fdvEncoder.Close() + if err != nil { + return 0, nil, err + } + + fdvOffsetsStart[fieldID] = uint64(s.w.Count()) + + _, err = fdvEncoder.Write() + if err != nil { + return 0, nil, err + } + + fdvOffsetsEnd[fieldID] = uint64(s.w.Count()) + + fdvEncoder.Reset() + } else { + fdvOffsetsStart[fieldID] = fieldNotUninverted + fdvOffsetsEnd[fieldID] = fieldNotUninverted + } + } + + fdvIndexOffset = uint64(s.w.Count()) + + for i := 0; i < len(fdvOffsetsStart); i++ { + n := binary.PutUvarint(buf, fdvOffsetsStart[i]) + _, err := s.w.Write(buf[:n]) + if err != nil { + return 0, nil, err + } + n = binary.PutUvarint(buf, fdvOffsetsEnd[i]) + _, err = s.w.Write(buf[:n]) + if err != nil { + return 0, nil, err + } + } + + return fdvIndexOffset, dictOffsets, nil +} + +// returns the total # of bytes needed to encode the given uint64's +// into binary.PutUVarint() encoding +func totalUvarintBytes(a, b, c, d, e uint64, more []uint64) (n int) { + n = numUvarintBytes(a) + n += numUvarintBytes(b) + n += numUvarintBytes(c) + n += numUvarintBytes(d) + n += numUvarintBytes(e) + for _, v := range more { + n += numUvarintBytes(v) + } + return n +} + +// returns # of bytes needed to encode x in binary.PutUvarint() encoding +func numUvarintBytes(x uint64) (n int) { + for x >= 0x80 { + x >>= 7 + n++ + } + return n + 1 +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/plugin.go b/backend/vendor/github.com/blevesearch/zapx/v14/plugin.go new file mode 100644 index 0000000000..f67297ec2f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/plugin.go @@ -0,0 +1,27 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +// ZapPlugin implements the Plugin interface of +// the blevesearch/scorch_segment_api pkg +type ZapPlugin struct{} + +func (*ZapPlugin) Type() string { + return Type +} + +func (*ZapPlugin) Version() uint32 { + return Version +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/posting.go b/backend/vendor/github.com/blevesearch/zapx/v14/posting.go new file mode 100644 index 0000000000..8d138509d2 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/posting.go @@ -0,0 +1,835 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "encoding/binary" + "fmt" + "math" + "reflect" + + "github.com/RoaringBitmap/roaring" + segment "github.com/blevesearch/scorch_segment_api/v2" +) + +var reflectStaticSizePostingsList int +var reflectStaticSizePostingsIterator int +var reflectStaticSizePosting int +var reflectStaticSizeLocation int + +func init() { + var pl PostingsList + reflectStaticSizePostingsList = int(reflect.TypeOf(pl).Size()) + var pi PostingsIterator + reflectStaticSizePostingsIterator = int(reflect.TypeOf(pi).Size()) + var p Posting + reflectStaticSizePosting = int(reflect.TypeOf(p).Size()) + var l Location + reflectStaticSizeLocation = int(reflect.TypeOf(l).Size()) +} + +// FST or vellum value (uint64) encoding is determined by the top two +// highest-order or most significant bits... +// +// encoding : MSB +// name : 63 62 61...to...bit #0 (LSB) +// ----------+---+---+--------------------------------------------------- +// general : 0 | 0 | 62-bits of postingsOffset. +// ~ : 0 | 1 | reserved for future. +// 1-hit : 1 | 0 | 31-bits of positive float31 norm | 31-bits docNum. +// ~ : 1 | 1 | reserved for future. +// +// Encoding "general" is able to handle all cases, where the +// postingsOffset points to more information about the postings for +// the term. +// +// Encoding "1-hit" is used to optimize a commonly seen case when a +// term has only a single hit. For example, a term in the _id field +// will have only 1 hit. The "1-hit" encoding is used for a term +// in a field when... +// +// - term vector info is disabled for that field; +// - and, the term appears in only a single doc for that field; +// - and, the term's freq is exactly 1 in that single doc for that field; +// - and, the docNum must fit into 31-bits; +// +// Otherwise, the "general" encoding is used instead. +// +// In the "1-hit" encoding, the field in that single doc may have +// other terms, which is supported in the "1-hit" encoding by the +// positive float31 norm. + +const FSTValEncodingMask = uint64(0xc000000000000000) +const FSTValEncodingGeneral = uint64(0x0000000000000000) +const FSTValEncoding1Hit = uint64(0x8000000000000000) + +func FSTValEncode1Hit(docNum uint64, normBits uint64) uint64 { + return FSTValEncoding1Hit | ((mask31Bits & normBits) << 31) | (mask31Bits & docNum) +} + +func FSTValDecode1Hit(v uint64) (docNum uint64, normBits uint64) { + return (mask31Bits & v), (mask31Bits & (v >> 31)) +} + +const mask31Bits = uint64(0x000000007fffffff) + +func under32Bits(x uint64) bool { + return x <= mask31Bits +} + +const DocNum1HitFinished = math.MaxUint64 + +var NormBits1Hit = uint64(math.Float32bits(float32(1))) + +// PostingsList is an in-memory representation of a postings list +type PostingsList struct { + sb *SegmentBase + postingsOffset uint64 + freqOffset uint64 + locOffset uint64 + postings *roaring.Bitmap + except *roaring.Bitmap + + // when normBits1Hit != 0, then this postings list came from a + // 1-hit encoding, and only the docNum1Hit & normBits1Hit apply + docNum1Hit uint64 + normBits1Hit uint64 + + chunkSize uint64 +} + +// represents an immutable, empty postings list +var emptyPostingsList = &PostingsList{} + +// Following methods are dummy implementations for the interface +// DiskStatsReporter (for backward compatibility). +// The working implementations are supported only in zap v15.x +// and not in the earlier versions of zap. +func (i *PostingsList) ResetBytesRead(uint64) {} + +func (i *PostingsList) BytesRead() uint64 { + return 0 +} + +func (i *PostingsList) incrementBytesRead(uint64) {} + +func (i *PostingsList) BytesWritten() uint64 { + return 0 +} + +func (p *PostingsList) Size() int { + sizeInBytes := reflectStaticSizePostingsList + SizeOfPtr + + if p.except != nil { + sizeInBytes += int(p.except.GetSizeInBytes()) + } + + return sizeInBytes +} + +func (p *PostingsList) OrInto(receiver *roaring.Bitmap) { + if p.normBits1Hit != 0 { + receiver.Add(uint32(p.docNum1Hit)) + return + } + + if p.postings != nil { + receiver.Or(p.postings) + } +} + +// Iterator returns an iterator for this postings list +func (p *PostingsList) Iterator(includeFreq, includeNorm, includeLocs bool, + prealloc segment.PostingsIterator) segment.PostingsIterator { + if p.normBits1Hit == 0 && p.postings == nil { + return emptyPostingsIterator + } + + var preallocPI *PostingsIterator + pi, ok := prealloc.(*PostingsIterator) + if ok && pi != nil { + preallocPI = pi + } + if preallocPI == emptyPostingsIterator { + preallocPI = nil + } + + return p.iterator(includeFreq, includeNorm, includeLocs, preallocPI) +} + +func (p *PostingsList) iterator(includeFreq, includeNorm, includeLocs bool, + rv *PostingsIterator) *PostingsIterator { + if rv == nil { + rv = &PostingsIterator{} + } else { + freqNormReader := rv.freqNormReader + if freqNormReader != nil { + freqNormReader.reset() + } + + locReader := rv.locReader + if locReader != nil { + locReader.reset() + } + + nextLocs := rv.nextLocs[:0] + nextSegmentLocs := rv.nextSegmentLocs[:0] + + buf := rv.buf + + *rv = PostingsIterator{} // clear the struct + + rv.freqNormReader = freqNormReader + rv.locReader = locReader + + rv.nextLocs = nextLocs + rv.nextSegmentLocs = nextSegmentLocs + + rv.buf = buf + } + + rv.postings = p + rv.includeFreqNorm = includeFreq || includeNorm || includeLocs + rv.includeLocs = includeLocs + + if p.normBits1Hit != 0 { + // "1-hit" encoding + rv.docNum1Hit = p.docNum1Hit + rv.normBits1Hit = p.normBits1Hit + + if p.except != nil && p.except.Contains(uint32(rv.docNum1Hit)) { + rv.docNum1Hit = DocNum1HitFinished + } + + return rv + } + + // "general" encoding, check if empty + if p.postings == nil { + return rv + } + + // initialize freq chunk reader + if rv.includeFreqNorm { + rv.freqNormReader = newChunkedIntDecoder(p.sb.mem, p.freqOffset, rv.freqNormReader) + } + + // initialize the loc chunk reader + if rv.includeLocs { + rv.locReader = newChunkedIntDecoder(p.sb.mem, p.locOffset, rv.locReader) + } + + rv.all = p.postings.Iterator() + if p.except != nil { + rv.ActualBM = roaring.AndNot(p.postings, p.except) + rv.Actual = rv.ActualBM.Iterator() + } else { + rv.ActualBM = p.postings + rv.Actual = rv.all // Optimize to use same iterator for all & Actual. + } + + return rv +} + +// Count returns the number of items on this postings list +func (p *PostingsList) Count() uint64 { + var n, e uint64 + if p.normBits1Hit != 0 { + n = 1 + if p.except != nil && p.except.Contains(uint32(p.docNum1Hit)) { + e = 1 + } + } else if p.postings != nil { + n = p.postings.GetCardinality() + if p.except != nil { + e = p.postings.AndCardinality(p.except) + } + } + return n - e +} + +func (rv *PostingsList) read(postingsOffset uint64, d *Dictionary) error { + rv.postingsOffset = postingsOffset + + // handle "1-hit" encoding special case + if rv.postingsOffset&FSTValEncodingMask == FSTValEncoding1Hit { + return rv.init1Hit(postingsOffset) + } + + // read the location of the freq/norm details + var n uint64 + var read int + + rv.freqOffset, read = binary.Uvarint(d.sb.mem[postingsOffset+n : postingsOffset+binary.MaxVarintLen64]) + n += uint64(read) + + rv.locOffset, read = binary.Uvarint(d.sb.mem[postingsOffset+n : postingsOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + + var postingsLen uint64 + postingsLen, read = binary.Uvarint(d.sb.mem[postingsOffset+n : postingsOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + + roaringBytes := d.sb.mem[postingsOffset+n : postingsOffset+n+postingsLen] + + if rv.postings == nil { + rv.postings = roaring.NewBitmap() + } + _, err := rv.postings.FromBuffer(roaringBytes) + if err != nil { + return fmt.Errorf("error loading roaring bitmap: %v", err) + } + + rv.chunkSize, err = getChunkSize(d.sb.chunkMode, + rv.postings.GetCardinality(), d.sb.numDocs) + if err != nil { + return err + } + + return nil +} + +func (rv *PostingsList) init1Hit(fstVal uint64) error { + docNum, normBits := FSTValDecode1Hit(fstVal) + + rv.docNum1Hit = docNum + rv.normBits1Hit = normBits + + return nil +} + +// PostingsIterator provides a way to iterate through the postings list +type PostingsIterator struct { + postings *PostingsList + all roaring.IntPeekable + Actual roaring.IntPeekable + ActualBM *roaring.Bitmap + + currChunk uint32 + freqNormReader *chunkedIntDecoder + locReader *chunkedIntDecoder + + next Posting // reused across Next() calls + nextLocs []Location // reused across Next() calls + nextSegmentLocs []segment.Location // reused across Next() calls + + docNum1Hit uint64 + normBits1Hit uint64 + + buf []byte + + includeFreqNorm bool + includeLocs bool +} + +var emptyPostingsIterator = &PostingsIterator{} + +// Following methods are dummy implementations for the interface +// DiskStatsReporter (for backward compatibility). +// The working implementations are supported only in zap v15.x +// and not in the earlier versions of zap. +func (i *PostingsIterator) ResetBytesRead(uint64) {} + +func (i *PostingsIterator) BytesRead() uint64 { + return 0 +} + +func (i *PostingsIterator) incrementBytesRead(uint64) {} + +func (i *PostingsIterator) BytesWritten() uint64 { + return 0 +} + +func (i *PostingsIterator) Size() int { + sizeInBytes := reflectStaticSizePostingsIterator + SizeOfPtr + + i.next.Size() + // account for freqNormReader, locReader if we start using this. + for _, entry := range i.nextLocs { + sizeInBytes += entry.Size() + } + + return sizeInBytes +} + +func (i *PostingsIterator) loadChunk(chunk int) error { + if i.includeFreqNorm { + err := i.freqNormReader.loadChunk(chunk) + if err != nil { + return err + } + } + + if i.includeLocs { + err := i.locReader.loadChunk(chunk) + if err != nil { + return err + } + } + + i.currChunk = uint32(chunk) + return nil +} + +func (i *PostingsIterator) readFreqNormHasLocs() (uint64, uint64, bool, error) { + if i.normBits1Hit != 0 { + return 1, i.normBits1Hit, false, nil + } + + freqHasLocs, err := i.freqNormReader.readUvarint() + if err != nil { + return 0, 0, false, fmt.Errorf("error reading frequency: %v", err) + } + + freq, hasLocs := decodeFreqHasLocs(freqHasLocs) + + normBits, err := i.freqNormReader.readUvarint() + if err != nil { + return 0, 0, false, fmt.Errorf("error reading norm: %v", err) + } + + return freq, normBits, hasLocs, nil +} + +func (i *PostingsIterator) skipFreqNormReadHasLocs() (bool, error) { + if i.normBits1Hit != 0 { + return false, nil + } + + freqHasLocs, err := i.freqNormReader.readUvarint() + if err != nil { + return false, fmt.Errorf("error reading freqHasLocs: %v", err) + } + + i.freqNormReader.SkipUvarint() // Skip normBits. + + return freqHasLocs&0x01 != 0, nil // See decodeFreqHasLocs() / hasLocs. +} + +func encodeFreqHasLocs(freq uint64, hasLocs bool) uint64 { + rv := freq << 1 + if hasLocs { + rv = rv | 0x01 // 0'th LSB encodes whether there are locations + } + return rv +} + +func decodeFreqHasLocs(freqHasLocs uint64) (uint64, bool) { + freq := freqHasLocs >> 1 + hasLocs := freqHasLocs&0x01 != 0 + return freq, hasLocs +} + +// readLocation processes all the integers on the stream representing a single +// location. +func (i *PostingsIterator) readLocation(l *Location) error { + // read off field + fieldID, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location field: %v", err) + } + // read off pos + pos, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location pos: %v", err) + } + // read off start + start, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location start: %v", err) + } + // read off end + end, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location end: %v", err) + } + // read off num array pos + numArrayPos, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location num array pos: %v", err) + } + + l.field = i.postings.sb.fieldsInv[fieldID] + l.pos = pos + l.start = start + l.end = end + + if cap(l.ap) < int(numArrayPos) { + l.ap = make([]uint64, int(numArrayPos)) + } else { + l.ap = l.ap[:int(numArrayPos)] + } + + // read off array positions + for k := 0; k < int(numArrayPos); k++ { + ap, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading array position: %v", err) + } + + l.ap[k] = ap + } + + return nil +} + +// Next returns the next posting on the postings list, or nil at the end +func (i *PostingsIterator) Next() (segment.Posting, error) { + return i.nextAtOrAfter(0) +} + +// Advance returns the posting at the specified docNum or it is not present +// the next posting, or if the end is reached, nil +func (i *PostingsIterator) Advance(docNum uint64) (segment.Posting, error) { + return i.nextAtOrAfter(docNum) +} + +// Next returns the next posting on the postings list, or nil at the end +func (i *PostingsIterator) nextAtOrAfter(atOrAfter uint64) (segment.Posting, error) { + docNum, exists, err := i.nextDocNumAtOrAfter(atOrAfter) + if err != nil || !exists { + return nil, err + } + + i.next = Posting{} // clear the struct + rv := &i.next + rv.docNum = docNum + + if !i.includeFreqNorm { + return rv, nil + } + + var normBits uint64 + var hasLocs bool + + rv.freq, normBits, hasLocs, err = i.readFreqNormHasLocs() + if err != nil { + return nil, err + } + + rv.norm = math.Float32frombits(uint32(normBits)) + + if i.includeLocs && hasLocs { + // prepare locations into reused slices, where we assume + // rv.freq >= "number of locs", since in a composite field, + // some component fields might have their IncludeTermVector + // flags disabled while other component fields are enabled + if cap(i.nextLocs) >= int(rv.freq) { + i.nextLocs = i.nextLocs[0:rv.freq] + } else { + i.nextLocs = make([]Location, rv.freq, rv.freq*2) + } + if cap(i.nextSegmentLocs) < int(rv.freq) { + i.nextSegmentLocs = make([]segment.Location, rv.freq, rv.freq*2) + } + rv.locs = i.nextSegmentLocs[:0] + + numLocsBytes, err := i.locReader.readUvarint() + if err != nil { + return nil, fmt.Errorf("error reading location numLocsBytes: %v", err) + } + + j := 0 + startBytesRemaining := i.locReader.Len() // # bytes remaining in the locReader + for startBytesRemaining-i.locReader.Len() < int(numLocsBytes) { + err := i.readLocation(&i.nextLocs[j]) + if err != nil { + return nil, err + } + rv.locs = append(rv.locs, &i.nextLocs[j]) + j++ + } + } + + return rv, nil +} + +// nextDocNum returns the next docNum on the postings list, and also +// sets up the currChunk / loc related fields of the iterator. +func (i *PostingsIterator) nextDocNumAtOrAfter(atOrAfter uint64) (uint64, bool, error) { + if i.normBits1Hit != 0 { + if i.docNum1Hit == DocNum1HitFinished { + return 0, false, nil + } + if i.docNum1Hit < atOrAfter { + // advanced past our 1-hit + i.docNum1Hit = DocNum1HitFinished // consume our 1-hit docNum + return 0, false, nil + } + docNum := i.docNum1Hit + i.docNum1Hit = DocNum1HitFinished // consume our 1-hit docNum + return docNum, true, nil + } + + if i.Actual == nil || !i.Actual.HasNext() { + return 0, false, nil + } + + if i.postings == nil || i.postings == emptyPostingsList { + // couldn't find anything + return 0, false, nil + } + + if i.postings.postings == i.ActualBM { + return i.nextDocNumAtOrAfterClean(atOrAfter) + } + + i.Actual.AdvanceIfNeeded(uint32(atOrAfter)) + + if !i.Actual.HasNext() || !i.all.HasNext() { + // couldn't find anything + return 0, false, nil + } + + n := i.Actual.Next() + allN := i.all.Next() + nChunk := n / uint32(i.postings.chunkSize) + + // when allN becomes >= to here, then allN is in the same chunk as nChunk. + allNReachesNChunk := nChunk * uint32(i.postings.chunkSize) + + // n is the next actual hit (excluding some postings), and + // allN is the next hit in the full postings, and + // if they don't match, move 'all' forwards until they do + for allN != n { + // we've reached same chunk, so move the freq/norm/loc decoders forward + if i.includeFreqNorm && allN >= allNReachesNChunk { + err := i.currChunkNext(nChunk) + if err != nil { + return 0, false, err + } + } + + if !i.all.HasNext() { + return 0, false, nil + } + + allN = i.all.Next() + } + + if i.includeFreqNorm && (i.currChunk != nChunk || i.freqNormReader.isNil()) { + err := i.loadChunk(int(nChunk)) + if err != nil { + return 0, false, fmt.Errorf("error loading chunk: %v", err) + } + } + + return uint64(n), true, nil +} + +// optimization when the postings list is "clean" (e.g., no updates & +// no deletions) where the all bitmap is the same as the actual bitmap +func (i *PostingsIterator) nextDocNumAtOrAfterClean( + atOrAfter uint64) (uint64, bool, error) { + if !i.includeFreqNorm { + i.Actual.AdvanceIfNeeded(uint32(atOrAfter)) + + if !i.Actual.HasNext() { + return 0, false, nil // couldn't find anything + } + + return uint64(i.Actual.Next()), true, nil + } + + // freq-norm's needed, so maintain freq-norm chunk reader + sameChunkNexts := 0 // # of times we called Next() in the same chunk + n := i.Actual.Next() + nChunk := n / uint32(i.postings.chunkSize) + + for uint64(n) < atOrAfter && i.Actual.HasNext() { + n = i.Actual.Next() + + nChunkPrev := nChunk + nChunk = n / uint32(i.postings.chunkSize) + + if nChunk != nChunkPrev { + sameChunkNexts = 0 + } else { + sameChunkNexts += 1 + } + } + + if uint64(n) < atOrAfter { + // couldn't find anything + return 0, false, nil + } + + for j := 0; j < sameChunkNexts; j++ { + err := i.currChunkNext(nChunk) + if err != nil { + return 0, false, fmt.Errorf("error optimized currChunkNext: %v", err) + } + } + + if i.currChunk != nChunk || i.freqNormReader.isNil() { + err := i.loadChunk(int(nChunk)) + if err != nil { + return 0, false, fmt.Errorf("error loading chunk: %v", err) + } + } + + return uint64(n), true, nil +} + +func (i *PostingsIterator) currChunkNext(nChunk uint32) error { + if i.currChunk != nChunk || i.freqNormReader.isNil() { + err := i.loadChunk(int(nChunk)) + if err != nil { + return fmt.Errorf("error loading chunk: %v", err) + } + } + + // read off freq/offsets even though we don't care about them + hasLocs, err := i.skipFreqNormReadHasLocs() + if err != nil { + return err + } + + if i.includeLocs && hasLocs { + numLocsBytes, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location numLocsBytes: %v", err) + } + + // skip over all the location bytes + i.locReader.SkipBytes(int(numLocsBytes)) + } + + return nil +} + +// DocNum1Hit returns the docNum and true if this is "1-hit" optimized +// and the docNum is available. +func (p *PostingsIterator) DocNum1Hit() (uint64, bool) { + if p.normBits1Hit != 0 && p.docNum1Hit != DocNum1HitFinished { + return p.docNum1Hit, true + } + return 0, false +} + +// ActualBitmap returns the underlying actual bitmap +// which can be used up the stack for optimizations +func (p *PostingsIterator) ActualBitmap() *roaring.Bitmap { + return p.ActualBM +} + +// ReplaceActual replaces the ActualBM with the provided +// bitmap +func (p *PostingsIterator) ReplaceActual(abm *roaring.Bitmap) { + p.ActualBM = abm + p.Actual = abm.Iterator() +} + +// PostingsIteratorFromBitmap constructs a PostingsIterator given an +// "actual" bitmap. +func PostingsIteratorFromBitmap(bm *roaring.Bitmap, + includeFreqNorm, includeLocs bool) (segment.PostingsIterator, error) { + return &PostingsIterator{ + ActualBM: bm, + Actual: bm.Iterator(), + includeFreqNorm: includeFreqNorm, + includeLocs: includeLocs, + }, nil +} + +// PostingsIteratorFrom1Hit constructs a PostingsIterator given a +// 1-hit docNum. +func PostingsIteratorFrom1Hit(docNum1Hit uint64, + includeFreqNorm, includeLocs bool) (segment.PostingsIterator, error) { + return &PostingsIterator{ + docNum1Hit: docNum1Hit, + normBits1Hit: NormBits1Hit, + includeFreqNorm: includeFreqNorm, + includeLocs: includeLocs, + }, nil +} + +// Posting is a single entry in a postings list +type Posting struct { + docNum uint64 + freq uint64 + norm float32 + locs []segment.Location +} + +func (p *Posting) Size() int { + sizeInBytes := reflectStaticSizePosting + + for _, entry := range p.locs { + sizeInBytes += entry.Size() + } + + return sizeInBytes +} + +// Number returns the document number of this posting in this segment +func (p *Posting) Number() uint64 { + return p.docNum +} + +// Frequency returns the frequencies of occurrence of this term in this doc/field +func (p *Posting) Frequency() uint64 { + return p.freq +} + +// Norm returns the normalization factor for this posting +func (p *Posting) Norm() float64 { + return float64(p.norm) +} + +// Locations returns the location information for each occurrence +func (p *Posting) Locations() []segment.Location { + return p.locs +} + +// Location represents the location of a single occurrence +type Location struct { + field string + pos uint64 + start uint64 + end uint64 + ap []uint64 +} + +func (l *Location) Size() int { + return reflectStaticSizeLocation + + len(l.field) + + len(l.ap)*SizeOfUint64 +} + +// Field returns the name of the field (useful in composite fields to know +// which original field the value came from) +func (l *Location) Field() string { + return l.field +} + +// Start returns the start byte offset of this occurrence +func (l *Location) Start() uint64 { + return l.start +} + +// End returns the end byte offset of this occurrence +func (l *Location) End() uint64 { + return l.end +} + +// Pos returns the 1-based phrase position of this occurrence +func (l *Location) Pos() uint64 { + return l.pos +} + +// ArrayPositions returns the array position vector associated with this occurrence +func (l *Location) ArrayPositions() []uint64 { + return l.ap +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/read.go b/backend/vendor/github.com/blevesearch/zapx/v14/read.go new file mode 100644 index 0000000000..e47d4c6abd --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/read.go @@ -0,0 +1,43 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import "encoding/binary" + +func (s *SegmentBase) getDocStoredMetaAndCompressed(docNum uint64) ([]byte, []byte) { + _, storedOffset, n, metaLen, dataLen := s.getDocStoredOffsets(docNum) + + meta := s.mem[storedOffset+n : storedOffset+n+metaLen] + data := s.mem[storedOffset+n+metaLen : storedOffset+n+metaLen+dataLen] + + return meta, data +} + +func (s *SegmentBase) getDocStoredOffsets(docNum uint64) ( + uint64, uint64, uint64, uint64, uint64) { + indexOffset := s.storedIndexOffset + (8 * docNum) + + storedOffset := binary.BigEndian.Uint64(s.mem[indexOffset : indexOffset+8]) + + var n uint64 + + metaLen, read := binary.Uvarint(s.mem[storedOffset : storedOffset+binary.MaxVarintLen64]) + n += uint64(read) + + dataLen, read := binary.Uvarint(s.mem[storedOffset+n : storedOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + + return indexOffset, storedOffset, n, metaLen, dataLen +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/segment.go b/backend/vendor/github.com/blevesearch/zapx/v14/segment.go new file mode 100644 index 0000000000..1fbf78480f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/segment.go @@ -0,0 +1,600 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" + "os" + "sync" + "unsafe" + + "github.com/RoaringBitmap/roaring" + mmap "github.com/blevesearch/mmap-go" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" + "github.com/golang/snappy" +) + +var reflectStaticSizeSegmentBase int + +func init() { + var sb SegmentBase + reflectStaticSizeSegmentBase = int(unsafe.Sizeof(sb)) +} + +// Open returns a zap impl of a segment +func (*ZapPlugin) Open(path string) (segment.Segment, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + mm, err := mmap.Map(f, mmap.RDONLY, 0) + if err != nil { + // mmap failed, try to close the file + _ = f.Close() + return nil, err + } + + rv := &Segment{ + SegmentBase: SegmentBase{ + mem: mm[0 : len(mm)-FooterSize], + fieldsMap: make(map[string]uint16), + fieldDvReaders: make(map[uint16]*docValueReader), + fieldFSTs: make(map[uint16]*vellum.FST), + }, + f: f, + mm: mm, + path: path, + refs: 1, + } + rv.SegmentBase.updateSize() + + err = rv.loadConfig() + if err != nil { + _ = rv.Close() + return nil, err + } + + err = rv.loadFields() + if err != nil { + _ = rv.Close() + return nil, err + } + + err = rv.loadDvReaders() + if err != nil { + _ = rv.Close() + return nil, err + } + + return rv, nil +} + +// SegmentBase is a memory only, read-only implementation of the +// segment.Segment interface, using zap's data representation. +type SegmentBase struct { + mem []byte + memCRC uint32 + chunkMode uint32 + fieldsMap map[string]uint16 // fieldName -> fieldID+1 + fieldsInv []string // fieldID -> fieldName + numDocs uint64 + storedIndexOffset uint64 + fieldsIndexOffset uint64 + docValueOffset uint64 + dictLocs []uint64 + fieldDvReaders map[uint16]*docValueReader // naive chunk cache per field + fieldDvNames []string // field names cached in fieldDvReaders + size uint64 + + m sync.Mutex + fieldFSTs map[uint16]*vellum.FST +} + +func (sb *SegmentBase) Size() int { + return int(sb.size) +} + +func (sb *SegmentBase) updateSize() { + sizeInBytes := reflectStaticSizeSegmentBase + + cap(sb.mem) + + // fieldsMap + for k := range sb.fieldsMap { + sizeInBytes += (len(k) + SizeOfString) + SizeOfUint16 + } + + // fieldsInv, dictLocs + for _, entry := range sb.fieldsInv { + sizeInBytes += len(entry) + SizeOfString + } + sizeInBytes += len(sb.dictLocs) * SizeOfUint64 + + // fieldDvReaders + for _, v := range sb.fieldDvReaders { + sizeInBytes += SizeOfUint16 + SizeOfPtr + if v != nil { + sizeInBytes += v.size() + } + } + + sb.size = uint64(sizeInBytes) +} + +func (sb *SegmentBase) AddRef() {} +func (sb *SegmentBase) DecRef() (err error) { return nil } +func (sb *SegmentBase) Close() (err error) { return nil } + +// Segment implements a persisted segment.Segment interface, by +// embedding an mmap()'ed SegmentBase. +type Segment struct { + SegmentBase + + f *os.File + mm mmap.MMap + path string + version uint32 + crc uint32 + + m sync.Mutex // Protects the fields that follow. + refs int64 +} + +func (s *Segment) Size() int { + // 8 /* size of file pointer */ + // 4 /* size of version -> uint32 */ + // 4 /* size of crc -> uint32 */ + sizeOfUints := 16 + + sizeInBytes := (len(s.path) + SizeOfString) + sizeOfUints + + // mutex, refs -> int64 + sizeInBytes += 16 + + // do not include the mmap'ed part + return sizeInBytes + s.SegmentBase.Size() - cap(s.mem) +} + +func (s *Segment) AddRef() { + s.m.Lock() + s.refs++ + s.m.Unlock() +} + +func (s *Segment) DecRef() (err error) { + s.m.Lock() + s.refs-- + if s.refs == 0 { + err = s.closeActual() + } + s.m.Unlock() + return err +} + +func (s *Segment) loadConfig() error { + crcOffset := len(s.mm) - 4 + s.crc = binary.BigEndian.Uint32(s.mm[crcOffset : crcOffset+4]) + + verOffset := crcOffset - 4 + s.version = binary.BigEndian.Uint32(s.mm[verOffset : verOffset+4]) + if s.version != Version { + return fmt.Errorf("unsupported version %d", s.version) + } + + chunkOffset := verOffset - 4 + s.chunkMode = binary.BigEndian.Uint32(s.mm[chunkOffset : chunkOffset+4]) + + docValueOffset := chunkOffset - 8 + s.docValueOffset = binary.BigEndian.Uint64(s.mm[docValueOffset : docValueOffset+8]) + + fieldsIndexOffset := docValueOffset - 8 + s.fieldsIndexOffset = binary.BigEndian.Uint64(s.mm[fieldsIndexOffset : fieldsIndexOffset+8]) + + storedIndexOffset := fieldsIndexOffset - 8 + s.storedIndexOffset = binary.BigEndian.Uint64(s.mm[storedIndexOffset : storedIndexOffset+8]) + + numDocsOffset := storedIndexOffset - 8 + s.numDocs = binary.BigEndian.Uint64(s.mm[numDocsOffset : numDocsOffset+8]) + return nil +} + +// Following methods are dummy implementations for the interface +// DiskStatsReporter (for backward compatibility). +// The working implementations are supported only in zap v15.x +// and not in the earlier versions of zap. +func (s *Segment) ResetBytesRead(uint64) {} + +func (s *Segment) BytesRead() uint64 { + return 0 +} + +func (s *Segment) BytesWritten() uint64 { + return 0 +} + +func (s *Segment) incrementBytesRead(uint64) {} + +func (s *SegmentBase) BytesWritten() uint64 { + return 0 +} + +func (s *SegmentBase) setBytesWritten(uint64) {} + +func (s *SegmentBase) BytesRead() uint64 { + return 0 +} + +func (s *SegmentBase) ResetBytesRead(uint64) {} + +func (s *SegmentBase) incrementBytesRead(uint64) {} + +func (s *SegmentBase) loadFields() error { + // NOTE for now we assume the fields index immediately precedes + // the footer, and if this changes, need to adjust accordingly (or + // store explicit length), where s.mem was sliced from s.mm in Open(). + fieldsIndexEnd := uint64(len(s.mem)) + + // iterate through fields index + var fieldID uint64 + for s.fieldsIndexOffset+(8*fieldID) < fieldsIndexEnd { + addr := binary.BigEndian.Uint64(s.mem[s.fieldsIndexOffset+(8*fieldID) : s.fieldsIndexOffset+(8*fieldID)+8]) + + dictLoc, read := binary.Uvarint(s.mem[addr:fieldsIndexEnd]) + n := uint64(read) + s.dictLocs = append(s.dictLocs, dictLoc) + + var nameLen uint64 + nameLen, read = binary.Uvarint(s.mem[addr+n : fieldsIndexEnd]) + n += uint64(read) + + name := string(s.mem[addr+n : addr+n+nameLen]) + s.fieldsInv = append(s.fieldsInv, name) + s.fieldsMap[name] = uint16(fieldID + 1) + + fieldID++ + } + return nil +} + +// Dictionary returns the term dictionary for the specified field +func (s *SegmentBase) Dictionary(field string) (segment.TermDictionary, error) { + dict, err := s.dictionary(field) + if err == nil && dict == nil { + return emptyDictionary, nil + } + return dict, err +} + +func (sb *SegmentBase) dictionary(field string) (rv *Dictionary, err error) { + fieldIDPlus1 := sb.fieldsMap[field] + if fieldIDPlus1 > 0 { + rv = &Dictionary{ + sb: sb, + field: field, + fieldID: fieldIDPlus1 - 1, + } + + dictStart := sb.dictLocs[rv.fieldID] + if dictStart > 0 { + var ok bool + sb.m.Lock() + if rv.fst, ok = sb.fieldFSTs[rv.fieldID]; !ok { + // read the length of the vellum data + vellumLen, read := binary.Uvarint(sb.mem[dictStart : dictStart+binary.MaxVarintLen64]) + fstBytes := sb.mem[dictStart+uint64(read) : dictStart+uint64(read)+vellumLen] + rv.fst, err = vellum.Load(fstBytes) + if err != nil { + sb.m.Unlock() + return nil, fmt.Errorf("dictionary field %s vellum err: %v", field, err) + } + + sb.fieldFSTs[rv.fieldID] = rv.fst + } + + sb.m.Unlock() + rv.fstReader, err = rv.fst.Reader() + if err != nil { + return nil, fmt.Errorf("dictionary field %s vellum reader err: %v", field, err) + } + } + } + + return rv, nil +} + +// visitDocumentCtx holds data structures that are reusable across +// multiple VisitDocument() calls to avoid memory allocations +type visitDocumentCtx struct { + buf []byte + reader bytes.Reader + arrayPos []uint64 +} + +var visitDocumentCtxPool = sync.Pool{ + New: func() interface{} { + reuse := &visitDocumentCtx{} + return reuse + }, +} + +// VisitStoredFields invokes the StoredFieldValueVisitor for each stored field +// for the specified doc number +func (s *SegmentBase) VisitStoredFields(num uint64, visitor segment.StoredFieldValueVisitor) error { + vdc := visitDocumentCtxPool.Get().(*visitDocumentCtx) + defer visitDocumentCtxPool.Put(vdc) + return s.visitStoredFields(vdc, num, visitor) +} + +func (s *SegmentBase) visitStoredFields(vdc *visitDocumentCtx, num uint64, + visitor segment.StoredFieldValueVisitor) error { + // first make sure this is a valid number in this segment + if num < s.numDocs { + meta, compressed := s.getDocStoredMetaAndCompressed(num) + + vdc.reader.Reset(meta) + + // handle _id field special case + idFieldValLen, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + idFieldVal := compressed[:idFieldValLen] + + keepGoing := visitor("_id", byte('t'), idFieldVal, nil) + if !keepGoing { + visitDocumentCtxPool.Put(vdc) + return nil + } + + // handle non-"_id" fields + compressed = compressed[idFieldValLen:] + + uncompressed, err := snappy.Decode(vdc.buf[:cap(vdc.buf)], compressed) + if err != nil { + return err + } + + for keepGoing { + field, err := binary.ReadUvarint(&vdc.reader) + if err == io.EOF { + break + } + if err != nil { + return err + } + typ, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + offset, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + l, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + numap, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + var arrayPos []uint64 + if numap > 0 { + if cap(vdc.arrayPos) < int(numap) { + vdc.arrayPos = make([]uint64, numap) + } + arrayPos = vdc.arrayPos[:numap] + for i := 0; i < int(numap); i++ { + ap, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + arrayPos[i] = ap + } + } + + value := uncompressed[offset : offset+l] + keepGoing = visitor(s.fieldsInv[field], byte(typ), value, arrayPos) + } + + vdc.buf = uncompressed + } + return nil +} + +// DocID returns the value of the _id field for the given docNum +func (s *SegmentBase) DocID(num uint64) ([]byte, error) { + if num >= s.numDocs { + return nil, nil + } + + vdc := visitDocumentCtxPool.Get().(*visitDocumentCtx) + + meta, compressed := s.getDocStoredMetaAndCompressed(num) + + vdc.reader.Reset(meta) + + // handle _id field special case + idFieldValLen, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return nil, err + } + idFieldVal := compressed[:idFieldValLen] + + visitDocumentCtxPool.Put(vdc) + + return idFieldVal, nil +} + +// Count returns the number of documents in this segment. +func (s *SegmentBase) Count() uint64 { + return s.numDocs +} + +// DocNumbers returns a bitset corresponding to the doc numbers of all the +// provided _id strings +func (s *SegmentBase) DocNumbers(ids []string) (*roaring.Bitmap, error) { + rv := roaring.New() + + if len(s.fieldsMap) > 0 { + idDict, err := s.dictionary("_id") + if err != nil { + return nil, err + } + + postingsList := emptyPostingsList + + sMax, err := idDict.fst.GetMaxKey() + if err != nil { + return nil, err + } + sMaxStr := string(sMax) + filteredIds := make([]string, 0, len(ids)) + for _, id := range ids { + if id <= sMaxStr { + filteredIds = append(filteredIds, id) + } + } + + for _, id := range filteredIds { + postingsList, err = idDict.postingsList([]byte(id), nil, postingsList) + if err != nil { + return nil, err + } + postingsList.OrInto(rv) + } + } + + return rv, nil +} + +// Fields returns the field names used in this segment +func (s *SegmentBase) Fields() []string { + return s.fieldsInv +} + +// Path returns the path of this segment on disk +func (s *Segment) Path() string { + return s.path +} + +// Close releases all resources associated with this segment +func (s *Segment) Close() (err error) { + return s.DecRef() +} + +func (s *Segment) closeActual() (err error) { + if s.mm != nil { + err = s.mm.Unmap() + } + // try to close file even if unmap failed + if s.f != nil { + err2 := s.f.Close() + if err == nil { + // try to return first error + err = err2 + } + } + return +} + +// some helpers i started adding for the command-line utility + +// Data returns the underlying mmaped data slice +func (s *Segment) Data() []byte { + return s.mm +} + +// CRC returns the CRC value stored in the file footer +func (s *Segment) CRC() uint32 { + return s.crc +} + +// Version returns the file version in the file footer +func (s *Segment) Version() uint32 { + return s.version +} + +// ChunkFactor returns the chunk factor in the file footer +func (s *Segment) ChunkMode() uint32 { + return s.chunkMode +} + +// FieldsIndexOffset returns the fields index offset in the file footer +func (s *Segment) FieldsIndexOffset() uint64 { + return s.fieldsIndexOffset +} + +// StoredIndexOffset returns the stored value index offset in the file footer +func (s *Segment) StoredIndexOffset() uint64 { + return s.storedIndexOffset +} + +// DocValueOffset returns the docValue offset in the file footer +func (s *Segment) DocValueOffset() uint64 { + return s.docValueOffset +} + +// NumDocs returns the number of documents in the file footer +func (s *Segment) NumDocs() uint64 { + return s.numDocs +} + +// DictAddr is a helper function to compute the file offset where the +// dictionary is stored for the specified field. +func (s *Segment) DictAddr(field string) (uint64, error) { + fieldIDPlus1, ok := s.fieldsMap[field] + if !ok { + return 0, fmt.Errorf("no such field '%s'", field) + } + + return s.dictLocs[fieldIDPlus1-1], nil +} + +func (s *SegmentBase) loadDvReaders() error { + if s.docValueOffset == fieldNotUninverted || s.numDocs == 0 { + return nil + } + + var read uint64 + for fieldID, field := range s.fieldsInv { + var fieldLocStart, fieldLocEnd uint64 + var n int + fieldLocStart, n = binary.Uvarint(s.mem[s.docValueOffset+read : s.docValueOffset+read+binary.MaxVarintLen64]) + if n <= 0 { + return fmt.Errorf("loadDvReaders: failed to read the docvalue offset start for field %d", fieldID) + } + read += uint64(n) + fieldLocEnd, n = binary.Uvarint(s.mem[s.docValueOffset+read : s.docValueOffset+read+binary.MaxVarintLen64]) + if n <= 0 { + return fmt.Errorf("loadDvReaders: failed to read the docvalue offset end for field %d", fieldID) + } + read += uint64(n) + + fieldDvReader, err := s.loadFieldDocValueReader(field, fieldLocStart, fieldLocEnd) + if err != nil { + return err + } + if fieldDvReader != nil { + s.fieldDvReaders[uint16(fieldID)] = fieldDvReader + s.fieldDvNames = append(s.fieldDvNames, field) + } + } + + return nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/sizes.go b/backend/vendor/github.com/blevesearch/zapx/v14/sizes.go new file mode 100644 index 0000000000..34166ea330 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/sizes.go @@ -0,0 +1,59 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "reflect" +) + +func init() { + var b bool + SizeOfBool = int(reflect.TypeOf(b).Size()) + var f32 float32 + SizeOfFloat32 = int(reflect.TypeOf(f32).Size()) + var f64 float64 + SizeOfFloat64 = int(reflect.TypeOf(f64).Size()) + var i int + SizeOfInt = int(reflect.TypeOf(i).Size()) + var m map[int]int + SizeOfMap = int(reflect.TypeOf(m).Size()) + var ptr *int + SizeOfPtr = int(reflect.TypeOf(ptr).Size()) + var slice []int + SizeOfSlice = int(reflect.TypeOf(slice).Size()) + var str string + SizeOfString = int(reflect.TypeOf(str).Size()) + var u8 uint8 + SizeOfUint8 = int(reflect.TypeOf(u8).Size()) + var u16 uint16 + SizeOfUint16 = int(reflect.TypeOf(u16).Size()) + var u32 uint32 + SizeOfUint32 = int(reflect.TypeOf(u32).Size()) + var u64 uint64 + SizeOfUint64 = int(reflect.TypeOf(u64).Size()) +} + +var SizeOfBool int +var SizeOfFloat32 int +var SizeOfFloat64 int +var SizeOfInt int +var SizeOfMap int +var SizeOfPtr int +var SizeOfSlice int +var SizeOfString int +var SizeOfUint8 int +var SizeOfUint16 int +var SizeOfUint32 int +var SizeOfUint64 int diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/write.go b/backend/vendor/github.com/blevesearch/zapx/v14/write.go new file mode 100644 index 0000000000..77aefdbfc8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/write.go @@ -0,0 +1,145 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "encoding/binary" + "io" + + "github.com/RoaringBitmap/roaring" +) + +// writes out the length of the roaring bitmap in bytes as varint +// then writes out the roaring bitmap itself +func writeRoaringWithLen(r *roaring.Bitmap, w io.Writer, + reuseBufVarint []byte) (int, error) { + buf, err := r.ToBytes() + if err != nil { + return 0, err + } + + var tw int + + // write out the length + n := binary.PutUvarint(reuseBufVarint, uint64(len(buf))) + nw, err := w.Write(reuseBufVarint[:n]) + tw += nw + if err != nil { + return tw, err + } + + // write out the roaring bytes + nw, err = w.Write(buf) + tw += nw + if err != nil { + return tw, err + } + + return tw, nil +} + +func persistFields(fieldsInv []string, w *CountHashWriter, dictLocs []uint64) (uint64, error) { + var rv uint64 + var fieldsOffsets []uint64 + + for fieldID, fieldName := range fieldsInv { + // record start of this field + fieldsOffsets = append(fieldsOffsets, uint64(w.Count())) + + // write out the dict location and field name length + _, err := writeUvarints(w, dictLocs[fieldID], uint64(len(fieldName))) + if err != nil { + return 0, err + } + + // write out the field name + _, err = w.Write([]byte(fieldName)) + if err != nil { + return 0, err + } + } + + // now write out the fields index + rv = uint64(w.Count()) + for fieldID := range fieldsInv { + err := binary.Write(w, binary.BigEndian, fieldsOffsets[fieldID]) + if err != nil { + return 0, err + } + } + + return rv, nil +} + +// FooterSize is the size of the footer record in bytes +// crc + ver + chunk + field offset + stored offset + num docs + docValueOffset +const FooterSize = 4 + 4 + 4 + 8 + 8 + 8 + 8 + +func persistFooter(numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset uint64, + chunkMode uint32, crcBeforeFooter uint32, writerIn io.Writer) error { + w := NewCountHashWriter(writerIn) + w.crc = crcBeforeFooter + + // write out the number of docs + err := binary.Write(w, binary.BigEndian, numDocs) + if err != nil { + return err + } + // write out the stored field index location: + err = binary.Write(w, binary.BigEndian, storedIndexOffset) + if err != nil { + return err + } + // write out the field index location + err = binary.Write(w, binary.BigEndian, fieldsIndexOffset) + if err != nil { + return err + } + // write out the fieldDocValue location + err = binary.Write(w, binary.BigEndian, docValueOffset) + if err != nil { + return err + } + // write out 32-bit chunk factor + err = binary.Write(w, binary.BigEndian, chunkMode) + if err != nil { + return err + } + // write out 32-bit version + err = binary.Write(w, binary.BigEndian, Version) + if err != nil { + return err + } + // write out CRC-32 of everything upto but not including this CRC + err = binary.Write(w, binary.BigEndian, w.crc) + if err != nil { + return err + } + return nil +} + +func writeUvarints(w io.Writer, vals ...uint64) (tw int, err error) { + buf := make([]byte, binary.MaxVarintLen64) + for _, val := range vals { + n := binary.PutUvarint(buf, val) + var nw int + nw, err = w.Write(buf[:n]) + tw += nw + if err != nil { + return tw, err + } + } + return tw, err +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v14/zap.md b/backend/vendor/github.com/blevesearch/zapx/v14/zap.md new file mode 100644 index 0000000000..d74dc548b8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v14/zap.md @@ -0,0 +1,177 @@ +# ZAP File Format + +## Legend + +### Sections + + |========| + | | section + |========| + +### Fixed-size fields + + |--------| |----| |--| |-| + | | uint64 | | uint32 | | uint16 | | uint8 + |--------| |----| |--| |-| + +### Varints + + |~~~~~~~~| + | | varint(up to uint64) + |~~~~~~~~| + +### Arbitrary-length fields + + |--------...---| + | | arbitrary-length field (string, vellum, roaring bitmap) + |--------...---| + +### Chunked data + + [--------] + [ ] + [--------] + +## Overview + +Footer section describes the configuration of particular ZAP file. The format of footer is version-dependent, so it is necessary to check `V` field before the parsing. + + |==================================================| + | Stored Fields | + |==================================================| + |-----> | Stored Fields Index | + | |==================================================| + | | Dictionaries + Postings + DocValues | + | |==================================================| + | |---> | DocValues Index | + | | |==================================================| + | | | Fields | + | | |==================================================| + | | |-> | Fields Index | + | | | |========|========|========|========|====|====|====| + | | | | D# | SF | F | FDV | CF | V | CC | (Footer) + | | | |========|====|===|====|===|====|===|====|====|====| + | | | | | | + |-+-+-----------------| | | + | |--------------------------| | + |-------------------------------------| + + D#. Number of Docs. + SF. Stored Fields Index Offset. + F. Field Index Offset. + FDV. Field DocValue Offset. + CF. Chunk Factor. + V. Version. + CC. CRC32. + +## Stored Fields + +Stored Fields Index is `D#` consecutive 64-bit unsigned integers - offsets, where relevant Stored Fields Data records are located. + + 0 [SF] [SF + D# * 8] + | Stored Fields | Stored Fields Index | + |================================|==================================| + | | | + | |--------------------| ||--------|--------|. . .|--------|| + | |-> | Stored Fields Data | || 0 | 1 | | D# - 1 || + | | |--------------------| ||--------|----|---|. . .|--------|| + | | | | | + |===|============================|==============|===================| + | | + |-------------------------------------------| + +Stored Fields Data is an arbitrary size record, which consists of metadata and [Snappy](https://github.com/golang/snappy)-compressed data. + + Stored Fields Data + |~~~~~~~~|~~~~~~~~|~~~~~~~~...~~~~~~~~|~~~~~~~~...~~~~~~~~| + | MDS | CDS | MD | CD | + |~~~~~~~~|~~~~~~~~|~~~~~~~~...~~~~~~~~|~~~~~~~~...~~~~~~~~| + + MDS. Metadata size. + CDS. Compressed data size. + MD. Metadata. + CD. Snappy-compressed data. + +## Fields + +Fields Index section located between addresses `F` and `len(file) - len(footer)` and consist of `uint64` values (`F1`, `F2`, ...) which are offsets to records in Fields section. We have `F# = (len(file) - len(footer) - F) / sizeof(uint64)` fields. + + + (...) [F] [F + F#] + | Fields | Fields Index. | + |================================|================================| + | | | + | |~~~~~~~~|~~~~~~~~|---...---|||--------|--------|...|--------|| + ||->| Dict | Length | Name ||| 0 | 1 | | F# - 1 || + || |~~~~~~~~|~~~~~~~~|---...---|||--------|----|---|...|--------|| + || | | | + ||===============================|==============|=================| + | | + |----------------------------------------------| + + +## Dictionaries + Postings + +Each of fields has its own dictionary, encoded in [Vellum](https://github.com/couchbase/vellum) format. Dictionary consists of pairs `(term, offset)`, where `offset` indicates the position of postings (list of documents) for this particular term. + + |================================================================|- Dictionaries + + | | Postings + + | | DocValues + | Freq/Norm (chunked) | + | [~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] | + | |->[ Freq | Norm (float32 under varint) ] | + | | [~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] | + | | | + | |------------------------------------------------------------| | + | Location Details (chunked) | | + | [~~~~~~|~~~~~|~~~~~~~|~~~~~|~~~~~~|~~~~~~~~|~~~~~] | | + | |->[ Size | Pos | Start | End | Arr# | ArrPos | ... ] | | + | | [~~~~~~|~~~~~|~~~~~~~|~~~~~|~~~~~~|~~~~~~~~|~~~~~] | | + | | | | + | |----------------------| | | + | Postings List | | | + | |~~~~~~~~|~~~~~|~~|~~~~~~~~|-----------...--| | | + | |->| F/N | LD | Length | ROARING BITMAP | | | + | | |~~~~~|~~|~~~~~~~~|~~~~~~~~|-----------...--| | | + | | |----------------------------------------------| | + | |--------------------------------------| | + | Dictionary | | + | |~~~~~~~~|--------------------------|-...-| | + | |->| Length | VELLUM DATA : (TERM -> OFFSET) | | + | | |~~~~~~~~|----------------------------...-| | + | | | + |======|=========================================================|- DocValues Index + | | | + |======|=========================================================|- Fields + | | | + | |~~~~|~~~|~~~~~~~~|---...---| | + | | Dict | Length | Name | | + | |~~~~~~~~|~~~~~~~~|---...---| | + | | + |================================================================| + +## DocValues + +DocValues Index is `F#` pairs of varints, one pair per field. Each pair of varints indicates start and end point of DocValues slice. + + |================================================================| + | |------...--| | + | |->| DocValues |<-| | + | | |------...--| | | + |==|=================|===========================================|- DocValues Index + ||~|~~~~~~~~~|~~~~~~~|~~| |~~~~~~~~~~~~~~|~~~~~~~~~~~~|| + || DV1 START | DV1 STOP | . . . . . | DV(F#) START | DV(F#) END || + ||~~~~~~~~~~~|~~~~~~~~~~| |~~~~~~~~~~~~~~|~~~~~~~~~~~~|| + |================================================================| + +DocValues is chunked Snappy-compressed values for each document and field. + + [~~~~~~~~~~~~~~~|~~~~~~|~~~~~~~~~|-...-|~~~~~~|~~~~~~~~~|--------------------...-] + [ Doc# in Chunk | Doc1 | Offset1 | ... | DocN | OffsetN | SNAPPY COMPRESSED DATA ] + [~~~~~~~~~~~~~~~|~~~~~~|~~~~~~~~~|-...-|~~~~~~|~~~~~~~~~|--------------------...-] + +Last 16 bytes are description of chunks. + + |~~~~~~~~~~~~...~|----------------|----------------| + | Chunk Sizes | Chunk Size Arr | Chunk# | + |~~~~~~~~~~~~...~|----------------|----------------| diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/.gitignore b/backend/vendor/github.com/blevesearch/zapx/v15/.gitignore new file mode 100644 index 0000000000..46d1cfad54 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/.gitignore @@ -0,0 +1,12 @@ +#* +*.sublime-* +*~ +.#* +.project +.settings +**/.idea/ +**/*.iml +.DS_Store +/cmd/zap/zap +*.test +tags diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/.golangci.yml b/backend/vendor/github.com/blevesearch/zapx/v15/.golangci.yml new file mode 100644 index 0000000000..1d55bfc00d --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/.golangci.yml @@ -0,0 +1,28 @@ +linters: + # please, do not use `enable-all`: it's deprecated and will be removed soon. + # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint + disable-all: true + enable: + - bodyclose + - deadcode + - depguard + - dupl + - errcheck + - gofmt + - goimports + - goprintffuncname + - gosec + - gosimple + - govet + - ineffassign + - misspell + - nakedret + - nolintlint + - rowserrcheck + - staticcheck + - structcheck + - typecheck + - unused + - varcheck + - whitespace + diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/LICENSE b/backend/vendor/github.com/blevesearch/zapx/v15/LICENSE new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/README.md b/backend/vendor/github.com/blevesearch/zapx/v15/README.md new file mode 100644 index 0000000000..4cbf1a145b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/README.md @@ -0,0 +1,163 @@ +# zapx file format + +The zapx module is fork of [zap](https://github.com/blevesearch/zap) module which maintains file format compatibility, but removes dependency on bleve, and instead depends only on the indepenent interface modules: + +- [bleve_index_api](https://github.com/blevesearch/scorch_segment_api) +- [scorch_segment_api](https://github.com/blevesearch/scorch_segment_api) + +Advanced ZAP File Format Documentation is [here](zap.md). + +The file is written in the reverse order that we typically access data. This helps us write in one pass since later sections of the file require file offsets of things we've already written. + +Current usage: + +- mmap the entire file +- crc-32 bytes and version are in fixed position at end of the file +- reading remainder of footer could be version specific +- remainder of footer gives us: + - 3 important offsets (docValue , fields index and stored data index) + - 2 important values (number of docs and chunk factor) +- field data is processed once and memoized onto the heap so that we never have to go back to disk for it +- access to stored data by doc number means first navigating to the stored data index, then accessing a fixed position offset into that slice, which gives us the actual address of the data. the first bytes of that section tell us the size of data so that we know where it ends. +- access to all other indexed data follows the following pattern: + - first know the field name -> convert to id + - next navigate to term dictionary for that field + - some operations stop here and do dictionary ops + - next use dictionary to navigate to posting list for a specific term + - walk posting list + - if necessary, walk posting details as we go + - if location info is desired, consult location bitmap to see if it is there + +## stored fields section + +- for each document + - preparation phase: + - produce a slice of metadata bytes and data bytes + - produce these slices in field id order + - field value is appended to the data slice + - metadata slice is varint encoded with the following values for each field value + - field id (uint16) + - field type (byte) + - field value start offset in uncompressed data slice (uint64) + - field value length (uint64) + - field number of array positions (uint64) + - one additional value for each array position (uint64) + - compress the data slice using snappy + - file writing phase: + - remember the start offset for this document + - write out meta data length (varint uint64) + - write out compressed data length (varint uint64) + - write out the metadata bytes + - write out the compressed data bytes + +## stored fields idx + +- for each document + - write start offset (remembered from previous section) of stored data (big endian uint64) + +With this index and a known document number, we have direct access to all the stored field data. + +## posting details (freq/norm) section + +- for each posting list + - produce a slice containing multiple consecutive chunks (each chunk is varint stream) + - produce a slice remembering offsets of where each chunk starts + - preparation phase: + - for each hit in the posting list + - if this hit is in next chunk close out encoding of last chunk and record offset start of next + - encode term frequency (uint64) + - encode norm factor (float32) + - file writing phase: + - remember start position for this posting list details + - write out number of chunks that follow (varint uint64) + - write out length of each chunk (each a varint uint64) + - write out the byte slice containing all the chunk data + +If you know the doc number you're interested in, this format lets you jump to the correct chunk (docNum/chunkFactor) directly and then seek within that chunk until you find it. + +## posting details (location) section + +- for each posting list + - produce a slice containing multiple consecutive chunks (each chunk is varint stream) + - produce a slice remembering offsets of where each chunk starts + - preparation phase: + - for each hit in the posting list + - if this hit is in next chunk close out encoding of last chunk and record offset start of next + - encode field (uint16) + - encode field pos (uint64) + - encode field start (uint64) + - encode field end (uint64) + - encode number of array positions to follow (uint64) + - encode each array position (each uint64) + - file writing phase: + - remember start position for this posting list details + - write out number of chunks that follow (varint uint64) + - write out length of each chunk (each a varint uint64) + - write out the byte slice containing all the chunk data + +If you know the doc number you're interested in, this format lets you jump to the correct chunk (docNum/chunkFactor) directly and then seek within that chunk until you find it. + +## postings list section + +- for each posting list + - preparation phase: + - encode roaring bitmap posting list to bytes (so we know the length) + - file writing phase: + - remember the start position for this posting list + - write freq/norm details offset (remembered from previous, as varint uint64) + - write location details offset (remembered from previous, as varint uint64) + - write length of encoded roaring bitmap + - write the serialized roaring bitmap data + +## dictionary + +- for each field + - preparation phase: + - encode vellum FST with dictionary data pointing to file offset of posting list (remembered from previous) + - file writing phase: + - remember the start position of this persistDictionary + - write length of vellum data (varint uint64) + - write out vellum data + +## fields section + +- for each field + - file writing phase: + - remember start offset for each field + - write dictionary address (remembered from previous) (varint uint64) + - write length of field name (varint uint64) + - write field name bytes + +## fields idx + +- for each field + - file writing phase: + - write big endian uint64 of start offset for each field + +NOTE: currently we don't know or record the length of this fields index. Instead we rely on the fact that we know it immediately precedes a footer of known size. + +## fields DocValue + +- for each field + - preparation phase: + - produce a slice containing multiple consecutive chunks, where each chunk is composed of a meta section followed by compressed columnar field data + - produce a slice remembering the length of each chunk + - file writing phase: + - remember the start position of this first field DocValue offset in the footer + - write out number of chunks that follow (varint uint64) + - write out length of each chunk (each a varint uint64) + - write out the byte slice containing all the chunk data + +NOTE: currently the meta header inside each chunk gives clue to the location offsets and size of the data pertaining to a given docID and any +read operation leverage that meta information to extract the document specific data from the file. + +## footer + +- file writing phase + - write number of docs (big endian uint64) + - write stored field index location (big endian uint64) + - write field index location (big endian uint64) + - write field docValue location (big endian uint64) + - write out chunk factor (big endian uint32) + - write out version (big endian uint32) + - write out file CRC of everything preceding this (big endian uint32) diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/build.go b/backend/vendor/github.com/blevesearch/zapx/v15/build.go new file mode 100644 index 0000000000..5db1d9ee24 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/build.go @@ -0,0 +1,186 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bufio" + "fmt" + "io" + "math" + "os" + + "github.com/blevesearch/vellum" +) + +const Version uint32 = 15 + +const Type string = "zap" + +const fieldNotUninverted = math.MaxUint64 + +func (sb *SegmentBase) Persist(path string) error { + return PersistSegmentBase(sb, path) +} + +// WriteTo is an implementation of io.WriterTo interface. +func (sb *SegmentBase) WriteTo(w io.Writer) (int64, error) { + if w == nil { + return 0, fmt.Errorf("invalid writer found") + } + + n, err := persistSegmentBaseToWriter(sb, w) + return int64(n), err +} + +// PersistSegmentBase persists SegmentBase in the zap file format. +func PersistSegmentBase(sb *SegmentBase, path string) error { + flag := os.O_RDWR | os.O_CREATE + + f, err := os.OpenFile(path, flag, 0600) + if err != nil { + return err + } + + cleanup := func() { + _ = f.Close() + _ = os.Remove(path) + } + + _, err = persistSegmentBaseToWriter(sb, f) + if err != nil { + cleanup() + return err + } + + err = f.Sync() + if err != nil { + cleanup() + return err + } + + err = f.Close() + if err != nil { + cleanup() + return err + } + + return err +} + +type bufWriter struct { + w *bufio.Writer + n int +} + +func (br *bufWriter) Write(in []byte) (int, error) { + n, err := br.w.Write(in) + br.n += n + return n, err +} + +func persistSegmentBaseToWriter(sb *SegmentBase, w io.Writer) (int, error) { + br := &bufWriter{w: bufio.NewWriter(w)} + + _, err := br.Write(sb.mem) + if err != nil { + return 0, err + } + + err = persistFooter(sb.numDocs, sb.storedIndexOffset, sb.fieldsIndexOffset, + sb.docValueOffset, sb.chunkMode, sb.memCRC, br) + if err != nil { + return 0, err + } + + err = br.w.Flush() + if err != nil { + return 0, err + } + + return br.n, nil +} + +func persistStoredFieldValues(fieldID int, + storedFieldValues [][]byte, stf []byte, spf [][]uint64, + curr int, metaEncode varintEncoder, data []byte) ( + int, []byte, error) { + for i := 0; i < len(storedFieldValues); i++ { + // encode field + _, err := metaEncode(uint64(fieldID)) + if err != nil { + return 0, nil, err + } + // encode type + _, err = metaEncode(uint64(stf[i])) + if err != nil { + return 0, nil, err + } + // encode start offset + _, err = metaEncode(uint64(curr)) + if err != nil { + return 0, nil, err + } + // end len + _, err = metaEncode(uint64(len(storedFieldValues[i]))) + if err != nil { + return 0, nil, err + } + // encode number of array pos + _, err = metaEncode(uint64(len(spf[i]))) + if err != nil { + return 0, nil, err + } + // encode all array positions + for _, pos := range spf[i] { + _, err = metaEncode(pos) + if err != nil { + return 0, nil, err + } + } + + data = append(data, storedFieldValues[i]...) + curr += len(storedFieldValues[i]) + } + + return curr, data, nil +} + +func InitSegmentBase(mem []byte, memCRC uint32, chunkMode uint32, + fieldsMap map[string]uint16, fieldsInv []string, numDocs uint64, + storedIndexOffset uint64, fieldsIndexOffset uint64, docValueOffset uint64, + dictLocs []uint64) (*SegmentBase, error) { + sb := &SegmentBase{ + mem: mem, + memCRC: memCRC, + chunkMode: chunkMode, + fieldsMap: fieldsMap, + fieldsInv: fieldsInv, + numDocs: numDocs, + storedIndexOffset: storedIndexOffset, + fieldsIndexOffset: fieldsIndexOffset, + docValueOffset: docValueOffset, + dictLocs: dictLocs, + fieldDvReaders: make(map[uint16]*docValueReader), + fieldFSTs: make(map[uint16]*vellum.FST), + } + sb.updateSize() + + err := sb.loadDvReaders() + if err != nil { + return nil, err + } + + return sb, nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/chunk.go b/backend/vendor/github.com/blevesearch/zapx/v15/chunk.go new file mode 100644 index 0000000000..4307d0ed29 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/chunk.go @@ -0,0 +1,67 @@ +// Copyright (c) 2019 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "fmt" +) + +// LegacyChunkMode was the original chunk mode (always chunk size 1024) +// this mode is still used for chunking doc values. +var LegacyChunkMode uint32 = 1024 + +// DefaultChunkMode is the most recent improvement to chunking and should +// be used by default. +var DefaultChunkMode uint32 = 1026 + +func getChunkSize(chunkMode uint32, cardinality uint64, maxDocs uint64) (uint64, error) { + switch { + // any chunkMode <= 1024 will always chunk with chunkSize=chunkMode + case chunkMode <= 1024: + // legacy chunk size + return uint64(chunkMode), nil + + case chunkMode == 1025: + // attempt at simple improvement + // theory - the point of chunking is to put a bound on the maximum number of + // calls to Next() needed to find a random document. ie, you should be able + // to do one jump to the correct chunk, and then walk through at most + // chunk-size items + // previously 1024 was chosen as the chunk size, but this is particularly + // wasteful for low cardinality terms. the observation is that if there + // are less than 1024 items, why not put them all in one chunk, + // this way you'll still achieve the same goal of visiting at most + // chunk-size items. + // no attempt is made to tweak any other case + if cardinality <= 1024 { + return maxDocs, nil + } + return 1024, nil + + case chunkMode == 1026: + // improve upon the ideas tested in chunkMode 1025 + // the observation that the fewest number of dense chunks is the most + // desirable layout, given the built-in assumptions of chunking + // (that we want to put an upper-bound on the number of items you must + // walk over without skipping, currently tuned to 1024) + // + // 1. compute the number of chunks needed (max 1024/chunk) + // 2. convert to chunkSize, dividing into maxDocs + numChunks := (cardinality / 1024) + 1 + chunkSize := maxDocs / numChunks + return chunkSize, nil + } + return 0, fmt.Errorf("unknown chunk mode %d", chunkMode) +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/contentcoder.go b/backend/vendor/github.com/blevesearch/zapx/v15/contentcoder.go new file mode 100644 index 0000000000..cd8b3fc86f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/contentcoder.go @@ -0,0 +1,257 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "io" + "reflect" + "sync/atomic" + + "github.com/golang/snappy" +) + +var reflectStaticSizeMetaData int + +func init() { + var md MetaData + reflectStaticSizeMetaData = int(reflect.TypeOf(md).Size()) +} + +var ( + termSeparator byte = 0xff + termSeparatorSplitSlice = []byte{termSeparator} +) + +type chunkedContentCoder struct { + bytesWritten uint64 // atomic access to this variable, moved to top to correct alignment issues on ARM, 386 and 32-bit MIPS. + + final []byte + chunkSize uint64 + currChunk uint64 + chunkLens []uint64 + + compressed []byte // temp buf for snappy compression + + w io.Writer + progressiveWrite bool + + chunkMeta []MetaData + chunkMetaBuf bytes.Buffer + chunkBuf bytes.Buffer +} + +// MetaData represents the data information inside a +// chunk. +type MetaData struct { + DocNum uint64 // docNum of the data inside the chunk + DocDvOffset uint64 // offset of data inside the chunk for the given docid +} + +// newChunkedContentCoder returns a new chunk content coder which +// packs data into chunks based on the provided chunkSize +func newChunkedContentCoder(chunkSize uint64, maxDocNum uint64, + w io.Writer, progressiveWrite bool, +) *chunkedContentCoder { + total := maxDocNum/chunkSize + 1 + rv := &chunkedContentCoder{ + chunkSize: chunkSize, + chunkLens: make([]uint64, total), + chunkMeta: make([]MetaData, 0, total), + w: w, + progressiveWrite: progressiveWrite, + } + + return rv +} + +// Reset lets you reuse this chunked content coder. Buffers are reset +// and re used. You cannot change the chunk size. +func (c *chunkedContentCoder) Reset() { + c.currChunk = 0 + c.bytesWritten = 0 + c.final = c.final[:0] + c.chunkBuf.Reset() + c.chunkMetaBuf.Reset() + for i := range c.chunkLens { + c.chunkLens[i] = 0 + } + c.chunkMeta = c.chunkMeta[:0] +} + +func (c *chunkedContentCoder) SetChunkSize(chunkSize uint64, maxDocNum uint64) { + total := int(maxDocNum/chunkSize + 1) + c.chunkSize = chunkSize + if cap(c.chunkLens) < total { + c.chunkLens = make([]uint64, total) + } else { + c.chunkLens = c.chunkLens[:total] + } + if cap(c.chunkMeta) < total { + c.chunkMeta = make([]MetaData, 0, total) + } +} + +// Close indicates you are done calling Add() this allows +// the final chunk to be encoded. +func (c *chunkedContentCoder) Close() error { + return c.flushContents() +} + +func (c *chunkedContentCoder) incrementBytesWritten(val uint64) { + atomic.AddUint64(&c.bytesWritten, val) +} + +func (c *chunkedContentCoder) getBytesWritten() uint64 { + return atomic.LoadUint64(&c.bytesWritten) +} + +func (c *chunkedContentCoder) flushContents() error { + // flush the contents, with meta information at first + buf := make([]byte, binary.MaxVarintLen64) + n := binary.PutUvarint(buf, uint64(len(c.chunkMeta))) + _, err := c.chunkMetaBuf.Write(buf[:n]) + if err != nil { + return err + } + + // write out the metaData slice + for _, meta := range c.chunkMeta { + _, err := writeUvarints(&c.chunkMetaBuf, meta.DocNum, meta.DocDvOffset) + if err != nil { + return err + } + } + + // write the metadata to final data + metaData := c.chunkMetaBuf.Bytes() + c.final = append(c.final, c.chunkMetaBuf.Bytes()...) + // write the compressed data to the final data + c.compressed = snappy.Encode(c.compressed[:cap(c.compressed)], c.chunkBuf.Bytes()) + c.incrementBytesWritten(uint64(len(c.compressed))) + c.final = append(c.final, c.compressed...) + + c.chunkLens[c.currChunk] = uint64(len(c.compressed) + len(metaData)) + + if c.progressiveWrite { + _, err := c.w.Write(c.final) + if err != nil { + return err + } + c.final = c.final[:0] + } + + return nil +} + +// Add encodes the provided byte slice into the correct chunk for the provided +// doc num. You MUST call Add() with increasing docNums. +func (c *chunkedContentCoder) Add(docNum uint64, vals []byte) error { + chunk := docNum / c.chunkSize + if chunk != c.currChunk { + // flush out the previous chunk details + err := c.flushContents() + if err != nil { + return err + } + // clearing the chunk specific meta for next chunk + c.chunkBuf.Reset() + c.chunkMetaBuf.Reset() + c.chunkMeta = c.chunkMeta[:0] + c.currChunk = chunk + } + + // get the starting offset for this doc + dvOffset := c.chunkBuf.Len() + dvSize, err := c.chunkBuf.Write(vals) + if err != nil { + return err + } + + c.chunkMeta = append(c.chunkMeta, MetaData{ + DocNum: docNum, + DocDvOffset: uint64(dvOffset + dvSize), + }) + return nil +} + +// Write commits all the encoded chunked contents to the provided writer. +// +// | ..... data ..... | chunk offsets (varints) +// | position of chunk offsets (uint64) | number of offsets (uint64) | +func (c *chunkedContentCoder) Write() (int, error) { + var tw int + + if c.final != nil { + // write out the data section first + nw, err := c.w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + } + + chunkOffsetsStart := uint64(tw) + + if cap(c.final) < binary.MaxVarintLen64 { + c.final = make([]byte, binary.MaxVarintLen64) + } else { + c.final = c.final[0:binary.MaxVarintLen64] + } + chunkOffsets := modifyLengthsToEndOffsets(c.chunkLens) + // write out the chunk offsets + for _, chunkOffset := range chunkOffsets { + n := binary.PutUvarint(c.final, chunkOffset) + nw, err := c.w.Write(c.final[:n]) + tw += nw + if err != nil { + return tw, err + } + } + + chunkOffsetsLen := uint64(tw) - chunkOffsetsStart + + c.final = c.final[0:8] + // write out the length of chunk offsets + binary.BigEndian.PutUint64(c.final, chunkOffsetsLen) + nw, err := c.w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + + // write out the number of chunks + binary.BigEndian.PutUint64(c.final, uint64(len(c.chunkLens))) + nw, err = c.w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + + c.final = c.final[:0] + + return tw, nil +} + +// ReadDocValueBoundary elicits the start, end offsets from a +// metaData header slice +func ReadDocValueBoundary(chunk int, metaHeaders []MetaData) (uint64, uint64) { + var start uint64 + if chunk > 0 { + start = metaHeaders[chunk-1].DocDvOffset + } + return start, metaHeaders[chunk].DocDvOffset +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/count.go b/backend/vendor/github.com/blevesearch/zapx/v15/count.go new file mode 100644 index 0000000000..b6135359fb --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/count.go @@ -0,0 +1,61 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "hash/crc32" + "io" + + segment "github.com/blevesearch/scorch_segment_api/v2" +) + +// CountHashWriter is a wrapper around a Writer which counts the number of +// bytes which have been written and computes a crc32 hash +type CountHashWriter struct { + w io.Writer + crc uint32 + n int + s segment.StatsReporter +} + +// NewCountHashWriter returns a CountHashWriter which wraps the provided Writer +func NewCountHashWriter(w io.Writer) *CountHashWriter { + return &CountHashWriter{w: w} +} + +func NewCountHashWriterWithStatsReporter(w io.Writer, s segment.StatsReporter) *CountHashWriter { + return &CountHashWriter{w: w, s: s} +} + +// Write writes the provided bytes to the wrapped writer and counts the bytes +func (c *CountHashWriter) Write(b []byte) (int, error) { + n, err := c.w.Write(b) + c.crc = crc32.Update(c.crc, crc32.IEEETable, b[:n]) + c.n += n + if c.s != nil { + c.s.ReportBytesWritten(uint64(n)) + } + return n, err +} + +// Count returns the number of bytes written +func (c *CountHashWriter) Count() int { + return c.n +} + +// Sum32 returns the CRC-32 hash of the content written to this writer +func (c *CountHashWriter) Sum32() uint32 { + return c.crc +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/dict.go b/backend/vendor/github.com/blevesearch/zapx/v15/dict.go new file mode 100644 index 0000000000..6b8acf52d3 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/dict.go @@ -0,0 +1,176 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "fmt" + + "github.com/RoaringBitmap/roaring" + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" +) + +// Dictionary is the zap representation of the term dictionary +type Dictionary struct { + sb *SegmentBase + field string + fieldID uint16 + fst *vellum.FST + fstReader *vellum.Reader + + bytesRead uint64 +} + +// represents an immutable, empty dictionary +var emptyDictionary = &Dictionary{} + +// PostingsList returns the postings list for the specified term +func (d *Dictionary) PostingsList(term []byte, except *roaring.Bitmap, + prealloc segment.PostingsList) (segment.PostingsList, error) { + var preallocPL *PostingsList + pl, ok := prealloc.(*PostingsList) + if ok && pl != nil { + preallocPL = pl + } + return d.postingsList(term, except, preallocPL) +} + +func (d *Dictionary) postingsList(term []byte, except *roaring.Bitmap, rv *PostingsList) (*PostingsList, error) { + if d.fstReader == nil { + if rv == nil || rv == emptyPostingsList { + return emptyPostingsList, nil + } + return d.postingsListInit(rv, except), nil + } + + postingsOffset, exists, err := d.fstReader.Get(term) + if err != nil { + return nil, fmt.Errorf("vellum err: %v", err) + } + if !exists { + if rv == nil || rv == emptyPostingsList { + return emptyPostingsList, nil + } + return d.postingsListInit(rv, except), nil + } + + return d.postingsListFromOffset(postingsOffset, except, rv) +} + +func (d *Dictionary) postingsListFromOffset(postingsOffset uint64, except *roaring.Bitmap, rv *PostingsList) (*PostingsList, error) { + rv = d.postingsListInit(rv, except) + + err := rv.read(postingsOffset, d) + if err != nil { + return nil, err + } + + return rv, nil +} + +func (d *Dictionary) postingsListInit(rv *PostingsList, except *roaring.Bitmap) *PostingsList { + if rv == nil || rv == emptyPostingsList { + rv = &PostingsList{} + } else { + postings := rv.postings + if postings != nil { + postings.Clear() + } + + *rv = PostingsList{} // clear the struct + + rv.postings = postings + } + rv.sb = d.sb + rv.except = except + return rv +} + +func (d *Dictionary) Contains(key []byte) (bool, error) { + if d.fst != nil { + return d.fst.Contains(key) + } + return false, nil +} + +// AutomatonIterator returns an iterator which only visits terms +// having the the vellum automaton and start/end key range +func (d *Dictionary) AutomatonIterator(a segment.Automaton, + startKeyInclusive, endKeyExclusive []byte) segment.DictionaryIterator { + if d.fst != nil { + rv := &DictionaryIterator{ + d: d, + } + + itr, err := d.fst.Search(a, startKeyInclusive, endKeyExclusive) + if err == nil { + rv.itr = itr + } else if err != vellum.ErrIteratorDone { + rv.err = err + } + + return rv + } + return emptyDictionaryIterator +} + +func (d *Dictionary) incrementBytesRead(val uint64) { + d.bytesRead += val +} + +func (d *Dictionary) BytesRead() uint64 { + return d.bytesRead +} + +func (d *Dictionary) ResetBytesRead(val uint64) { + d.bytesRead = val +} + +func (d *Dictionary) BytesWritten() uint64 { + return 0 +} + +// DictionaryIterator is an iterator for term dictionary +type DictionaryIterator struct { + d *Dictionary + itr vellum.Iterator + err error + tmp PostingsList + entry index.DictEntry + omitCount bool +} + +var emptyDictionaryIterator = &DictionaryIterator{} + +// Next returns the next entry in the dictionary +func (i *DictionaryIterator) Next() (*index.DictEntry, error) { + if i.err != nil && i.err != vellum.ErrIteratorDone { + return nil, i.err + } else if i.itr == nil || i.err == vellum.ErrIteratorDone { + return nil, nil + } + term, postingsOffset := i.itr.Current() + i.entry.Term = string(term) + if !i.omitCount { + i.err = i.tmp.read(postingsOffset, i.d) + if i.err != nil { + return nil, i.err + } + i.entry.Count = i.tmp.Count() + } + i.err = i.itr.Next() + return &i.entry, nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/docvalues.go b/backend/vendor/github.com/blevesearch/zapx/v15/docvalues.go new file mode 100644 index 0000000000..046244d130 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/docvalues.go @@ -0,0 +1,356 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "fmt" + "math" + "reflect" + "sort" + + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/golang/snappy" +) + +var reflectStaticSizedocValueReader int + +func init() { + var dvi docValueReader + reflectStaticSizedocValueReader = int(reflect.TypeOf(dvi).Size()) +} + +type docNumTermsVisitor func(docNum uint64, terms []byte) error + +type docVisitState struct { + dvrs map[uint16]*docValueReader + segment *SegmentBase + + bytesRead uint64 +} + +// Implements the segment.DiskStatsReporter interface +// The purpose of this implementation is to get +// the bytes read from the disk (pertaining to the +// docvalues) while querying. +// the loadDvChunk retrieves the next chunk of docvalues +// and the bytes retrieved off the disk pertaining to that +// is accounted as well. +func (d *docVisitState) incrementBytesRead(val uint64) { + d.bytesRead += val +} + +func (d *docVisitState) BytesRead() uint64 { + return d.bytesRead +} + +func (d *docVisitState) BytesWritten() uint64 { + return 0 +} + +func (d *docVisitState) ResetBytesRead(val uint64) { + d.bytesRead = val +} + +type docValueReader struct { + field string + curChunkNum uint64 + chunkOffsets []uint64 + dvDataLoc uint64 + curChunkHeader []MetaData + curChunkData []byte // compressed data cache + uncompressed []byte // temp buf for snappy decompression + + // atomic access to this variable + bytesRead uint64 +} + +func (di *docValueReader) size() int { + return reflectStaticSizedocValueReader + SizeOfPtr + + len(di.field) + + len(di.chunkOffsets)*SizeOfUint64 + + len(di.curChunkHeader)*reflectStaticSizeMetaData + + len(di.curChunkData) +} + +func (di *docValueReader) cloneInto(rv *docValueReader) *docValueReader { + if rv == nil { + rv = &docValueReader{} + } + + rv.field = di.field + rv.curChunkNum = math.MaxUint64 + rv.chunkOffsets = di.chunkOffsets // immutable, so it's sharable + rv.dvDataLoc = di.dvDataLoc + rv.curChunkHeader = rv.curChunkHeader[:0] + rv.curChunkData = nil + rv.uncompressed = rv.uncompressed[:0] + + return rv +} + +func (di *docValueReader) curChunkNumber() uint64 { + return di.curChunkNum +} + +func (s *SegmentBase) loadFieldDocValueReader(field string, + fieldDvLocStart, fieldDvLocEnd uint64) (*docValueReader, error) { + // get the docValue offset for the given fields + if fieldDvLocStart == fieldNotUninverted { + // no docValues found, nothing to do + return nil, nil + } + + // read the number of chunks, and chunk offsets position + var numChunks, chunkOffsetsPosition uint64 + + if fieldDvLocEnd-fieldDvLocStart > 16 { + numChunks = binary.BigEndian.Uint64(s.mem[fieldDvLocEnd-8 : fieldDvLocEnd]) + // read the length of chunk offsets + chunkOffsetsLen := binary.BigEndian.Uint64(s.mem[fieldDvLocEnd-16 : fieldDvLocEnd-8]) + // acquire position of chunk offsets + chunkOffsetsPosition = (fieldDvLocEnd - 16) - chunkOffsetsLen + + // 16 bytes since it corresponds to the length + // of chunk offsets and the position of the offsets + s.incrementBytesRead(16) + } else { + return nil, fmt.Errorf("loadFieldDocValueReader: fieldDvLoc too small: %d-%d", fieldDvLocEnd, fieldDvLocStart) + } + + fdvIter := &docValueReader{ + curChunkNum: math.MaxUint64, + field: field, + chunkOffsets: make([]uint64, int(numChunks)), + } + + // read the chunk offsets + var offset uint64 + for i := 0; i < int(numChunks); i++ { + loc, read := binary.Uvarint(s.mem[chunkOffsetsPosition+offset : chunkOffsetsPosition+offset+binary.MaxVarintLen64]) + if read <= 0 { + return nil, fmt.Errorf("corrupted chunk offset during segment load") + } + fdvIter.chunkOffsets[i] = loc + offset += uint64(read) + } + s.incrementBytesRead(offset) + // set the data offset + fdvIter.dvDataLoc = fieldDvLocStart + + return fdvIter, nil +} + +func (d *docValueReader) getBytesRead() uint64 { + return d.bytesRead +} + +func (d *docValueReader) incrementBytesRead(val uint64) { + d.bytesRead += val +} + +func (di *docValueReader) loadDvChunk(chunkNumber uint64, s *SegmentBase) error { + // advance to the chunk where the docValues + // reside for the given docNum + destChunkDataLoc, curChunkEnd := di.dvDataLoc, di.dvDataLoc + start, end := readChunkBoundary(int(chunkNumber), di.chunkOffsets) + if start >= end { + di.curChunkHeader = di.curChunkHeader[:0] + di.curChunkData = nil + di.curChunkNum = chunkNumber + di.uncompressed = di.uncompressed[:0] + return nil + } + + destChunkDataLoc += start + curChunkEnd += end + + // read the number of docs reside in the chunk + numDocs, read := binary.Uvarint(s.mem[destChunkDataLoc : destChunkDataLoc+binary.MaxVarintLen64]) + if read <= 0 { + return fmt.Errorf("failed to read the chunk") + } + chunkMetaLoc := destChunkDataLoc + uint64(read) + di.incrementBytesRead(uint64(read)) + offset := uint64(0) + if cap(di.curChunkHeader) < int(numDocs) { + di.curChunkHeader = make([]MetaData, int(numDocs)) + } else { + di.curChunkHeader = di.curChunkHeader[:int(numDocs)] + } + for i := 0; i < int(numDocs); i++ { + di.curChunkHeader[i].DocNum, read = binary.Uvarint(s.mem[chunkMetaLoc+offset : chunkMetaLoc+offset+binary.MaxVarintLen64]) + offset += uint64(read) + di.curChunkHeader[i].DocDvOffset, read = binary.Uvarint(s.mem[chunkMetaLoc+offset : chunkMetaLoc+offset+binary.MaxVarintLen64]) + offset += uint64(read) + } + + compressedDataLoc := chunkMetaLoc + offset + dataLength := curChunkEnd - compressedDataLoc + di.incrementBytesRead(uint64(dataLength + offset)) + di.curChunkData = s.mem[compressedDataLoc : compressedDataLoc+dataLength] + di.curChunkNum = chunkNumber + di.uncompressed = di.uncompressed[:0] + return nil +} + +func (di *docValueReader) iterateAllDocValues(s *SegmentBase, visitor docNumTermsVisitor) error { + for i := 0; i < len(di.chunkOffsets); i++ { + err := di.loadDvChunk(uint64(i), s) + if err != nil { + return err + } + if di.curChunkData == nil || len(di.curChunkHeader) == 0 { + continue + } + + // uncompress the already loaded data + uncompressed, err := snappy.Decode(di.uncompressed[:cap(di.uncompressed)], di.curChunkData) + if err != nil { + return err + } + di.uncompressed = uncompressed + + start := uint64(0) + for _, entry := range di.curChunkHeader { + err = visitor(entry.DocNum, uncompressed[start:entry.DocDvOffset]) + if err != nil { + return err + } + + start = entry.DocDvOffset + } + } + + return nil +} + +func (di *docValueReader) visitDocValues(docNum uint64, + visitor index.DocValueVisitor) error { + // binary search the term locations for the docNum + start, end := di.getDocValueLocs(docNum) + if start == math.MaxUint64 || end == math.MaxUint64 || start == end { + return nil + } + + var uncompressed []byte + var err error + // use the uncompressed copy if available + if len(di.uncompressed) > 0 { + uncompressed = di.uncompressed + } else { + // uncompress the already loaded data + uncompressed, err = snappy.Decode(di.uncompressed[:cap(di.uncompressed)], di.curChunkData) + if err != nil { + return err + } + di.uncompressed = uncompressed + } + + // pick the terms for the given docNum + uncompressed = uncompressed[start:end] + for { + i := bytes.Index(uncompressed, termSeparatorSplitSlice) + if i < 0 { + break + } + + visitor(di.field, uncompressed[0:i]) + uncompressed = uncompressed[i+1:] + } + + return nil +} + +func (di *docValueReader) getDocValueLocs(docNum uint64) (uint64, uint64) { + i := sort.Search(len(di.curChunkHeader), func(i int) bool { + return di.curChunkHeader[i].DocNum >= docNum + }) + if i < len(di.curChunkHeader) && di.curChunkHeader[i].DocNum == docNum { + return ReadDocValueBoundary(i, di.curChunkHeader) + } + return math.MaxUint64, math.MaxUint64 +} + +// VisitDocValues is an implementation of the +// DocValueVisitable interface +func (s *SegmentBase) VisitDocValues(localDocNum uint64, fields []string, + visitor index.DocValueVisitor, dvsIn segment.DocVisitState) ( + segment.DocVisitState, error) { + dvs, ok := dvsIn.(*docVisitState) + if !ok || dvs == nil { + dvs = &docVisitState{} + } else { + if dvs.segment != s { + dvs.segment = s + dvs.dvrs = nil + dvs.bytesRead = 0 + } + } + + var fieldIDPlus1 uint16 + if dvs.dvrs == nil { + dvs.dvrs = make(map[uint16]*docValueReader, len(fields)) + for _, field := range fields { + if fieldIDPlus1, ok = s.fieldsMap[field]; !ok { + continue + } + fieldID := fieldIDPlus1 - 1 + if dvIter, exists := s.fieldDvReaders[fieldID]; exists && + dvIter != nil { + dvs.dvrs[fieldID] = dvIter.cloneInto(dvs.dvrs[fieldID]) + } + } + } + + // find the chunkNumber where the docValues are stored + // NOTE: doc values continue to use legacy chunk mode + chunkFactor, err := getChunkSize(LegacyChunkMode, 0, 0) + if err != nil { + return nil, err + } + docInChunk := localDocNum / chunkFactor + var dvr *docValueReader + for _, field := range fields { + if fieldIDPlus1, ok = s.fieldsMap[field]; !ok { + continue + } + fieldID := fieldIDPlus1 - 1 + if dvr, ok = dvs.dvrs[fieldID]; ok && dvr != nil { + // check if the chunk is already loaded + if docInChunk != dvr.curChunkNumber() { + err := dvr.loadDvChunk(docInChunk, s) + if err != nil { + return dvs, err + } + dvs.ResetBytesRead(dvr.getBytesRead()) + } else { + dvs.ResetBytesRead(0) + } + + _ = dvr.visitDocValues(localDocNum, visitor) + } + } + return dvs, nil +} + +// VisitableDocValueFields returns the list of fields with +// persisted doc value terms ready to be visitable using the +// VisitDocumentFieldTerms method. +func (s *SegmentBase) VisitableDocValueFields() ([]string, error) { + return s.fieldDvNames, nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/enumerator.go b/backend/vendor/github.com/blevesearch/zapx/v15/enumerator.go new file mode 100644 index 0000000000..972a224165 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/enumerator.go @@ -0,0 +1,138 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + + "github.com/blevesearch/vellum" +) + +// enumerator provides an ordered traversal of multiple vellum +// iterators. Like JOIN of iterators, the enumerator produces a +// sequence of (key, iteratorIndex, value) tuples, sorted by key ASC, +// then iteratorIndex ASC, where the same key might be seen or +// repeated across multiple child iterators. +type enumerator struct { + itrs []vellum.Iterator + currKs [][]byte + currVs []uint64 + + lowK []byte + lowIdxs []int + lowCurr int +} + +// newEnumerator returns a new enumerator over the vellum Iterators +func newEnumerator(itrs []vellum.Iterator) (*enumerator, error) { + rv := &enumerator{ + itrs: itrs, + currKs: make([][]byte, len(itrs)), + currVs: make([]uint64, len(itrs)), + lowIdxs: make([]int, 0, len(itrs)), + } + for i, itr := range rv.itrs { + rv.currKs[i], rv.currVs[i] = itr.Current() + } + rv.updateMatches(false) + if rv.lowK == nil && len(rv.lowIdxs) == 0 { + return rv, vellum.ErrIteratorDone + } + return rv, nil +} + +// updateMatches maintains the low key matches based on the currKs +func (m *enumerator) updateMatches(skipEmptyKey bool) { + m.lowK = nil + m.lowIdxs = m.lowIdxs[:0] + m.lowCurr = 0 + + for i, key := range m.currKs { + if (key == nil && m.currVs[i] == 0) || // in case of empty iterator + (len(key) == 0 && skipEmptyKey) { // skip empty keys + continue + } + + cmp := bytes.Compare(key, m.lowK) + if cmp < 0 || len(m.lowIdxs) == 0 { + // reached a new low + m.lowK = key + m.lowIdxs = m.lowIdxs[:0] + m.lowIdxs = append(m.lowIdxs, i) + } else if cmp == 0 { + m.lowIdxs = append(m.lowIdxs, i) + } + } +} + +// Current returns the enumerator's current key, iterator-index, and +// value. If the enumerator is not pointing at a valid value (because +// Next returned an error previously), Current will return nil,0,0. +func (m *enumerator) Current() ([]byte, int, uint64) { + var i int + var v uint64 + if m.lowCurr < len(m.lowIdxs) { + i = m.lowIdxs[m.lowCurr] + v = m.currVs[i] + } + return m.lowK, i, v +} + +// GetLowIdxsAndValues will return all of the iterator indices +// which point to the current key, and their corresponding +// values. This can be used by advanced caller which may need +// to peek into these other sets of data before processing. +func (m *enumerator) GetLowIdxsAndValues() ([]int, []uint64) { + values := make([]uint64, 0, len(m.lowIdxs)) + for _, idx := range m.lowIdxs { + values = append(values, m.currVs[idx]) + } + return m.lowIdxs, values +} + +// Next advances the enumerator to the next key/iterator/value result, +// else vellum.ErrIteratorDone is returned. +func (m *enumerator) Next() error { + m.lowCurr += 1 + if m.lowCurr >= len(m.lowIdxs) { + // move all the current low iterators forwards + for _, vi := range m.lowIdxs { + err := m.itrs[vi].Next() + if err != nil && err != vellum.ErrIteratorDone { + return err + } + m.currKs[vi], m.currVs[vi] = m.itrs[vi].Current() + } + // can skip any empty keys encountered at this point + m.updateMatches(true) + } + if m.lowK == nil && len(m.lowIdxs) == 0 { + return vellum.ErrIteratorDone + } + return nil +} + +// Close all the underlying Iterators. The first error, if any, will +// be returned. +func (m *enumerator) Close() error { + var rv error + for _, itr := range m.itrs { + err := itr.Close() + if rv == nil { + rv = err + } + } + return rv +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/intDecoder.go b/backend/vendor/github.com/blevesearch/zapx/v15/intDecoder.go new file mode 100644 index 0000000000..e50c471722 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/intDecoder.go @@ -0,0 +1,139 @@ +// Copyright (c) 2019 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "encoding/binary" + "fmt" +) + +type chunkedIntDecoder struct { + startOffset uint64 + dataStartOffset uint64 + chunkOffsets []uint64 + curChunkBytes []byte + data []byte + r *memUvarintReader + + // atomic access to this variable + bytesRead uint64 +} + +// newChunkedIntDecoder expects an optional or reset chunkedIntDecoder for better reuse. +func newChunkedIntDecoder(buf []byte, offset uint64, rv *chunkedIntDecoder) *chunkedIntDecoder { + if rv == nil { + rv = &chunkedIntDecoder{startOffset: offset, data: buf} + } else { + rv.startOffset = offset + rv.data = buf + } + + var n, numChunks uint64 + var read int + if offset == termNotEncoded { + numChunks = 0 + } else { + numChunks, read = binary.Uvarint(buf[offset+n : offset+n+binary.MaxVarintLen64]) + } + + n += uint64(read) + if cap(rv.chunkOffsets) >= int(numChunks) { + rv.chunkOffsets = rv.chunkOffsets[:int(numChunks)] + } else { + rv.chunkOffsets = make([]uint64, int(numChunks)) + } + for i := 0; i < int(numChunks); i++ { + rv.chunkOffsets[i], read = binary.Uvarint(buf[offset+n : offset+n+binary.MaxVarintLen64]) + n += uint64(read) + } + rv.bytesRead += n + rv.dataStartOffset = offset + n + return rv +} + +// A util function which fetches the query time +// specific bytes encoded by intcoder (for eg the +// freqNorm and location details of a term in document) +// the loadChunk retrieves the next chunk and the +// number of bytes retrieve in that operation is accounted +func (d *chunkedIntDecoder) getBytesRead() uint64 { + return d.bytesRead +} + +func (d *chunkedIntDecoder) loadChunk(chunk int) error { + if d.startOffset == termNotEncoded { + d.r = newMemUvarintReader([]byte(nil)) + return nil + } + + if chunk >= len(d.chunkOffsets) { + return fmt.Errorf("tried to load freq chunk that doesn't exist %d/(%d)", + chunk, len(d.chunkOffsets)) + } + + end, start := d.dataStartOffset, d.dataStartOffset + s, e := readChunkBoundary(chunk, d.chunkOffsets) + start += s + end += e + d.curChunkBytes = d.data[start:end] + d.bytesRead += uint64(len(d.curChunkBytes)) + if d.r == nil { + d.r = newMemUvarintReader(d.curChunkBytes) + } else { + d.r.Reset(d.curChunkBytes) + } + + return nil +} + +func (d *chunkedIntDecoder) reset() { + d.startOffset = 0 + d.dataStartOffset = 0 + d.chunkOffsets = d.chunkOffsets[:0] + d.curChunkBytes = d.curChunkBytes[:0] + d.bytesRead = 0 + d.data = d.data[:0] + if d.r != nil { + d.r.Reset([]byte(nil)) + } +} + +func (d *chunkedIntDecoder) isNil() bool { + return d.curChunkBytes == nil || len(d.curChunkBytes) == 0 +} + +func (d *chunkedIntDecoder) readUvarint() (uint64, error) { + return d.r.ReadUvarint() +} + +func (d *chunkedIntDecoder) readBytes(start, end int) []byte { + return d.curChunkBytes[start:end] +} + +func (d *chunkedIntDecoder) SkipUvarint() { + d.r.SkipUvarint() +} + +func (d *chunkedIntDecoder) SkipBytes(count int) { + d.r.SkipBytes(count) +} + +func (d *chunkedIntDecoder) Len() int { + return d.r.Len() +} + +func (d *chunkedIntDecoder) remainingLen() int { + return len(d.curChunkBytes) - d.r.Len() +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/intcoder.go b/backend/vendor/github.com/blevesearch/zapx/v15/intcoder.go new file mode 100644 index 0000000000..2957fbd098 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/intcoder.go @@ -0,0 +1,220 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "io" + "sync/atomic" +) + +// We can safely use 0 to represent termNotEncoded since 0 +// could never be a valid address for term location information. +// (stored field index is always non-empty and earlier in the +// file) +const termNotEncoded = 0 + +type chunkedIntCoder struct { + final []byte + chunkSize uint64 + chunkBuf bytes.Buffer + chunkLens []uint64 + currChunk uint64 + + buf []byte + + // atomic access to this variable + bytesWritten uint64 +} + +// newChunkedIntCoder returns a new chunk int coder which packs data into +// chunks based on the provided chunkSize and supports up to the specified +// maxDocNum +func newChunkedIntCoder(chunkSize uint64, maxDocNum uint64) *chunkedIntCoder { + total := maxDocNum/chunkSize + 1 + rv := &chunkedIntCoder{ + chunkSize: chunkSize, + chunkLens: make([]uint64, total), + final: make([]byte, 0, 64), + } + + return rv +} + +// Reset lets you reuse this chunked int coder. buffers are reset and reused +// from previous use. you cannot change the chunk size or max doc num. +func (c *chunkedIntCoder) Reset() { + c.final = c.final[:0] + c.bytesWritten = 0 + c.chunkBuf.Reset() + c.currChunk = 0 + for i := range c.chunkLens { + c.chunkLens[i] = 0 + } +} + +// SetChunkSize changes the chunk size. It is only valid to do so +// with a new chunkedIntCoder, or immediately after calling Reset() +func (c *chunkedIntCoder) SetChunkSize(chunkSize uint64, maxDocNum uint64) { + total := int(maxDocNum/chunkSize + 1) + c.chunkSize = chunkSize + if cap(c.chunkLens) < total { + c.chunkLens = make([]uint64, total) + } else { + c.chunkLens = c.chunkLens[:total] + } +} + +func (c *chunkedIntCoder) incrementBytesWritten(val uint64) { + atomic.AddUint64(&c.bytesWritten, val) +} + +func (c *chunkedIntCoder) getBytesWritten() uint64 { + return atomic.LoadUint64(&c.bytesWritten) +} + +// Add encodes the provided integers into the correct chunk for the provided +// doc num. You MUST call Add() with increasing docNums. +func (c *chunkedIntCoder) Add(docNum uint64, vals ...uint64) error { + chunk := docNum / c.chunkSize + if chunk != c.currChunk { + // starting a new chunk + c.Close() + c.chunkBuf.Reset() + c.currChunk = chunk + } + + if len(c.buf) < binary.MaxVarintLen64 { + c.buf = make([]byte, binary.MaxVarintLen64) + } + + for _, val := range vals { + wb := binary.PutUvarint(c.buf, val) + _, err := c.chunkBuf.Write(c.buf[:wb]) + if err != nil { + return err + } + } + + return nil +} + +func (c *chunkedIntCoder) AddBytes(docNum uint64, buf []byte) error { + chunk := docNum / c.chunkSize + if chunk != c.currChunk { + // starting a new chunk + c.Close() + c.chunkBuf.Reset() + c.currChunk = chunk + } + + _, err := c.chunkBuf.Write(buf) + return err +} + +// Close indicates you are done calling Add() this allows the final chunk +// to be encoded. +func (c *chunkedIntCoder) Close() { + encodingBytes := c.chunkBuf.Bytes() + c.incrementBytesWritten(uint64(len(encodingBytes))) + c.chunkLens[c.currChunk] = uint64(len(encodingBytes)) + c.final = append(c.final, encodingBytes...) + c.currChunk = uint64(cap(c.chunkLens)) // sentinel to detect double close +} + +// Write commits all the encoded chunked integers to the provided writer. +func (c *chunkedIntCoder) Write(w io.Writer) (int, error) { + bufNeeded := binary.MaxVarintLen64 * (1 + len(c.chunkLens)) + if len(c.buf) < bufNeeded { + c.buf = make([]byte, bufNeeded) + } + buf := c.buf + + // convert the chunk lengths into chunk offsets + chunkOffsets := modifyLengthsToEndOffsets(c.chunkLens) + + // write out the number of chunks & each chunk offsets + n := binary.PutUvarint(buf, uint64(len(chunkOffsets))) + for _, chunkOffset := range chunkOffsets { + n += binary.PutUvarint(buf[n:], chunkOffset) + } + + tw, err := w.Write(buf[:n]) + if err != nil { + return tw, err + } + + // write out the data + nw, err := w.Write(c.final) + tw += nw + if err != nil { + return tw, err + } + return tw, nil +} + +// writeAt commits all the encoded chunked integers to the provided writer +// and returns the starting offset, total bytes written and an error +func (c *chunkedIntCoder) writeAt(w io.Writer) (uint64, int, error) { + startOffset := uint64(termNotEncoded) + if len(c.final) <= 0 { + return startOffset, 0, nil + } + + if chw := w.(*CountHashWriter); chw != nil { + startOffset = uint64(chw.Count()) + } + + tw, err := c.Write(w) + return startOffset, tw, err +} + +func (c *chunkedIntCoder) FinalSize() int { + return len(c.final) +} + +// modifyLengthsToEndOffsets converts the chunk length array +// to a chunk offset array. The readChunkBoundary +// will figure out the start and end of every chunk from +// these offsets. Starting offset of i'th index is stored +// in i-1'th position except for 0'th index and ending offset +// is stored at i'th index position. +// For 0'th element, starting position is always zero. +// eg: +// Lens -> 5 5 5 5 => 5 10 15 20 +// Lens -> 0 5 0 5 => 0 5 5 10 +// Lens -> 0 0 0 5 => 0 0 0 5 +// Lens -> 5 0 0 0 => 5 5 5 5 +// Lens -> 0 5 0 0 => 0 5 5 5 +// Lens -> 0 0 5 0 => 0 0 5 5 +func modifyLengthsToEndOffsets(lengths []uint64) []uint64 { + var runningOffset uint64 + var index, i int + for i = 1; i <= len(lengths); i++ { + runningOffset += lengths[i-1] + lengths[index] = runningOffset + index++ + } + return lengths +} + +func readChunkBoundary(chunk int, offsets []uint64) (uint64, uint64) { + var start uint64 + if chunk > 0 { + start = offsets[chunk-1] + } + return start, offsets[chunk] +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/memuvarint.go b/backend/vendor/github.com/blevesearch/zapx/v15/memuvarint.go new file mode 100644 index 0000000000..48a57f9c85 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/memuvarint.go @@ -0,0 +1,103 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "fmt" +) + +type memUvarintReader struct { + C int // index of next byte to read from S + S []byte +} + +func newMemUvarintReader(s []byte) *memUvarintReader { + return &memUvarintReader{S: s} +} + +// Len returns the number of unread bytes. +func (r *memUvarintReader) Len() int { + n := len(r.S) - r.C + if n < 0 { + return 0 + } + return n +} + +// ReadUvarint reads an encoded uint64. The original code this was +// based on is at encoding/binary/ReadUvarint(). +func (r *memUvarintReader) ReadUvarint() (uint64, error) { + if r.C >= len(r.S) { + // nothing else to read + return 0, nil + } + + var x uint64 + var s uint + var C = r.C + var S = r.S + + for { + b := S[C] + C++ + + if b < 0x80 { + r.C = C + + // why 63? The original code had an 'i += 1' loop var and + // checked for i > 9 || i == 9 ...; but, we no longer + // check for the i var, but instead check here for s, + // which is incremented by 7. So, 7*9 == 63. + // + // why the "extra" >= check? The normal case is that s < + // 63, so we check this single >= guard first so that we + // hit the normal, nil-error return pathway sooner. + if s >= 63 && (s > 63 || b > 1) { + return 0, fmt.Errorf("memUvarintReader overflow") + } + + return x | uint64(b)<= len(r.S) { + return + } + + b := r.S[r.C] + r.C++ + + if b < 0x80 { + return + } + } +} + +// SkipBytes skips a count number of bytes. +func (r *memUvarintReader) SkipBytes(count int) { + r.C = r.C + count +} + +func (r *memUvarintReader) Reset(s []byte) { + r.C = 0 + r.S = s +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/merge.go b/backend/vendor/github.com/blevesearch/zapx/v15/merge.go new file mode 100644 index 0000000000..887d3447e8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/merge.go @@ -0,0 +1,895 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bufio" + "bytes" + "encoding/binary" + "fmt" + "math" + "os" + "sort" + + "github.com/RoaringBitmap/roaring" + seg "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" + "github.com/golang/snappy" +) + +var DefaultFileMergerBufferSize = 1024 * 1024 + +const docDropped = math.MaxUint64 // sentinel docNum to represent a deleted doc + +// Merge takes a slice of segments and bit masks describing which +// documents may be dropped, and creates a new segment containing the +// remaining data. This new segment is built at the specified path. +func (*ZapPlugin) Merge(segments []seg.Segment, drops []*roaring.Bitmap, path string, + closeCh chan struct{}, s seg.StatsReporter) ( + [][]uint64, uint64, error) { + segmentBases := make([]*SegmentBase, len(segments)) + for segmenti, segment := range segments { + switch segmentx := segment.(type) { + case *Segment: + segmentBases[segmenti] = &segmentx.SegmentBase + case *SegmentBase: + segmentBases[segmenti] = segmentx + default: + panic(fmt.Sprintf("oops, unexpected segment type: %T", segment)) + } + } + return mergeSegmentBases(segmentBases, drops, path, DefaultChunkMode, closeCh, s) +} + +func mergeSegmentBases(segmentBases []*SegmentBase, drops []*roaring.Bitmap, path string, + chunkMode uint32, closeCh chan struct{}, s seg.StatsReporter) ( + [][]uint64, uint64, error) { + flag := os.O_RDWR | os.O_CREATE + + f, err := os.OpenFile(path, flag, 0600) + if err != nil { + return nil, 0, err + } + + cleanup := func() { + _ = f.Close() + _ = os.Remove(path) + } + + // buffer the output + br := bufio.NewWriterSize(f, DefaultFileMergerBufferSize) + + // wrap it for counting (tracking offsets) + cr := NewCountHashWriterWithStatsReporter(br, s) + + newDocNums, numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset, _, _, _, err := + MergeToWriter(segmentBases, drops, chunkMode, cr, closeCh) + if err != nil { + cleanup() + return nil, 0, err + } + + err = persistFooter(numDocs, storedIndexOffset, fieldsIndexOffset, + docValueOffset, chunkMode, cr.Sum32(), cr) + if err != nil { + cleanup() + return nil, 0, err + } + + err = br.Flush() + if err != nil { + cleanup() + return nil, 0, err + } + + err = f.Sync() + if err != nil { + cleanup() + return nil, 0, err + } + + err = f.Close() + if err != nil { + cleanup() + return nil, 0, err + } + + return newDocNums, uint64(cr.Count()), nil +} + +func MergeToWriter(segments []*SegmentBase, drops []*roaring.Bitmap, + chunkMode uint32, cr *CountHashWriter, closeCh chan struct{}) ( + newDocNums [][]uint64, + numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset uint64, + dictLocs []uint64, fieldsInv []string, fieldsMap map[string]uint16, + err error) { + docValueOffset = uint64(fieldNotUninverted) + + var fieldsSame bool + fieldsSame, fieldsInv = mergeFields(segments) + fieldsMap = mapFields(fieldsInv) + + numDocs = computeNewDocCount(segments, drops) + + if isClosed(closeCh) { + return nil, 0, 0, 0, 0, nil, nil, nil, seg.ErrClosed + } + + if numDocs > 0 { + storedIndexOffset, newDocNums, err = mergeStoredAndRemap(segments, drops, + fieldsMap, fieldsInv, fieldsSame, numDocs, cr, closeCh) + if err != nil { + return nil, 0, 0, 0, 0, nil, nil, nil, err + } + + dictLocs, docValueOffset, err = persistMergedRest(segments, drops, + fieldsInv, fieldsMap, fieldsSame, + newDocNums, numDocs, chunkMode, cr, closeCh) + if err != nil { + return nil, 0, 0, 0, 0, nil, nil, nil, err + } + } else { + dictLocs = make([]uint64, len(fieldsInv)) + } + + fieldsIndexOffset, err = persistFields(fieldsInv, cr, dictLocs) + if err != nil { + return nil, 0, 0, 0, 0, nil, nil, nil, err + } + + return newDocNums, numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset, dictLocs, fieldsInv, fieldsMap, nil +} + +// mapFields takes the fieldsInv list and returns a map of fieldName +// to fieldID+1 +func mapFields(fields []string) map[string]uint16 { + rv := make(map[string]uint16, len(fields)) + for i, fieldName := range fields { + rv[fieldName] = uint16(i) + 1 + } + return rv +} + +// computeNewDocCount determines how many documents will be in the newly +// merged segment when obsoleted docs are dropped +func computeNewDocCount(segments []*SegmentBase, drops []*roaring.Bitmap) uint64 { + var newDocCount uint64 + for segI, segment := range segments { + newDocCount += segment.numDocs + if drops[segI] != nil { + newDocCount -= drops[segI].GetCardinality() + } + } + return newDocCount +} + +func persistMergedRest(segments []*SegmentBase, dropsIn []*roaring.Bitmap, + fieldsInv []string, fieldsMap map[string]uint16, fieldsSame bool, + newDocNumsIn [][]uint64, newSegDocCount uint64, chunkMode uint32, + w *CountHashWriter, closeCh chan struct{}) ([]uint64, uint64, error) { + var bufMaxVarintLen64 []byte = make([]byte, binary.MaxVarintLen64) + var bufLoc []uint64 + + var postings *PostingsList + var postItr *PostingsIterator + + rv := make([]uint64, len(fieldsInv)) + fieldDvLocsStart := make([]uint64, len(fieldsInv)) + fieldDvLocsEnd := make([]uint64, len(fieldsInv)) + + // these int coders are initialized with chunk size 1024 + // however this will be reset to the correct chunk size + // while processing each individual field-term section + tfEncoder := newChunkedIntCoder(1024, newSegDocCount-1) + locEncoder := newChunkedIntCoder(1024, newSegDocCount-1) + + var vellumBuf bytes.Buffer + newVellum, err := vellum.New(&vellumBuf, nil) + if err != nil { + return nil, 0, err + } + + newRoaring := roaring.NewBitmap() + + // for each field + for fieldID, fieldName := range fieldsInv { + // collect FST iterators from all active segments for this field + var newDocNums [][]uint64 + var drops []*roaring.Bitmap + var dicts []*Dictionary + var itrs []vellum.Iterator + + var segmentsInFocus []*SegmentBase + + for segmentI, segment := range segments { + // check for the closure in meantime + if isClosed(closeCh) { + return nil, 0, seg.ErrClosed + } + + dict, err2 := segment.dictionary(fieldName) + if err2 != nil { + return nil, 0, err2 + } + if dict != nil && dict.fst != nil { + itr, err2 := dict.fst.Iterator(nil, nil) + if err2 != nil && err2 != vellum.ErrIteratorDone { + return nil, 0, err2 + } + if itr != nil { + newDocNums = append(newDocNums, newDocNumsIn[segmentI]) + if dropsIn[segmentI] != nil && !dropsIn[segmentI].IsEmpty() { + drops = append(drops, dropsIn[segmentI]) + } else { + drops = append(drops, nil) + } + dicts = append(dicts, dict) + itrs = append(itrs, itr) + segmentsInFocus = append(segmentsInFocus, segment) + } + } + } + + var prevTerm []byte + + newRoaring.Clear() + + var lastDocNum, lastFreq, lastNorm uint64 + + // determines whether to use "1-hit" encoding optimization + // when a term appears in only 1 doc, with no loc info, + // has freq of 1, and the docNum fits into 31-bits + use1HitEncoding := func(termCardinality uint64) (bool, uint64, uint64) { + if termCardinality == uint64(1) && locEncoder.FinalSize() <= 0 { + docNum := uint64(newRoaring.Minimum()) + if under32Bits(docNum) && docNum == lastDocNum && lastFreq == 1 { + return true, docNum, lastNorm + } + } + return false, 0, 0 + } + + finishTerm := func(term []byte) error { + tfEncoder.Close() + locEncoder.Close() + + postingsOffset, err := writePostings(newRoaring, + tfEncoder, locEncoder, use1HitEncoding, w, bufMaxVarintLen64) + if err != nil { + return err + } + + if postingsOffset > 0 { + err = newVellum.Insert(term, postingsOffset) + if err != nil { + return err + } + } + + newRoaring.Clear() + + tfEncoder.Reset() + locEncoder.Reset() + + lastDocNum = 0 + lastFreq = 0 + lastNorm = 0 + + return nil + } + + enumerator, err := newEnumerator(itrs) + + for err == nil { + term, itrI, postingsOffset := enumerator.Current() + + if !bytes.Equal(prevTerm, term) { + // check for the closure in meantime + if isClosed(closeCh) { + return nil, 0, seg.ErrClosed + } + + // if the term changed, write out the info collected + // for the previous term + err = finishTerm(prevTerm) + if err != nil { + return nil, 0, err + } + } + if !bytes.Equal(prevTerm, term) || prevTerm == nil { + // compute cardinality of field-term in new seg + var newCard uint64 + lowItrIdxs, lowItrVals := enumerator.GetLowIdxsAndValues() + for i, idx := range lowItrIdxs { + pl, err := dicts[idx].postingsListFromOffset(lowItrVals[i], drops[idx], nil) + if err != nil { + return nil, 0, err + } + newCard += pl.Count() + } + // compute correct chunk size with this + chunkSize, err := getChunkSize(chunkMode, newCard, newSegDocCount) + if err != nil { + return nil, 0, err + } + // update encoders chunk + tfEncoder.SetChunkSize(chunkSize, newSegDocCount-1) + locEncoder.SetChunkSize(chunkSize, newSegDocCount-1) + } + + postings, err = dicts[itrI].postingsListFromOffset( + postingsOffset, drops[itrI], postings) + if err != nil { + return nil, 0, err + } + + postItr = postings.iterator(true, true, true, postItr) + + if fieldsSame { + // can optimize by copying freq/norm/loc bytes directly + lastDocNum, lastFreq, lastNorm, err = mergeTermFreqNormLocsByCopying( + term, postItr, newDocNums[itrI], newRoaring, + tfEncoder, locEncoder) + } else { + lastDocNum, lastFreq, lastNorm, bufLoc, err = mergeTermFreqNormLocs( + fieldsMap, term, postItr, newDocNums[itrI], newRoaring, + tfEncoder, locEncoder, bufLoc) + } + if err != nil { + return nil, 0, err + } + + prevTerm = prevTerm[:0] // copy to prevTerm in case Next() reuses term mem + prevTerm = append(prevTerm, term...) + + err = enumerator.Next() + } + if err != vellum.ErrIteratorDone { + return nil, 0, err + } + + err = finishTerm(prevTerm) + if err != nil { + return nil, 0, err + } + + dictOffset := uint64(w.Count()) + + err = newVellum.Close() + if err != nil { + return nil, 0, err + } + vellumData := vellumBuf.Bytes() + + // write out the length of the vellum data + n := binary.PutUvarint(bufMaxVarintLen64, uint64(len(vellumData))) + _, err = w.Write(bufMaxVarintLen64[:n]) + if err != nil { + return nil, 0, err + } + + // write this vellum to disk + _, err = w.Write(vellumData) + if err != nil { + return nil, 0, err + } + + rv[fieldID] = dictOffset + + // get the field doc value offset (start) + fieldDvLocsStart[fieldID] = uint64(w.Count()) + + // update the field doc values + // NOTE: doc values continue to use legacy chunk mode + chunkSize, err := getChunkSize(LegacyChunkMode, 0, 0) + if err != nil { + return nil, 0, err + } + fdvEncoder := newChunkedContentCoder(chunkSize, newSegDocCount-1, w, true) + + fdvReadersAvailable := false + var dvIterClone *docValueReader + for segmentI, segment := range segmentsInFocus { + // check for the closure in meantime + if isClosed(closeCh) { + return nil, 0, seg.ErrClosed + } + + fieldIDPlus1 := uint16(segment.fieldsMap[fieldName]) + if dvIter, exists := segment.fieldDvReaders[fieldIDPlus1-1]; exists && + dvIter != nil { + fdvReadersAvailable = true + dvIterClone = dvIter.cloneInto(dvIterClone) + err = dvIterClone.iterateAllDocValues(segment, func(docNum uint64, terms []byte) error { + if newDocNums[segmentI][docNum] == docDropped { + return nil + } + err := fdvEncoder.Add(newDocNums[segmentI][docNum], terms) + if err != nil { + return err + } + return nil + }) + if err != nil { + return nil, 0, err + } + } + } + + if fdvReadersAvailable { + err = fdvEncoder.Close() + if err != nil { + return nil, 0, err + } + + // persist the doc value details for this field + _, err = fdvEncoder.Write() + if err != nil { + return nil, 0, err + } + + // get the field doc value offset (end) + fieldDvLocsEnd[fieldID] = uint64(w.Count()) + } else { + fieldDvLocsStart[fieldID] = fieldNotUninverted + fieldDvLocsEnd[fieldID] = fieldNotUninverted + } + + // reset vellum buffer and vellum builder + vellumBuf.Reset() + err = newVellum.Reset(&vellumBuf) + if err != nil { + return nil, 0, err + } + } + + fieldDvLocsOffset := uint64(w.Count()) + + buf := bufMaxVarintLen64 + for i := 0; i < len(fieldDvLocsStart); i++ { + n := binary.PutUvarint(buf, fieldDvLocsStart[i]) + _, err := w.Write(buf[:n]) + if err != nil { + return nil, 0, err + } + n = binary.PutUvarint(buf, fieldDvLocsEnd[i]) + _, err = w.Write(buf[:n]) + if err != nil { + return nil, 0, err + } + } + + return rv, fieldDvLocsOffset, nil +} + +func mergeTermFreqNormLocsByCopying(term []byte, postItr *PostingsIterator, + newDocNums []uint64, newRoaring *roaring.Bitmap, + tfEncoder *chunkedIntCoder, locEncoder *chunkedIntCoder) ( + lastDocNum uint64, lastFreq uint64, lastNorm uint64, err error) { + nextDocNum, nextFreq, nextNorm, nextFreqNormBytes, nextLocBytes, err := + postItr.nextBytes() + for err == nil && len(nextFreqNormBytes) > 0 { + hitNewDocNum := newDocNums[nextDocNum] + if hitNewDocNum == docDropped { + return 0, 0, 0, fmt.Errorf("see hit with dropped doc num") + } + + newRoaring.Add(uint32(hitNewDocNum)) + + err = tfEncoder.AddBytes(hitNewDocNum, nextFreqNormBytes) + if err != nil { + return 0, 0, 0, err + } + + if len(nextLocBytes) > 0 { + err = locEncoder.AddBytes(hitNewDocNum, nextLocBytes) + if err != nil { + return 0, 0, 0, err + } + } + + lastDocNum = hitNewDocNum + lastFreq = nextFreq + lastNorm = nextNorm + + nextDocNum, nextFreq, nextNorm, nextFreqNormBytes, nextLocBytes, err = + postItr.nextBytes() + } + + return lastDocNum, lastFreq, lastNorm, err +} + +func mergeTermFreqNormLocs(fieldsMap map[string]uint16, term []byte, postItr *PostingsIterator, + newDocNums []uint64, newRoaring *roaring.Bitmap, + tfEncoder *chunkedIntCoder, locEncoder *chunkedIntCoder, bufLoc []uint64) ( + lastDocNum uint64, lastFreq uint64, lastNorm uint64, bufLocOut []uint64, err error) { + next, err := postItr.Next() + for next != nil && err == nil { + hitNewDocNum := newDocNums[next.Number()] + if hitNewDocNum == docDropped { + return 0, 0, 0, nil, fmt.Errorf("see hit with dropped docNum") + } + + newRoaring.Add(uint32(hitNewDocNum)) + + nextFreq := next.Frequency() + var nextNorm uint64 + if pi, ok := next.(*Posting); ok { + nextNorm = pi.NormUint64() + } else { + return 0, 0, 0, nil, fmt.Errorf("unexpected posting type %T", next) + } + + locs := next.Locations() + + if nextFreq > 0 { + err = tfEncoder.Add(hitNewDocNum, + encodeFreqHasLocs(nextFreq, len(locs) > 0), nextNorm) + } else { + err = tfEncoder.Add(hitNewDocNum, + encodeFreqHasLocs(nextFreq, len(locs) > 0)) + } + if err != nil { + return 0, 0, 0, nil, err + } + + if len(locs) > 0 { + numBytesLocs := 0 + for _, loc := range locs { + ap := loc.ArrayPositions() + numBytesLocs += totalUvarintBytes(uint64(fieldsMap[loc.Field()]-1), + loc.Pos(), loc.Start(), loc.End(), uint64(len(ap)), ap) + } + + err = locEncoder.Add(hitNewDocNum, uint64(numBytesLocs)) + if err != nil { + return 0, 0, 0, nil, err + } + + for _, loc := range locs { + ap := loc.ArrayPositions() + if cap(bufLoc) < 5+len(ap) { + bufLoc = make([]uint64, 0, 5+len(ap)) + } + args := bufLoc[0:5] + args[0] = uint64(fieldsMap[loc.Field()] - 1) + args[1] = loc.Pos() + args[2] = loc.Start() + args[3] = loc.End() + args[4] = uint64(len(ap)) + args = append(args, ap...) + err = locEncoder.Add(hitNewDocNum, args...) + if err != nil { + return 0, 0, 0, nil, err + } + } + } + + lastDocNum = hitNewDocNum + lastFreq = nextFreq + lastNorm = nextNorm + + next, err = postItr.Next() + } + + return lastDocNum, lastFreq, lastNorm, bufLoc, err +} + +func writePostings(postings *roaring.Bitmap, tfEncoder, locEncoder *chunkedIntCoder, + use1HitEncoding func(uint64) (bool, uint64, uint64), + w *CountHashWriter, bufMaxVarintLen64 []byte) ( + offset uint64, err error) { + termCardinality := postings.GetCardinality() + if termCardinality <= 0 { + return 0, nil + } + + if use1HitEncoding != nil { + encodeAs1Hit, docNum1Hit, normBits1Hit := use1HitEncoding(termCardinality) + if encodeAs1Hit { + return FSTValEncode1Hit(docNum1Hit, normBits1Hit), nil + } + } + + var tfOffset uint64 + tfOffset, _, err = tfEncoder.writeAt(w) + if err != nil { + return 0, err + } + + var locOffset uint64 + locOffset, _, err = locEncoder.writeAt(w) + if err != nil { + return 0, err + } + + postingsOffset := uint64(w.Count()) + + n := binary.PutUvarint(bufMaxVarintLen64, tfOffset) + _, err = w.Write(bufMaxVarintLen64[:n]) + if err != nil { + return 0, err + } + + n = binary.PutUvarint(bufMaxVarintLen64, locOffset) + _, err = w.Write(bufMaxVarintLen64[:n]) + if err != nil { + return 0, err + } + + _, err = writeRoaringWithLen(postings, w, bufMaxVarintLen64) + if err != nil { + return 0, err + } + + return postingsOffset, nil +} + +type varintEncoder func(uint64) (int, error) + +func mergeStoredAndRemap(segments []*SegmentBase, drops []*roaring.Bitmap, + fieldsMap map[string]uint16, fieldsInv []string, fieldsSame bool, newSegDocCount uint64, + w *CountHashWriter, closeCh chan struct{}) (uint64, [][]uint64, error) { + var rv [][]uint64 // The remapped or newDocNums for each segment. + + var newDocNum uint64 + + var curr int + var data, compressed []byte + var metaBuf bytes.Buffer + varBuf := make([]byte, binary.MaxVarintLen64) + metaEncode := func(val uint64) (int, error) { + wb := binary.PutUvarint(varBuf, val) + return metaBuf.Write(varBuf[:wb]) + } + + vals := make([][][]byte, len(fieldsInv)) + typs := make([][]byte, len(fieldsInv)) + poss := make([][][]uint64, len(fieldsInv)) + + var posBuf []uint64 + + docNumOffsets := make([]uint64, newSegDocCount) + + vdc := visitDocumentCtxPool.Get().(*visitDocumentCtx) + defer visitDocumentCtxPool.Put(vdc) + + // for each segment + for segI, segment := range segments { + // check for the closure in meantime + if isClosed(closeCh) { + return 0, nil, seg.ErrClosed + } + + segNewDocNums := make([]uint64, segment.numDocs) + + dropsI := drops[segI] + + // optimize when the field mapping is the same across all + // segments and there are no deletions, via byte-copying + // of stored docs bytes directly to the writer + if fieldsSame && (dropsI == nil || dropsI.GetCardinality() == 0) { + err := segment.copyStoredDocs(newDocNum, docNumOffsets, w) + if err != nil { + return 0, nil, err + } + + for i := uint64(0); i < segment.numDocs; i++ { + segNewDocNums[i] = newDocNum + newDocNum++ + } + rv = append(rv, segNewDocNums) + + continue + } + + // for each doc num + for docNum := uint64(0); docNum < segment.numDocs; docNum++ { + // TODO: roaring's API limits docNums to 32-bits? + if dropsI != nil && dropsI.Contains(uint32(docNum)) { + segNewDocNums[docNum] = docDropped + continue + } + + segNewDocNums[docNum] = newDocNum + + curr = 0 + metaBuf.Reset() + data = data[:0] + + posTemp := posBuf + + // collect all the data + for i := 0; i < len(fieldsInv); i++ { + vals[i] = vals[i][:0] + typs[i] = typs[i][:0] + poss[i] = poss[i][:0] + } + err := segment.visitStoredFields(vdc, docNum, func(field string, typ byte, value []byte, pos []uint64) bool { + fieldID := int(fieldsMap[field]) - 1 + vals[fieldID] = append(vals[fieldID], value) + typs[fieldID] = append(typs[fieldID], typ) + + // copy array positions to preserve them beyond the scope of this callback + var curPos []uint64 + if len(pos) > 0 { + if cap(posTemp) < len(pos) { + posBuf = make([]uint64, len(pos)*len(fieldsInv)) + posTemp = posBuf + } + curPos = posTemp[0:len(pos)] + copy(curPos, pos) + posTemp = posTemp[len(pos):] + } + poss[fieldID] = append(poss[fieldID], curPos) + + return true + }) + if err != nil { + return 0, nil, err + } + + // _id field special case optimizes ExternalID() lookups + idFieldVal := vals[uint16(0)][0] + _, err = metaEncode(uint64(len(idFieldVal))) + if err != nil { + return 0, nil, err + } + + // now walk the non-"_id" fields in order + for fieldID := 1; fieldID < len(fieldsInv); fieldID++ { + storedFieldValues := vals[fieldID] + + stf := typs[fieldID] + spf := poss[fieldID] + + var err2 error + curr, data, err2 = persistStoredFieldValues(fieldID, + storedFieldValues, stf, spf, curr, metaEncode, data) + if err2 != nil { + return 0, nil, err2 + } + } + + metaBytes := metaBuf.Bytes() + + compressed = snappy.Encode(compressed[:cap(compressed)], data) + + // record where we're about to start writing + docNumOffsets[newDocNum] = uint64(w.Count()) + + // write out the meta len and compressed data len + _, err = writeUvarints(w, + uint64(len(metaBytes)), + uint64(len(idFieldVal)+len(compressed))) + if err != nil { + return 0, nil, err + } + // now write the meta + _, err = w.Write(metaBytes) + if err != nil { + return 0, nil, err + } + // now write the _id field val (counted as part of the 'compressed' data) + _, err = w.Write(idFieldVal) + if err != nil { + return 0, nil, err + } + // now write the compressed data + _, err = w.Write(compressed) + if err != nil { + return 0, nil, err + } + + newDocNum++ + } + + rv = append(rv, segNewDocNums) + } + + // return value is the start of the stored index + storedIndexOffset := uint64(w.Count()) + + // now write out the stored doc index + for _, docNumOffset := range docNumOffsets { + err := binary.Write(w, binary.BigEndian, docNumOffset) + if err != nil { + return 0, nil, err + } + } + + return storedIndexOffset, rv, nil +} + +// copyStoredDocs writes out a segment's stored doc info, optimized by +// using a single Write() call for the entire set of bytes. The +// newDocNumOffsets is filled with the new offsets for each doc. +func (s *SegmentBase) copyStoredDocs(newDocNum uint64, newDocNumOffsets []uint64, + w *CountHashWriter) error { + if s.numDocs <= 0 { + return nil + } + + indexOffset0, storedOffset0, _, _, _ := + s.getDocStoredOffsets(0) // the segment's first doc + + indexOffsetN, storedOffsetN, readN, metaLenN, dataLenN := + s.getDocStoredOffsets(s.numDocs - 1) // the segment's last doc + + storedOffset0New := uint64(w.Count()) + + storedBytes := s.mem[storedOffset0 : storedOffsetN+readN+metaLenN+dataLenN] + _, err := w.Write(storedBytes) + if err != nil { + return err + } + + // remap the storedOffset's for the docs into new offsets relative + // to storedOffset0New, filling the given docNumOffsetsOut array + for indexOffset := indexOffset0; indexOffset <= indexOffsetN; indexOffset += 8 { + storedOffset := binary.BigEndian.Uint64(s.mem[indexOffset : indexOffset+8]) + storedOffsetNew := storedOffset - storedOffset0 + storedOffset0New + newDocNumOffsets[newDocNum] = storedOffsetNew + newDocNum += 1 + } + + return nil +} + +// mergeFields builds a unified list of fields used across all the +// input segments, and computes whether the fields are the same across +// segments (which depends on fields to be sorted in the same way +// across segments) +func mergeFields(segments []*SegmentBase) (bool, []string) { + fieldsSame := true + + var segment0Fields []string + if len(segments) > 0 { + segment0Fields = segments[0].Fields() + } + + fieldsExist := map[string]struct{}{} + for _, segment := range segments { + fields := segment.Fields() + for fieldi, field := range fields { + fieldsExist[field] = struct{}{} + if len(segment0Fields) != len(fields) || segment0Fields[fieldi] != field { + fieldsSame = false + } + } + } + + rv := make([]string, 0, len(fieldsExist)) + // ensure _id stays first + rv = append(rv, "_id") + for k := range fieldsExist { + if k != "_id" { + rv = append(rv, k) + } + } + + sort.Strings(rv[1:]) // leave _id as first + + return fieldsSame, rv +} + +func isClosed(closeCh chan struct{}) bool { + select { + case <-closeCh: + return true + default: + return false + } +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/new.go b/backend/vendor/github.com/blevesearch/zapx/v15/new.go new file mode 100644 index 0000000000..f659a5d08b --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/new.go @@ -0,0 +1,865 @@ +// Copyright (c) 2018 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "math" + "sort" + "sync" + "sync/atomic" + + "github.com/RoaringBitmap/roaring" + index "github.com/blevesearch/bleve_index_api" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" + "github.com/golang/snappy" +) + +var NewSegmentBufferNumResultsBump int = 100 +var NewSegmentBufferNumResultsFactor float64 = 1.0 +var NewSegmentBufferAvgBytesPerDocFactor float64 = 1.0 + +// ValidateDocFields can be set by applications to perform additional checks +// on fields in a document being added to a new segment, by default it does +// nothing. +// This API is experimental and may be removed at any time. +var ValidateDocFields = func(field index.Field) error { + return nil +} + +// New creates an in-memory zap-encoded SegmentBase from a set of Documents +func (z *ZapPlugin) New(results []index.Document) ( + segment.Segment, uint64, error) { + return z.newWithChunkMode(results, DefaultChunkMode) +} + +func (*ZapPlugin) newWithChunkMode(results []index.Document, + chunkMode uint32) (segment.Segment, uint64, error) { + s := interimPool.Get().(*interim) + + var br bytes.Buffer + if s.lastNumDocs > 0 { + // use previous results to initialize the buf with an estimate + // size, but note that the interim instance comes from a + // global interimPool, so multiple scorch instances indexing + // different docs can lead to low quality estimates + estimateAvgBytesPerDoc := int(float64(s.lastOutSize/s.lastNumDocs) * + NewSegmentBufferNumResultsFactor) + estimateNumResults := int(float64(len(results)+NewSegmentBufferNumResultsBump) * + NewSegmentBufferAvgBytesPerDocFactor) + br.Grow(estimateAvgBytesPerDoc * estimateNumResults) + } + + s.results = results + s.chunkMode = chunkMode + s.w = NewCountHashWriter(&br) + + storedIndexOffset, fieldsIndexOffset, fdvIndexOffset, dictOffsets, + err := s.convert() + if err != nil { + return nil, uint64(0), err + } + + sb, err := InitSegmentBase(br.Bytes(), s.w.Sum32(), chunkMode, + s.FieldsMap, s.FieldsInv, uint64(len(results)), + storedIndexOffset, fieldsIndexOffset, fdvIndexOffset, dictOffsets) + + // get the bytes written before the interim's reset() call + // write it to the newly formed segment base. + totalBytesWritten := s.getBytesWritten() + if err == nil && s.reset() == nil { + s.lastNumDocs = len(results) + s.lastOutSize = len(br.Bytes()) + sb.setBytesWritten(totalBytesWritten) + interimPool.Put(s) + } + + return sb, uint64(len(br.Bytes())), err +} + +var interimPool = sync.Pool{New: func() interface{} { return &interim{} }} + +// interim holds temporary working data used while converting from +// analysis results to a zap-encoded segment +type interim struct { + results []index.Document + + chunkMode uint32 + + w *CountHashWriter + + // FieldsMap adds 1 to field id to avoid zero value issues + // name -> field id + 1 + FieldsMap map[string]uint16 + + // FieldsInv is the inverse of FieldsMap + // field id -> name + FieldsInv []string + + // Term dictionaries for each field + // field id -> term -> postings list id + 1 + Dicts []map[string]uint64 + + // Terms for each field, where terms are sorted ascending + // field id -> []term + DictKeys [][]string + + // Fields whose IncludeDocValues is true + // field id -> bool + IncludeDocValues []bool + + // postings id -> bitmap of docNums + Postings []*roaring.Bitmap + + // postings id -> freq/norm's, one for each docNum in postings + FreqNorms [][]interimFreqNorm + freqNormsBacking []interimFreqNorm + + // postings id -> locs, one for each freq + Locs [][]interimLoc + locsBacking []interimLoc + + numTermsPerPostingsList []int // key is postings list id + numLocsPerPostingsList []int // key is postings list id + + builder *vellum.Builder + builderBuf bytes.Buffer + + metaBuf bytes.Buffer + + tmp0 []byte + tmp1 []byte + + lastNumDocs int + lastOutSize int + + // atomic access to this variable + bytesWritten uint64 +} + +func (s *interim) reset() (err error) { + s.results = nil + s.chunkMode = 0 + s.w = nil + s.FieldsMap = nil + s.FieldsInv = nil + for i := range s.Dicts { + s.Dicts[i] = nil + } + s.Dicts = s.Dicts[:0] + for i := range s.DictKeys { + s.DictKeys[i] = s.DictKeys[i][:0] + } + s.DictKeys = s.DictKeys[:0] + for i := range s.IncludeDocValues { + s.IncludeDocValues[i] = false + } + s.IncludeDocValues = s.IncludeDocValues[:0] + for _, idn := range s.Postings { + idn.Clear() + } + s.Postings = s.Postings[:0] + s.FreqNorms = s.FreqNorms[:0] + for i := range s.freqNormsBacking { + s.freqNormsBacking[i] = interimFreqNorm{} + } + s.freqNormsBacking = s.freqNormsBacking[:0] + s.Locs = s.Locs[:0] + for i := range s.locsBacking { + s.locsBacking[i] = interimLoc{} + } + s.locsBacking = s.locsBacking[:0] + s.numTermsPerPostingsList = s.numTermsPerPostingsList[:0] + s.numLocsPerPostingsList = s.numLocsPerPostingsList[:0] + s.builderBuf.Reset() + if s.builder != nil { + err = s.builder.Reset(&s.builderBuf) + } + s.metaBuf.Reset() + s.tmp0 = s.tmp0[:0] + s.tmp1 = s.tmp1[:0] + s.lastNumDocs = 0 + s.lastOutSize = 0 + + // reset the bytes written stat count + // to avoid leaking of bytesWritten across reuse cycles. + s.setBytesWritten(0) + + return err +} + +func (s *interim) grabBuf(size int) []byte { + buf := s.tmp0 + if cap(buf) < size { + buf = make([]byte, size) + s.tmp0 = buf + } + return buf[0:size] +} + +type interimStoredField struct { + vals [][]byte + typs []byte + arrayposs [][]uint64 // array positions +} + +type interimFreqNorm struct { + freq uint64 + norm float32 + numLocs int +} + +type interimLoc struct { + fieldID uint16 + pos uint64 + start uint64 + end uint64 + arrayposs []uint64 +} + +func (s *interim) convert() (uint64, uint64, uint64, []uint64, error) { + s.FieldsMap = map[string]uint16{} + + s.getOrDefineField("_id") // _id field is fieldID 0 + + for _, result := range s.results { + result.VisitComposite(func(field index.CompositeField) { + s.getOrDefineField(field.Name()) + }) + result.VisitFields(func(field index.Field) { + s.getOrDefineField(field.Name()) + }) + } + + sort.Strings(s.FieldsInv[1:]) // keep _id as first field + + for fieldID, fieldName := range s.FieldsInv { + s.FieldsMap[fieldName] = uint16(fieldID + 1) + } + + if cap(s.IncludeDocValues) >= len(s.FieldsInv) { + s.IncludeDocValues = s.IncludeDocValues[:len(s.FieldsInv)] + } else { + s.IncludeDocValues = make([]bool, len(s.FieldsInv)) + } + + s.prepareDicts() + + for _, dict := range s.DictKeys { + sort.Strings(dict) + } + + s.processDocuments() + + storedIndexOffset, err := s.writeStoredFields() + if err != nil { + return 0, 0, 0, nil, err + } + + var fdvIndexOffset uint64 + var dictOffsets []uint64 + + if len(s.results) > 0 { + fdvIndexOffset, dictOffsets, err = s.writeDicts() + if err != nil { + return 0, 0, 0, nil, err + } + } else { + dictOffsets = make([]uint64, len(s.FieldsInv)) + } + + fieldsIndexOffset, err := persistFields(s.FieldsInv, s.w, dictOffsets) + if err != nil { + return 0, 0, 0, nil, err + } + + return storedIndexOffset, fieldsIndexOffset, fdvIndexOffset, dictOffsets, nil +} + +func (s *interim) getOrDefineField(fieldName string) int { + fieldIDPlus1, exists := s.FieldsMap[fieldName] + if !exists { + fieldIDPlus1 = uint16(len(s.FieldsInv) + 1) + s.FieldsMap[fieldName] = fieldIDPlus1 + s.FieldsInv = append(s.FieldsInv, fieldName) + + s.Dicts = append(s.Dicts, make(map[string]uint64)) + + n := len(s.DictKeys) + if n < cap(s.DictKeys) { + s.DictKeys = s.DictKeys[:n+1] + s.DictKeys[n] = s.DictKeys[n][:0] + } else { + s.DictKeys = append(s.DictKeys, []string(nil)) + } + } + + return int(fieldIDPlus1 - 1) +} + +// fill Dicts and DictKeys from analysis results +func (s *interim) prepareDicts() { + var pidNext int + + var totTFs int + var totLocs int + + visitField := func(field index.Field) { + fieldID := uint16(s.getOrDefineField(field.Name())) + + dict := s.Dicts[fieldID] + dictKeys := s.DictKeys[fieldID] + + tfs := field.AnalyzedTokenFrequencies() + for term, tf := range tfs { + pidPlus1, exists := dict[term] + if !exists { + pidNext++ + pidPlus1 = uint64(pidNext) + + dict[term] = pidPlus1 + dictKeys = append(dictKeys, term) + + s.numTermsPerPostingsList = append(s.numTermsPerPostingsList, 0) + s.numLocsPerPostingsList = append(s.numLocsPerPostingsList, 0) + } + + pid := pidPlus1 - 1 + + s.numTermsPerPostingsList[pid] += 1 + s.numLocsPerPostingsList[pid] += len(tf.Locations) + + totLocs += len(tf.Locations) + } + + totTFs += len(tfs) + + s.DictKeys[fieldID] = dictKeys + } + + for _, result := range s.results { + // walk each composite field + result.VisitComposite(func(field index.CompositeField) { + visitField(field) + }) + + // walk each field + result.VisitFields(visitField) + } + + numPostingsLists := pidNext + + if cap(s.Postings) >= numPostingsLists { + s.Postings = s.Postings[:numPostingsLists] + } else { + postings := make([]*roaring.Bitmap, numPostingsLists) + copy(postings, s.Postings[:cap(s.Postings)]) + for i := 0; i < numPostingsLists; i++ { + if postings[i] == nil { + postings[i] = roaring.New() + } + } + s.Postings = postings + } + + if cap(s.FreqNorms) >= numPostingsLists { + s.FreqNorms = s.FreqNorms[:numPostingsLists] + } else { + s.FreqNorms = make([][]interimFreqNorm, numPostingsLists) + } + + if cap(s.freqNormsBacking) >= totTFs { + s.freqNormsBacking = s.freqNormsBacking[:totTFs] + } else { + s.freqNormsBacking = make([]interimFreqNorm, totTFs) + } + + freqNormsBacking := s.freqNormsBacking + for pid, numTerms := range s.numTermsPerPostingsList { + s.FreqNorms[pid] = freqNormsBacking[0:0] + freqNormsBacking = freqNormsBacking[numTerms:] + } + + if cap(s.Locs) >= numPostingsLists { + s.Locs = s.Locs[:numPostingsLists] + } else { + s.Locs = make([][]interimLoc, numPostingsLists) + } + + if cap(s.locsBacking) >= totLocs { + s.locsBacking = s.locsBacking[:totLocs] + } else { + s.locsBacking = make([]interimLoc, totLocs) + } + + locsBacking := s.locsBacking + for pid, numLocs := range s.numLocsPerPostingsList { + s.Locs[pid] = locsBacking[0:0] + locsBacking = locsBacking[numLocs:] + } +} + +func (s *interim) processDocuments() { + numFields := len(s.FieldsInv) + reuseFieldLens := make([]int, numFields) + reuseFieldTFs := make([]index.TokenFrequencies, numFields) + + for docNum, result := range s.results { + for i := 0; i < numFields; i++ { // clear these for reuse + reuseFieldLens[i] = 0 + reuseFieldTFs[i] = nil + } + + s.processDocument(uint64(docNum), result, + reuseFieldLens, reuseFieldTFs) + } +} + +func (s *interim) processDocument(docNum uint64, + result index.Document, + fieldLens []int, fieldTFs []index.TokenFrequencies) { + visitField := func(field index.Field) { + fieldID := uint16(s.getOrDefineField(field.Name())) + fieldLens[fieldID] += field.AnalyzedLength() + + existingFreqs := fieldTFs[fieldID] + if existingFreqs != nil { + existingFreqs.MergeAll(field.Name(), field.AnalyzedTokenFrequencies()) + } else { + fieldTFs[fieldID] = field.AnalyzedTokenFrequencies() + } + } + + // walk each composite field + result.VisitComposite(func(field index.CompositeField) { + visitField(field) + }) + + // walk each field + result.VisitFields(visitField) + + // now that it's been rolled up into fieldTFs, walk that + for fieldID, tfs := range fieldTFs { + dict := s.Dicts[fieldID] + norm := math.Float32frombits(uint32(fieldLens[fieldID])) + + for term, tf := range tfs { + pid := dict[term] - 1 + bs := s.Postings[pid] + bs.Add(uint32(docNum)) + + s.FreqNorms[pid] = append(s.FreqNorms[pid], + interimFreqNorm{ + freq: uint64(tf.Frequency()), + norm: norm, + numLocs: len(tf.Locations), + }) + + if len(tf.Locations) > 0 { + locs := s.Locs[pid] + + for _, loc := range tf.Locations { + var locf = uint16(fieldID) + if loc.Field != "" { + locf = uint16(s.getOrDefineField(loc.Field)) + } + var arrayposs []uint64 + if len(loc.ArrayPositions) > 0 { + arrayposs = loc.ArrayPositions + } + locs = append(locs, interimLoc{ + fieldID: locf, + pos: uint64(loc.Position), + start: uint64(loc.Start), + end: uint64(loc.End), + arrayposs: arrayposs, + }) + } + + s.Locs[pid] = locs + } + } + } +} + +func (s *interim) getBytesWritten() uint64 { + return atomic.LoadUint64(&s.bytesWritten) +} + +func (s *interim) incrementBytesWritten(val uint64) { + atomic.AddUint64(&s.bytesWritten, val) +} + +func (s *interim) writeStoredFields() ( + storedIndexOffset uint64, err error) { + varBuf := make([]byte, binary.MaxVarintLen64) + metaEncode := func(val uint64) (int, error) { + wb := binary.PutUvarint(varBuf, val) + return s.metaBuf.Write(varBuf[:wb]) + } + + data, compressed := s.tmp0[:0], s.tmp1[:0] + defer func() { s.tmp0, s.tmp1 = data, compressed }() + + // keyed by docNum + docStoredOffsets := make([]uint64, len(s.results)) + + // keyed by fieldID, for the current doc in the loop + docStoredFields := map[uint16]interimStoredField{} + + for docNum, result := range s.results { + for fieldID := range docStoredFields { // reset for next doc + delete(docStoredFields, fieldID) + } + + var validationErr error + result.VisitFields(func(field index.Field) { + fieldID := uint16(s.getOrDefineField(field.Name())) + + if field.Options().IsStored() { + isf := docStoredFields[fieldID] + isf.vals = append(isf.vals, field.Value()) + isf.typs = append(isf.typs, field.EncodedFieldType()) + isf.arrayposs = append(isf.arrayposs, field.ArrayPositions()) + docStoredFields[fieldID] = isf + } + + if field.Options().IncludeDocValues() { + s.IncludeDocValues[fieldID] = true + } + + err := ValidateDocFields(field) + if err != nil && validationErr == nil { + validationErr = err + } + }) + if validationErr != nil { + return 0, validationErr + } + + var curr int + + s.metaBuf.Reset() + data = data[:0] + + // _id field special case optimizes ExternalID() lookups + idFieldVal := docStoredFields[uint16(0)].vals[0] + _, err = metaEncode(uint64(len(idFieldVal))) + if err != nil { + return 0, err + } + + // handle non-"_id" fields + for fieldID := 1; fieldID < len(s.FieldsInv); fieldID++ { + isf, exists := docStoredFields[uint16(fieldID)] + if exists { + curr, data, err = persistStoredFieldValues( + fieldID, isf.vals, isf.typs, isf.arrayposs, + curr, metaEncode, data) + if err != nil { + return 0, err + } + } + } + + metaBytes := s.metaBuf.Bytes() + + compressed = snappy.Encode(compressed[:cap(compressed)], data) + s.incrementBytesWritten(uint64(len(compressed))) + docStoredOffsets[docNum] = uint64(s.w.Count()) + + _, err := writeUvarints(s.w, + uint64(len(metaBytes)), + uint64(len(idFieldVal)+len(compressed))) + if err != nil { + return 0, err + } + + _, err = s.w.Write(metaBytes) + if err != nil { + return 0, err + } + + _, err = s.w.Write(idFieldVal) + if err != nil { + return 0, err + } + + _, err = s.w.Write(compressed) + if err != nil { + return 0, err + } + } + + storedIndexOffset = uint64(s.w.Count()) + + for _, docStoredOffset := range docStoredOffsets { + err = binary.Write(s.w, binary.BigEndian, docStoredOffset) + if err != nil { + return 0, err + } + } + + return storedIndexOffset, nil +} + +func (s *interim) setBytesWritten(val uint64) { + atomic.StoreUint64(&s.bytesWritten, val) +} + +func (s *interim) writeDicts() (fdvIndexOffset uint64, dictOffsets []uint64, err error) { + dictOffsets = make([]uint64, len(s.FieldsInv)) + + fdvOffsetsStart := make([]uint64, len(s.FieldsInv)) + fdvOffsetsEnd := make([]uint64, len(s.FieldsInv)) + + buf := s.grabBuf(binary.MaxVarintLen64) + + // these int coders are initialized with chunk size 1024 + // however this will be reset to the correct chunk size + // while processing each individual field-term section + tfEncoder := newChunkedIntCoder(1024, uint64(len(s.results)-1)) + locEncoder := newChunkedIntCoder(1024, uint64(len(s.results)-1)) + + var docTermMap [][]byte + + if s.builder == nil { + s.builder, err = vellum.New(&s.builderBuf, nil) + if err != nil { + return 0, nil, err + } + } + + for fieldID, terms := range s.DictKeys { + if cap(docTermMap) < len(s.results) { + docTermMap = make([][]byte, len(s.results)) + } else { + docTermMap = docTermMap[0:len(s.results)] + for docNum := range docTermMap { // reset the docTermMap + docTermMap[docNum] = docTermMap[docNum][:0] + } + } + + dict := s.Dicts[fieldID] + + for _, term := range terms { // terms are already sorted + pid := dict[term] - 1 + + postingsBS := s.Postings[pid] + + freqNorms := s.FreqNorms[pid] + freqNormOffset := 0 + + locs := s.Locs[pid] + locOffset := 0 + + chunkSize, err := getChunkSize(s.chunkMode, postingsBS.GetCardinality(), uint64(len(s.results))) + if err != nil { + return 0, nil, err + } + tfEncoder.SetChunkSize(chunkSize, uint64(len(s.results)-1)) + locEncoder.SetChunkSize(chunkSize, uint64(len(s.results)-1)) + + postingsItr := postingsBS.Iterator() + for postingsItr.HasNext() { + docNum := uint64(postingsItr.Next()) + + freqNorm := freqNorms[freqNormOffset] + + // check if freq/norm is enabled + if freqNorm.freq > 0 { + err = tfEncoder.Add(docNum, + encodeFreqHasLocs(freqNorm.freq, freqNorm.numLocs > 0), + uint64(math.Float32bits(freqNorm.norm))) + } else { + // if disabled, then skip the norm part + err = tfEncoder.Add(docNum, + encodeFreqHasLocs(freqNorm.freq, freqNorm.numLocs > 0)) + } + if err != nil { + return 0, nil, err + } + + if freqNorm.numLocs > 0 { + numBytesLocs := 0 + for _, loc := range locs[locOffset : locOffset+freqNorm.numLocs] { + numBytesLocs += totalUvarintBytes( + uint64(loc.fieldID), loc.pos, loc.start, loc.end, + uint64(len(loc.arrayposs)), loc.arrayposs) + } + + err = locEncoder.Add(docNum, uint64(numBytesLocs)) + if err != nil { + return 0, nil, err + } + for _, loc := range locs[locOffset : locOffset+freqNorm.numLocs] { + err = locEncoder.Add(docNum, + uint64(loc.fieldID), loc.pos, loc.start, loc.end, + uint64(len(loc.arrayposs))) + if err != nil { + return 0, nil, err + } + + err = locEncoder.Add(docNum, loc.arrayposs...) + if err != nil { + return 0, nil, err + } + } + locOffset += freqNorm.numLocs + } + + freqNormOffset++ + + docTermMap[docNum] = append( + append(docTermMap[docNum], term...), + termSeparator) + } + + tfEncoder.Close() + locEncoder.Close() + s.incrementBytesWritten(locEncoder.getBytesWritten()) + + postingsOffset, err := + writePostings(postingsBS, tfEncoder, locEncoder, nil, s.w, buf) + if err != nil { + return 0, nil, err + } + + if postingsOffset > uint64(0) { + err = s.builder.Insert([]byte(term), postingsOffset) + if err != nil { + return 0, nil, err + } + } + + tfEncoder.Reset() + locEncoder.Reset() + } + + err = s.builder.Close() + if err != nil { + return 0, nil, err + } + + // record where this dictionary starts + dictOffsets[fieldID] = uint64(s.w.Count()) + + vellumData := s.builderBuf.Bytes() + + // write out the length of the vellum data + n := binary.PutUvarint(buf, uint64(len(vellumData))) + _, err = s.w.Write(buf[:n]) + if err != nil { + return 0, nil, err + } + + // write this vellum to disk + _, err = s.w.Write(vellumData) + if err != nil { + return 0, nil, err + } + + s.incrementBytesWritten(uint64(len(vellumData))) + + // reset vellum for reuse + s.builderBuf.Reset() + + err = s.builder.Reset(&s.builderBuf) + if err != nil { + return 0, nil, err + } + + // write the field doc values + // NOTE: doc values continue to use legacy chunk mode + chunkSize, err := getChunkSize(LegacyChunkMode, 0, 0) + if err != nil { + return 0, nil, err + } + + fdvEncoder := newChunkedContentCoder(chunkSize, uint64(len(s.results)-1), s.w, false) + if s.IncludeDocValues[fieldID] { + for docNum, docTerms := range docTermMap { + if len(docTerms) > 0 { + err = fdvEncoder.Add(uint64(docNum), docTerms) + if err != nil { + return 0, nil, err + } + } + } + err = fdvEncoder.Close() + if err != nil { + return 0, nil, err + } + + s.incrementBytesWritten(fdvEncoder.getBytesWritten()) + + fdvOffsetsStart[fieldID] = uint64(s.w.Count()) + + _, err = fdvEncoder.Write() + if err != nil { + return 0, nil, err + } + + fdvOffsetsEnd[fieldID] = uint64(s.w.Count()) + + fdvEncoder.Reset() + } else { + fdvOffsetsStart[fieldID] = fieldNotUninverted + fdvOffsetsEnd[fieldID] = fieldNotUninverted + } + } + + fdvIndexOffset = uint64(s.w.Count()) + + for i := 0; i < len(fdvOffsetsStart); i++ { + n := binary.PutUvarint(buf, fdvOffsetsStart[i]) + _, err := s.w.Write(buf[:n]) + if err != nil { + return 0, nil, err + } + n = binary.PutUvarint(buf, fdvOffsetsEnd[i]) + _, err = s.w.Write(buf[:n]) + if err != nil { + return 0, nil, err + } + } + + return fdvIndexOffset, dictOffsets, nil +} + +// returns the total # of bytes needed to encode the given uint64's +// into binary.PutUVarint() encoding +func totalUvarintBytes(a, b, c, d, e uint64, more []uint64) (n int) { + n = numUvarintBytes(a) + n += numUvarintBytes(b) + n += numUvarintBytes(c) + n += numUvarintBytes(d) + n += numUvarintBytes(e) + for _, v := range more { + n += numUvarintBytes(v) + } + return n +} + +// returns # of bytes needed to encode x in binary.PutUvarint() encoding +func numUvarintBytes(x uint64) (n int) { + for x >= 0x80 { + x >>= 7 + n++ + } + return n + 1 +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/plugin.go b/backend/vendor/github.com/blevesearch/zapx/v15/plugin.go new file mode 100644 index 0000000000..f67297ec2f --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/plugin.go @@ -0,0 +1,27 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +// ZapPlugin implements the Plugin interface of +// the blevesearch/scorch_segment_api pkg +type ZapPlugin struct{} + +func (*ZapPlugin) Type() string { + return Type +} + +func (*ZapPlugin) Version() uint32 { + return Version +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/posting.go b/backend/vendor/github.com/blevesearch/zapx/v15/posting.go new file mode 100644 index 0000000000..c1060f92eb --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/posting.go @@ -0,0 +1,936 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "encoding/binary" + "fmt" + "math" + "reflect" + + "github.com/RoaringBitmap/roaring" + segment "github.com/blevesearch/scorch_segment_api/v2" +) + +var reflectStaticSizePostingsList int +var reflectStaticSizePostingsIterator int +var reflectStaticSizePosting int +var reflectStaticSizeLocation int + +func init() { + var pl PostingsList + reflectStaticSizePostingsList = int(reflect.TypeOf(pl).Size()) + var pi PostingsIterator + reflectStaticSizePostingsIterator = int(reflect.TypeOf(pi).Size()) + var p Posting + reflectStaticSizePosting = int(reflect.TypeOf(p).Size()) + var l Location + reflectStaticSizeLocation = int(reflect.TypeOf(l).Size()) +} + +// FST or vellum value (uint64) encoding is determined by the top two +// highest-order or most significant bits... +// +// encoding : MSB +// name : 63 62 61...to...bit #0 (LSB) +// ----------+---+---+--------------------------------------------------- +// general : 0 | 0 | 62-bits of postingsOffset. +// ~ : 0 | 1 | reserved for future. +// 1-hit : 1 | 0 | 31-bits of positive float31 norm | 31-bits docNum. +// ~ : 1 | 1 | reserved for future. +// +// Encoding "general" is able to handle all cases, where the +// postingsOffset points to more information about the postings for +// the term. +// +// Encoding "1-hit" is used to optimize a commonly seen case when a +// term has only a single hit. For example, a term in the _id field +// will have only 1 hit. The "1-hit" encoding is used for a term +// in a field when... +// +// - term vector info is disabled for that field; +// - and, the term appears in only a single doc for that field; +// - and, the term's freq is exactly 1 in that single doc for that field; +// - and, the docNum must fit into 31-bits; +// +// Otherwise, the "general" encoding is used instead. +// +// In the "1-hit" encoding, the field in that single doc may have +// other terms, which is supported in the "1-hit" encoding by the +// positive float31 norm. + +const FSTValEncodingMask = uint64(0xc000000000000000) +const FSTValEncodingGeneral = uint64(0x0000000000000000) +const FSTValEncoding1Hit = uint64(0x8000000000000000) + +func FSTValEncode1Hit(docNum uint64, normBits uint64) uint64 { + return FSTValEncoding1Hit | ((mask31Bits & normBits) << 31) | (mask31Bits & docNum) +} + +func FSTValDecode1Hit(v uint64) (docNum uint64, normBits uint64) { + return (mask31Bits & v), (mask31Bits & (v >> 31)) +} + +const mask31Bits = uint64(0x000000007fffffff) + +func under32Bits(x uint64) bool { + return x <= mask31Bits +} + +const DocNum1HitFinished = math.MaxUint64 + +var NormBits1Hit = uint64(1) + +// PostingsList is an in-memory representation of a postings list +type PostingsList struct { + sb *SegmentBase + postingsOffset uint64 + freqOffset uint64 + locOffset uint64 + postings *roaring.Bitmap + except *roaring.Bitmap + + // when normBits1Hit != 0, then this postings list came from a + // 1-hit encoding, and only the docNum1Hit & normBits1Hit apply + docNum1Hit uint64 + normBits1Hit uint64 + + chunkSize uint64 + + // atomic access to this variable + bytesRead uint64 +} + +// represents an immutable, empty postings list +var emptyPostingsList = &PostingsList{} + +func (p *PostingsList) Size() int { + sizeInBytes := reflectStaticSizePostingsList + SizeOfPtr + + if p.except != nil { + sizeInBytes += int(p.except.GetSizeInBytes()) + } + + return sizeInBytes +} + +func (p *PostingsList) OrInto(receiver *roaring.Bitmap) { + if p.normBits1Hit != 0 { + receiver.Add(uint32(p.docNum1Hit)) + return + } + + if p.postings != nil { + receiver.Or(p.postings) + } +} + +// Iterator returns an iterator for this postings list +func (p *PostingsList) Iterator(includeFreq, includeNorm, includeLocs bool, + prealloc segment.PostingsIterator) segment.PostingsIterator { + if p.normBits1Hit == 0 && p.postings == nil { + return emptyPostingsIterator + } + + var preallocPI *PostingsIterator + pi, ok := prealloc.(*PostingsIterator) + if ok && pi != nil { + preallocPI = pi + } + if preallocPI == emptyPostingsIterator { + preallocPI = nil + } + + return p.iterator(includeFreq, includeNorm, includeLocs, preallocPI) +} + +func (p *PostingsList) iterator(includeFreq, includeNorm, includeLocs bool, + rv *PostingsIterator) *PostingsIterator { + if rv == nil { + rv = &PostingsIterator{} + } else { + freqNormReader := rv.freqNormReader + if freqNormReader != nil { + freqNormReader.reset() + } + + locReader := rv.locReader + if locReader != nil { + locReader.reset() + } + + nextLocs := rv.nextLocs[:0] + nextSegmentLocs := rv.nextSegmentLocs[:0] + + buf := rv.buf + + *rv = PostingsIterator{} // clear the struct + + rv.freqNormReader = freqNormReader + rv.locReader = locReader + + rv.nextLocs = nextLocs + rv.nextSegmentLocs = nextSegmentLocs + + rv.buf = buf + } + + rv.postings = p + rv.includeFreqNorm = includeFreq || includeNorm || includeLocs + rv.includeLocs = includeLocs + + if p.normBits1Hit != 0 { + // "1-hit" encoding + rv.docNum1Hit = p.docNum1Hit + rv.normBits1Hit = p.normBits1Hit + + if p.except != nil && p.except.Contains(uint32(rv.docNum1Hit)) { + rv.docNum1Hit = DocNum1HitFinished + } + + return rv + } + + // "general" encoding, check if empty + if p.postings == nil { + return rv + } + + // initialize freq chunk reader + if rv.includeFreqNorm { + rv.freqNormReader = newChunkedIntDecoder(p.sb.mem, p.freqOffset, rv.freqNormReader) + rv.incrementBytesRead(rv.freqNormReader.getBytesRead()) + } + + // initialize the loc chunk reader + if rv.includeLocs { + rv.locReader = newChunkedIntDecoder(p.sb.mem, p.locOffset, rv.locReader) + rv.incrementBytesRead(rv.locReader.getBytesRead()) + } + + rv.all = p.postings.Iterator() + if p.except != nil { + rv.ActualBM = roaring.AndNot(p.postings, p.except) + rv.Actual = rv.ActualBM.Iterator() + } else { + rv.ActualBM = p.postings + rv.Actual = rv.all // Optimize to use same iterator for all & Actual. + } + + return rv +} + +// Count returns the number of items on this postings list +func (p *PostingsList) Count() uint64 { + var n, e uint64 + if p.normBits1Hit != 0 { + n = 1 + if p.except != nil && p.except.Contains(uint32(p.docNum1Hit)) { + e = 1 + } + } else if p.postings != nil { + n = p.postings.GetCardinality() + if p.except != nil { + e = p.postings.AndCardinality(p.except) + } + } + return n - e +} + +// Implements the segment.DiskStatsReporter interface +// The purpose of this implementation is to get +// the bytes read from the postings lists stored +// on disk, while querying +func (p *PostingsList) ResetBytesRead(val uint64) { + p.bytesRead = val +} + +func (p *PostingsList) BytesRead() uint64 { + return p.bytesRead +} + +func (p *PostingsList) incrementBytesRead(val uint64) { + p.bytesRead += val +} + +func (p *PostingsList) BytesWritten() uint64 { + return 0 +} + +func (rv *PostingsList) read(postingsOffset uint64, d *Dictionary) error { + rv.postingsOffset = postingsOffset + + // handle "1-hit" encoding special case + if rv.postingsOffset&FSTValEncodingMask == FSTValEncoding1Hit { + return rv.init1Hit(postingsOffset) + } + + // read the location of the freq/norm details + var n uint64 + var read int + + rv.freqOffset, read = binary.Uvarint(d.sb.mem[postingsOffset+n : postingsOffset+binary.MaxVarintLen64]) + n += uint64(read) + + rv.locOffset, read = binary.Uvarint(d.sb.mem[postingsOffset+n : postingsOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + + var postingsLen uint64 + postingsLen, read = binary.Uvarint(d.sb.mem[postingsOffset+n : postingsOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + + roaringBytes := d.sb.mem[postingsOffset+n : postingsOffset+n+postingsLen] + + rv.incrementBytesRead(n + postingsLen) + + if rv.postings == nil { + rv.postings = roaring.NewBitmap() + } + _, err := rv.postings.FromBuffer(roaringBytes) + if err != nil { + return fmt.Errorf("error loading roaring bitmap: %v", err) + } + + rv.chunkSize, err = getChunkSize(d.sb.chunkMode, + rv.postings.GetCardinality(), d.sb.numDocs) + if err != nil { + return err + } + + return nil +} + +func (rv *PostingsList) init1Hit(fstVal uint64) error { + docNum, normBits := FSTValDecode1Hit(fstVal) + + rv.docNum1Hit = docNum + rv.normBits1Hit = normBits + + return nil +} + +// PostingsIterator provides a way to iterate through the postings list +type PostingsIterator struct { + postings *PostingsList + all roaring.IntPeekable + Actual roaring.IntPeekable + ActualBM *roaring.Bitmap + + currChunk uint32 + freqNormReader *chunkedIntDecoder + locReader *chunkedIntDecoder + + next Posting // reused across Next() calls + nextLocs []Location // reused across Next() calls + nextSegmentLocs []segment.Location // reused across Next() calls + + docNum1Hit uint64 + normBits1Hit uint64 + + buf []byte + + includeFreqNorm bool + includeLocs bool + + // atomic access to this variable + bytesRead uint64 +} + +var emptyPostingsIterator = &PostingsIterator{} + +func (i *PostingsIterator) Size() int { + sizeInBytes := reflectStaticSizePostingsIterator + SizeOfPtr + + i.next.Size() + // account for freqNormReader, locReader if we start using this. + for _, entry := range i.nextLocs { + sizeInBytes += entry.Size() + } + + return sizeInBytes +} + +// Implements the segment.DiskStatsReporter interface +// The purpose of this implementation is to get +// the bytes read from the disk which includes +// the freqNorm and location specific information +// of a hit +func (i *PostingsIterator) ResetBytesRead(val uint64) { + i.bytesRead = val +} + +func (i *PostingsIterator) BytesRead() uint64 { + return i.bytesRead +} + +func (i *PostingsIterator) incrementBytesRead(val uint64) { + i.bytesRead += val +} + +func (i *PostingsIterator) BytesWritten() uint64 { + return 0 +} + +func (i *PostingsIterator) loadChunk(chunk int) error { + if i.includeFreqNorm { + err := i.freqNormReader.loadChunk(chunk) + if err != nil { + return err + } + + // assign the bytes read at this point, since + // the postingsIterator is tracking only the chunk loaded + // and the cumulation is tracked correctly in the downstream + // intDecoder + i.ResetBytesRead(i.freqNormReader.getBytesRead()) + } + + if i.includeLocs { + err := i.locReader.loadChunk(chunk) + if err != nil { + return err + } + i.ResetBytesRead(i.locReader.getBytesRead()) + } + + i.currChunk = uint32(chunk) + return nil +} + +func (i *PostingsIterator) readFreqNormHasLocs() (uint64, uint64, bool, error) { + if i.normBits1Hit != 0 { + return 1, i.normBits1Hit, false, nil + } + + freqHasLocs, err := i.freqNormReader.readUvarint() + if err != nil { + return 0, 0, false, fmt.Errorf("error reading frequency: %v", err) + } + + freq, hasLocs := decodeFreqHasLocs(freqHasLocs) + if freq == 0 { + return freq, 0, hasLocs, nil + } + + normBits, err := i.freqNormReader.readUvarint() + if err != nil { + return 0, 0, false, fmt.Errorf("error reading norm: %v", err) + } + + return freq, normBits, hasLocs, nil +} + +func (i *PostingsIterator) skipFreqNormReadHasLocs() (bool, error) { + if i.normBits1Hit != 0 { + return false, nil + } + + freqHasLocs, err := i.freqNormReader.readUvarint() + if err != nil { + return false, fmt.Errorf("error reading freqHasLocs: %v", err) + } + + freq, hasLocs := decodeFreqHasLocs(freqHasLocs) + if freq == 0 { + return hasLocs, nil + } + + i.freqNormReader.SkipUvarint() // Skip normBits. + + return hasLocs, nil // See decodeFreqHasLocs() / hasLocs. +} + +func encodeFreqHasLocs(freq uint64, hasLocs bool) uint64 { + rv := freq << 1 + if hasLocs { + rv = rv | 0x01 // 0'th LSB encodes whether there are locations + } + return rv +} + +func decodeFreqHasLocs(freqHasLocs uint64) (uint64, bool) { + freq := freqHasLocs >> 1 + hasLocs := freqHasLocs&0x01 != 0 + return freq, hasLocs +} + +// readLocation processes all the integers on the stream representing a single +// location. +func (i *PostingsIterator) readLocation(l *Location) error { + // read off field + fieldID, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location field: %v", err) + } + // read off pos + pos, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location pos: %v", err) + } + // read off start + start, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location start: %v", err) + } + // read off end + end, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location end: %v", err) + } + // read off num array pos + numArrayPos, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location num array pos: %v", err) + } + + l.field = i.postings.sb.fieldsInv[fieldID] + l.pos = pos + l.start = start + l.end = end + + if cap(l.ap) < int(numArrayPos) { + l.ap = make([]uint64, int(numArrayPos)) + } else { + l.ap = l.ap[:int(numArrayPos)] + } + + // read off array positions + for k := 0; k < int(numArrayPos); k++ { + ap, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading array position: %v", err) + } + + l.ap[k] = ap + } + + return nil +} + +// Next returns the next posting on the postings list, or nil at the end +func (i *PostingsIterator) Next() (segment.Posting, error) { + return i.nextAtOrAfter(0) +} + +// Advance returns the posting at the specified docNum or it is not present +// the next posting, or if the end is reached, nil +func (i *PostingsIterator) Advance(docNum uint64) (segment.Posting, error) { + return i.nextAtOrAfter(docNum) +} + +// Next returns the next posting on the postings list, or nil at the end +func (i *PostingsIterator) nextAtOrAfter(atOrAfter uint64) (segment.Posting, error) { + docNum, exists, err := i.nextDocNumAtOrAfter(atOrAfter) + if err != nil || !exists { + return nil, err + } + + i.next = Posting{} // clear the struct + rv := &i.next + rv.docNum = docNum + + if !i.includeFreqNorm { + return rv, nil + } + + var normBits uint64 + var hasLocs bool + + rv.freq, normBits, hasLocs, err = i.readFreqNormHasLocs() + if err != nil { + return nil, err + } + + rv.norm = math.Float32frombits(uint32(normBits)) + + if i.includeLocs && hasLocs { + // prepare locations into reused slices, where we assume + // rv.freq >= "number of locs", since in a composite field, + // some component fields might have their IncludeTermVector + // flags disabled while other component fields are enabled + if rv.freq > 0 { + if cap(i.nextLocs) >= int(rv.freq) { + i.nextLocs = i.nextLocs[0:rv.freq] + } else { + i.nextLocs = make([]Location, rv.freq, rv.freq*2) + } + if cap(i.nextSegmentLocs) < int(rv.freq) { + i.nextSegmentLocs = make([]segment.Location, rv.freq, rv.freq*2) + } + rv.locs = i.nextSegmentLocs[:0] + } + + numLocsBytes, err := i.locReader.readUvarint() + if err != nil { + return nil, fmt.Errorf("error reading location numLocsBytes: %v", err) + } + + j := 0 + var nextLoc *Location + startBytesRemaining := i.locReader.Len() // # bytes remaining in the locReader + for startBytesRemaining-i.locReader.Len() < int(numLocsBytes) { + if len(i.nextLocs) > j { + nextLoc = &i.nextLocs[j] + } else { + nextLoc = &Location{} + } + + err := i.readLocation(nextLoc) + if err != nil { + return nil, err + } + + rv.locs = append(rv.locs, nextLoc) + j++ + } + } + + return rv, nil +} + +// nextDocNum returns the next docNum on the postings list, and also +// sets up the currChunk / loc related fields of the iterator. +func (i *PostingsIterator) nextDocNumAtOrAfter(atOrAfter uint64) (uint64, bool, error) { + if i.normBits1Hit != 0 { + if i.docNum1Hit == DocNum1HitFinished { + return 0, false, nil + } + if i.docNum1Hit < atOrAfter { + // advanced past our 1-hit + i.docNum1Hit = DocNum1HitFinished // consume our 1-hit docNum + return 0, false, nil + } + docNum := i.docNum1Hit + i.docNum1Hit = DocNum1HitFinished // consume our 1-hit docNum + return docNum, true, nil + } + + if i.Actual == nil || !i.Actual.HasNext() { + return 0, false, nil + } + + if i.postings == nil || i.postings == emptyPostingsList { + // couldn't find anything + return 0, false, nil + } + + if i.postings.postings == i.ActualBM { + return i.nextDocNumAtOrAfterClean(atOrAfter) + } + + i.Actual.AdvanceIfNeeded(uint32(atOrAfter)) + + if !i.Actual.HasNext() || !i.all.HasNext() { + // couldn't find anything + return 0, false, nil + } + + n := i.Actual.Next() + allN := i.all.Next() + nChunk := n / uint32(i.postings.chunkSize) + + // when allN becomes >= to here, then allN is in the same chunk as nChunk. + allNReachesNChunk := nChunk * uint32(i.postings.chunkSize) + + // n is the next actual hit (excluding some postings), and + // allN is the next hit in the full postings, and + // if they don't match, move 'all' forwards until they do + for allN != n { + // we've reached same chunk, so move the freq/norm/loc decoders forward + if i.includeFreqNorm && allN >= allNReachesNChunk { + err := i.currChunkNext(nChunk) + if err != nil { + return 0, false, err + } + } + + if !i.all.HasNext() { + return 0, false, nil + } + + allN = i.all.Next() + } + + if i.includeFreqNorm && (i.currChunk != nChunk || i.freqNormReader.isNil()) { + err := i.loadChunk(int(nChunk)) + if err != nil { + return 0, false, fmt.Errorf("error loading chunk: %v", err) + } + } + + return uint64(n), true, nil +} + +var freqHasLocs1Hit = encodeFreqHasLocs(1, false) + +// nextBytes returns the docNum and the encoded freq & loc bytes for +// the next posting +func (i *PostingsIterator) nextBytes() ( + docNumOut uint64, freq uint64, normBits uint64, + bytesFreqNorm []byte, bytesLoc []byte, err error) { + docNum, exists, err := i.nextDocNumAtOrAfter(0) + if err != nil || !exists { + return 0, 0, 0, nil, nil, err + } + + if i.normBits1Hit != 0 { + if i.buf == nil { + i.buf = make([]byte, binary.MaxVarintLen64*2) + } + n := binary.PutUvarint(i.buf, freqHasLocs1Hit) + n += binary.PutUvarint(i.buf[n:], i.normBits1Hit) + return docNum, uint64(1), i.normBits1Hit, i.buf[:n], nil, nil + } + + startFreqNorm := i.freqNormReader.remainingLen() + + var hasLocs bool + + freq, normBits, hasLocs, err = i.readFreqNormHasLocs() + if err != nil { + return 0, 0, 0, nil, nil, err + } + + endFreqNorm := i.freqNormReader.remainingLen() + bytesFreqNorm = i.freqNormReader.readBytes(startFreqNorm, endFreqNorm) + + if hasLocs { + startLoc := i.locReader.remainingLen() + + numLocsBytes, err := i.locReader.readUvarint() + if err != nil { + return 0, 0, 0, nil, nil, + fmt.Errorf("error reading location nextBytes numLocs: %v", err) + } + + // skip over all the location bytes + i.locReader.SkipBytes(int(numLocsBytes)) + + endLoc := i.locReader.remainingLen() + bytesLoc = i.locReader.readBytes(startLoc, endLoc) + } + + return docNum, freq, normBits, bytesFreqNorm, bytesLoc, nil +} + +// optimization when the postings list is "clean" (e.g., no updates & +// no deletions) where the all bitmap is the same as the actual bitmap +func (i *PostingsIterator) nextDocNumAtOrAfterClean( + atOrAfter uint64) (uint64, bool, error) { + if !i.includeFreqNorm { + i.Actual.AdvanceIfNeeded(uint32(atOrAfter)) + + if !i.Actual.HasNext() { + return 0, false, nil // couldn't find anything + } + + return uint64(i.Actual.Next()), true, nil + } + + // freq-norm's needed, so maintain freq-norm chunk reader + sameChunkNexts := 0 // # of times we called Next() in the same chunk + n := i.Actual.Next() + nChunk := n / uint32(i.postings.chunkSize) + + for uint64(n) < atOrAfter && i.Actual.HasNext() { + n = i.Actual.Next() + + nChunkPrev := nChunk + nChunk = n / uint32(i.postings.chunkSize) + + if nChunk != nChunkPrev { + sameChunkNexts = 0 + } else { + sameChunkNexts += 1 + } + } + + if uint64(n) < atOrAfter { + // couldn't find anything + return 0, false, nil + } + + for j := 0; j < sameChunkNexts; j++ { + err := i.currChunkNext(nChunk) + if err != nil { + return 0, false, fmt.Errorf("error optimized currChunkNext: %v", err) + } + } + + if i.currChunk != nChunk || i.freqNormReader.isNil() { + err := i.loadChunk(int(nChunk)) + if err != nil { + return 0, false, fmt.Errorf("error loading chunk: %v", err) + } + } + + return uint64(n), true, nil +} + +func (i *PostingsIterator) currChunkNext(nChunk uint32) error { + if i.currChunk != nChunk || i.freqNormReader.isNil() { + err := i.loadChunk(int(nChunk)) + if err != nil { + return fmt.Errorf("error loading chunk: %v", err) + } + } + + // read off freq/offsets even though we don't care about them + hasLocs, err := i.skipFreqNormReadHasLocs() + if err != nil { + return err + } + + if i.includeLocs && hasLocs { + numLocsBytes, err := i.locReader.readUvarint() + if err != nil { + return fmt.Errorf("error reading location numLocsBytes: %v", err) + } + + // skip over all the location bytes + i.locReader.SkipBytes(int(numLocsBytes)) + } + + return nil +} + +// DocNum1Hit returns the docNum and true if this is "1-hit" optimized +// and the docNum is available. +func (p *PostingsIterator) DocNum1Hit() (uint64, bool) { + if p.normBits1Hit != 0 && p.docNum1Hit != DocNum1HitFinished { + return p.docNum1Hit, true + } + return 0, false +} + +// ActualBitmap returns the underlying actual bitmap +// which can be used up the stack for optimizations +func (p *PostingsIterator) ActualBitmap() *roaring.Bitmap { + return p.ActualBM +} + +// ReplaceActual replaces the ActualBM with the provided +// bitmap +func (p *PostingsIterator) ReplaceActual(abm *roaring.Bitmap) { + p.ActualBM = abm + p.Actual = abm.Iterator() +} + +// PostingsIteratorFromBitmap constructs a PostingsIterator given an +// "actual" bitmap. +func PostingsIteratorFromBitmap(bm *roaring.Bitmap, + includeFreqNorm, includeLocs bool) (segment.PostingsIterator, error) { + return &PostingsIterator{ + ActualBM: bm, + Actual: bm.Iterator(), + includeFreqNorm: includeFreqNorm, + includeLocs: includeLocs, + }, nil +} + +// PostingsIteratorFrom1Hit constructs a PostingsIterator given a +// 1-hit docNum. +func PostingsIteratorFrom1Hit(docNum1Hit uint64, + includeFreqNorm, includeLocs bool) (segment.PostingsIterator, error) { + return &PostingsIterator{ + docNum1Hit: docNum1Hit, + normBits1Hit: NormBits1Hit, + includeFreqNorm: includeFreqNorm, + includeLocs: includeLocs, + }, nil +} + +// Posting is a single entry in a postings list +type Posting struct { + docNum uint64 + freq uint64 + norm float32 + locs []segment.Location +} + +func (p *Posting) Size() int { + sizeInBytes := reflectStaticSizePosting + + for _, entry := range p.locs { + sizeInBytes += entry.Size() + } + + return sizeInBytes +} + +// Number returns the document number of this posting in this segment +func (p *Posting) Number() uint64 { + return p.docNum +} + +// Frequency returns the frequencies of occurrence of this term in this doc/field +func (p *Posting) Frequency() uint64 { + return p.freq +} + +// Norm returns the normalization factor for this posting +func (p *Posting) Norm() float64 { + return float64(float32(1.0 / math.Sqrt(float64(math.Float32bits(p.norm))))) +} + +// Locations returns the location information for each occurrence +func (p *Posting) Locations() []segment.Location { + return p.locs +} + +// NormUint64 returns the norm value as uint64 +func (p *Posting) NormUint64() uint64 { + return uint64(math.Float32bits(p.norm)) +} + +// Location represents the location of a single occurrence +type Location struct { + field string + pos uint64 + start uint64 + end uint64 + ap []uint64 +} + +func (l *Location) Size() int { + return reflectStaticSizeLocation + + len(l.field) + + len(l.ap)*SizeOfUint64 +} + +// Field returns the name of the field (useful in composite fields to know +// which original field the value came from) +func (l *Location) Field() string { + return l.field +} + +// Start returns the start byte offset of this occurrence +func (l *Location) Start() uint64 { + return l.start +} + +// End returns the end byte offset of this occurrence +func (l *Location) End() uint64 { + return l.end +} + +// Pos returns the 1-based phrase position of this occurrence +func (l *Location) Pos() uint64 { + return l.pos +} + +// ArrayPositions returns the array position vector associated with this occurrence +func (l *Location) ArrayPositions() []uint64 { + return l.ap +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/read.go b/backend/vendor/github.com/blevesearch/zapx/v15/read.go new file mode 100644 index 0000000000..e47d4c6abd --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/read.go @@ -0,0 +1,43 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import "encoding/binary" + +func (s *SegmentBase) getDocStoredMetaAndCompressed(docNum uint64) ([]byte, []byte) { + _, storedOffset, n, metaLen, dataLen := s.getDocStoredOffsets(docNum) + + meta := s.mem[storedOffset+n : storedOffset+n+metaLen] + data := s.mem[storedOffset+n+metaLen : storedOffset+n+metaLen+dataLen] + + return meta, data +} + +func (s *SegmentBase) getDocStoredOffsets(docNum uint64) ( + uint64, uint64, uint64, uint64, uint64) { + indexOffset := s.storedIndexOffset + (8 * docNum) + + storedOffset := binary.BigEndian.Uint64(s.mem[indexOffset : indexOffset+8]) + + var n uint64 + + metaLen, read := binary.Uvarint(s.mem[storedOffset : storedOffset+binary.MaxVarintLen64]) + n += uint64(read) + + dataLen, read := binary.Uvarint(s.mem[storedOffset+n : storedOffset+n+binary.MaxVarintLen64]) + n += uint64(read) + + return indexOffset, storedOffset, n, metaLen, dataLen +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/segment.go b/backend/vendor/github.com/blevesearch/zapx/v15/segment.go new file mode 100644 index 0000000000..d5b291e373 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/segment.go @@ -0,0 +1,625 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" + "os" + "sync" + "sync/atomic" + "unsafe" + + "github.com/RoaringBitmap/roaring" + mmap "github.com/blevesearch/mmap-go" + segment "github.com/blevesearch/scorch_segment_api/v2" + "github.com/blevesearch/vellum" + "github.com/golang/snappy" +) + +var reflectStaticSizeSegmentBase int + +func init() { + var sb SegmentBase + reflectStaticSizeSegmentBase = int(unsafe.Sizeof(sb)) +} + +// Open returns a zap impl of a segment +func (*ZapPlugin) Open(path string) (segment.Segment, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + mm, err := mmap.Map(f, mmap.RDONLY, 0) + if err != nil { + // mmap failed, try to close the file + _ = f.Close() + return nil, err + } + + rv := &Segment{ + SegmentBase: SegmentBase{ + mem: mm[0 : len(mm)-FooterSize], + fieldsMap: make(map[string]uint16), + fieldDvReaders: make(map[uint16]*docValueReader), + fieldFSTs: make(map[uint16]*vellum.FST), + }, + f: f, + mm: mm, + path: path, + refs: 1, + } + rv.SegmentBase.updateSize() + + err = rv.loadConfig() + if err != nil { + _ = rv.Close() + return nil, err + } + + err = rv.loadFields() + if err != nil { + _ = rv.Close() + return nil, err + } + + err = rv.loadDvReaders() + if err != nil { + _ = rv.Close() + return nil, err + } + + return rv, nil +} + +// SegmentBase is a memory only, read-only implementation of the +// segment.Segment interface, using zap's data representation. +type SegmentBase struct { + mem []byte + memCRC uint32 + chunkMode uint32 + fieldsMap map[string]uint16 // fieldName -> fieldID+1 + fieldsInv []string // fieldID -> fieldName + numDocs uint64 + storedIndexOffset uint64 + fieldsIndexOffset uint64 + docValueOffset uint64 + dictLocs []uint64 + fieldDvReaders map[uint16]*docValueReader // naive chunk cache per field + fieldDvNames []string // field names cached in fieldDvReaders + size uint64 + + // atomic access to this variable + bytesRead uint64 + bytesWritten uint64 + + m sync.Mutex + fieldFSTs map[uint16]*vellum.FST +} + +func (sb *SegmentBase) Size() int { + return int(sb.size) +} + +func (sb *SegmentBase) updateSize() { + sizeInBytes := reflectStaticSizeSegmentBase + + cap(sb.mem) + + // fieldsMap + for k := range sb.fieldsMap { + sizeInBytes += (len(k) + SizeOfString) + SizeOfUint16 + } + + // fieldsInv, dictLocs + for _, entry := range sb.fieldsInv { + sizeInBytes += len(entry) + SizeOfString + } + sizeInBytes += len(sb.dictLocs) * SizeOfUint64 + + // fieldDvReaders + for _, v := range sb.fieldDvReaders { + sizeInBytes += SizeOfUint16 + SizeOfPtr + if v != nil { + sizeInBytes += v.size() + } + } + + sb.size = uint64(sizeInBytes) +} + +func (sb *SegmentBase) AddRef() {} +func (sb *SegmentBase) DecRef() (err error) { return nil } +func (sb *SegmentBase) Close() (err error) { return nil } + +// Segment implements a persisted segment.Segment interface, by +// embedding an mmap()'ed SegmentBase. +type Segment struct { + SegmentBase + + f *os.File + mm mmap.MMap + path string + version uint32 + crc uint32 + + m sync.Mutex // Protects the fields that follow. + refs int64 +} + +func (s *Segment) Size() int { + // 8 /* size of file pointer */ + // 4 /* size of version -> uint32 */ + // 4 /* size of crc -> uint32 */ + sizeOfUints := 16 + + sizeInBytes := (len(s.path) + SizeOfString) + sizeOfUints + + // mutex, refs -> int64 + sizeInBytes += 16 + + // do not include the mmap'ed part + return sizeInBytes + s.SegmentBase.Size() - cap(s.mem) +} + +func (s *Segment) AddRef() { + s.m.Lock() + s.refs++ + s.m.Unlock() +} + +func (s *Segment) DecRef() (err error) { + s.m.Lock() + s.refs-- + if s.refs == 0 { + err = s.closeActual() + } + s.m.Unlock() + return err +} + +func (s *Segment) loadConfig() error { + crcOffset := len(s.mm) - 4 + s.crc = binary.BigEndian.Uint32(s.mm[crcOffset : crcOffset+4]) + + verOffset := crcOffset - 4 + s.version = binary.BigEndian.Uint32(s.mm[verOffset : verOffset+4]) + if s.version != Version { + return fmt.Errorf("unsupported version %d != %d", s.version, Version) + } + + chunkOffset := verOffset - 4 + s.chunkMode = binary.BigEndian.Uint32(s.mm[chunkOffset : chunkOffset+4]) + + docValueOffset := chunkOffset - 8 + s.docValueOffset = binary.BigEndian.Uint64(s.mm[docValueOffset : docValueOffset+8]) + + fieldsIndexOffset := docValueOffset - 8 + s.fieldsIndexOffset = binary.BigEndian.Uint64(s.mm[fieldsIndexOffset : fieldsIndexOffset+8]) + + storedIndexOffset := fieldsIndexOffset - 8 + s.storedIndexOffset = binary.BigEndian.Uint64(s.mm[storedIndexOffset : storedIndexOffset+8]) + + numDocsOffset := storedIndexOffset - 8 + s.numDocs = binary.BigEndian.Uint64(s.mm[numDocsOffset : numDocsOffset+8]) + + // 8*4 + 4*3 = 44 bytes being accounted from all the offsets + // above being read from the file + s.incrementBytesRead(44) + return nil +} + +// Implements the segment.DiskStatsReporter interface +// Only the persistedSegment type implments the +// interface, as the intention is to retrieve the bytes +// read from the on-disk segment as part of the current +// query. +func (s *Segment) ResetBytesRead(val uint64) { + atomic.StoreUint64(&s.SegmentBase.bytesRead, val) +} + +func (s *Segment) BytesRead() uint64 { + return atomic.LoadUint64(&s.bytesRead) +} + +func (s *Segment) BytesWritten() uint64 { + return 0 +} + +func (s *Segment) incrementBytesRead(val uint64) { + atomic.AddUint64(&s.bytesRead, val) +} + +func (s *SegmentBase) BytesWritten() uint64 { + return atomic.LoadUint64(&s.bytesWritten) +} + +func (s *SegmentBase) setBytesWritten(val uint64) { + atomic.AddUint64(&s.bytesWritten, val) +} + +func (s *SegmentBase) BytesRead() uint64 { + return 0 +} + +func (s *SegmentBase) ResetBytesRead(val uint64) {} + +func (s *SegmentBase) incrementBytesRead(val uint64) { + atomic.AddUint64(&s.bytesRead, val) +} + +func (s *SegmentBase) loadFields() error { + // NOTE for now we assume the fields index immediately precedes + // the footer, and if this changes, need to adjust accordingly (or + // store explicit length), where s.mem was sliced from s.mm in Open(). + fieldsIndexEnd := uint64(len(s.mem)) + + // iterate through fields index + var fieldID uint64 + for s.fieldsIndexOffset+(8*fieldID) < fieldsIndexEnd { + addr := binary.BigEndian.Uint64(s.mem[s.fieldsIndexOffset+(8*fieldID) : s.fieldsIndexOffset+(8*fieldID)+8]) + + // accounting the address of the dictLoc being read from file + s.incrementBytesRead(8) + + dictLoc, read := binary.Uvarint(s.mem[addr:fieldsIndexEnd]) + n := uint64(read) + s.dictLocs = append(s.dictLocs, dictLoc) + + var nameLen uint64 + nameLen, read = binary.Uvarint(s.mem[addr+n : fieldsIndexEnd]) + n += uint64(read) + + name := string(s.mem[addr+n : addr+n+nameLen]) + + s.incrementBytesRead(n + nameLen) + s.fieldsInv = append(s.fieldsInv, name) + s.fieldsMap[name] = uint16(fieldID + 1) + + fieldID++ + } + return nil +} + +// Dictionary returns the term dictionary for the specified field +func (s *SegmentBase) Dictionary(field string) (segment.TermDictionary, error) { + dict, err := s.dictionary(field) + if err == nil && dict == nil { + return emptyDictionary, nil + } + return dict, err +} + +func (sb *SegmentBase) dictionary(field string) (rv *Dictionary, err error) { + fieldIDPlus1 := sb.fieldsMap[field] + if fieldIDPlus1 > 0 { + rv = &Dictionary{ + sb: sb, + field: field, + fieldID: fieldIDPlus1 - 1, + } + + dictStart := sb.dictLocs[rv.fieldID] + if dictStart > 0 { + var ok bool + sb.m.Lock() + if rv.fst, ok = sb.fieldFSTs[rv.fieldID]; !ok { + // read the length of the vellum data + vellumLen, read := binary.Uvarint(sb.mem[dictStart : dictStart+binary.MaxVarintLen64]) + fstBytes := sb.mem[dictStart+uint64(read) : dictStart+uint64(read)+vellumLen] + rv.incrementBytesRead(uint64(read) + vellumLen) + rv.fst, err = vellum.Load(fstBytes) + if err != nil { + sb.m.Unlock() + return nil, fmt.Errorf("dictionary field %s vellum err: %v", field, err) + } + + sb.fieldFSTs[rv.fieldID] = rv.fst + } + + sb.m.Unlock() + rv.fstReader, err = rv.fst.Reader() + if err != nil { + return nil, fmt.Errorf("dictionary field %s vellum reader err: %v", field, err) + } + } + } + + return rv, nil +} + +// visitDocumentCtx holds data structures that are reusable across +// multiple VisitDocument() calls to avoid memory allocations +type visitDocumentCtx struct { + buf []byte + reader bytes.Reader + arrayPos []uint64 +} + +var visitDocumentCtxPool = sync.Pool{ + New: func() interface{} { + reuse := &visitDocumentCtx{} + return reuse + }, +} + +// VisitStoredFields invokes the StoredFieldValueVisitor for each stored field +// for the specified doc number +func (s *SegmentBase) VisitStoredFields(num uint64, visitor segment.StoredFieldValueVisitor) error { + vdc := visitDocumentCtxPool.Get().(*visitDocumentCtx) + defer visitDocumentCtxPool.Put(vdc) + return s.visitStoredFields(vdc, num, visitor) +} + +func (s *SegmentBase) visitStoredFields(vdc *visitDocumentCtx, num uint64, + visitor segment.StoredFieldValueVisitor) error { + // first make sure this is a valid number in this segment + if num < s.numDocs { + meta, compressed := s.getDocStoredMetaAndCompressed(num) + + vdc.reader.Reset(meta) + + // handle _id field special case + idFieldValLen, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + idFieldVal := compressed[:idFieldValLen] + + keepGoing := visitor("_id", byte('t'), idFieldVal, nil) + if !keepGoing { + visitDocumentCtxPool.Put(vdc) + return nil + } + + // handle non-"_id" fields + compressed = compressed[idFieldValLen:] + + uncompressed, err := snappy.Decode(vdc.buf[:cap(vdc.buf)], compressed) + if err != nil { + return err + } + + for keepGoing { + field, err := binary.ReadUvarint(&vdc.reader) + if err == io.EOF { + break + } + if err != nil { + return err + } + typ, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + offset, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + l, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + numap, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + var arrayPos []uint64 + if numap > 0 { + if cap(vdc.arrayPos) < int(numap) { + vdc.arrayPos = make([]uint64, numap) + } + arrayPos = vdc.arrayPos[:numap] + for i := 0; i < int(numap); i++ { + ap, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return err + } + arrayPos[i] = ap + } + } + + value := uncompressed[offset : offset+l] + keepGoing = visitor(s.fieldsInv[field], byte(typ), value, arrayPos) + } + + vdc.buf = uncompressed + } + return nil +} + +// DocID returns the value of the _id field for the given docNum +func (s *SegmentBase) DocID(num uint64) ([]byte, error) { + if num >= s.numDocs { + return nil, nil + } + + vdc := visitDocumentCtxPool.Get().(*visitDocumentCtx) + + meta, compressed := s.getDocStoredMetaAndCompressed(num) + + vdc.reader.Reset(meta) + + // handle _id field special case + idFieldValLen, err := binary.ReadUvarint(&vdc.reader) + if err != nil { + return nil, err + } + idFieldVal := compressed[:idFieldValLen] + + visitDocumentCtxPool.Put(vdc) + + return idFieldVal, nil +} + +// Count returns the number of documents in this segment. +func (s *SegmentBase) Count() uint64 { + return s.numDocs +} + +// DocNumbers returns a bitset corresponding to the doc numbers of all the +// provided _id strings +func (s *SegmentBase) DocNumbers(ids []string) (*roaring.Bitmap, error) { + rv := roaring.New() + + if len(s.fieldsMap) > 0 { + idDict, err := s.dictionary("_id") + if err != nil { + return nil, err + } + + postingsList := emptyPostingsList + + sMax, err := idDict.fst.GetMaxKey() + if err != nil { + return nil, err + } + sMaxStr := string(sMax) + filteredIds := make([]string, 0, len(ids)) + for _, id := range ids { + if id <= sMaxStr { + filteredIds = append(filteredIds, id) + } + } + + for _, id := range filteredIds { + postingsList, err = idDict.postingsList([]byte(id), nil, postingsList) + if err != nil { + return nil, err + } + postingsList.OrInto(rv) + } + } + + return rv, nil +} + +// Fields returns the field names used in this segment +func (s *SegmentBase) Fields() []string { + return s.fieldsInv +} + +// Path returns the path of this segment on disk +func (s *Segment) Path() string { + return s.path +} + +// Close releases all resources associated with this segment +func (s *Segment) Close() (err error) { + return s.DecRef() +} + +func (s *Segment) closeActual() (err error) { + if s.mm != nil { + err = s.mm.Unmap() + } + // try to close file even if unmap failed + if s.f != nil { + err2 := s.f.Close() + if err == nil { + // try to return first error + err = err2 + } + } + return +} + +// some helpers i started adding for the command-line utility + +// Data returns the underlying mmaped data slice +func (s *Segment) Data() []byte { + return s.mm +} + +// CRC returns the CRC value stored in the file footer +func (s *Segment) CRC() uint32 { + return s.crc +} + +// Version returns the file version in the file footer +func (s *Segment) Version() uint32 { + return s.version +} + +// ChunkFactor returns the chunk factor in the file footer +func (s *Segment) ChunkMode() uint32 { + return s.chunkMode +} + +// FieldsIndexOffset returns the fields index offset in the file footer +func (s *Segment) FieldsIndexOffset() uint64 { + return s.fieldsIndexOffset +} + +// StoredIndexOffset returns the stored value index offset in the file footer +func (s *Segment) StoredIndexOffset() uint64 { + return s.storedIndexOffset +} + +// DocValueOffset returns the docValue offset in the file footer +func (s *Segment) DocValueOffset() uint64 { + return s.docValueOffset +} + +// NumDocs returns the number of documents in the file footer +func (s *Segment) NumDocs() uint64 { + return s.numDocs +} + +// DictAddr is a helper function to compute the file offset where the +// dictionary is stored for the specified field. +func (s *Segment) DictAddr(field string) (uint64, error) { + fieldIDPlus1, ok := s.fieldsMap[field] + if !ok { + return 0, fmt.Errorf("no such field '%s'", field) + } + + return s.dictLocs[fieldIDPlus1-1], nil +} + +func (s *SegmentBase) loadDvReaders() error { + if s.docValueOffset == fieldNotUninverted || s.numDocs == 0 { + return nil + } + + var read uint64 + for fieldID, field := range s.fieldsInv { + var fieldLocStart, fieldLocEnd uint64 + var n int + fieldLocStart, n = binary.Uvarint(s.mem[s.docValueOffset+read : s.docValueOffset+read+binary.MaxVarintLen64]) + if n <= 0 { + return fmt.Errorf("loadDvReaders: failed to read the docvalue offset start for field %d", fieldID) + } + read += uint64(n) + fieldLocEnd, n = binary.Uvarint(s.mem[s.docValueOffset+read : s.docValueOffset+read+binary.MaxVarintLen64]) + if n <= 0 { + return fmt.Errorf("loadDvReaders: failed to read the docvalue offset end for field %d", fieldID) + } + read += uint64(n) + + s.incrementBytesRead(read) + fieldDvReader, err := s.loadFieldDocValueReader(field, fieldLocStart, fieldLocEnd) + if err != nil { + return err + } + if fieldDvReader != nil { + s.fieldDvReaders[uint16(fieldID)] = fieldDvReader + s.fieldDvNames = append(s.fieldDvNames, field) + } + } + + return nil +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/sizes.go b/backend/vendor/github.com/blevesearch/zapx/v15/sizes.go new file mode 100644 index 0000000000..34166ea330 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/sizes.go @@ -0,0 +1,59 @@ +// Copyright (c) 2020 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "reflect" +) + +func init() { + var b bool + SizeOfBool = int(reflect.TypeOf(b).Size()) + var f32 float32 + SizeOfFloat32 = int(reflect.TypeOf(f32).Size()) + var f64 float64 + SizeOfFloat64 = int(reflect.TypeOf(f64).Size()) + var i int + SizeOfInt = int(reflect.TypeOf(i).Size()) + var m map[int]int + SizeOfMap = int(reflect.TypeOf(m).Size()) + var ptr *int + SizeOfPtr = int(reflect.TypeOf(ptr).Size()) + var slice []int + SizeOfSlice = int(reflect.TypeOf(slice).Size()) + var str string + SizeOfString = int(reflect.TypeOf(str).Size()) + var u8 uint8 + SizeOfUint8 = int(reflect.TypeOf(u8).Size()) + var u16 uint16 + SizeOfUint16 = int(reflect.TypeOf(u16).Size()) + var u32 uint32 + SizeOfUint32 = int(reflect.TypeOf(u32).Size()) + var u64 uint64 + SizeOfUint64 = int(reflect.TypeOf(u64).Size()) +} + +var SizeOfBool int +var SizeOfFloat32 int +var SizeOfFloat64 int +var SizeOfInt int +var SizeOfMap int +var SizeOfPtr int +var SizeOfSlice int +var SizeOfString int +var SizeOfUint8 int +var SizeOfUint16 int +var SizeOfUint32 int +var SizeOfUint64 int diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/write.go b/backend/vendor/github.com/blevesearch/zapx/v15/write.go new file mode 100644 index 0000000000..77aefdbfc8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/write.go @@ -0,0 +1,145 @@ +// Copyright (c) 2017 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zap + +import ( + "encoding/binary" + "io" + + "github.com/RoaringBitmap/roaring" +) + +// writes out the length of the roaring bitmap in bytes as varint +// then writes out the roaring bitmap itself +func writeRoaringWithLen(r *roaring.Bitmap, w io.Writer, + reuseBufVarint []byte) (int, error) { + buf, err := r.ToBytes() + if err != nil { + return 0, err + } + + var tw int + + // write out the length + n := binary.PutUvarint(reuseBufVarint, uint64(len(buf))) + nw, err := w.Write(reuseBufVarint[:n]) + tw += nw + if err != nil { + return tw, err + } + + // write out the roaring bytes + nw, err = w.Write(buf) + tw += nw + if err != nil { + return tw, err + } + + return tw, nil +} + +func persistFields(fieldsInv []string, w *CountHashWriter, dictLocs []uint64) (uint64, error) { + var rv uint64 + var fieldsOffsets []uint64 + + for fieldID, fieldName := range fieldsInv { + // record start of this field + fieldsOffsets = append(fieldsOffsets, uint64(w.Count())) + + // write out the dict location and field name length + _, err := writeUvarints(w, dictLocs[fieldID], uint64(len(fieldName))) + if err != nil { + return 0, err + } + + // write out the field name + _, err = w.Write([]byte(fieldName)) + if err != nil { + return 0, err + } + } + + // now write out the fields index + rv = uint64(w.Count()) + for fieldID := range fieldsInv { + err := binary.Write(w, binary.BigEndian, fieldsOffsets[fieldID]) + if err != nil { + return 0, err + } + } + + return rv, nil +} + +// FooterSize is the size of the footer record in bytes +// crc + ver + chunk + field offset + stored offset + num docs + docValueOffset +const FooterSize = 4 + 4 + 4 + 8 + 8 + 8 + 8 + +func persistFooter(numDocs, storedIndexOffset, fieldsIndexOffset, docValueOffset uint64, + chunkMode uint32, crcBeforeFooter uint32, writerIn io.Writer) error { + w := NewCountHashWriter(writerIn) + w.crc = crcBeforeFooter + + // write out the number of docs + err := binary.Write(w, binary.BigEndian, numDocs) + if err != nil { + return err + } + // write out the stored field index location: + err = binary.Write(w, binary.BigEndian, storedIndexOffset) + if err != nil { + return err + } + // write out the field index location + err = binary.Write(w, binary.BigEndian, fieldsIndexOffset) + if err != nil { + return err + } + // write out the fieldDocValue location + err = binary.Write(w, binary.BigEndian, docValueOffset) + if err != nil { + return err + } + // write out 32-bit chunk factor + err = binary.Write(w, binary.BigEndian, chunkMode) + if err != nil { + return err + } + // write out 32-bit version + err = binary.Write(w, binary.BigEndian, Version) + if err != nil { + return err + } + // write out CRC-32 of everything upto but not including this CRC + err = binary.Write(w, binary.BigEndian, w.crc) + if err != nil { + return err + } + return nil +} + +func writeUvarints(w io.Writer, vals ...uint64) (tw int, err error) { + buf := make([]byte, binary.MaxVarintLen64) + for _, val := range vals { + n := binary.PutUvarint(buf, val) + var nw int + nw, err = w.Write(buf[:n]) + tw += nw + if err != nil { + return tw, err + } + } + return tw, err +} diff --git a/backend/vendor/github.com/blevesearch/zapx/v15/zap.md b/backend/vendor/github.com/blevesearch/zapx/v15/zap.md new file mode 100644 index 0000000000..d74dc548b8 --- /dev/null +++ b/backend/vendor/github.com/blevesearch/zapx/v15/zap.md @@ -0,0 +1,177 @@ +# ZAP File Format + +## Legend + +### Sections + + |========| + | | section + |========| + +### Fixed-size fields + + |--------| |----| |--| |-| + | | uint64 | | uint32 | | uint16 | | uint8 + |--------| |----| |--| |-| + +### Varints + + |~~~~~~~~| + | | varint(up to uint64) + |~~~~~~~~| + +### Arbitrary-length fields + + |--------...---| + | | arbitrary-length field (string, vellum, roaring bitmap) + |--------...---| + +### Chunked data + + [--------] + [ ] + [--------] + +## Overview + +Footer section describes the configuration of particular ZAP file. The format of footer is version-dependent, so it is necessary to check `V` field before the parsing. + + |==================================================| + | Stored Fields | + |==================================================| + |-----> | Stored Fields Index | + | |==================================================| + | | Dictionaries + Postings + DocValues | + | |==================================================| + | |---> | DocValues Index | + | | |==================================================| + | | | Fields | + | | |==================================================| + | | |-> | Fields Index | + | | | |========|========|========|========|====|====|====| + | | | | D# | SF | F | FDV | CF | V | CC | (Footer) + | | | |========|====|===|====|===|====|===|====|====|====| + | | | | | | + |-+-+-----------------| | | + | |--------------------------| | + |-------------------------------------| + + D#. Number of Docs. + SF. Stored Fields Index Offset. + F. Field Index Offset. + FDV. Field DocValue Offset. + CF. Chunk Factor. + V. Version. + CC. CRC32. + +## Stored Fields + +Stored Fields Index is `D#` consecutive 64-bit unsigned integers - offsets, where relevant Stored Fields Data records are located. + + 0 [SF] [SF + D# * 8] + | Stored Fields | Stored Fields Index | + |================================|==================================| + | | | + | |--------------------| ||--------|--------|. . .|--------|| + | |-> | Stored Fields Data | || 0 | 1 | | D# - 1 || + | | |--------------------| ||--------|----|---|. . .|--------|| + | | | | | + |===|============================|==============|===================| + | | + |-------------------------------------------| + +Stored Fields Data is an arbitrary size record, which consists of metadata and [Snappy](https://github.com/golang/snappy)-compressed data. + + Stored Fields Data + |~~~~~~~~|~~~~~~~~|~~~~~~~~...~~~~~~~~|~~~~~~~~...~~~~~~~~| + | MDS | CDS | MD | CD | + |~~~~~~~~|~~~~~~~~|~~~~~~~~...~~~~~~~~|~~~~~~~~...~~~~~~~~| + + MDS. Metadata size. + CDS. Compressed data size. + MD. Metadata. + CD. Snappy-compressed data. + +## Fields + +Fields Index section located between addresses `F` and `len(file) - len(footer)` and consist of `uint64` values (`F1`, `F2`, ...) which are offsets to records in Fields section. We have `F# = (len(file) - len(footer) - F) / sizeof(uint64)` fields. + + + (...) [F] [F + F#] + | Fields | Fields Index. | + |================================|================================| + | | | + | |~~~~~~~~|~~~~~~~~|---...---|||--------|--------|...|--------|| + ||->| Dict | Length | Name ||| 0 | 1 | | F# - 1 || + || |~~~~~~~~|~~~~~~~~|---...---|||--------|----|---|...|--------|| + || | | | + ||===============================|==============|=================| + | | + |----------------------------------------------| + + +## Dictionaries + Postings + +Each of fields has its own dictionary, encoded in [Vellum](https://github.com/couchbase/vellum) format. Dictionary consists of pairs `(term, offset)`, where `offset` indicates the position of postings (list of documents) for this particular term. + + |================================================================|- Dictionaries + + | | Postings + + | | DocValues + | Freq/Norm (chunked) | + | [~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] | + | |->[ Freq | Norm (float32 under varint) ] | + | | [~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] | + | | | + | |------------------------------------------------------------| | + | Location Details (chunked) | | + | [~~~~~~|~~~~~|~~~~~~~|~~~~~|~~~~~~|~~~~~~~~|~~~~~] | | + | |->[ Size | Pos | Start | End | Arr# | ArrPos | ... ] | | + | | [~~~~~~|~~~~~|~~~~~~~|~~~~~|~~~~~~|~~~~~~~~|~~~~~] | | + | | | | + | |----------------------| | | + | Postings List | | | + | |~~~~~~~~|~~~~~|~~|~~~~~~~~|-----------...--| | | + | |->| F/N | LD | Length | ROARING BITMAP | | | + | | |~~~~~|~~|~~~~~~~~|~~~~~~~~|-----------...--| | | + | | |----------------------------------------------| | + | |--------------------------------------| | + | Dictionary | | + | |~~~~~~~~|--------------------------|-...-| | + | |->| Length | VELLUM DATA : (TERM -> OFFSET) | | + | | |~~~~~~~~|----------------------------...-| | + | | | + |======|=========================================================|- DocValues Index + | | | + |======|=========================================================|- Fields + | | | + | |~~~~|~~~|~~~~~~~~|---...---| | + | | Dict | Length | Name | | + | |~~~~~~~~|~~~~~~~~|---...---| | + | | + |================================================================| + +## DocValues + +DocValues Index is `F#` pairs of varints, one pair per field. Each pair of varints indicates start and end point of DocValues slice. + + |================================================================| + | |------...--| | + | |->| DocValues |<-| | + | | |------...--| | | + |==|=================|===========================================|- DocValues Index + ||~|~~~~~~~~~|~~~~~~~|~~| |~~~~~~~~~~~~~~|~~~~~~~~~~~~|| + || DV1 START | DV1 STOP | . . . . . | DV(F#) START | DV(F#) END || + ||~~~~~~~~~~~|~~~~~~~~~~| |~~~~~~~~~~~~~~|~~~~~~~~~~~~|| + |================================================================| + +DocValues is chunked Snappy-compressed values for each document and field. + + [~~~~~~~~~~~~~~~|~~~~~~|~~~~~~~~~|-...-|~~~~~~|~~~~~~~~~|--------------------...-] + [ Doc# in Chunk | Doc1 | Offset1 | ... | DocN | OffsetN | SNAPPY COMPRESSED DATA ] + [~~~~~~~~~~~~~~~|~~~~~~|~~~~~~~~~|-...-|~~~~~~|~~~~~~~~~|--------------------...-] + +Last 16 bytes are description of chunks. + + |~~~~~~~~~~~~...~|----------------|----------------| + | Chunk Sizes | Chunk Size Arr | Chunk# | + |~~~~~~~~~~~~...~|----------------|----------------| diff --git a/backend/vendor/github.com/golang/geo/LICENSE b/backend/vendor/github.com/golang/geo/LICENSE new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/backend/vendor/github.com/golang/geo/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/backend/vendor/github.com/golang/geo/r1/doc.go b/backend/vendor/github.com/golang/geo/r1/doc.go new file mode 100644 index 0000000000..c6b65c0e03 --- /dev/null +++ b/backend/vendor/github.com/golang/geo/r1/doc.go @@ -0,0 +1,20 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* +Package r1 implements types and functions for working with geometry in ℝ¹. + +See ../s2 for a more detailed overview. +*/ +package r1 diff --git a/backend/vendor/github.com/golang/geo/r1/interval.go b/backend/vendor/github.com/golang/geo/r1/interval.go new file mode 100644 index 0000000000..48ea51982f --- /dev/null +++ b/backend/vendor/github.com/golang/geo/r1/interval.go @@ -0,0 +1,177 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package r1 + +import ( + "fmt" + "math" +) + +// Interval represents a closed interval on ℝ. +// Zero-length intervals (where Lo == Hi) represent single points. +// If Lo > Hi then the interval is empty. +type Interval struct { + Lo, Hi float64 +} + +// EmptyInterval returns an empty interval. +func EmptyInterval() Interval { return Interval{1, 0} } + +// IntervalFromPoint returns an interval representing a single point. +func IntervalFromPoint(p float64) Interval { return Interval{p, p} } + +// IsEmpty reports whether the interval is empty. +func (i Interval) IsEmpty() bool { return i.Lo > i.Hi } + +// Equal returns true iff the interval contains the same points as oi. +func (i Interval) Equal(oi Interval) bool { + return i == oi || i.IsEmpty() && oi.IsEmpty() +} + +// Center returns the midpoint of the interval. +// It is undefined for empty intervals. +func (i Interval) Center() float64 { return 0.5 * (i.Lo + i.Hi) } + +// Length returns the length of the interval. +// The length of an empty interval is negative. +func (i Interval) Length() float64 { return i.Hi - i.Lo } + +// Contains returns true iff the interval contains p. +func (i Interval) Contains(p float64) bool { return i.Lo <= p && p <= i.Hi } + +// ContainsInterval returns true iff the interval contains oi. +func (i Interval) ContainsInterval(oi Interval) bool { + if oi.IsEmpty() { + return true + } + return i.Lo <= oi.Lo && oi.Hi <= i.Hi +} + +// InteriorContains returns true iff the interval strictly contains p. +func (i Interval) InteriorContains(p float64) bool { + return i.Lo < p && p < i.Hi +} + +// InteriorContainsInterval returns true iff the interval strictly contains oi. +func (i Interval) InteriorContainsInterval(oi Interval) bool { + if oi.IsEmpty() { + return true + } + return i.Lo < oi.Lo && oi.Hi < i.Hi +} + +// Intersects returns true iff the interval contains any points in common with oi. +func (i Interval) Intersects(oi Interval) bool { + if i.Lo <= oi.Lo { + return oi.Lo <= i.Hi && oi.Lo <= oi.Hi // oi.Lo ∈ i and oi is not empty + } + return i.Lo <= oi.Hi && i.Lo <= i.Hi // i.Lo ∈ oi and i is not empty +} + +// InteriorIntersects returns true iff the interior of the interval contains any points in common with oi, including the latter's boundary. +func (i Interval) InteriorIntersects(oi Interval) bool { + return oi.Lo < i.Hi && i.Lo < oi.Hi && i.Lo < i.Hi && oi.Lo <= oi.Hi +} + +// Intersection returns the interval containing all points common to i and j. +func (i Interval) Intersection(j Interval) Interval { + // Empty intervals do not need to be special-cased. + return Interval{ + Lo: math.Max(i.Lo, j.Lo), + Hi: math.Min(i.Hi, j.Hi), + } +} + +// AddPoint returns the interval expanded so that it contains the given point. +func (i Interval) AddPoint(p float64) Interval { + if i.IsEmpty() { + return Interval{p, p} + } + if p < i.Lo { + return Interval{p, i.Hi} + } + if p > i.Hi { + return Interval{i.Lo, p} + } + return i +} + +// ClampPoint returns the closest point in the interval to the given point "p". +// The interval must be non-empty. +func (i Interval) ClampPoint(p float64) float64 { + return math.Max(i.Lo, math.Min(i.Hi, p)) +} + +// Expanded returns an interval that has been expanded on each side by margin. +// If margin is negative, then the function shrinks the interval on +// each side by margin instead. The resulting interval may be empty. Any +// expansion of an empty interval remains empty. +func (i Interval) Expanded(margin float64) Interval { + if i.IsEmpty() { + return i + } + return Interval{i.Lo - margin, i.Hi + margin} +} + +// Union returns the smallest interval that contains this interval and the given interval. +func (i Interval) Union(other Interval) Interval { + if i.IsEmpty() { + return other + } + if other.IsEmpty() { + return i + } + return Interval{math.Min(i.Lo, other.Lo), math.Max(i.Hi, other.Hi)} +} + +func (i Interval) String() string { return fmt.Sprintf("[%.7f, %.7f]", i.Lo, i.Hi) } + +const ( + // epsilon is a small number that represents a reasonable level of noise between two + // values that can be considered to be equal. + epsilon = 1e-15 + // dblEpsilon is a smaller number for values that require more precision. + // This is the C++ DBL_EPSILON equivalent. + dblEpsilon = 2.220446049250313e-16 +) + +// ApproxEqual reports whether the interval can be transformed into the +// given interval by moving each endpoint a small distance. +// The empty interval is considered to be positioned arbitrarily on the +// real line, so any interval with a small enough length will match +// the empty interval. +func (i Interval) ApproxEqual(other Interval) bool { + if i.IsEmpty() { + return other.Length() <= 2*epsilon + } + if other.IsEmpty() { + return i.Length() <= 2*epsilon + } + return math.Abs(other.Lo-i.Lo) <= epsilon && + math.Abs(other.Hi-i.Hi) <= epsilon +} + +// DirectedHausdorffDistance returns the Hausdorff distance to the given interval. For two +// intervals x and y, this distance is defined as +// h(x, y) = max_{p in x} min_{q in y} d(p, q). +func (i Interval) DirectedHausdorffDistance(other Interval) float64 { + if i.IsEmpty() { + return 0 + } + if other.IsEmpty() { + return math.Inf(1) + } + return math.Max(0, math.Max(i.Hi-other.Hi, other.Lo-i.Lo)) +} diff --git a/backend/vendor/github.com/golang/geo/r2/doc.go b/backend/vendor/github.com/golang/geo/r2/doc.go new file mode 100644 index 0000000000..05b155543a --- /dev/null +++ b/backend/vendor/github.com/golang/geo/r2/doc.go @@ -0,0 +1,20 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* +Package r2 implements types and functions for working with geometry in ℝ². + +See package s2 for a more detailed overview. +*/ +package r2 diff --git a/backend/vendor/github.com/golang/geo/r2/rect.go b/backend/vendor/github.com/golang/geo/r2/rect.go new file mode 100644 index 0000000000..495545bba6 --- /dev/null +++ b/backend/vendor/github.com/golang/geo/r2/rect.go @@ -0,0 +1,255 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package r2 + +import ( + "fmt" + "math" + + "github.com/golang/geo/r1" +) + +// Point represents a point in ℝ². +type Point struct { + X, Y float64 +} + +// Add returns the sum of p and op. +func (p Point) Add(op Point) Point { return Point{p.X + op.X, p.Y + op.Y} } + +// Sub returns the difference of p and op. +func (p Point) Sub(op Point) Point { return Point{p.X - op.X, p.Y - op.Y} } + +// Mul returns the scalar product of p and m. +func (p Point) Mul(m float64) Point { return Point{m * p.X, m * p.Y} } + +// Ortho returns a counterclockwise orthogonal point with the same norm. +func (p Point) Ortho() Point { return Point{-p.Y, p.X} } + +// Dot returns the dot product between p and op. +func (p Point) Dot(op Point) float64 { return p.X*op.X + p.Y*op.Y } + +// Cross returns the cross product of p and op. +func (p Point) Cross(op Point) float64 { return p.X*op.Y - p.Y*op.X } + +// Norm returns the vector's norm. +func (p Point) Norm() float64 { return math.Hypot(p.X, p.Y) } + +// Normalize returns a unit point in the same direction as p. +func (p Point) Normalize() Point { + if p.X == 0 && p.Y == 0 { + return p + } + return p.Mul(1 / p.Norm()) +} + +func (p Point) String() string { return fmt.Sprintf("(%.12f, %.12f)", p.X, p.Y) } + +// Rect represents a closed axis-aligned rectangle in the (x,y) plane. +type Rect struct { + X, Y r1.Interval +} + +// RectFromPoints constructs a rect that contains the given points. +func RectFromPoints(pts ...Point) Rect { + // Because the default value on interval is 0,0, we need to manually + // define the interval from the first point passed in as our starting + // interval, otherwise we end up with the case of passing in + // Point{0.2, 0.3} and getting the starting Rect of {0, 0.2}, {0, 0.3} + // instead of the Rect {0.2, 0.2}, {0.3, 0.3} which is not correct. + if len(pts) == 0 { + return Rect{} + } + + r := Rect{ + X: r1.Interval{Lo: pts[0].X, Hi: pts[0].X}, + Y: r1.Interval{Lo: pts[0].Y, Hi: pts[0].Y}, + } + + for _, p := range pts[1:] { + r = r.AddPoint(p) + } + return r +} + +// RectFromCenterSize constructs a rectangle with the given center and size. +// Both dimensions of size must be non-negative. +func RectFromCenterSize(center, size Point) Rect { + return Rect{ + r1.Interval{Lo: center.X - size.X/2, Hi: center.X + size.X/2}, + r1.Interval{Lo: center.Y - size.Y/2, Hi: center.Y + size.Y/2}, + } +} + +// EmptyRect constructs the canonical empty rectangle. Use IsEmpty() to test +// for empty rectangles, since they have more than one representation. A Rect{} +// is not the same as the EmptyRect. +func EmptyRect() Rect { + return Rect{r1.EmptyInterval(), r1.EmptyInterval()} +} + +// IsValid reports whether the rectangle is valid. +// This requires the width to be empty iff the height is empty. +func (r Rect) IsValid() bool { + return r.X.IsEmpty() == r.Y.IsEmpty() +} + +// IsEmpty reports whether the rectangle is empty. +func (r Rect) IsEmpty() bool { + return r.X.IsEmpty() +} + +// Vertices returns all four vertices of the rectangle. Vertices are returned in +// CCW direction starting with the lower left corner. +func (r Rect) Vertices() [4]Point { + return [4]Point{ + {r.X.Lo, r.Y.Lo}, + {r.X.Hi, r.Y.Lo}, + {r.X.Hi, r.Y.Hi}, + {r.X.Lo, r.Y.Hi}, + } +} + +// VertexIJ returns the vertex in direction i along the X-axis (0=left, 1=right) and +// direction j along the Y-axis (0=down, 1=up). +func (r Rect) VertexIJ(i, j int) Point { + x := r.X.Lo + if i == 1 { + x = r.X.Hi + } + y := r.Y.Lo + if j == 1 { + y = r.Y.Hi + } + return Point{x, y} +} + +// Lo returns the low corner of the rect. +func (r Rect) Lo() Point { + return Point{r.X.Lo, r.Y.Lo} +} + +// Hi returns the high corner of the rect. +func (r Rect) Hi() Point { + return Point{r.X.Hi, r.Y.Hi} +} + +// Center returns the center of the rectangle in (x,y)-space +func (r Rect) Center() Point { + return Point{r.X.Center(), r.Y.Center()} +} + +// Size returns the width and height of this rectangle in (x,y)-space. Empty +// rectangles have a negative width and height. +func (r Rect) Size() Point { + return Point{r.X.Length(), r.Y.Length()} +} + +// ContainsPoint reports whether the rectangle contains the given point. +// Rectangles are closed regions, i.e. they contain their boundary. +func (r Rect) ContainsPoint(p Point) bool { + return r.X.Contains(p.X) && r.Y.Contains(p.Y) +} + +// InteriorContainsPoint returns true iff the given point is contained in the interior +// of the region (i.e. the region excluding its boundary). +func (r Rect) InteriorContainsPoint(p Point) bool { + return r.X.InteriorContains(p.X) && r.Y.InteriorContains(p.Y) +} + +// Contains reports whether the rectangle contains the given rectangle. +func (r Rect) Contains(other Rect) bool { + return r.X.ContainsInterval(other.X) && r.Y.ContainsInterval(other.Y) +} + +// InteriorContains reports whether the interior of this rectangle contains all of the +// points of the given other rectangle (including its boundary). +func (r Rect) InteriorContains(other Rect) bool { + return r.X.InteriorContainsInterval(other.X) && r.Y.InteriorContainsInterval(other.Y) +} + +// Intersects reports whether this rectangle and the other rectangle have any points in common. +func (r Rect) Intersects(other Rect) bool { + return r.X.Intersects(other.X) && r.Y.Intersects(other.Y) +} + +// InteriorIntersects reports whether the interior of this rectangle intersects +// any point (including the boundary) of the given other rectangle. +func (r Rect) InteriorIntersects(other Rect) bool { + return r.X.InteriorIntersects(other.X) && r.Y.InteriorIntersects(other.Y) +} + +// AddPoint expands the rectangle to include the given point. The rectangle is +// expanded by the minimum amount possible. +func (r Rect) AddPoint(p Point) Rect { + return Rect{r.X.AddPoint(p.X), r.Y.AddPoint(p.Y)} +} + +// AddRect expands the rectangle to include the given rectangle. This is the +// same as replacing the rectangle by the union of the two rectangles, but +// is more efficient. +func (r Rect) AddRect(other Rect) Rect { + return Rect{r.X.Union(other.X), r.Y.Union(other.Y)} +} + +// ClampPoint returns the closest point in the rectangle to the given point. +// The rectangle must be non-empty. +func (r Rect) ClampPoint(p Point) Point { + return Point{r.X.ClampPoint(p.X), r.Y.ClampPoint(p.Y)} +} + +// Expanded returns a rectangle that has been expanded in the x-direction +// by margin.X, and in y-direction by margin.Y. If either margin is empty, +// then shrink the interval on the corresponding sides instead. The resulting +// rectangle may be empty. Any expansion of an empty rectangle remains empty. +func (r Rect) Expanded(margin Point) Rect { + xx := r.X.Expanded(margin.X) + yy := r.Y.Expanded(margin.Y) + if xx.IsEmpty() || yy.IsEmpty() { + return EmptyRect() + } + return Rect{xx, yy} +} + +// ExpandedByMargin returns a Rect that has been expanded by the amount on all sides. +func (r Rect) ExpandedByMargin(margin float64) Rect { + return r.Expanded(Point{margin, margin}) +} + +// Union returns the smallest rectangle containing the union of this rectangle and +// the given rectangle. +func (r Rect) Union(other Rect) Rect { + return Rect{r.X.Union(other.X), r.Y.Union(other.Y)} +} + +// Intersection returns the smallest rectangle containing the intersection of this +// rectangle and the given rectangle. +func (r Rect) Intersection(other Rect) Rect { + xx := r.X.Intersection(other.X) + yy := r.Y.Intersection(other.Y) + if xx.IsEmpty() || yy.IsEmpty() { + return EmptyRect() + } + + return Rect{xx, yy} +} + +// ApproxEqual returns true if the x- and y-intervals of the two rectangles are +// the same up to the given tolerance. +func (r Rect) ApproxEqual(r2 Rect) bool { + return r.X.ApproxEqual(r2.X) && r.Y.ApproxEqual(r2.Y) +} + +func (r Rect) String() string { return fmt.Sprintf("[Lo%s, Hi%s]", r.Lo(), r.Hi()) } diff --git a/backend/vendor/github.com/golang/geo/r3/doc.go b/backend/vendor/github.com/golang/geo/r3/doc.go new file mode 100644 index 0000000000..1eb4710c88 --- /dev/null +++ b/backend/vendor/github.com/golang/geo/r3/doc.go @@ -0,0 +1,20 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* +Package r3 implements types and functions for working with geometry in ℝ³. + +See ../s2 for a more detailed overview. +*/ +package r3 diff --git a/backend/vendor/github.com/golang/geo/r3/precisevector.go b/backend/vendor/github.com/golang/geo/r3/precisevector.go new file mode 100644 index 0000000000..b13393dbcb --- /dev/null +++ b/backend/vendor/github.com/golang/geo/r3/precisevector.go @@ -0,0 +1,198 @@ +// Copyright 2016 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package r3 + +import ( + "fmt" + "math/big" +) + +const ( + // prec is the number of bits of precision to use for the Float values. + // To keep things simple, we use the maximum allowable precision on big + // values. This allows us to handle all values we expect in the s2 library. + prec = big.MaxPrec +) + +// define some commonly referenced values. +var ( + precise0 = precInt(0) + precise1 = precInt(1) +) + +// precStr wraps the conversion from a string into a big.Float. For results that +// actually can be represented exactly, this should only be used on values that +// are integer multiples of integer powers of 2. +func precStr(s string) *big.Float { + // Explicitly ignoring the bool return for this usage. + f, _ := new(big.Float).SetPrec(prec).SetString(s) + return f +} + +func precInt(i int64) *big.Float { + return new(big.Float).SetPrec(prec).SetInt64(i) +} + +func precFloat(f float64) *big.Float { + return new(big.Float).SetPrec(prec).SetFloat64(f) +} + +func precAdd(a, b *big.Float) *big.Float { + return new(big.Float).SetPrec(prec).Add(a, b) +} + +func precSub(a, b *big.Float) *big.Float { + return new(big.Float).SetPrec(prec).Sub(a, b) +} + +func precMul(a, b *big.Float) *big.Float { + return new(big.Float).SetPrec(prec).Mul(a, b) +} + +// PreciseVector represents a point in ℝ³ using high-precision values. +// Note that this is NOT a complete implementation because there are some +// operations that Vector supports that are not feasible with arbitrary precision +// math. (e.g., methods that need division like Normalize, or methods needing a +// square root operation such as Norm) +type PreciseVector struct { + X, Y, Z *big.Float +} + +// PreciseVectorFromVector creates a high precision vector from the given Vector. +func PreciseVectorFromVector(v Vector) PreciseVector { + return NewPreciseVector(v.X, v.Y, v.Z) +} + +// NewPreciseVector creates a high precision vector from the given floating point values. +func NewPreciseVector(x, y, z float64) PreciseVector { + return PreciseVector{ + X: precFloat(x), + Y: precFloat(y), + Z: precFloat(z), + } +} + +// Vector returns this precise vector converted to a Vector. +func (v PreciseVector) Vector() Vector { + // The accuracy flag is ignored on these conversions back to float64. + x, _ := v.X.Float64() + y, _ := v.Y.Float64() + z, _ := v.Z.Float64() + return Vector{x, y, z}.Normalize() +} + +// Equal reports whether v and ov are equal. +func (v PreciseVector) Equal(ov PreciseVector) bool { + return v.X.Cmp(ov.X) == 0 && v.Y.Cmp(ov.Y) == 0 && v.Z.Cmp(ov.Z) == 0 +} + +func (v PreciseVector) String() string { + return fmt.Sprintf("(%10g, %10g, %10g)", v.X, v.Y, v.Z) +} + +// Norm2 returns the square of the norm. +func (v PreciseVector) Norm2() *big.Float { return v.Dot(v) } + +// IsUnit reports whether this vector is of unit length. +func (v PreciseVector) IsUnit() bool { + return v.Norm2().Cmp(precise1) == 0 +} + +// Abs returns the vector with nonnegative components. +func (v PreciseVector) Abs() PreciseVector { + return PreciseVector{ + X: new(big.Float).Abs(v.X), + Y: new(big.Float).Abs(v.Y), + Z: new(big.Float).Abs(v.Z), + } +} + +// Add returns the standard vector sum of v and ov. +func (v PreciseVector) Add(ov PreciseVector) PreciseVector { + return PreciseVector{ + X: precAdd(v.X, ov.X), + Y: precAdd(v.Y, ov.Y), + Z: precAdd(v.Z, ov.Z), + } +} + +// Sub returns the standard vector difference of v and ov. +func (v PreciseVector) Sub(ov PreciseVector) PreciseVector { + return PreciseVector{ + X: precSub(v.X, ov.X), + Y: precSub(v.Y, ov.Y), + Z: precSub(v.Z, ov.Z), + } +} + +// Mul returns the standard scalar product of v and f. +func (v PreciseVector) Mul(f *big.Float) PreciseVector { + return PreciseVector{ + X: precMul(v.X, f), + Y: precMul(v.Y, f), + Z: precMul(v.Z, f), + } +} + +// MulByFloat64 returns the standard scalar product of v and f. +func (v PreciseVector) MulByFloat64(f float64) PreciseVector { + return v.Mul(precFloat(f)) +} + +// Dot returns the standard dot product of v and ov. +func (v PreciseVector) Dot(ov PreciseVector) *big.Float { + return precAdd(precMul(v.X, ov.X), precAdd(precMul(v.Y, ov.Y), precMul(v.Z, ov.Z))) +} + +// Cross returns the standard cross product of v and ov. +func (v PreciseVector) Cross(ov PreciseVector) PreciseVector { + return PreciseVector{ + X: precSub(precMul(v.Y, ov.Z), precMul(v.Z, ov.Y)), + Y: precSub(precMul(v.Z, ov.X), precMul(v.X, ov.Z)), + Z: precSub(precMul(v.X, ov.Y), precMul(v.Y, ov.X)), + } +} + +// LargestComponent returns the axis that represents the largest component in this vector. +func (v PreciseVector) LargestComponent() Axis { + t := v.Abs() + + if t.X.Cmp(t.Y) > 0 { + if t.X.Cmp(t.Z) > 0 { + return XAxis + } + return ZAxis + } + if t.Y.Cmp(t.Z) > 0 { + return YAxis + } + return ZAxis +} + +// SmallestComponent returns the axis that represents the smallest component in this vector. +func (v PreciseVector) SmallestComponent() Axis { + t := v.Abs() + + if t.X.Cmp(t.Y) < 0 { + if t.X.Cmp(t.Z) < 0 { + return XAxis + } + return ZAxis + } + if t.Y.Cmp(t.Z) < 0 { + return YAxis + } + return ZAxis +} diff --git a/backend/vendor/github.com/golang/geo/r3/vector.go b/backend/vendor/github.com/golang/geo/r3/vector.go new file mode 100644 index 0000000000..ccda622f4d --- /dev/null +++ b/backend/vendor/github.com/golang/geo/r3/vector.go @@ -0,0 +1,183 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package r3 + +import ( + "fmt" + "math" + + "github.com/golang/geo/s1" +) + +// Vector represents a point in ℝ³. +type Vector struct { + X, Y, Z float64 +} + +// ApproxEqual reports whether v and ov are equal within a small epsilon. +func (v Vector) ApproxEqual(ov Vector) bool { + const epsilon = 1e-16 + return math.Abs(v.X-ov.X) < epsilon && math.Abs(v.Y-ov.Y) < epsilon && math.Abs(v.Z-ov.Z) < epsilon +} + +func (v Vector) String() string { return fmt.Sprintf("(%0.24f, %0.24f, %0.24f)", v.X, v.Y, v.Z) } + +// Norm returns the vector's norm. +func (v Vector) Norm() float64 { return math.Sqrt(v.Dot(v)) } + +// Norm2 returns the square of the norm. +func (v Vector) Norm2() float64 { return v.Dot(v) } + +// Normalize returns a unit vector in the same direction as v. +func (v Vector) Normalize() Vector { + n2 := v.Norm2() + if n2 == 0 { + return Vector{0, 0, 0} + } + return v.Mul(1 / math.Sqrt(n2)) +} + +// IsUnit returns whether this vector is of approximately unit length. +func (v Vector) IsUnit() bool { + const epsilon = 5e-14 + return math.Abs(v.Norm2()-1) <= epsilon +} + +// Abs returns the vector with nonnegative components. +func (v Vector) Abs() Vector { return Vector{math.Abs(v.X), math.Abs(v.Y), math.Abs(v.Z)} } + +// Add returns the standard vector sum of v and ov. +func (v Vector) Add(ov Vector) Vector { return Vector{v.X + ov.X, v.Y + ov.Y, v.Z + ov.Z} } + +// Sub returns the standard vector difference of v and ov. +func (v Vector) Sub(ov Vector) Vector { return Vector{v.X - ov.X, v.Y - ov.Y, v.Z - ov.Z} } + +// Mul returns the standard scalar product of v and m. +func (v Vector) Mul(m float64) Vector { return Vector{m * v.X, m * v.Y, m * v.Z} } + +// Dot returns the standard dot product of v and ov. +func (v Vector) Dot(ov Vector) float64 { return v.X*ov.X + v.Y*ov.Y + v.Z*ov.Z } + +// Cross returns the standard cross product of v and ov. +func (v Vector) Cross(ov Vector) Vector { + return Vector{ + v.Y*ov.Z - v.Z*ov.Y, + v.Z*ov.X - v.X*ov.Z, + v.X*ov.Y - v.Y*ov.X, + } +} + +// Distance returns the Euclidean distance between v and ov. +func (v Vector) Distance(ov Vector) float64 { return v.Sub(ov).Norm() } + +// Angle returns the angle between v and ov. +func (v Vector) Angle(ov Vector) s1.Angle { + return s1.Angle(math.Atan2(v.Cross(ov).Norm(), v.Dot(ov))) * s1.Radian +} + +// Axis enumerates the 3 axes of ℝ³. +type Axis int + +// The three axes of ℝ³. +const ( + XAxis Axis = iota + YAxis + ZAxis +) + +// Ortho returns a unit vector that is orthogonal to v. +// Ortho(-v) = -Ortho(v) for all v. +func (v Vector) Ortho() Vector { + ov := Vector{0.012, 0.0053, 0.00457} + switch v.LargestComponent() { + case XAxis: + ov.Z = 1 + case YAxis: + ov.X = 1 + default: + ov.Y = 1 + } + return v.Cross(ov).Normalize() +} + +// LargestComponent returns the axis that represents the largest component in this vector. +func (v Vector) LargestComponent() Axis { + t := v.Abs() + + if t.X > t.Y { + if t.X > t.Z { + return XAxis + } + return ZAxis + } + if t.Y > t.Z { + return YAxis + } + return ZAxis +} + +// SmallestComponent returns the axis that represents the smallest component in this vector. +func (v Vector) SmallestComponent() Axis { + t := v.Abs() + + if t.X < t.Y { + if t.X < t.Z { + return XAxis + } + return ZAxis + } + if t.Y < t.Z { + return YAxis + } + return ZAxis +} + +// Cmp compares v and ov lexicographically and returns: +// +// -1 if v < ov +// 0 if v == ov +// +1 if v > ov +// +// This method is based on C++'s std::lexicographical_compare. Two entities +// are compared element by element with the given operator. The first mismatch +// defines which is less (or greater) than the other. If both have equivalent +// values they are lexicographically equal. +func (v Vector) Cmp(ov Vector) int { + if v.X < ov.X { + return -1 + } + if v.X > ov.X { + return 1 + } + + // First elements were the same, try the next. + if v.Y < ov.Y { + return -1 + } + if v.Y > ov.Y { + return 1 + } + + // Second elements were the same return the final compare. + if v.Z < ov.Z { + return -1 + } + if v.Z > ov.Z { + return 1 + } + + // Both are equal + return 0 +} diff --git a/backend/vendor/github.com/golang/geo/s1/angle.go b/backend/vendor/github.com/golang/geo/s1/angle.go new file mode 100644 index 0000000000..747b23dea1 --- /dev/null +++ b/backend/vendor/github.com/golang/geo/s1/angle.go @@ -0,0 +1,120 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s1 + +import ( + "math" + "strconv" +) + +// Angle represents a 1D angle. The internal representation is a double precision +// value in radians, so conversion to and from radians is exact. +// Conversions between E5, E6, E7, and Degrees are not always +// exact. For example, Degrees(3.1) is different from E6(3100000) or E7(31000000). +// +// The following conversions between degrees and radians are exact: +// +// Degree*180 == Radian*math.Pi +// Degree*(180/n) == Radian*(math.Pi/n) for n == 0..8 +// +// These identities hold when the arguments are scaled up or down by any power +// of 2. Some similar identities are also true, for example, +// +// Degree*60 == Radian*(math.Pi/3) +// +// But be aware that this type of identity does not hold in general. For example, +// +// Degree*3 != Radian*(math.Pi/60) +// +// Similarly, the conversion to radians means that (Angle(x)*Degree).Degrees() +// does not always equal x. For example, +// +// (Angle(45*n)*Degree).Degrees() == 45*n for n == 0..8 +// +// but +// +// (60*Degree).Degrees() != 60 +// +// When testing for equality, you should allow for numerical errors (ApproxEqual) +// or convert to discrete E5/E6/E7 values first. +type Angle float64 + +// Angle units. +const ( + Radian Angle = 1 + Degree = (math.Pi / 180) * Radian + + E5 = 1e-5 * Degree + E6 = 1e-6 * Degree + E7 = 1e-7 * Degree +) + +// Radians returns the angle in radians. +func (a Angle) Radians() float64 { return float64(a) } + +// Degrees returns the angle in degrees. +func (a Angle) Degrees() float64 { return float64(a / Degree) } + +// round returns the value rounded to nearest as an int32. +// This does not match C++ exactly for the case of x.5. +func round(val float64) int32 { + if val < 0 { + return int32(val - 0.5) + } + return int32(val + 0.5) +} + +// InfAngle returns an angle larger than any finite angle. +func InfAngle() Angle { + return Angle(math.Inf(1)) +} + +// isInf reports whether this Angle is infinite. +func (a Angle) isInf() bool { + return math.IsInf(float64(a), 0) +} + +// E5 returns the angle in hundred thousandths of degrees. +func (a Angle) E5() int32 { return round(a.Degrees() * 1e5) } + +// E6 returns the angle in millionths of degrees. +func (a Angle) E6() int32 { return round(a.Degrees() * 1e6) } + +// E7 returns the angle in ten millionths of degrees. +func (a Angle) E7() int32 { return round(a.Degrees() * 1e7) } + +// Abs returns the absolute value of the angle. +func (a Angle) Abs() Angle { return Angle(math.Abs(float64(a))) } + +// Normalized returns an equivalent angle in (-π, π]. +func (a Angle) Normalized() Angle { + rad := math.Remainder(float64(a), 2*math.Pi) + if rad <= -math.Pi { + rad = math.Pi + } + return Angle(rad) +} + +func (a Angle) String() string { + return strconv.FormatFloat(a.Degrees(), 'f', 7, 64) // like "%.7f" +} + +// ApproxEqual reports whether the two angles are the same up to a small tolerance. +func (a Angle) ApproxEqual(other Angle) bool { + return math.Abs(float64(a)-float64(other)) <= epsilon +} + +// BUG(dsymonds): The major differences from the C++ version are: +// - no unsigned E5/E6/E7 methods diff --git a/backend/vendor/github.com/golang/geo/s1/chordangle.go b/backend/vendor/github.com/golang/geo/s1/chordangle.go new file mode 100644 index 0000000000..77d71648f0 --- /dev/null +++ b/backend/vendor/github.com/golang/geo/s1/chordangle.go @@ -0,0 +1,320 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s1 + +import ( + "math" +) + +// ChordAngle represents the angle subtended by a chord (i.e., the straight +// line segment connecting two points on the sphere). Its representation +// makes it very efficient for computing and comparing distances, but unlike +// Angle it is only capable of representing angles between 0 and π radians. +// Generally, ChordAngle should only be used in loops where many angles need +// to be calculated and compared. Otherwise it is simpler to use Angle. +// +// ChordAngle loses some accuracy as the angle approaches π radians. +// There are several different ways to measure this error, including the +// representational error (i.e., how accurately ChordAngle can represent +// angles near π radians), the conversion error (i.e., how much precision is +// lost when an Angle is converted to an ChordAngle), and the measurement +// error (i.e., how accurate the ChordAngle(a, b) constructor is when the +// points A and B are separated by angles close to π radians). All of these +// errors differ by a small constant factor. +// +// For the measurement error (which is the largest of these errors and also +// the most important in practice), let the angle between A and B be (π - x) +// radians, i.e. A and B are within "x" radians of being antipodal. The +// corresponding chord length is +// +// r = 2 * sin((π - x) / 2) = 2 * cos(x / 2) +// +// For values of x not close to π the relative error in the squared chord +// length is at most 4.5 * dblEpsilon (see MaxPointError below). +// The relative error in "r" is thus at most 2.25 * dblEpsilon ~= 5e-16. To +// convert this error into an equivalent angle, we have +// +// |dr / dx| = sin(x / 2) +// +// and therefore +// +// |dx| = dr / sin(x / 2) +// = 5e-16 * (2 * cos(x / 2)) / sin(x / 2) +// = 1e-15 / tan(x / 2) +// +// The maximum error is attained when +// +// x = |dx| +// = 1e-15 / tan(x / 2) +// ~= 1e-15 / (x / 2) +// ~= sqrt(2e-15) +// +// In summary, the measurement error for an angle (π - x) is at most +// +// dx = min(1e-15 / tan(x / 2), sqrt(2e-15)) +// (~= min(2e-15 / x, sqrt(2e-15)) when x is small) +// +// On the Earth's surface (assuming a radius of 6371km), this corresponds to +// the following worst-case measurement errors: +// +// Accuracy: Unless antipodal to within: +// --------- --------------------------- +// 6.4 nanometers 10,000 km (90 degrees) +// 1 micrometer 81.2 kilometers +// 1 millimeter 81.2 meters +// 1 centimeter 8.12 meters +// 28.5 centimeters 28.5 centimeters +// +// The representational and conversion errors referred to earlier are somewhat +// smaller than this. For example, maximum distance between adjacent +// representable ChordAngle values is only 13.5 cm rather than 28.5 cm. To +// see this, observe that the closest representable value to r^2 = 4 is +// r^2 = 4 * (1 - dblEpsilon / 2). Thus r = 2 * (1 - dblEpsilon / 4) and +// the angle between these two representable values is +// +// x = 2 * acos(r / 2) +// = 2 * acos(1 - dblEpsilon / 4) +// ~= 2 * asin(sqrt(dblEpsilon / 2) +// ~= sqrt(2 * dblEpsilon) +// ~= 2.1e-8 +// +// which is 13.5 cm on the Earth's surface. +// +// The worst case rounding error occurs when the value halfway between these +// two representable values is rounded up to 4. This halfway value is +// r^2 = (4 * (1 - dblEpsilon / 4)), thus r = 2 * (1 - dblEpsilon / 8) and +// the worst case rounding error is +// +// x = 2 * acos(r / 2) +// = 2 * acos(1 - dblEpsilon / 8) +// ~= 2 * asin(sqrt(dblEpsilon / 4) +// ~= sqrt(dblEpsilon) +// ~= 1.5e-8 +// +// which is 9.5 cm on the Earth's surface. +type ChordAngle float64 + +const ( + // NegativeChordAngle represents a chord angle smaller than the zero angle. + // The only valid operations on a NegativeChordAngle are comparisons, + // Angle conversions, and Successor/Predecessor. + NegativeChordAngle = ChordAngle(-1) + + // RightChordAngle represents a chord angle of 90 degrees (a "right angle"). + RightChordAngle = ChordAngle(2) + + // StraightChordAngle represents a chord angle of 180 degrees (a "straight angle"). + // This is the maximum finite chord angle. + StraightChordAngle = ChordAngle(4) + + // maxLength2 is the square of the maximum length allowed in a ChordAngle. + maxLength2 = 4.0 +) + +// ChordAngleFromAngle returns a ChordAngle from the given Angle. +func ChordAngleFromAngle(a Angle) ChordAngle { + if a < 0 { + return NegativeChordAngle + } + if a.isInf() { + return InfChordAngle() + } + l := 2 * math.Sin(0.5*math.Min(math.Pi, a.Radians())) + return ChordAngle(l * l) +} + +// ChordAngleFromSquaredLength returns a ChordAngle from the squared chord length. +// Note that the argument is automatically clamped to a maximum of 4 to +// handle possible roundoff errors. The argument must be non-negative. +func ChordAngleFromSquaredLength(length2 float64) ChordAngle { + if length2 > maxLength2 { + return StraightChordAngle + } + return ChordAngle(length2) +} + +// Expanded returns a new ChordAngle that has been adjusted by the given error +// bound (which can be positive or negative). Error should be the value +// returned by either MaxPointError or MaxAngleError. For example: +// a := ChordAngleFromPoints(x, y) +// a1 := a.Expanded(a.MaxPointError()) +func (c ChordAngle) Expanded(e float64) ChordAngle { + // If the angle is special, don't change it. Otherwise clamp it to the valid range. + if c.isSpecial() { + return c + } + return ChordAngle(math.Max(0.0, math.Min(maxLength2, float64(c)+e))) +} + +// Angle converts this ChordAngle to an Angle. +func (c ChordAngle) Angle() Angle { + if c < 0 { + return -1 * Radian + } + if c.isInf() { + return InfAngle() + } + return Angle(2 * math.Asin(0.5*math.Sqrt(float64(c)))) +} + +// InfChordAngle returns a chord angle larger than any finite chord angle. +// The only valid operations on an InfChordAngle are comparisons, Angle +// conversions, and Successor/Predecessor. +func InfChordAngle() ChordAngle { + return ChordAngle(math.Inf(1)) +} + +// isInf reports whether this ChordAngle is infinite. +func (c ChordAngle) isInf() bool { + return math.IsInf(float64(c), 1) +} + +// isSpecial reports whether this ChordAngle is one of the special cases. +func (c ChordAngle) isSpecial() bool { + return c < 0 || c.isInf() +} + +// isValid reports whether this ChordAngle is valid or not. +func (c ChordAngle) isValid() bool { + return (c >= 0 && c <= maxLength2) || c.isSpecial() +} + +// Successor returns the smallest representable ChordAngle larger than this one. +// This can be used to convert a "<" comparison to a "<=" comparison. +// +// Note the following special cases: +// NegativeChordAngle.Successor == 0 +// StraightChordAngle.Successor == InfChordAngle +// InfChordAngle.Successor == InfChordAngle +func (c ChordAngle) Successor() ChordAngle { + if c >= maxLength2 { + return InfChordAngle() + } + if c < 0 { + return 0 + } + return ChordAngle(math.Nextafter(float64(c), 10.0)) +} + +// Predecessor returns the largest representable ChordAngle less than this one. +// +// Note the following special cases: +// InfChordAngle.Predecessor == StraightChordAngle +// ChordAngle(0).Predecessor == NegativeChordAngle +// NegativeChordAngle.Predecessor == NegativeChordAngle +func (c ChordAngle) Predecessor() ChordAngle { + if c <= 0 { + return NegativeChordAngle + } + if c > maxLength2 { + return StraightChordAngle + } + + return ChordAngle(math.Nextafter(float64(c), -10.0)) +} + +// MaxPointError returns the maximum error size for a ChordAngle constructed +// from 2 Points x and y, assuming that x and y are normalized to within the +// bounds guaranteed by s2.Point.Normalize. The error is defined with respect to +// the true distance after the points are projected to lie exactly on the sphere. +func (c ChordAngle) MaxPointError() float64 { + // There is a relative error of (2.5*dblEpsilon) when computing the squared + // distance, plus a relative error of 2 * dblEpsilon, plus an absolute error + // of (16 * dblEpsilon**2) because the lengths of the input points may differ + // from 1 by up to (2*dblEpsilon) each. (This is the maximum error in Normalize). + return 4.5*dblEpsilon*float64(c) + 16*dblEpsilon*dblEpsilon +} + +// MaxAngleError returns the maximum error for a ChordAngle constructed +// as an Angle distance. +func (c ChordAngle) MaxAngleError() float64 { + return dblEpsilon * float64(c) +} + +// Add adds the other ChordAngle to this one and returns the resulting value. +// This method assumes the ChordAngles are not special. +func (c ChordAngle) Add(other ChordAngle) ChordAngle { + // Note that this method (and Sub) is much more efficient than converting + // the ChordAngle to an Angle and adding those and converting back. It + // requires only one square root plus a few additions and multiplications. + + // Optimization for the common case where b is an error tolerance + // parameter that happens to be set to zero. + if other == 0 { + return c + } + + // Clamp the angle sum to at most 180 degrees. + if c+other >= maxLength2 { + return StraightChordAngle + } + + // Let a and b be the (non-squared) chord lengths, and let c = a+b. + // Let A, B, and C be the corresponding half-angles (a = 2*sin(A), etc). + // Then the formula below can be derived from c = 2 * sin(A+B) and the + // relationships sin(A+B) = sin(A)*cos(B) + sin(B)*cos(A) + // cos(X) = sqrt(1 - sin^2(X)) + x := float64(c * (1 - 0.25*other)) + y := float64(other * (1 - 0.25*c)) + return ChordAngle(math.Min(maxLength2, x+y+2*math.Sqrt(x*y))) +} + +// Sub subtracts the other ChordAngle from this one and returns the resulting +// value. This method assumes the ChordAngles are not special. +func (c ChordAngle) Sub(other ChordAngle) ChordAngle { + if other == 0 { + return c + } + if c <= other { + return 0 + } + x := float64(c * (1 - 0.25*other)) + y := float64(other * (1 - 0.25*c)) + return ChordAngle(math.Max(0.0, x+y-2*math.Sqrt(x*y))) +} + +// Sin returns the sine of this chord angle. This method is more efficient +// than converting to Angle and performing the computation. +func (c ChordAngle) Sin() float64 { + return math.Sqrt(c.Sin2()) +} + +// Sin2 returns the square of the sine of this chord angle. +// It is more efficient than Sin. +func (c ChordAngle) Sin2() float64 { + // Let a be the (non-squared) chord length, and let A be the corresponding + // half-angle (a = 2*sin(A)). The formula below can be derived from: + // sin(2*A) = 2 * sin(A) * cos(A) + // cos^2(A) = 1 - sin^2(A) + // This is much faster than converting to an angle and computing its sine. + return float64(c * (1 - 0.25*c)) +} + +// Cos returns the cosine of this chord angle. This method is more efficient +// than converting to Angle and performing the computation. +func (c ChordAngle) Cos() float64 { + // cos(2*A) = cos^2(A) - sin^2(A) = 1 - 2*sin^2(A) + return float64(1 - 0.5*c) +} + +// Tan returns the tangent of this chord angle. +func (c ChordAngle) Tan() float64 { + return c.Sin() / c.Cos() +} + +// TODO(roberts): Differences from C++: +// Helpers to/from E5/E6/E7 +// Helpers to/from degrees and radians directly. +// FastUpperBoundFrom(angle Angle) diff --git a/backend/vendor/github.com/golang/geo/s1/doc.go b/backend/vendor/github.com/golang/geo/s1/doc.go new file mode 100644 index 0000000000..52a2c526db --- /dev/null +++ b/backend/vendor/github.com/golang/geo/s1/doc.go @@ -0,0 +1,20 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* +Package s1 implements types and functions for working with geometry in S¹ (circular geometry). + +See ../s2 for a more detailed overview. +*/ +package s1 diff --git a/backend/vendor/github.com/golang/geo/s1/interval.go b/backend/vendor/github.com/golang/geo/s1/interval.go new file mode 100644 index 0000000000..6fea5221f9 --- /dev/null +++ b/backend/vendor/github.com/golang/geo/s1/interval.go @@ -0,0 +1,462 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s1 + +import ( + "math" + "strconv" +) + +// An Interval represents a closed interval on a unit circle (also known +// as a 1-dimensional sphere). It is capable of representing the empty +// interval (containing no points), the full interval (containing all +// points), and zero-length intervals (containing a single point). +// +// Points are represented by the angle they make with the positive x-axis in +// the range [-π, π]. An interval is represented by its lower and upper +// bounds (both inclusive, since the interval is closed). The lower bound may +// be greater than the upper bound, in which case the interval is "inverted" +// (i.e. it passes through the point (-1, 0)). +// +// The point (-1, 0) has two valid representations, π and -π. The +// normalized representation of this point is π, so that endpoints +// of normal intervals are in the range (-π, π]. We normalize the latter to +// the former in IntervalFromEndpoints. However, we take advantage of the point +// -π to construct two special intervals: +// The full interval is [-π, π] +// The empty interval is [π, -π]. +// +// Treat the exported fields as read-only. +type Interval struct { + Lo, Hi float64 +} + +// IntervalFromEndpoints constructs a new interval from endpoints. +// Both arguments must be in the range [-π,π]. This function allows inverted intervals +// to be created. +func IntervalFromEndpoints(lo, hi float64) Interval { + i := Interval{lo, hi} + if lo == -math.Pi && hi != math.Pi { + i.Lo = math.Pi + } + if hi == -math.Pi && lo != math.Pi { + i.Hi = math.Pi + } + return i +} + +// IntervalFromPointPair returns the minimal interval containing the two given points. +// Both arguments must be in [-π,π]. +func IntervalFromPointPair(a, b float64) Interval { + if a == -math.Pi { + a = math.Pi + } + if b == -math.Pi { + b = math.Pi + } + if positiveDistance(a, b) <= math.Pi { + return Interval{a, b} + } + return Interval{b, a} +} + +// EmptyInterval returns an empty interval. +func EmptyInterval() Interval { return Interval{math.Pi, -math.Pi} } + +// FullInterval returns a full interval. +func FullInterval() Interval { return Interval{-math.Pi, math.Pi} } + +// IsValid reports whether the interval is valid. +func (i Interval) IsValid() bool { + return (math.Abs(i.Lo) <= math.Pi && math.Abs(i.Hi) <= math.Pi && + !(i.Lo == -math.Pi && i.Hi != math.Pi) && + !(i.Hi == -math.Pi && i.Lo != math.Pi)) +} + +// IsFull reports whether the interval is full. +func (i Interval) IsFull() bool { return i.Lo == -math.Pi && i.Hi == math.Pi } + +// IsEmpty reports whether the interval is empty. +func (i Interval) IsEmpty() bool { return i.Lo == math.Pi && i.Hi == -math.Pi } + +// IsInverted reports whether the interval is inverted; that is, whether Lo > Hi. +func (i Interval) IsInverted() bool { return i.Lo > i.Hi } + +// Invert returns the interval with endpoints swapped. +func (i Interval) Invert() Interval { + return Interval{i.Hi, i.Lo} +} + +// Center returns the midpoint of the interval. +// It is undefined for full and empty intervals. +func (i Interval) Center() float64 { + c := 0.5 * (i.Lo + i.Hi) + if !i.IsInverted() { + return c + } + if c <= 0 { + return c + math.Pi + } + return c - math.Pi +} + +// Length returns the length of the interval. +// The length of an empty interval is negative. +func (i Interval) Length() float64 { + l := i.Hi - i.Lo + if l >= 0 { + return l + } + l += 2 * math.Pi + if l > 0 { + return l + } + return -1 +} + +// Assumes p ∈ (-π,π]. +func (i Interval) fastContains(p float64) bool { + if i.IsInverted() { + return (p >= i.Lo || p <= i.Hi) && !i.IsEmpty() + } + return p >= i.Lo && p <= i.Hi +} + +// Contains returns true iff the interval contains p. +// Assumes p ∈ [-π,π]. +func (i Interval) Contains(p float64) bool { + if p == -math.Pi { + p = math.Pi + } + return i.fastContains(p) +} + +// ContainsInterval returns true iff the interval contains oi. +func (i Interval) ContainsInterval(oi Interval) bool { + if i.IsInverted() { + if oi.IsInverted() { + return oi.Lo >= i.Lo && oi.Hi <= i.Hi + } + return (oi.Lo >= i.Lo || oi.Hi <= i.Hi) && !i.IsEmpty() + } + if oi.IsInverted() { + return i.IsFull() || oi.IsEmpty() + } + return oi.Lo >= i.Lo && oi.Hi <= i.Hi +} + +// InteriorContains returns true iff the interior of the interval contains p. +// Assumes p ∈ [-π,π]. +func (i Interval) InteriorContains(p float64) bool { + if p == -math.Pi { + p = math.Pi + } + if i.IsInverted() { + return p > i.Lo || p < i.Hi + } + return (p > i.Lo && p < i.Hi) || i.IsFull() +} + +// InteriorContainsInterval returns true iff the interior of the interval contains oi. +func (i Interval) InteriorContainsInterval(oi Interval) bool { + if i.IsInverted() { + if oi.IsInverted() { + return (oi.Lo > i.Lo && oi.Hi < i.Hi) || oi.IsEmpty() + } + return oi.Lo > i.Lo || oi.Hi < i.Hi + } + if oi.IsInverted() { + return i.IsFull() || oi.IsEmpty() + } + return (oi.Lo > i.Lo && oi.Hi < i.Hi) || i.IsFull() +} + +// Intersects returns true iff the interval contains any points in common with oi. +func (i Interval) Intersects(oi Interval) bool { + if i.IsEmpty() || oi.IsEmpty() { + return false + } + if i.IsInverted() { + return oi.IsInverted() || oi.Lo <= i.Hi || oi.Hi >= i.Lo + } + if oi.IsInverted() { + return oi.Lo <= i.Hi || oi.Hi >= i.Lo + } + return oi.Lo <= i.Hi && oi.Hi >= i.Lo +} + +// InteriorIntersects returns true iff the interior of the interval contains any points in common with oi, including the latter's boundary. +func (i Interval) InteriorIntersects(oi Interval) bool { + if i.IsEmpty() || oi.IsEmpty() || i.Lo == i.Hi { + return false + } + if i.IsInverted() { + return oi.IsInverted() || oi.Lo < i.Hi || oi.Hi > i.Lo + } + if oi.IsInverted() { + return oi.Lo < i.Hi || oi.Hi > i.Lo + } + return (oi.Lo < i.Hi && oi.Hi > i.Lo) || i.IsFull() +} + +// Compute distance from a to b in [0,2π], in a numerically stable way. +func positiveDistance(a, b float64) float64 { + d := b - a + if d >= 0 { + return d + } + return (b + math.Pi) - (a - math.Pi) +} + +// Union returns the smallest interval that contains both the interval and oi. +func (i Interval) Union(oi Interval) Interval { + if oi.IsEmpty() { + return i + } + if i.fastContains(oi.Lo) { + if i.fastContains(oi.Hi) { + // Either oi ⊂ i, or i ∪ oi is the full interval. + if i.ContainsInterval(oi) { + return i + } + return FullInterval() + } + return Interval{i.Lo, oi.Hi} + } + if i.fastContains(oi.Hi) { + return Interval{oi.Lo, i.Hi} + } + + // Neither endpoint of oi is in i. Either i ⊂ oi, or i and oi are disjoint. + if i.IsEmpty() || oi.fastContains(i.Lo) { + return oi + } + + // This is the only hard case where we need to find the closest pair of endpoints. + if positiveDistance(oi.Hi, i.Lo) < positiveDistance(i.Hi, oi.Lo) { + return Interval{oi.Lo, i.Hi} + } + return Interval{i.Lo, oi.Hi} +} + +// Intersection returns the smallest interval that contains the intersection of the interval and oi. +func (i Interval) Intersection(oi Interval) Interval { + if oi.IsEmpty() { + return EmptyInterval() + } + if i.fastContains(oi.Lo) { + if i.fastContains(oi.Hi) { + // Either oi ⊂ i, or i and oi intersect twice. Neither are empty. + // In the first case we want to return i (which is shorter than oi). + // In the second case one of them is inverted, and the smallest interval + // that covers the two disjoint pieces is the shorter of i and oi. + // We thus want to pick the shorter of i and oi in both cases. + if oi.Length() < i.Length() { + return oi + } + return i + } + return Interval{oi.Lo, i.Hi} + } + if i.fastContains(oi.Hi) { + return Interval{i.Lo, oi.Hi} + } + + // Neither endpoint of oi is in i. Either i ⊂ oi, or i and oi are disjoint. + if oi.fastContains(i.Lo) { + return i + } + return EmptyInterval() +} + +// AddPoint returns the interval expanded by the minimum amount necessary such +// that it contains the given point "p" (an angle in the range [-π, π]). +func (i Interval) AddPoint(p float64) Interval { + if math.Abs(p) > math.Pi { + return i + } + if p == -math.Pi { + p = math.Pi + } + if i.fastContains(p) { + return i + } + if i.IsEmpty() { + return Interval{p, p} + } + if positiveDistance(p, i.Lo) < positiveDistance(i.Hi, p) { + return Interval{p, i.Hi} + } + return Interval{i.Lo, p} +} + +// Define the maximum rounding error for arithmetic operations. Depending on the +// platform the mantissa precision may be different than others, so we choose to +// use specific values to be consistent across all. +// The values come from the C++ implementation. +var ( + // epsilon is a small number that represents a reasonable level of noise between two + // values that can be considered to be equal. + epsilon = 1e-15 + // dblEpsilon is a smaller number for values that require more precision. + dblEpsilon = 2.220446049e-16 +) + +// Expanded returns an interval that has been expanded on each side by margin. +// If margin is negative, then the function shrinks the interval on +// each side by margin instead. The resulting interval may be empty or +// full. Any expansion (positive or negative) of a full interval remains +// full, and any expansion of an empty interval remains empty. +func (i Interval) Expanded(margin float64) Interval { + if margin >= 0 { + if i.IsEmpty() { + return i + } + // Check whether this interval will be full after expansion, allowing + // for a rounding error when computing each endpoint. + if i.Length()+2*margin+2*dblEpsilon >= 2*math.Pi { + return FullInterval() + } + } else { + if i.IsFull() { + return i + } + // Check whether this interval will be empty after expansion, allowing + // for a rounding error when computing each endpoint. + if i.Length()+2*margin-2*dblEpsilon <= 0 { + return EmptyInterval() + } + } + result := IntervalFromEndpoints( + math.Remainder(i.Lo-margin, 2*math.Pi), + math.Remainder(i.Hi+margin, 2*math.Pi), + ) + if result.Lo <= -math.Pi { + result.Lo = math.Pi + } + return result +} + +// ApproxEqual reports whether this interval can be transformed into the given +// interval by moving each endpoint by at most ε, without the +// endpoints crossing (which would invert the interval). Empty and full +// intervals are considered to start at an arbitrary point on the unit circle, +// so any interval with (length <= 2*ε) matches the empty interval, and +// any interval with (length >= 2*π - 2*ε) matches the full interval. +func (i Interval) ApproxEqual(other Interval) bool { + // Full and empty intervals require special cases because the endpoints + // are considered to be positioned arbitrarily. + if i.IsEmpty() { + return other.Length() <= 2*epsilon + } + if other.IsEmpty() { + return i.Length() <= 2*epsilon + } + if i.IsFull() { + return other.Length() >= 2*(math.Pi-epsilon) + } + if other.IsFull() { + return i.Length() >= 2*(math.Pi-epsilon) + } + + // The purpose of the last test below is to verify that moving the endpoints + // does not invert the interval, e.g. [-1e20, 1e20] vs. [1e20, -1e20]. + return (math.Abs(math.Remainder(other.Lo-i.Lo, 2*math.Pi)) <= epsilon && + math.Abs(math.Remainder(other.Hi-i.Hi, 2*math.Pi)) <= epsilon && + math.Abs(i.Length()-other.Length()) <= 2*epsilon) + +} + +func (i Interval) String() string { + // like "[%.7f, %.7f]" + return "[" + strconv.FormatFloat(i.Lo, 'f', 7, 64) + ", " + strconv.FormatFloat(i.Hi, 'f', 7, 64) + "]" +} + +// Complement returns the complement of the interior of the interval. An interval and +// its complement have the same boundary but do not share any interior +// values. The complement operator is not a bijection, since the complement +// of a singleton interval (containing a single value) is the same as the +// complement of an empty interval. +func (i Interval) Complement() Interval { + if i.Lo == i.Hi { + // Singleton. The interval just contains a single point. + return FullInterval() + } + // Handles empty and full. + return Interval{i.Hi, i.Lo} +} + +// ComplementCenter returns the midpoint of the complement of the interval. For full and empty +// intervals, the result is arbitrary. For a singleton interval (containing a +// single point), the result is its antipodal point on S1. +func (i Interval) ComplementCenter() float64 { + if i.Lo != i.Hi { + return i.Complement().Center() + } + // Singleton. The interval just contains a single point. + if i.Hi <= 0 { + return i.Hi + math.Pi + } + return i.Hi - math.Pi +} + +// DirectedHausdorffDistance returns the Hausdorff distance to the given interval. +// For two intervals i and y, this distance is defined by +// h(i, y) = max_{p in i} min_{q in y} d(p, q), +// where d(.,.) is measured along S1. +func (i Interval) DirectedHausdorffDistance(y Interval) Angle { + if y.ContainsInterval(i) { + return 0 // This includes the case i is empty. + } + if y.IsEmpty() { + return Angle(math.Pi) // maximum possible distance on s1. + } + yComplementCenter := y.ComplementCenter() + if i.Contains(yComplementCenter) { + return Angle(positiveDistance(y.Hi, yComplementCenter)) + } + + // The Hausdorff distance is realized by either two i.Hi endpoints or two + // i.Lo endpoints, whichever is farther apart. + hiHi := 0.0 + if IntervalFromEndpoints(y.Hi, yComplementCenter).Contains(i.Hi) { + hiHi = positiveDistance(y.Hi, i.Hi) + } + + loLo := 0.0 + if IntervalFromEndpoints(yComplementCenter, y.Lo).Contains(i.Lo) { + loLo = positiveDistance(i.Lo, y.Lo) + } + + return Angle(math.Max(hiHi, loLo)) +} + +// Project returns the closest point in the interval to the given point p. +// The interval must be non-empty. +func (i Interval) Project(p float64) float64 { + if p == -math.Pi { + p = math.Pi + } + if i.fastContains(p) { + return p + } + // Compute distance from p to each endpoint. + dlo := positiveDistance(p, i.Lo) + dhi := positiveDistance(i.Hi, p) + if dlo < dhi { + return i.Lo + } + return i.Hi +} diff --git a/backend/vendor/github.com/json-iterator/go/.codecov.yml b/backend/vendor/github.com/json-iterator/go/.codecov.yml new file mode 100644 index 0000000000..955dc0be5f --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/.codecov.yml @@ -0,0 +1,3 @@ +ignore: + - "output_tests/.*" + diff --git a/backend/vendor/github.com/json-iterator/go/.gitignore b/backend/vendor/github.com/json-iterator/go/.gitignore new file mode 100644 index 0000000000..ce242daf75 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/.gitignore @@ -0,0 +1,4 @@ +.idea +/coverage.txt +/profile.out +/bug_test.go diff --git a/backend/vendor/github.com/json-iterator/go/.travis.yml b/backend/vendor/github.com/json-iterator/go/.travis.yml new file mode 100644 index 0000000000..449e67cd01 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/.travis.yml @@ -0,0 +1,14 @@ +language: go + +go: + - 1.8.x + - 1.x + +before_install: + - go get -t -v ./... + +script: + - ./test.sh + +after_success: + - bash <(curl -s https://codecov.io/bash) diff --git a/backend/vendor/github.com/json-iterator/go/LICENSE b/backend/vendor/github.com/json-iterator/go/LICENSE new file mode 100644 index 0000000000..2cf4f5ab28 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 json-iterator + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/backend/vendor/github.com/json-iterator/go/README.md b/backend/vendor/github.com/json-iterator/go/README.md new file mode 100644 index 0000000000..3a0d680983 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/README.md @@ -0,0 +1,86 @@ +[![Sourcegraph](https://sourcegraph.com/github.com/json-iterator/go/-/badge.svg)](https://sourcegraph.com/github.com/json-iterator/go?badge) +[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/json-iterator/go) +[![Build Status](https://travis-ci.org/json-iterator/go.svg?branch=master)](https://travis-ci.org/json-iterator/go) +[![codecov](https://codecov.io/gh/json-iterator/go/branch/master/graph/badge.svg)](https://codecov.io/gh/json-iterator/go) +[![rcard](https://goreportcard.com/badge/github.com/json-iterator/go)](https://goreportcard.com/report/github.com/json-iterator/go) +[![License](http://img.shields.io/badge/license-mit-blue.svg?style=flat-square)](https://raw.githubusercontent.com/json-iterator/go/master/LICENSE) +[![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/json-iterator/Lobby) + +A high-performance 100% compatible drop-in replacement of "encoding/json" + +``` +Go开发者们请加入我们,滴滴出行平台技术部 taowen@didichuxing.com +``` + +# Benchmark + +![benchmark](http://jsoniter.com/benchmarks/go-benchmark.png) + +Source code: https://github.com/json-iterator/go-benchmark/blob/master/src/github.com/json-iterator/go-benchmark/benchmark_medium_payload_test.go + +Raw Result (easyjson requires static code generation) + +| | ns/op | allocation bytes | allocation times | +| --- | --- | --- | --- | +| std decode | 35510 ns/op | 1960 B/op | 99 allocs/op | +| easyjson decode | 8499 ns/op | 160 B/op | 4 allocs/op | +| jsoniter decode | 5623 ns/op | 160 B/op | 3 allocs/op | +| std encode | 2213 ns/op | 712 B/op | 5 allocs/op | +| easyjson encode | 883 ns/op | 576 B/op | 3 allocs/op | +| jsoniter encode | 837 ns/op | 384 B/op | 4 allocs/op | + +# Usage + +100% compatibility with standard lib + +Replace + +```go +import "encoding/json" +json.Marshal(&data) +``` + +with + +```go +import "github.com/json-iterator/go" + +var json = jsoniter.ConfigCompatibleWithStandardLibrary +json.Marshal(&data) +``` + +Replace + +```go +import "encoding/json" +json.Unmarshal(input, &data) +``` + +with + +```go +import "github.com/json-iterator/go" + +var json = jsoniter.ConfigCompatibleWithStandardLibrary +json.Unmarshal(input, &data) +``` + +[More documentation](http://jsoniter.com/migrate-from-go-std.html) + +# How to get + +``` +go get github.com/json-iterator/go +``` + +# Contribution Welcomed ! + +Contributors + +* [thockin](https://github.com/thockin) +* [mattn](https://github.com/mattn) +* [cch123](https://github.com/cch123) +* [Oleg Shaldybin](https://github.com/olegshaldybin) +* [Jason Toffaletti](https://github.com/toffaletti) + +Report issue or pull request, or email taowen@gmail.com, or [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/json-iterator/Lobby) diff --git a/backend/vendor/github.com/json-iterator/go/feature_adapter.go b/backend/vendor/github.com/json-iterator/go/feature_adapter.go new file mode 100644 index 0000000000..0214b711a6 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_adapter.go @@ -0,0 +1,133 @@ +package jsoniter + +import ( + "bytes" + "io" +) + +// RawMessage to make replace json with jsoniter +type RawMessage []byte + +// Unmarshal adapts to json/encoding Unmarshal API +// +// Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. +// Refer to https://godoc.org/encoding/json#Unmarshal for more information +func Unmarshal(data []byte, v interface{}) error { + return ConfigDefault.Unmarshal(data, v) +} + +func lastNotSpacePos(data []byte) int { + for i := len(data) - 1; i >= 0; i-- { + if data[i] != ' ' && data[i] != '\t' && data[i] != '\r' && data[i] != '\n' { + return i + 1 + } + } + return 0 +} + +// UnmarshalFromString convenient method to read from string instead of []byte +func UnmarshalFromString(str string, v interface{}) error { + return ConfigDefault.UnmarshalFromString(str, v) +} + +// Get quick method to get value from deeply nested JSON structure +func Get(data []byte, path ...interface{}) Any { + return ConfigDefault.Get(data, path...) +} + +// Marshal adapts to json/encoding Marshal API +// +// Marshal returns the JSON encoding of v, adapts to json/encoding Marshal API +// Refer to https://godoc.org/encoding/json#Marshal for more information +func Marshal(v interface{}) ([]byte, error) { + return ConfigDefault.Marshal(v) +} + +// MarshalIndent same as json.MarshalIndent. Prefix is not supported. +func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + return ConfigDefault.MarshalIndent(v, prefix, indent) +} + +// MarshalToString convenient method to write as string instead of []byte +func MarshalToString(v interface{}) (string, error) { + return ConfigDefault.MarshalToString(v) +} + +// NewDecoder adapts to json/stream NewDecoder API. +// +// NewDecoder returns a new decoder that reads from r. +// +// Instead of a json/encoding Decoder, an Decoder is returned +// Refer to https://godoc.org/encoding/json#NewDecoder for more information +func NewDecoder(reader io.Reader) *Decoder { + return ConfigDefault.NewDecoder(reader) +} + +// Decoder reads and decodes JSON values from an input stream. +// Decoder provides identical APIs with json/stream Decoder (Token() and UseNumber() are in progress) +type Decoder struct { + iter *Iterator +} + +// Decode decode JSON into interface{} +func (adapter *Decoder) Decode(obj interface{}) error { + adapter.iter.ReadVal(obj) + err := adapter.iter.Error + if err == io.EOF { + return nil + } + return adapter.iter.Error +} + +// More is there more? +func (adapter *Decoder) More() bool { + return adapter.iter.head != adapter.iter.tail +} + +// Buffered remaining buffer +func (adapter *Decoder) Buffered() io.Reader { + remaining := adapter.iter.buf[adapter.iter.head:adapter.iter.tail] + return bytes.NewReader(remaining) +} + +// UseNumber for number JSON element, use float64 or json.NumberValue (alias of string) +func (adapter *Decoder) UseNumber() { + origCfg := adapter.iter.cfg.configBeforeFrozen + origCfg.UseNumber = true + adapter.iter.cfg = origCfg.Froze().(*frozenConfig) +} + +// NewEncoder same as json.NewEncoder +func NewEncoder(writer io.Writer) *Encoder { + return ConfigDefault.NewEncoder(writer) +} + +// Encoder same as json.Encoder +type Encoder struct { + stream *Stream +} + +// Encode encode interface{} as JSON to io.Writer +func (adapter *Encoder) Encode(val interface{}) error { + adapter.stream.WriteVal(val) + adapter.stream.WriteRaw("\n") + adapter.stream.Flush() + return adapter.stream.Error +} + +// SetIndent set the indention. Prefix is not supported +func (adapter *Encoder) SetIndent(prefix, indent string) { + adapter.stream.cfg.indentionStep = len(indent) +} + +// SetEscapeHTML escape html by default, set to false to disable +func (adapter *Encoder) SetEscapeHTML(escapeHTML bool) { + config := adapter.stream.cfg.configBeforeFrozen + config.EscapeHTML = escapeHTML + adapter.stream.cfg = config.Froze().(*frozenConfig) +} + +// Valid reports whether data is a valid JSON encoding. +func Valid(data []byte) bool { + return ConfigDefault.Valid(data) +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_any.go b/backend/vendor/github.com/json-iterator/go/feature_any.go new file mode 100644 index 0000000000..87716d1fcf --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_any.go @@ -0,0 +1,245 @@ +package jsoniter + +import ( + "errors" + "fmt" + "io" + "reflect" +) + +// Any generic object representation. +// The lazy json implementation holds []byte and parse lazily. +type Any interface { + LastError() error + ValueType() ValueType + MustBeValid() Any + ToBool() bool + ToInt() int + ToInt32() int32 + ToInt64() int64 + ToUint() uint + ToUint32() uint32 + ToUint64() uint64 + ToFloat32() float32 + ToFloat64() float64 + ToString() string + ToVal(val interface{}) + Get(path ...interface{}) Any + // TODO: add Set + Size() int + Keys() []string + GetInterface() interface{} + WriteTo(stream *Stream) +} + +type baseAny struct{} + +func (any *baseAny) Get(path ...interface{}) Any { + return &invalidAny{baseAny{}, fmt.Errorf("Get %v from simple value", path)} +} + +func (any *baseAny) Size() int { + return 0 +} + +func (any *baseAny) Keys() []string { + return []string{} +} + +func (any *baseAny) ToVal(obj interface{}) { + panic("not implemented") +} + +// WrapInt32 turn int32 into Any interface +func WrapInt32(val int32) Any { + return &int32Any{baseAny{}, val} +} + +// WrapInt64 turn int64 into Any interface +func WrapInt64(val int64) Any { + return &int64Any{baseAny{}, val} +} + +// WrapUint32 turn uint32 into Any interface +func WrapUint32(val uint32) Any { + return &uint32Any{baseAny{}, val} +} + +// WrapUint64 turn uint64 into Any interface +func WrapUint64(val uint64) Any { + return &uint64Any{baseAny{}, val} +} + +// WrapFloat64 turn float64 into Any interface +func WrapFloat64(val float64) Any { + return &floatAny{baseAny{}, val} +} + +// WrapString turn string into Any interface +func WrapString(val string) Any { + return &stringAny{baseAny{}, val} +} + +// Wrap turn a go object into Any interface +func Wrap(val interface{}) Any { + if val == nil { + return &nilAny{} + } + asAny, isAny := val.(Any) + if isAny { + return asAny + } + typ := reflect.TypeOf(val) + switch typ.Kind() { + case reflect.Slice: + return wrapArray(val) + case reflect.Struct: + return wrapStruct(val) + case reflect.Map: + return wrapMap(val) + case reflect.String: + return WrapString(val.(string)) + case reflect.Int: + return WrapInt64(int64(val.(int))) + case reflect.Int8: + return WrapInt32(int32(val.(int8))) + case reflect.Int16: + return WrapInt32(int32(val.(int16))) + case reflect.Int32: + return WrapInt32(val.(int32)) + case reflect.Int64: + return WrapInt64(val.(int64)) + case reflect.Uint: + return WrapUint64(uint64(val.(uint))) + case reflect.Uint8: + return WrapUint32(uint32(val.(uint8))) + case reflect.Uint16: + return WrapUint32(uint32(val.(uint16))) + case reflect.Uint32: + return WrapUint32(uint32(val.(uint32))) + case reflect.Uint64: + return WrapUint64(val.(uint64)) + case reflect.Float32: + return WrapFloat64(float64(val.(float32))) + case reflect.Float64: + return WrapFloat64(val.(float64)) + case reflect.Bool: + if val.(bool) == true { + return &trueAny{} + } + return &falseAny{} + } + return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", typ)} +} + +// ReadAny read next JSON element as an Any object. It is a better json.RawMessage. +func (iter *Iterator) ReadAny() Any { + return iter.readAny() +} + +func (iter *Iterator) readAny() Any { + c := iter.nextToken() + switch c { + case '"': + iter.unreadByte() + return &stringAny{baseAny{}, iter.ReadString()} + case 'n': + iter.skipThreeBytes('u', 'l', 'l') // null + return &nilAny{} + case 't': + iter.skipThreeBytes('r', 'u', 'e') // true + return &trueAny{} + case 'f': + iter.skipFourBytes('a', 'l', 's', 'e') // false + return &falseAny{} + case '{': + return iter.readObjectAny() + case '[': + return iter.readArrayAny() + case '-': + return iter.readNumberAny(false) + case 0: + return &invalidAny{baseAny{}, errors.New("input is empty")} + default: + return iter.readNumberAny(true) + } +} + +func (iter *Iterator) readNumberAny(positive bool) Any { + iter.startCapture(iter.head - 1) + iter.skipNumber() + lazyBuf := iter.stopCapture() + return &numberLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} +} + +func (iter *Iterator) readObjectAny() Any { + iter.startCapture(iter.head - 1) + iter.skipObject() + lazyBuf := iter.stopCapture() + return &objectLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} +} + +func (iter *Iterator) readArrayAny() Any { + iter.startCapture(iter.head - 1) + iter.skipArray() + lazyBuf := iter.stopCapture() + return &arrayLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} +} + +func locateObjectField(iter *Iterator, target string) []byte { + var found []byte + iter.ReadObjectCB(func(iter *Iterator, field string) bool { + if field == target { + found = iter.SkipAndReturnBytes() + return false + } + iter.Skip() + return true + }) + return found +} + +func locateArrayElement(iter *Iterator, target int) []byte { + var found []byte + n := 0 + iter.ReadArrayCB(func(iter *Iterator) bool { + if n == target { + found = iter.SkipAndReturnBytes() + return false + } + iter.Skip() + n++ + return true + }) + return found +} + +func locatePath(iter *Iterator, path []interface{}) Any { + for i, pathKeyObj := range path { + switch pathKey := pathKeyObj.(type) { + case string: + valueBytes := locateObjectField(iter, pathKey) + if valueBytes == nil { + return newInvalidAny(path[i:]) + } + iter.ResetBytes(valueBytes) + case int: + valueBytes := locateArrayElement(iter, pathKey) + if valueBytes == nil { + return newInvalidAny(path[i:]) + } + iter.ResetBytes(valueBytes) + case int32: + if '*' == pathKey { + return iter.readAny().Get(path[i:]...) + } + return newInvalidAny(path[i:]) + default: + return newInvalidAny(path[i:]) + } + } + if iter.Error != nil && iter.Error != io.EOF { + return &invalidAny{baseAny{}, iter.Error} + } + return iter.readAny() +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_any_array.go b/backend/vendor/github.com/json-iterator/go/feature_any_array.go new file mode 100644 index 0000000000..0449e9aa42 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_any_array.go @@ -0,0 +1,278 @@ +package jsoniter + +import ( + "reflect" + "unsafe" +) + +type arrayLazyAny struct { + baseAny + cfg *frozenConfig + buf []byte + err error +} + +func (any *arrayLazyAny) ValueType() ValueType { + return ArrayValue +} + +func (any *arrayLazyAny) MustBeValid() Any { + return any +} + +func (any *arrayLazyAny) LastError() error { + return any.err +} + +func (any *arrayLazyAny) ToBool() bool { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.ReadArray() +} + +func (any *arrayLazyAny) ToInt() int { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToInt32() int32 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToInt64() int64 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToUint() uint { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToUint32() uint32 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToUint64() uint64 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToFloat32() float32 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToFloat64() float64 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToString() string { + return *(*string)(unsafe.Pointer(&any.buf)) +} + +func (any *arrayLazyAny) ToVal(val interface{}) { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadVal(val) +} + +func (any *arrayLazyAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case int: + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + valueBytes := locateArrayElement(iter, firstPath) + if valueBytes == nil { + return newInvalidAny(path) + } + iter.ResetBytes(valueBytes) + return locatePath(iter, path[1:]) + case int32: + if '*' == firstPath { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + arr := make([]Any, 0) + iter.ReadArrayCB(func(iter *Iterator) bool { + found := iter.readAny().Get(path[1:]...) + if found.ValueType() != InvalidValue { + arr = append(arr, found) + } + return true + }) + return wrapArray(arr) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *arrayLazyAny) Size() int { + size := 0 + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadArrayCB(func(iter *Iterator) bool { + size++ + iter.Skip() + return true + }) + return size +} + +func (any *arrayLazyAny) WriteTo(stream *Stream) { + stream.Write(any.buf) +} + +func (any *arrayLazyAny) GetInterface() interface{} { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.Read() +} + +type arrayAny struct { + baseAny + val reflect.Value +} + +func wrapArray(val interface{}) *arrayAny { + return &arrayAny{baseAny{}, reflect.ValueOf(val)} +} + +func (any *arrayAny) ValueType() ValueType { + return ArrayValue +} + +func (any *arrayAny) MustBeValid() Any { + return any +} + +func (any *arrayAny) LastError() error { + return nil +} + +func (any *arrayAny) ToBool() bool { + return any.val.Len() != 0 +} + +func (any *arrayAny) ToInt() int { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToInt32() int32 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToInt64() int64 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToUint() uint { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToUint32() uint32 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToUint64() uint64 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToFloat32() float32 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToFloat64() float64 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToString() string { + str, _ := MarshalToString(any.val.Interface()) + return str +} + +func (any *arrayAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case int: + if firstPath < 0 || firstPath >= any.val.Len() { + return newInvalidAny(path) + } + return Wrap(any.val.Index(firstPath).Interface()) + case int32: + if '*' == firstPath { + mappedAll := make([]Any, 0) + for i := 0; i < any.val.Len(); i++ { + mapped := Wrap(any.val.Index(i).Interface()).Get(path[1:]...) + if mapped.ValueType() != InvalidValue { + mappedAll = append(mappedAll, mapped) + } + } + return wrapArray(mappedAll) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *arrayAny) Size() int { + return any.val.Len() +} + +func (any *arrayAny) WriteTo(stream *Stream) { + stream.WriteVal(any.val) +} + +func (any *arrayAny) GetInterface() interface{} { + return any.val.Interface() +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_any_bool.go b/backend/vendor/github.com/json-iterator/go/feature_any_bool.go new file mode 100644 index 0000000000..9452324af5 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_any_bool.go @@ -0,0 +1,137 @@ +package jsoniter + +type trueAny struct { + baseAny +} + +func (any *trueAny) LastError() error { + return nil +} + +func (any *trueAny) ToBool() bool { + return true +} + +func (any *trueAny) ToInt() int { + return 1 +} + +func (any *trueAny) ToInt32() int32 { + return 1 +} + +func (any *trueAny) ToInt64() int64 { + return 1 +} + +func (any *trueAny) ToUint() uint { + return 1 +} + +func (any *trueAny) ToUint32() uint32 { + return 1 +} + +func (any *trueAny) ToUint64() uint64 { + return 1 +} + +func (any *trueAny) ToFloat32() float32 { + return 1 +} + +func (any *trueAny) ToFloat64() float64 { + return 1 +} + +func (any *trueAny) ToString() string { + return "true" +} + +func (any *trueAny) WriteTo(stream *Stream) { + stream.WriteTrue() +} + +func (any *trueAny) Parse() *Iterator { + return nil +} + +func (any *trueAny) GetInterface() interface{} { + return true +} + +func (any *trueAny) ValueType() ValueType { + return BoolValue +} + +func (any *trueAny) MustBeValid() Any { + return any +} + +type falseAny struct { + baseAny +} + +func (any *falseAny) LastError() error { + return nil +} + +func (any *falseAny) ToBool() bool { + return false +} + +func (any *falseAny) ToInt() int { + return 0 +} + +func (any *falseAny) ToInt32() int32 { + return 0 +} + +func (any *falseAny) ToInt64() int64 { + return 0 +} + +func (any *falseAny) ToUint() uint { + return 0 +} + +func (any *falseAny) ToUint32() uint32 { + return 0 +} + +func (any *falseAny) ToUint64() uint64 { + return 0 +} + +func (any *falseAny) ToFloat32() float32 { + return 0 +} + +func (any *falseAny) ToFloat64() float64 { + return 0 +} + +func (any *falseAny) ToString() string { + return "false" +} + +func (any *falseAny) WriteTo(stream *Stream) { + stream.WriteFalse() +} + +func (any *falseAny) Parse() *Iterator { + return nil +} + +func (any *falseAny) GetInterface() interface{} { + return false +} + +func (any *falseAny) ValueType() ValueType { + return BoolValue +} + +func (any *falseAny) MustBeValid() Any { + return any +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_any_float.go b/backend/vendor/github.com/json-iterator/go/feature_any_float.go new file mode 100644 index 0000000000..35fdb09497 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_any_float.go @@ -0,0 +1,83 @@ +package jsoniter + +import ( + "strconv" +) + +type floatAny struct { + baseAny + val float64 +} + +func (any *floatAny) Parse() *Iterator { + return nil +} + +func (any *floatAny) ValueType() ValueType { + return NumberValue +} + +func (any *floatAny) MustBeValid() Any { + return any +} + +func (any *floatAny) LastError() error { + return nil +} + +func (any *floatAny) ToBool() bool { + return any.ToFloat64() != 0 +} + +func (any *floatAny) ToInt() int { + return int(any.val) +} + +func (any *floatAny) ToInt32() int32 { + return int32(any.val) +} + +func (any *floatAny) ToInt64() int64 { + return int64(any.val) +} + +func (any *floatAny) ToUint() uint { + if any.val > 0 { + return uint(any.val) + } + return 0 +} + +func (any *floatAny) ToUint32() uint32 { + if any.val > 0 { + return uint32(any.val) + } + return 0 +} + +func (any *floatAny) ToUint64() uint64 { + if any.val > 0 { + return uint64(any.val) + } + return 0 +} + +func (any *floatAny) ToFloat32() float32 { + return float32(any.val) +} + +func (any *floatAny) ToFloat64() float64 { + return any.val +} + +func (any *floatAny) ToString() string { + return strconv.FormatFloat(any.val, 'E', -1, 64) +} + +func (any *floatAny) WriteTo(stream *Stream) { + stream.WriteFloat64(any.val) +} + +func (any *floatAny) GetInterface() interface{} { + return any.val +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_any_int32.go b/backend/vendor/github.com/json-iterator/go/feature_any_int32.go new file mode 100644 index 0000000000..1b56f39915 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_any_int32.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type int32Any struct { + baseAny + val int32 +} + +func (any *int32Any) LastError() error { + return nil +} + +func (any *int32Any) ValueType() ValueType { + return NumberValue +} + +func (any *int32Any) MustBeValid() Any { + return any +} + +func (any *int32Any) ToBool() bool { + return any.val != 0 +} + +func (any *int32Any) ToInt() int { + return int(any.val) +} + +func (any *int32Any) ToInt32() int32 { + return any.val +} + +func (any *int32Any) ToInt64() int64 { + return int64(any.val) +} + +func (any *int32Any) ToUint() uint { + return uint(any.val) +} + +func (any *int32Any) ToUint32() uint32 { + return uint32(any.val) +} + +func (any *int32Any) ToUint64() uint64 { + return uint64(any.val) +} + +func (any *int32Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *int32Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *int32Any) ToString() string { + return strconv.FormatInt(int64(any.val), 10) +} + +func (any *int32Any) WriteTo(stream *Stream) { + stream.WriteInt32(any.val) +} + +func (any *int32Any) Parse() *Iterator { + return nil +} + +func (any *int32Any) GetInterface() interface{} { + return any.val +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_any_int64.go b/backend/vendor/github.com/json-iterator/go/feature_any_int64.go new file mode 100644 index 0000000000..c440d72b6d --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_any_int64.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type int64Any struct { + baseAny + val int64 +} + +func (any *int64Any) LastError() error { + return nil +} + +func (any *int64Any) ValueType() ValueType { + return NumberValue +} + +func (any *int64Any) MustBeValid() Any { + return any +} + +func (any *int64Any) ToBool() bool { + return any.val != 0 +} + +func (any *int64Any) ToInt() int { + return int(any.val) +} + +func (any *int64Any) ToInt32() int32 { + return int32(any.val) +} + +func (any *int64Any) ToInt64() int64 { + return any.val +} + +func (any *int64Any) ToUint() uint { + return uint(any.val) +} + +func (any *int64Any) ToUint32() uint32 { + return uint32(any.val) +} + +func (any *int64Any) ToUint64() uint64 { + return uint64(any.val) +} + +func (any *int64Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *int64Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *int64Any) ToString() string { + return strconv.FormatInt(any.val, 10) +} + +func (any *int64Any) WriteTo(stream *Stream) { + stream.WriteInt64(any.val) +} + +func (any *int64Any) Parse() *Iterator { + return nil +} + +func (any *int64Any) GetInterface() interface{} { + return any.val +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_any_invalid.go b/backend/vendor/github.com/json-iterator/go/feature_any_invalid.go new file mode 100644 index 0000000000..1d859eac32 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_any_invalid.go @@ -0,0 +1,82 @@ +package jsoniter + +import "fmt" + +type invalidAny struct { + baseAny + err error +} + +func newInvalidAny(path []interface{}) *invalidAny { + return &invalidAny{baseAny{}, fmt.Errorf("%v not found", path)} +} + +func (any *invalidAny) LastError() error { + return any.err +} + +func (any *invalidAny) ValueType() ValueType { + return InvalidValue +} + +func (any *invalidAny) MustBeValid() Any { + panic(any.err) +} + +func (any *invalidAny) ToBool() bool { + return false +} + +func (any *invalidAny) ToInt() int { + return 0 +} + +func (any *invalidAny) ToInt32() int32 { + return 0 +} + +func (any *invalidAny) ToInt64() int64 { + return 0 +} + +func (any *invalidAny) ToUint() uint { + return 0 +} + +func (any *invalidAny) ToUint32() uint32 { + return 0 +} + +func (any *invalidAny) ToUint64() uint64 { + return 0 +} + +func (any *invalidAny) ToFloat32() float32 { + return 0 +} + +func (any *invalidAny) ToFloat64() float64 { + return 0 +} + +func (any *invalidAny) ToString() string { + return "" +} + +func (any *invalidAny) WriteTo(stream *Stream) { +} + +func (any *invalidAny) Get(path ...interface{}) Any { + if any.err == nil { + return &invalidAny{baseAny{}, fmt.Errorf("get %v from invalid", path)} + } + return &invalidAny{baseAny{}, fmt.Errorf("%v, get %v from invalid", any.err, path)} +} + +func (any *invalidAny) Parse() *Iterator { + return nil +} + +func (any *invalidAny) GetInterface() interface{} { + return nil +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_any_nil.go b/backend/vendor/github.com/json-iterator/go/feature_any_nil.go new file mode 100644 index 0000000000..d04cb54c11 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_any_nil.go @@ -0,0 +1,69 @@ +package jsoniter + +type nilAny struct { + baseAny +} + +func (any *nilAny) LastError() error { + return nil +} + +func (any *nilAny) ValueType() ValueType { + return NilValue +} + +func (any *nilAny) MustBeValid() Any { + return any +} + +func (any *nilAny) ToBool() bool { + return false +} + +func (any *nilAny) ToInt() int { + return 0 +} + +func (any *nilAny) ToInt32() int32 { + return 0 +} + +func (any *nilAny) ToInt64() int64 { + return 0 +} + +func (any *nilAny) ToUint() uint { + return 0 +} + +func (any *nilAny) ToUint32() uint32 { + return 0 +} + +func (any *nilAny) ToUint64() uint64 { + return 0 +} + +func (any *nilAny) ToFloat32() float32 { + return 0 +} + +func (any *nilAny) ToFloat64() float64 { + return 0 +} + +func (any *nilAny) ToString() string { + return "" +} + +func (any *nilAny) WriteTo(stream *Stream) { + stream.WriteNil() +} + +func (any *nilAny) Parse() *Iterator { + return nil +} + +func (any *nilAny) GetInterface() interface{} { + return nil +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_any_number.go b/backend/vendor/github.com/json-iterator/go/feature_any_number.go new file mode 100644 index 0000000000..4e1c27641d --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_any_number.go @@ -0,0 +1,104 @@ +package jsoniter + +import "unsafe" + +type numberLazyAny struct { + baseAny + cfg *frozenConfig + buf []byte + err error +} + +func (any *numberLazyAny) ValueType() ValueType { + return NumberValue +} + +func (any *numberLazyAny) MustBeValid() Any { + return any +} + +func (any *numberLazyAny) LastError() error { + return any.err +} + +func (any *numberLazyAny) ToBool() bool { + return any.ToFloat64() != 0 +} + +func (any *numberLazyAny) ToInt() int { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadInt() + any.err = iter.Error + return val +} + +func (any *numberLazyAny) ToInt32() int32 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadInt32() + any.err = iter.Error + return val +} + +func (any *numberLazyAny) ToInt64() int64 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadInt64() + any.err = iter.Error + return val +} + +func (any *numberLazyAny) ToUint() uint { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadUint() + any.err = iter.Error + return val +} + +func (any *numberLazyAny) ToUint32() uint32 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadUint32() + any.err = iter.Error + return val +} + +func (any *numberLazyAny) ToUint64() uint64 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadUint64() + any.err = iter.Error + return val +} + +func (any *numberLazyAny) ToFloat32() float32 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadFloat32() + any.err = iter.Error + return val +} + +func (any *numberLazyAny) ToFloat64() float64 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadFloat64() + any.err = iter.Error + return val +} + +func (any *numberLazyAny) ToString() string { + return *(*string)(unsafe.Pointer(&any.buf)) +} + +func (any *numberLazyAny) WriteTo(stream *Stream) { + stream.Write(any.buf) +} + +func (any *numberLazyAny) GetInterface() interface{} { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.Read() +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_any_object.go b/backend/vendor/github.com/json-iterator/go/feature_any_object.go new file mode 100644 index 0000000000..c44ef5c989 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_any_object.go @@ -0,0 +1,374 @@ +package jsoniter + +import ( + "reflect" + "unsafe" +) + +type objectLazyAny struct { + baseAny + cfg *frozenConfig + buf []byte + err error +} + +func (any *objectLazyAny) ValueType() ValueType { + return ObjectValue +} + +func (any *objectLazyAny) MustBeValid() Any { + return any +} + +func (any *objectLazyAny) LastError() error { + return any.err +} + +func (any *objectLazyAny) ToBool() bool { + return true +} + +func (any *objectLazyAny) ToInt() int { + return 0 +} + +func (any *objectLazyAny) ToInt32() int32 { + return 0 +} + +func (any *objectLazyAny) ToInt64() int64 { + return 0 +} + +func (any *objectLazyAny) ToUint() uint { + return 0 +} + +func (any *objectLazyAny) ToUint32() uint32 { + return 0 +} + +func (any *objectLazyAny) ToUint64() uint64 { + return 0 +} + +func (any *objectLazyAny) ToFloat32() float32 { + return 0 +} + +func (any *objectLazyAny) ToFloat64() float64 { + return 0 +} + +func (any *objectLazyAny) ToString() string { + return *(*string)(unsafe.Pointer(&any.buf)) +} + +func (any *objectLazyAny) ToVal(obj interface{}) { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadVal(obj) +} + +func (any *objectLazyAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case string: + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + valueBytes := locateObjectField(iter, firstPath) + if valueBytes == nil { + return newInvalidAny(path) + } + iter.ResetBytes(valueBytes) + return locatePath(iter, path[1:]) + case int32: + if '*' == firstPath { + mappedAll := map[string]Any{} + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadMapCB(func(iter *Iterator, field string) bool { + mapped := locatePath(iter, path[1:]) + if mapped.ValueType() != InvalidValue { + mappedAll[field] = mapped + } + return true + }) + return wrapMap(mappedAll) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *objectLazyAny) Keys() []string { + keys := []string{} + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadMapCB(func(iter *Iterator, field string) bool { + iter.Skip() + keys = append(keys, field) + return true + }) + return keys +} + +func (any *objectLazyAny) Size() int { + size := 0 + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadObjectCB(func(iter *Iterator, field string) bool { + iter.Skip() + size++ + return true + }) + return size +} + +func (any *objectLazyAny) WriteTo(stream *Stream) { + stream.Write(any.buf) +} + +func (any *objectLazyAny) GetInterface() interface{} { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.Read() +} + +type objectAny struct { + baseAny + err error + val reflect.Value +} + +func wrapStruct(val interface{}) *objectAny { + return &objectAny{baseAny{}, nil, reflect.ValueOf(val)} +} + +func (any *objectAny) ValueType() ValueType { + return ObjectValue +} + +func (any *objectAny) MustBeValid() Any { + return any +} + +func (any *objectAny) Parse() *Iterator { + return nil +} + +func (any *objectAny) LastError() error { + return any.err +} + +func (any *objectAny) ToBool() bool { + return any.val.NumField() != 0 +} + +func (any *objectAny) ToInt() int { + return 0 +} + +func (any *objectAny) ToInt32() int32 { + return 0 +} + +func (any *objectAny) ToInt64() int64 { + return 0 +} + +func (any *objectAny) ToUint() uint { + return 0 +} + +func (any *objectAny) ToUint32() uint32 { + return 0 +} + +func (any *objectAny) ToUint64() uint64 { + return 0 +} + +func (any *objectAny) ToFloat32() float32 { + return 0 +} + +func (any *objectAny) ToFloat64() float64 { + return 0 +} + +func (any *objectAny) ToString() string { + str, err := MarshalToString(any.val.Interface()) + any.err = err + return str +} + +func (any *objectAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case string: + field := any.val.FieldByName(firstPath) + if !field.IsValid() { + return newInvalidAny(path) + } + return Wrap(field.Interface()) + case int32: + if '*' == firstPath { + mappedAll := map[string]Any{} + for i := 0; i < any.val.NumField(); i++ { + field := any.val.Field(i) + if field.CanInterface() { + mapped := Wrap(field.Interface()).Get(path[1:]...) + if mapped.ValueType() != InvalidValue { + mappedAll[any.val.Type().Field(i).Name] = mapped + } + } + } + return wrapMap(mappedAll) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *objectAny) Keys() []string { + keys := make([]string, 0, any.val.NumField()) + for i := 0; i < any.val.NumField(); i++ { + keys = append(keys, any.val.Type().Field(i).Name) + } + return keys +} + +func (any *objectAny) Size() int { + return any.val.NumField() +} + +func (any *objectAny) WriteTo(stream *Stream) { + stream.WriteVal(any.val) +} + +func (any *objectAny) GetInterface() interface{} { + return any.val.Interface() +} + +type mapAny struct { + baseAny + err error + val reflect.Value +} + +func wrapMap(val interface{}) *mapAny { + return &mapAny{baseAny{}, nil, reflect.ValueOf(val)} +} + +func (any *mapAny) ValueType() ValueType { + return ObjectValue +} + +func (any *mapAny) MustBeValid() Any { + return any +} + +func (any *mapAny) Parse() *Iterator { + return nil +} + +func (any *mapAny) LastError() error { + return any.err +} + +func (any *mapAny) ToBool() bool { + return true +} + +func (any *mapAny) ToInt() int { + return 0 +} + +func (any *mapAny) ToInt32() int32 { + return 0 +} + +func (any *mapAny) ToInt64() int64 { + return 0 +} + +func (any *mapAny) ToUint() uint { + return 0 +} + +func (any *mapAny) ToUint32() uint32 { + return 0 +} + +func (any *mapAny) ToUint64() uint64 { + return 0 +} + +func (any *mapAny) ToFloat32() float32 { + return 0 +} + +func (any *mapAny) ToFloat64() float64 { + return 0 +} + +func (any *mapAny) ToString() string { + str, err := MarshalToString(any.val.Interface()) + any.err = err + return str +} + +func (any *mapAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case int32: + if '*' == firstPath { + mappedAll := map[string]Any{} + for _, key := range any.val.MapKeys() { + keyAsStr := key.String() + element := Wrap(any.val.MapIndex(key).Interface()) + mapped := element.Get(path[1:]...) + if mapped.ValueType() != InvalidValue { + mappedAll[keyAsStr] = mapped + } + } + return wrapMap(mappedAll) + } + return newInvalidAny(path) + default: + value := any.val.MapIndex(reflect.ValueOf(firstPath)) + if !value.IsValid() { + return newInvalidAny(path) + } + return Wrap(value.Interface()) + } +} + +func (any *mapAny) Keys() []string { + keys := make([]string, 0, any.val.Len()) + for _, key := range any.val.MapKeys() { + keys = append(keys, key.String()) + } + return keys +} + +func (any *mapAny) Size() int { + return any.val.Len() +} + +func (any *mapAny) WriteTo(stream *Stream) { + stream.WriteVal(any.val) +} + +func (any *mapAny) GetInterface() interface{} { + return any.val.Interface() +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_any_string.go b/backend/vendor/github.com/json-iterator/go/feature_any_string.go new file mode 100644 index 0000000000..abf060bd59 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_any_string.go @@ -0,0 +1,166 @@ +package jsoniter + +import ( + "fmt" + "strconv" +) + +type stringAny struct { + baseAny + val string +} + +func (any *stringAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + return &invalidAny{baseAny{}, fmt.Errorf("Get %v from simple value", path)} +} + +func (any *stringAny) Parse() *Iterator { + return nil +} + +func (any *stringAny) ValueType() ValueType { + return StringValue +} + +func (any *stringAny) MustBeValid() Any { + return any +} + +func (any *stringAny) LastError() error { + return nil +} + +func (any *stringAny) ToBool() bool { + str := any.ToString() + if str == "0" { + return false + } + for _, c := range str { + switch c { + case ' ', '\n', '\r', '\t': + default: + return true + } + } + return false +} + +func (any *stringAny) ToInt() int { + return int(any.ToInt64()) + +} + +func (any *stringAny) ToInt32() int32 { + return int32(any.ToInt64()) +} + +func (any *stringAny) ToInt64() int64 { + if any.val == "" { + return 0 + } + + flag := 1 + startPos := 0 + endPos := 0 + if any.val[0] == '+' || any.val[0] == '-' { + startPos = 1 + } + + if any.val[0] == '-' { + flag = -1 + } + + for i := startPos; i < len(any.val); i++ { + if any.val[i] >= '0' && any.val[i] <= '9' { + endPos = i + 1 + } else { + break + } + } + parsed, _ := strconv.ParseInt(any.val[startPos:endPos], 10, 64) + return int64(flag) * parsed +} + +func (any *stringAny) ToUint() uint { + return uint(any.ToUint64()) +} + +func (any *stringAny) ToUint32() uint32 { + return uint32(any.ToUint64()) +} + +func (any *stringAny) ToUint64() uint64 { + if any.val == "" { + return 0 + } + + startPos := 0 + endPos := 0 + + if any.val[0] == '-' { + return 0 + } + if any.val[0] == '+' { + startPos = 1 + } + + for i := startPos; i < len(any.val); i++ { + if any.val[i] >= '0' && any.val[i] <= '9' { + endPos = i + 1 + } else { + break + } + } + parsed, _ := strconv.ParseUint(any.val[startPos:endPos], 10, 64) + return parsed +} + +func (any *stringAny) ToFloat32() float32 { + return float32(any.ToFloat64()) +} + +func (any *stringAny) ToFloat64() float64 { + if len(any.val) == 0 { + return 0 + } + + // first char invalid + if any.val[0] != '+' && any.val[0] != '-' && (any.val[0] > '9' || any.val[0] < '0') { + return 0 + } + + // extract valid num expression from string + // eg 123true => 123, -12.12xxa => -12.12 + endPos := 1 + for i := 1; i < len(any.val); i++ { + if any.val[i] == '.' || any.val[i] == 'e' || any.val[i] == 'E' || any.val[i] == '+' || any.val[i] == '-' { + endPos = i + 1 + continue + } + + // end position is the first char which is not digit + if any.val[i] >= '0' && any.val[i] <= '9' { + endPos = i + 1 + } else { + endPos = i + break + } + } + parsed, _ := strconv.ParseFloat(any.val[:endPos], 64) + return parsed +} + +func (any *stringAny) ToString() string { + return any.val +} + +func (any *stringAny) WriteTo(stream *Stream) { + stream.WriteString(any.val) +} + +func (any *stringAny) GetInterface() interface{} { + return any.val +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_any_uint32.go b/backend/vendor/github.com/json-iterator/go/feature_any_uint32.go new file mode 100644 index 0000000000..656bbd33d7 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_any_uint32.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type uint32Any struct { + baseAny + val uint32 +} + +func (any *uint32Any) LastError() error { + return nil +} + +func (any *uint32Any) ValueType() ValueType { + return NumberValue +} + +func (any *uint32Any) MustBeValid() Any { + return any +} + +func (any *uint32Any) ToBool() bool { + return any.val != 0 +} + +func (any *uint32Any) ToInt() int { + return int(any.val) +} + +func (any *uint32Any) ToInt32() int32 { + return int32(any.val) +} + +func (any *uint32Any) ToInt64() int64 { + return int64(any.val) +} + +func (any *uint32Any) ToUint() uint { + return uint(any.val) +} + +func (any *uint32Any) ToUint32() uint32 { + return any.val +} + +func (any *uint32Any) ToUint64() uint64 { + return uint64(any.val) +} + +func (any *uint32Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *uint32Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *uint32Any) ToString() string { + return strconv.FormatInt(int64(any.val), 10) +} + +func (any *uint32Any) WriteTo(stream *Stream) { + stream.WriteUint32(any.val) +} + +func (any *uint32Any) Parse() *Iterator { + return nil +} + +func (any *uint32Any) GetInterface() interface{} { + return any.val +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_any_uint64.go b/backend/vendor/github.com/json-iterator/go/feature_any_uint64.go new file mode 100644 index 0000000000..7df2fce33b --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_any_uint64.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type uint64Any struct { + baseAny + val uint64 +} + +func (any *uint64Any) LastError() error { + return nil +} + +func (any *uint64Any) ValueType() ValueType { + return NumberValue +} + +func (any *uint64Any) MustBeValid() Any { + return any +} + +func (any *uint64Any) ToBool() bool { + return any.val != 0 +} + +func (any *uint64Any) ToInt() int { + return int(any.val) +} + +func (any *uint64Any) ToInt32() int32 { + return int32(any.val) +} + +func (any *uint64Any) ToInt64() int64 { + return int64(any.val) +} + +func (any *uint64Any) ToUint() uint { + return uint(any.val) +} + +func (any *uint64Any) ToUint32() uint32 { + return uint32(any.val) +} + +func (any *uint64Any) ToUint64() uint64 { + return any.val +} + +func (any *uint64Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *uint64Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *uint64Any) ToString() string { + return strconv.FormatUint(any.val, 10) +} + +func (any *uint64Any) WriteTo(stream *Stream) { + stream.WriteUint64(any.val) +} + +func (any *uint64Any) Parse() *Iterator { + return nil +} + +func (any *uint64Any) GetInterface() interface{} { + return any.val +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_config.go b/backend/vendor/github.com/json-iterator/go/feature_config.go new file mode 100644 index 0000000000..1406795369 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_config.go @@ -0,0 +1,347 @@ +package jsoniter + +import ( + "encoding/json" + "errors" + "io" + "reflect" + "sync/atomic" + "unsafe" +) + +// Config customize how the API should behave. +// The API is created from Config by Froze. +type Config struct { + IndentionStep int + MarshalFloatWith6Digits bool + EscapeHTML bool + SortMapKeys bool + UseNumber bool + TagKey string + ValidateJsonRawMessage bool + ObjectFieldMustBeSimpleString bool +} + +type frozenConfig struct { + configBeforeFrozen Config + sortMapKeys bool + indentionStep int + objectFieldMustBeSimpleString bool + decoderCache unsafe.Pointer + encoderCache unsafe.Pointer + extensions []Extension + streamPool chan *Stream + iteratorPool chan *Iterator +} + +// API the public interface of this package. +// Primary Marshal and Unmarshal. +type API interface { + IteratorPool + StreamPool + MarshalToString(v interface{}) (string, error) + Marshal(v interface{}) ([]byte, error) + MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) + UnmarshalFromString(str string, v interface{}) error + Unmarshal(data []byte, v interface{}) error + Get(data []byte, path ...interface{}) Any + NewEncoder(writer io.Writer) *Encoder + NewDecoder(reader io.Reader) *Decoder + Valid(data []byte) bool +} + +// ConfigDefault the default API +var ConfigDefault = Config{ + EscapeHTML: true, +}.Froze() + +// ConfigCompatibleWithStandardLibrary tries to be 100% compatible with standard library behavior +var ConfigCompatibleWithStandardLibrary = Config{ + EscapeHTML: true, + SortMapKeys: true, + ValidateJsonRawMessage: true, +}.Froze() + +// ConfigFastest marshals float with only 6 digits precision +var ConfigFastest = Config{ + EscapeHTML: false, + MarshalFloatWith6Digits: true, // will lose precession + ObjectFieldMustBeSimpleString: true, // do not unescape object field +}.Froze() + +// Froze forge API from config +func (cfg Config) Froze() API { + // TODO: cache frozen config + frozenConfig := &frozenConfig{ + sortMapKeys: cfg.SortMapKeys, + indentionStep: cfg.IndentionStep, + objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString, + streamPool: make(chan *Stream, 16), + iteratorPool: make(chan *Iterator, 16), + } + atomic.StorePointer(&frozenConfig.decoderCache, unsafe.Pointer(&map[string]ValDecoder{})) + atomic.StorePointer(&frozenConfig.encoderCache, unsafe.Pointer(&map[string]ValEncoder{})) + if cfg.MarshalFloatWith6Digits { + frozenConfig.marshalFloatWith6Digits() + } + if cfg.EscapeHTML { + frozenConfig.escapeHTML() + } + if cfg.UseNumber { + frozenConfig.useNumber() + } + if cfg.ValidateJsonRawMessage { + frozenConfig.validateJsonRawMessage() + } + frozenConfig.configBeforeFrozen = cfg + return frozenConfig +} + +func (cfg *frozenConfig) validateJsonRawMessage() { + encoder := &funcEncoder{func(ptr unsafe.Pointer, stream *Stream) { + rawMessage := *(*json.RawMessage)(ptr) + iter := cfg.BorrowIterator([]byte(rawMessage)) + iter.Read() + if iter.Error != nil { + stream.WriteRaw("null") + } else { + cfg.ReturnIterator(iter) + stream.WriteRaw(string(rawMessage)) + } + }, func(ptr unsafe.Pointer) bool { + return false + }} + cfg.addEncoderToCache(reflect.TypeOf((*json.RawMessage)(nil)).Elem(), encoder) + cfg.addEncoderToCache(reflect.TypeOf((*RawMessage)(nil)).Elem(), encoder) +} + +func (cfg *frozenConfig) useNumber() { + cfg.addDecoderToCache(reflect.TypeOf((*interface{})(nil)).Elem(), &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) { + if iter.WhatIsNext() == NumberValue { + *((*interface{})(ptr)) = json.Number(iter.readNumberAsString()) + } else { + *((*interface{})(ptr)) = iter.Read() + } + }}) +} +func (cfg *frozenConfig) getTagKey() string { + tagKey := cfg.configBeforeFrozen.TagKey + if tagKey == "" { + return "json" + } + return tagKey +} + +func (cfg *frozenConfig) registerExtension(extension Extension) { + cfg.extensions = append(cfg.extensions, extension) +} + +type lossyFloat32Encoder struct { +} + +func (encoder *lossyFloat32Encoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat32Lossy(*((*float32)(ptr))) +} + +func (encoder *lossyFloat32Encoder) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, encoder) +} + +func (encoder *lossyFloat32Encoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float32)(ptr)) == 0 +} + +type lossyFloat64Encoder struct { +} + +func (encoder *lossyFloat64Encoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat64Lossy(*((*float64)(ptr))) +} + +func (encoder *lossyFloat64Encoder) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, encoder) +} + +func (encoder *lossyFloat64Encoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float64)(ptr)) == 0 +} + +// EnableLossyFloatMarshalling keeps 10**(-6) precision +// for float variables for better performance. +func (cfg *frozenConfig) marshalFloatWith6Digits() { + // for better performance + cfg.addEncoderToCache(reflect.TypeOf((*float32)(nil)).Elem(), &lossyFloat32Encoder{}) + cfg.addEncoderToCache(reflect.TypeOf((*float64)(nil)).Elem(), &lossyFloat64Encoder{}) +} + +type htmlEscapedStringEncoder struct { +} + +func (encoder *htmlEscapedStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + str := *((*string)(ptr)) + stream.WriteStringWithHTMLEscaped(str) +} + +func (encoder *htmlEscapedStringEncoder) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, encoder) +} + +func (encoder *htmlEscapedStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*string)(ptr)) == "" +} + +func (cfg *frozenConfig) escapeHTML() { + cfg.addEncoderToCache(reflect.TypeOf((*string)(nil)).Elem(), &htmlEscapedStringEncoder{}) +} + +func (cfg *frozenConfig) addDecoderToCache(cacheKey reflect.Type, decoder ValDecoder) { + done := false + for !done { + ptr := atomic.LoadPointer(&cfg.decoderCache) + cache := *(*map[reflect.Type]ValDecoder)(ptr) + copied := map[reflect.Type]ValDecoder{} + for k, v := range cache { + copied[k] = v + } + copied[cacheKey] = decoder + done = atomic.CompareAndSwapPointer(&cfg.decoderCache, ptr, unsafe.Pointer(&copied)) + } +} + +func (cfg *frozenConfig) addEncoderToCache(cacheKey reflect.Type, encoder ValEncoder) { + done := false + for !done { + ptr := atomic.LoadPointer(&cfg.encoderCache) + cache := *(*map[reflect.Type]ValEncoder)(ptr) + copied := map[reflect.Type]ValEncoder{} + for k, v := range cache { + copied[k] = v + } + copied[cacheKey] = encoder + done = atomic.CompareAndSwapPointer(&cfg.encoderCache, ptr, unsafe.Pointer(&copied)) + } +} + +func (cfg *frozenConfig) getDecoderFromCache(cacheKey reflect.Type) ValDecoder { + ptr := atomic.LoadPointer(&cfg.decoderCache) + cache := *(*map[reflect.Type]ValDecoder)(ptr) + return cache[cacheKey] +} + +func (cfg *frozenConfig) getEncoderFromCache(cacheKey reflect.Type) ValEncoder { + ptr := atomic.LoadPointer(&cfg.encoderCache) + cache := *(*map[reflect.Type]ValEncoder)(ptr) + return cache[cacheKey] +} + +func (cfg *frozenConfig) cleanDecoders() { + typeDecoders = map[string]ValDecoder{} + fieldDecoders = map[string]ValDecoder{} + *cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig)) +} + +func (cfg *frozenConfig) cleanEncoders() { + typeEncoders = map[string]ValEncoder{} + fieldEncoders = map[string]ValEncoder{} + *cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig)) +} + +func (cfg *frozenConfig) MarshalToString(v interface{}) (string, error) { + stream := cfg.BorrowStream(nil) + defer cfg.ReturnStream(stream) + stream.WriteVal(v) + if stream.Error != nil { + return "", stream.Error + } + return string(stream.Buffer()), nil +} + +func (cfg *frozenConfig) Marshal(v interface{}) ([]byte, error) { + stream := cfg.BorrowStream(nil) + defer cfg.ReturnStream(stream) + stream.WriteVal(v) + if stream.Error != nil { + return nil, stream.Error + } + result := stream.Buffer() + copied := make([]byte, len(result)) + copy(copied, result) + return copied, nil +} + +func (cfg *frozenConfig) MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + if prefix != "" { + panic("prefix is not supported") + } + for _, r := range indent { + if r != ' ' { + panic("indent can only be space") + } + } + newCfg := cfg.configBeforeFrozen + newCfg.IndentionStep = len(indent) + return newCfg.Froze().Marshal(v) +} + +func (cfg *frozenConfig) UnmarshalFromString(str string, v interface{}) error { + data := []byte(str) + data = data[:lastNotSpacePos(data)] + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + iter.ReadVal(v) + if iter.head == iter.tail { + iter.loadMore() + } + if iter.Error == io.EOF { + return nil + } + if iter.Error == nil { + iter.ReportError("UnmarshalFromString", "there are bytes left after unmarshal") + } + return iter.Error +} + +func (cfg *frozenConfig) Get(data []byte, path ...interface{}) Any { + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + return locatePath(iter, path) +} + +func (cfg *frozenConfig) Unmarshal(data []byte, v interface{}) error { + data = data[:lastNotSpacePos(data)] + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + typ := reflect.TypeOf(v) + if typ.Kind() != reflect.Ptr { + // return non-pointer error + return errors.New("the second param must be ptr type") + } + iter.ReadVal(v) + if iter.head == iter.tail { + iter.loadMore() + } + if iter.Error == io.EOF { + return nil + } + if iter.Error == nil { + iter.ReportError("Unmarshal", "there are bytes left after unmarshal") + } + return iter.Error +} + +func (cfg *frozenConfig) NewEncoder(writer io.Writer) *Encoder { + stream := NewStream(cfg, writer, 512) + return &Encoder{stream} +} + +func (cfg *frozenConfig) NewDecoder(reader io.Reader) *Decoder { + iter := Parse(cfg, reader, 512) + return &Decoder{iter} +} + +func (cfg *frozenConfig) Valid(data []byte) bool { + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + iter.Skip() + return iter.Error == nil +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_iter.go b/backend/vendor/github.com/json-iterator/go/feature_iter.go new file mode 100644 index 0000000000..95ae54fbfe --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_iter.go @@ -0,0 +1,322 @@ +package jsoniter + +import ( + "encoding/json" + "fmt" + "io" +) + +// ValueType the type for JSON element +type ValueType int + +const ( + // InvalidValue invalid JSON element + InvalidValue ValueType = iota + // StringValue JSON element "string" + StringValue + // NumberValue JSON element 100 or 0.10 + NumberValue + // NilValue JSON element null + NilValue + // BoolValue JSON element true or false + BoolValue + // ArrayValue JSON element [] + ArrayValue + // ObjectValue JSON element {} + ObjectValue +) + +var hexDigits []byte +var valueTypes []ValueType + +func init() { + hexDigits = make([]byte, 256) + for i := 0; i < len(hexDigits); i++ { + hexDigits[i] = 255 + } + for i := '0'; i <= '9'; i++ { + hexDigits[i] = byte(i - '0') + } + for i := 'a'; i <= 'f'; i++ { + hexDigits[i] = byte((i - 'a') + 10) + } + for i := 'A'; i <= 'F'; i++ { + hexDigits[i] = byte((i - 'A') + 10) + } + valueTypes = make([]ValueType, 256) + for i := 0; i < len(valueTypes); i++ { + valueTypes[i] = InvalidValue + } + valueTypes['"'] = StringValue + valueTypes['-'] = NumberValue + valueTypes['0'] = NumberValue + valueTypes['1'] = NumberValue + valueTypes['2'] = NumberValue + valueTypes['3'] = NumberValue + valueTypes['4'] = NumberValue + valueTypes['5'] = NumberValue + valueTypes['6'] = NumberValue + valueTypes['7'] = NumberValue + valueTypes['8'] = NumberValue + valueTypes['9'] = NumberValue + valueTypes['t'] = BoolValue + valueTypes['f'] = BoolValue + valueTypes['n'] = NilValue + valueTypes['['] = ArrayValue + valueTypes['{'] = ObjectValue +} + +// Iterator is a io.Reader like object, with JSON specific read functions. +// Error is not returned as return value, but stored as Error member on this iterator instance. +type Iterator struct { + cfg *frozenConfig + reader io.Reader + buf []byte + head int + tail int + captureStartedAt int + captured []byte + Error error + Attachment interface{} // open for customized decoder +} + +// NewIterator creates an empty Iterator instance +func NewIterator(cfg API) *Iterator { + return &Iterator{ + cfg: cfg.(*frozenConfig), + reader: nil, + buf: nil, + head: 0, + tail: 0, + } +} + +// Parse creates an Iterator instance from io.Reader +func Parse(cfg API, reader io.Reader, bufSize int) *Iterator { + return &Iterator{ + cfg: cfg.(*frozenConfig), + reader: reader, + buf: make([]byte, bufSize), + head: 0, + tail: 0, + } +} + +// ParseBytes creates an Iterator instance from byte array +func ParseBytes(cfg API, input []byte) *Iterator { + return &Iterator{ + cfg: cfg.(*frozenConfig), + reader: nil, + buf: input, + head: 0, + tail: len(input), + } +} + +// ParseString creates an Iterator instance from string +func ParseString(cfg API, input string) *Iterator { + return ParseBytes(cfg, []byte(input)) +} + +// Pool returns a pool can provide more iterator with same configuration +func (iter *Iterator) Pool() IteratorPool { + return iter.cfg +} + +// Reset reuse iterator instance by specifying another reader +func (iter *Iterator) Reset(reader io.Reader) *Iterator { + iter.reader = reader + iter.head = 0 + iter.tail = 0 + return iter +} + +// ResetBytes reuse iterator instance by specifying another byte array as input +func (iter *Iterator) ResetBytes(input []byte) *Iterator { + iter.reader = nil + iter.buf = input + iter.head = 0 + iter.tail = len(input) + return iter +} + +// WhatIsNext gets ValueType of relatively next json element +func (iter *Iterator) WhatIsNext() ValueType { + valueType := valueTypes[iter.nextToken()] + iter.unreadByte() + return valueType +} + +func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case ' ', '\n', '\t', '\r': + continue + } + iter.head = i + return false + } + return true +} + +func (iter *Iterator) isObjectEnd() bool { + c := iter.nextToken() + if c == ',' { + return false + } + if c == '}' { + return true + } + iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c})) + return true +} + +func (iter *Iterator) nextToken() byte { + // a variation of skip whitespaces, returning the next non-whitespace token + for { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case ' ', '\n', '\t', '\r': + continue + } + iter.head = i + 1 + return c + } + if !iter.loadMore() { + return 0 + } + } +} + +// ReportError record a error in iterator instance with current position. +func (iter *Iterator) ReportError(operation string, msg string) { + if iter.Error != nil { + if iter.Error != io.EOF { + return + } + } + peekStart := iter.head - 10 + if peekStart < 0 { + peekStart = 0 + } + peekEnd := iter.head + 10 + if peekEnd > iter.tail { + peekEnd = iter.tail + } + parsing := string(iter.buf[peekStart:peekEnd]) + contextStart := iter.head - 50 + if contextStart < 0 { + contextStart = 0 + } + contextEnd := iter.head + 50 + if contextEnd > iter.tail { + contextEnd = iter.tail + } + context := string(iter.buf[contextStart:contextEnd]) + iter.Error = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...", + operation, msg, iter.head-peekStart, parsing, context) +} + +// CurrentBuffer gets current buffer as string for debugging purpose +func (iter *Iterator) CurrentBuffer() string { + peekStart := iter.head - 10 + if peekStart < 0 { + peekStart = 0 + } + return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", iter.head, + string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail])) +} + +func (iter *Iterator) readByte() (ret byte) { + if iter.head == iter.tail { + if iter.loadMore() { + ret = iter.buf[iter.head] + iter.head++ + return ret + } + return 0 + } + ret = iter.buf[iter.head] + iter.head++ + return ret +} + +func (iter *Iterator) loadMore() bool { + if iter.reader == nil { + if iter.Error == nil { + iter.head = iter.tail + iter.Error = io.EOF + } + return false + } + if iter.captured != nil { + iter.captured = append(iter.captured, + iter.buf[iter.captureStartedAt:iter.tail]...) + iter.captureStartedAt = 0 + } + for { + n, err := iter.reader.Read(iter.buf) + if n == 0 { + if err != nil { + if iter.Error == nil { + iter.Error = err + } + return false + } + } else { + iter.head = 0 + iter.tail = n + return true + } + } +} + +func (iter *Iterator) unreadByte() { + if iter.Error != nil { + return + } + iter.head-- + return +} + +// Read read the next JSON element as generic interface{}. +func (iter *Iterator) Read() interface{} { + valueType := iter.WhatIsNext() + switch valueType { + case StringValue: + return iter.ReadString() + case NumberValue: + if iter.cfg.configBeforeFrozen.UseNumber { + return json.Number(iter.readNumberAsString()) + } + return iter.ReadFloat64() + case NilValue: + iter.skipFourBytes('n', 'u', 'l', 'l') + return nil + case BoolValue: + return iter.ReadBool() + case ArrayValue: + arr := []interface{}{} + iter.ReadArrayCB(func(iter *Iterator) bool { + var elem interface{} + iter.ReadVal(&elem) + arr = append(arr, elem) + return true + }) + return arr + case ObjectValue: + obj := map[string]interface{}{} + iter.ReadMapCB(func(Iter *Iterator, field string) bool { + var elem interface{} + iter.ReadVal(&elem) + obj[field] = elem + return true + }) + return obj + default: + iter.ReportError("Read", fmt.Sprintf("unexpected value type: %v", valueType)) + return nil + } +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_iter_array.go b/backend/vendor/github.com/json-iterator/go/feature_iter_array.go new file mode 100644 index 0000000000..6188cb4577 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_iter_array.go @@ -0,0 +1,58 @@ +package jsoniter + +// ReadArray read array element, tells if the array has more element to read. +func (iter *Iterator) ReadArray() (ret bool) { + c := iter.nextToken() + switch c { + case 'n': + iter.skipThreeBytes('u', 'l', 'l') + return false // null + case '[': + c = iter.nextToken() + if c != ']' { + iter.unreadByte() + return true + } + return false + case ']': + return false + case ',': + return true + default: + iter.ReportError("ReadArray", "expect [ or , or ] or n, but found "+string([]byte{c})) + return + } +} + +// ReadArrayCB read array with callback +func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) { + c := iter.nextToken() + if c == '[' { + c = iter.nextToken() + if c != ']' { + iter.unreadByte() + if !callback(iter) { + return false + } + c = iter.nextToken() + for c == ',' { + if !callback(iter) { + return false + } + c = iter.nextToken() + } + if c != ']' { + iter.ReportError("ReadArrayCB", "expect ] in the end, but found "+string([]byte{c})) + return false + } + return true + } + return true + } + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return true // null + } + iter.ReportError("ReadArrayCB", "expect [ or n, but found "+string([]byte{c})) + return false +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_iter_float.go b/backend/vendor/github.com/json-iterator/go/feature_iter_float.go new file mode 100644 index 0000000000..86f4599122 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_iter_float.go @@ -0,0 +1,341 @@ +package jsoniter + +import ( + "io" + "math/big" + "strconv" + "strings" + "unsafe" +) + +var floatDigits []int8 + +const invalidCharForNumber = int8(-1) +const endOfNumber = int8(-2) +const dotInNumber = int8(-3) + +func init() { + floatDigits = make([]int8, 256) + for i := 0; i < len(floatDigits); i++ { + floatDigits[i] = invalidCharForNumber + } + for i := int8('0'); i <= int8('9'); i++ { + floatDigits[i] = i - int8('0') + } + floatDigits[','] = endOfNumber + floatDigits[']'] = endOfNumber + floatDigits['}'] = endOfNumber + floatDigits[' '] = endOfNumber + floatDigits['\t'] = endOfNumber + floatDigits['\n'] = endOfNumber + floatDigits['.'] = dotInNumber +} + +// ReadBigFloat read big.Float +func (iter *Iterator) ReadBigFloat() (ret *big.Float) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return nil + } + prec := 64 + if len(str) > prec { + prec = len(str) + } + val, _, err := big.ParseFloat(str, 10, uint(prec), big.ToZero) + if err != nil { + iter.Error = err + return nil + } + return val +} + +// ReadBigInt read big.Int +func (iter *Iterator) ReadBigInt() (ret *big.Int) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return nil + } + ret = big.NewInt(0) + var success bool + ret, success = ret.SetString(str, 10) + if !success { + iter.ReportError("ReadBigInt", "invalid big int") + return nil + } + return ret +} + +//ReadFloat32 read float32 +func (iter *Iterator) ReadFloat32() (ret float32) { + c := iter.nextToken() + if c == '-' { + return -iter.readPositiveFloat32() + } + iter.unreadByte() + return iter.readPositiveFloat32() +} + +func (iter *Iterator) readPositiveFloat32() (ret float32) { + value := uint64(0) + c := byte(' ') + i := iter.head + // first char + if i == iter.tail { + return iter.readFloat32SlowPath() + } + c = iter.buf[i] + i++ + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat32SlowPath() + case endOfNumber: + iter.ReportError("readFloat32", "empty number") + return + case dotInNumber: + iter.ReportError("readFloat32", "leading dot is invalid") + return + case 0: + if i == iter.tail { + return iter.readFloat32SlowPath() + } + c = iter.buf[i] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + iter.ReportError("readFloat32", "leading zero is invalid") + return + } + } + value = uint64(ind) + // chars before dot +non_decimal_loop: + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat32SlowPath() + case endOfNumber: + iter.head = i + return float32(value) + case dotInNumber: + break non_decimal_loop + } + if value > uint64SafeToMultiple10 { + return iter.readFloat32SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind; + } + // chars after dot + if c == '.' { + i++ + decimalPlaces := 0 + if i == iter.tail { + return iter.readFloat32SlowPath() + } + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case endOfNumber: + if decimalPlaces > 0 && decimalPlaces < len(pow10) { + iter.head = i + return float32(float64(value) / float64(pow10[decimalPlaces])) + } + // too many decimal places + return iter.readFloat32SlowPath() + case invalidCharForNumber: + fallthrough + case dotInNumber: + return iter.readFloat32SlowPath() + } + decimalPlaces++ + if value > uint64SafeToMultiple10 { + return iter.readFloat32SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) + } + } + return iter.readFloat32SlowPath() +} + +func (iter *Iterator) readNumberAsString() (ret string) { + strBuf := [16]byte{} + str := strBuf[0:0] +load_loop: + for { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case '+', '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + str = append(str, c) + continue + default: + iter.head = i + break load_loop + } + } + if !iter.loadMore() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + return + } + if len(str) == 0 { + iter.ReportError("readNumberAsString", "invalid number") + } + return *(*string)(unsafe.Pointer(&str)) +} + +func (iter *Iterator) readFloat32SlowPath() (ret float32) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return + } + errMsg := validateFloat(str) + if errMsg != "" { + iter.ReportError("readFloat32SlowPath", errMsg) + return + } + val, err := strconv.ParseFloat(str, 32) + if err != nil { + iter.Error = err + return + } + return float32(val) +} + +// ReadFloat64 read float64 +func (iter *Iterator) ReadFloat64() (ret float64) { + c := iter.nextToken() + if c == '-' { + return -iter.readPositiveFloat64() + } + iter.unreadByte() + return iter.readPositiveFloat64() +} + +func (iter *Iterator) readPositiveFloat64() (ret float64) { + value := uint64(0) + c := byte(' ') + i := iter.head + // first char + if i == iter.tail { + return iter.readFloat64SlowPath() + } + c = iter.buf[i] + i++ + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat64SlowPath() + case endOfNumber: + iter.ReportError("readFloat64", "empty number") + return + case dotInNumber: + iter.ReportError("readFloat64", "leading dot is invalid") + return + case 0: + if i == iter.tail { + return iter.readFloat64SlowPath() + } + c = iter.buf[i] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + iter.ReportError("readFloat64", "leading zero is invalid") + return + } + } + value = uint64(ind) + // chars before dot +non_decimal_loop: + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat64SlowPath() + case endOfNumber: + iter.head = i + return float64(value) + case dotInNumber: + break non_decimal_loop + } + if value > uint64SafeToMultiple10 { + return iter.readFloat64SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind; + } + // chars after dot + if c == '.' { + i++ + decimalPlaces := 0 + if i == iter.tail { + return iter.readFloat64SlowPath() + } + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case endOfNumber: + if decimalPlaces > 0 && decimalPlaces < len(pow10) { + iter.head = i + return float64(value) / float64(pow10[decimalPlaces]) + } + // too many decimal places + return iter.readFloat64SlowPath() + case invalidCharForNumber: + fallthrough + case dotInNumber: + return iter.readFloat64SlowPath() + } + decimalPlaces++ + if value > uint64SafeToMultiple10 { + return iter.readFloat64SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) + } + } + return iter.readFloat64SlowPath() +} + +func (iter *Iterator) readFloat64SlowPath() (ret float64) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return + } + errMsg := validateFloat(str) + if errMsg != "" { + iter.ReportError("readFloat64SlowPath", errMsg) + return + } + val, err := strconv.ParseFloat(str, 64) + if err != nil { + iter.Error = err + return + } + return val +} + +func validateFloat(str string) string { + // strconv.ParseFloat is not validating `1.` or `1.e1` + if len(str) == 0 { + return "empty number" + } + if str[0] == '-' { + return "-- is not valid" + } + dotPos := strings.IndexByte(str, '.') + if dotPos != -1 { + if dotPos == len(str)-1 { + return "dot can not be last character" + } + switch str[dotPos+1] { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + default: + return "missing digit after dot" + } + } + return "" +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_iter_int.go b/backend/vendor/github.com/json-iterator/go/feature_iter_int.go new file mode 100644 index 0000000000..6137348cd2 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_iter_int.go @@ -0,0 +1,268 @@ +package jsoniter + +import ( + "math" + "strconv" +) + +var intDigits []int8 + +const uint32SafeToMultiply10 = uint32(0xffffffff)/10 - 1 +const uint64SafeToMultiple10 = uint64(0xffffffffffffffff)/10 - 1 + +func init() { + intDigits = make([]int8, 256) + for i := 0; i < len(intDigits); i++ { + intDigits[i] = invalidCharForNumber + } + for i := int8('0'); i <= int8('9'); i++ { + intDigits[i] = i - int8('0') + } +} + +// ReadUint read uint +func (iter *Iterator) ReadUint() uint { + return uint(iter.ReadUint64()) +} + +// ReadInt read int +func (iter *Iterator) ReadInt() int { + return int(iter.ReadInt64()) +} + +// ReadInt8 read int8 +func (iter *Iterator) ReadInt8() (ret int8) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint32(iter.readByte()) + if val > math.MaxInt8+1 { + iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return -int8(val) + } + val := iter.readUint32(c) + if val > math.MaxInt8 { + iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return int8(val) +} + +// ReadUint8 read uint8 +func (iter *Iterator) ReadUint8() (ret uint8) { + val := iter.readUint32(iter.nextToken()) + if val > math.MaxUint8 { + iter.ReportError("ReadUint8", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return uint8(val) +} + +// ReadInt16 read int16 +func (iter *Iterator) ReadInt16() (ret int16) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint32(iter.readByte()) + if val > math.MaxInt16+1 { + iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return -int16(val) + } + val := iter.readUint32(c) + if val > math.MaxInt16 { + iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return int16(val) +} + +// ReadUint16 read uint16 +func (iter *Iterator) ReadUint16() (ret uint16) { + val := iter.readUint32(iter.nextToken()) + if val > math.MaxUint16 { + iter.ReportError("ReadUint16", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return uint16(val) +} + +// ReadInt32 read int32 +func (iter *Iterator) ReadInt32() (ret int32) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint32(iter.readByte()) + if val > math.MaxInt32+1 { + iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return -int32(val) + } + val := iter.readUint32(c) + if val > math.MaxInt32 { + iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return int32(val) +} + +// ReadUint32 read uint32 +func (iter *Iterator) ReadUint32() (ret uint32) { + return iter.readUint32(iter.nextToken()) +} + +func (iter *Iterator) readUint32(c byte) (ret uint32) { + defer func() { + if iter.head < len(iter.buf) && iter.buf[iter.head] == '.' { + iter.ReportError("readUint32", "can not decode float as int") + } + }() + ind := intDigits[c] + if ind == 0 { + return 0 // single zero + } + if ind == invalidCharForNumber { + iter.ReportError("readUint32", "unexpected character: "+string([]byte{byte(ind)})) + return + } + value := uint32(ind) + if iter.tail-iter.head > 10 { + i := iter.head + ind2 := intDigits[iter.buf[i]] + if ind2 == invalidCharForNumber { + iter.head = i + return value + } + i++ + ind3 := intDigits[iter.buf[i]] + if ind3 == invalidCharForNumber { + iter.head = i + return value*10 + uint32(ind2) + } + //iter.head = i + 1 + //value = value * 100 + uint32(ind2) * 10 + uint32(ind3) + i++ + ind4 := intDigits[iter.buf[i]] + if ind4 == invalidCharForNumber { + iter.head = i + return value*100 + uint32(ind2)*10 + uint32(ind3) + } + i++ + ind5 := intDigits[iter.buf[i]] + if ind5 == invalidCharForNumber { + iter.head = i + return value*1000 + uint32(ind2)*100 + uint32(ind3)*10 + uint32(ind4) + } + i++ + ind6 := intDigits[iter.buf[i]] + if ind6 == invalidCharForNumber { + iter.head = i + return value*10000 + uint32(ind2)*1000 + uint32(ind3)*100 + uint32(ind4)*10 + uint32(ind5) + } + i++ + ind7 := intDigits[iter.buf[i]] + if ind7 == invalidCharForNumber { + iter.head = i + return value*100000 + uint32(ind2)*10000 + uint32(ind3)*1000 + uint32(ind4)*100 + uint32(ind5)*10 + uint32(ind6) + } + i++ + ind8 := intDigits[iter.buf[i]] + if ind8 == invalidCharForNumber { + iter.head = i + return value*1000000 + uint32(ind2)*100000 + uint32(ind3)*10000 + uint32(ind4)*1000 + uint32(ind5)*100 + uint32(ind6)*10 + uint32(ind7) + } + i++ + ind9 := intDigits[iter.buf[i]] + value = value*10000000 + uint32(ind2)*1000000 + uint32(ind3)*100000 + uint32(ind4)*10000 + uint32(ind5)*1000 + uint32(ind6)*100 + uint32(ind7)*10 + uint32(ind8) + iter.head = i + if ind9 == invalidCharForNumber { + return value + } + } + for { + for i := iter.head; i < iter.tail; i++ { + ind = intDigits[iter.buf[i]] + if ind == invalidCharForNumber { + iter.head = i + return value + } + if value > uint32SafeToMultiply10 { + value2 := (value << 3) + (value << 1) + uint32(ind) + if value2 < value { + iter.ReportError("readUint32", "overflow") + return + } + value = value2 + continue + } + value = (value << 3) + (value << 1) + uint32(ind) + } + if !iter.loadMore() { + return value + } + } +} + +// ReadInt64 read int64 +func (iter *Iterator) ReadInt64() (ret int64) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint64(iter.readByte()) + if val > math.MaxInt64+1 { + iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10)) + return + } + return -int64(val) + } + val := iter.readUint64(c) + if val > math.MaxInt64 { + iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10)) + return + } + return int64(val) +} + +// ReadUint64 read uint64 +func (iter *Iterator) ReadUint64() uint64 { + return iter.readUint64(iter.nextToken()) +} + +func (iter *Iterator) readUint64(c byte) (ret uint64) { + defer func() { + if iter.head < len(iter.buf) && iter.buf[iter.head] == '.' { + iter.ReportError("readUint64", "can not decode float as int") + } + }() + ind := intDigits[c] + if ind == 0 { + return 0 // single zero + } + if ind == invalidCharForNumber { + iter.ReportError("readUint64", "unexpected character: "+string([]byte{byte(ind)})) + return + } + value := uint64(ind) + for { + for i := iter.head; i < iter.tail; i++ { + ind = intDigits[iter.buf[i]] + if ind == invalidCharForNumber { + iter.head = i + return value + } + if value > uint64SafeToMultiple10 { + value2 := (value << 3) + (value << 1) + uint64(ind) + if value2 < value { + iter.ReportError("readUint64", "overflow") + return + } + value = value2 + continue + } + value = (value << 3) + (value << 1) + uint64(ind) + } + if !iter.loadMore() { + return value + } + } +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_iter_object.go b/backend/vendor/github.com/json-iterator/go/feature_iter_object.go new file mode 100644 index 0000000000..dfd91fa60d --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_iter_object.go @@ -0,0 +1,267 @@ +package jsoniter + +import ( + "fmt" + "unicode" + "unsafe" +) + +// ReadObject read one field from object. +// If object ended, returns empty string. +// Otherwise, returns the field name. +func (iter *Iterator) ReadObject() (ret string) { + c := iter.nextToken() + switch c { + case 'n': + iter.skipThreeBytes('u', 'l', 'l') + return "" // null + case '{': + c = iter.nextToken() + if c == '"' { + iter.unreadByte() + if iter.cfg.objectFieldMustBeSimpleString { + return string(iter.readObjectFieldAsBytes()) + } else { + field := iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + return field + } + } + if c == '}' { + return "" // end of object + } + iter.ReportError("ReadObject", `expect " after {, but found `+string([]byte{c})) + return + case ',': + if iter.cfg.objectFieldMustBeSimpleString { + return string(iter.readObjectFieldAsBytes()) + } else { + field := iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + return field + } + case '}': + return "" // end of object + default: + iter.ReportError("ReadObject", fmt.Sprintf(`expect { or , or } or n, but found %s`, string([]byte{c}))) + return + } +} + +func (iter *Iterator) readFieldHash() int32 { + hash := int64(0x811c9dc5) + c := iter.nextToken() + if c == '"' { + for { + for i := iter.head; i < iter.tail; i++ { + // require ascii string and no escape + b := iter.buf[i] + if !iter.cfg.objectFieldMustBeSimpleString && b == '\\' { + iter.head = i + for _, b := range iter.readStringSlowPath() { + if 'A' <= b && b <= 'Z' { + b += 'a' - 'A' + } + hash ^= int64(b) + hash *= 0x1000193 + } + c = iter.nextToken() + if c != ':' { + iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) + return 0 + } + return int32(hash) + } + if b == '"' { + iter.head = i + 1 + c = iter.nextToken() + if c != ':' { + iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) + return 0 + } + return int32(hash) + } + if 'A' <= b && b <= 'Z' { + b += 'a' - 'A' + } + hash ^= int64(b) + hash *= 0x1000193 + } + if !iter.loadMore() { + iter.ReportError("readFieldHash", `incomplete field name`) + return 0 + } + } + } + iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c})) + return 0 +} + +func calcHash(str string) int32 { + hash := int64(0x811c9dc5) + for _, b := range str { + hash ^= int64(unicode.ToLower(b)) + hash *= 0x1000193 + } + return int32(hash) +} + +// ReadObjectCB read object with callback, the key is ascii only and field name not copied +func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool { + c := iter.nextToken() + var fieldBytes []byte + var field string + if c == '{' { + c = iter.nextToken() + if c == '"' { + iter.unreadByte() + if iter.cfg.objectFieldMustBeSimpleString { + fieldBytes = iter.readObjectFieldAsBytes() + field = *(*string)(unsafe.Pointer(&fieldBytes)) + } else { + field = iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + } + if !callback(iter, field) { + return false + } + c = iter.nextToken() + for c == ',' { + if iter.cfg.objectFieldMustBeSimpleString { + fieldBytes = iter.readObjectFieldAsBytes() + field = *(*string)(unsafe.Pointer(&fieldBytes)) + } else { + field = iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + } + if !callback(iter, field) { + return false + } + c = iter.nextToken() + } + if c != '}' { + iter.ReportError("ReadObjectCB", `object not ended with }`) + return false + } + return true + } + if c == '}' { + return true + } + iter.ReportError("ReadObjectCB", `expect " after }, but found `+string([]byte{c})) + return false + } + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return true // null + } + iter.ReportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c})) + return false +} + +// ReadMapCB read map with callback, the key can be any string +func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool { + c := iter.nextToken() + if c == '{' { + c = iter.nextToken() + if c == '"' { + iter.unreadByte() + field := iter.ReadString() + if iter.nextToken() != ':' { + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) + return false + } + if !callback(iter, field) { + return false + } + c = iter.nextToken() + for c == ',' { + field = iter.ReadString() + if iter.nextToken() != ':' { + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) + return false + } + if !callback(iter, field) { + return false + } + c = iter.nextToken() + } + if c != '}' { + iter.ReportError("ReadMapCB", `object not ended with }`) + return false + } + return true + } + if c == '}' { + return true + } + iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c})) + return false + } + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return true // null + } + iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) + return false +} + +func (iter *Iterator) readObjectStart() bool { + c := iter.nextToken() + if c == '{' { + c = iter.nextToken() + if c == '}' { + return false + } + iter.unreadByte() + return true + } else if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return false + } + iter.ReportError("readObjectStart", "expect { or n, but found "+string([]byte{c})) + return false +} + +func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) { + str := iter.ReadStringAsSlice() + if iter.skipWhitespacesWithoutLoadMore() { + if ret == nil { + ret = make([]byte, len(str)) + copy(ret, str) + } + if !iter.loadMore() { + return + } + } + if iter.buf[iter.head] != ':' { + iter.ReportError("readObjectFieldAsBytes", "expect : after object field, but found "+string([]byte{iter.buf[iter.head]})) + return + } + iter.head++ + if iter.skipWhitespacesWithoutLoadMore() { + if ret == nil { + ret = make([]byte, len(str)) + copy(ret, str) + } + if !iter.loadMore() { + return + } + } + if ret == nil { + return str + } + return ret +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_iter_skip.go b/backend/vendor/github.com/json-iterator/go/feature_iter_skip.go new file mode 100644 index 0000000000..f58beb9137 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_iter_skip.go @@ -0,0 +1,129 @@ +package jsoniter + +import "fmt" + +// ReadNil reads a json object as nil and +// returns whether it's a nil or not +func (iter *Iterator) ReadNil() (ret bool) { + c := iter.nextToken() + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') // null + return true + } + iter.unreadByte() + return false +} + +// ReadBool reads a json object as BoolValue +func (iter *Iterator) ReadBool() (ret bool) { + c := iter.nextToken() + if c == 't' { + iter.skipThreeBytes('r', 'u', 'e') + return true + } + if c == 'f' { + iter.skipFourBytes('a', 'l', 's', 'e') + return false + } + iter.ReportError("ReadBool", "expect t or f, but found "+string([]byte{c})) + return +} + +// SkipAndReturnBytes skip next JSON element, and return its content as []byte. +// The []byte can be kept, it is a copy of data. +func (iter *Iterator) SkipAndReturnBytes() []byte { + iter.startCapture(iter.head) + iter.Skip() + return iter.stopCapture() +} + +type captureBuffer struct { + startedAt int + captured []byte +} + +func (iter *Iterator) startCapture(captureStartedAt int) { + if iter.captured != nil { + panic("already in capture mode") + } + iter.captureStartedAt = captureStartedAt + iter.captured = make([]byte, 0, 32) +} + +func (iter *Iterator) stopCapture() []byte { + if iter.captured == nil { + panic("not in capture mode") + } + captured := iter.captured + remaining := iter.buf[iter.captureStartedAt:iter.head] + iter.captureStartedAt = -1 + iter.captured = nil + if len(captured) == 0 { + copied := make([]byte, len(remaining)) + copy(copied, remaining) + return copied + } + captured = append(captured, remaining...) + return captured +} + +// Skip skips a json object and positions to relatively the next json object +func (iter *Iterator) Skip() { + c := iter.nextToken() + switch c { + case '"': + iter.skipString() + case 'n': + iter.skipThreeBytes('u', 'l', 'l') // null + case 't': + iter.skipThreeBytes('r', 'u', 'e') // true + case 'f': + iter.skipFourBytes('a', 'l', 's', 'e') // false + case '0': + iter.unreadByte() + iter.ReadFloat32() + case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9': + iter.skipNumber() + case '[': + iter.skipArray() + case '{': + iter.skipObject() + default: + iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c)) + return + } +} + +func (iter *Iterator) skipFourBytes(b1, b2, b3, b4 byte) { + if iter.readByte() != b1 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } + if iter.readByte() != b2 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } + if iter.readByte() != b3 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } + if iter.readByte() != b4 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } +} + +func (iter *Iterator) skipThreeBytes(b1, b2, b3 byte) { + if iter.readByte() != b1 { + iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) + return + } + if iter.readByte() != b2 { + iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) + return + } + if iter.readByte() != b3 { + iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) + return + } +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_iter_skip_sloppy.go b/backend/vendor/github.com/json-iterator/go/feature_iter_skip_sloppy.go new file mode 100644 index 0000000000..8fcdc3b69b --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_iter_skip_sloppy.go @@ -0,0 +1,144 @@ +//+build jsoniter_sloppy + +package jsoniter + +// sloppy but faster implementation, do not validate the input json + +func (iter *Iterator) skipNumber() { + for { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case ' ', '\n', '\r', '\t', ',', '}', ']': + iter.head = i + return + } + } + if !iter.loadMore() { + return + } + } +} + +func (iter *Iterator) skipArray() { + level := 1 + for { + for i := iter.head; i < iter.tail; i++ { + switch iter.buf[i] { + case '"': // If inside string, skip it + iter.head = i + 1 + iter.skipString() + i = iter.head - 1 // it will be i++ soon + case '[': // If open symbol, increase level + level++ + case ']': // If close symbol, increase level + level-- + + // If we have returned to the original level, we're done + if level == 0 { + iter.head = i + 1 + return + } + } + } + if !iter.loadMore() { + iter.ReportError("skipObject", "incomplete array") + return + } + } +} + +func (iter *Iterator) skipObject() { + level := 1 + for { + for i := iter.head; i < iter.tail; i++ { + switch iter.buf[i] { + case '"': // If inside string, skip it + iter.head = i + 1 + iter.skipString() + i = iter.head - 1 // it will be i++ soon + case '{': // If open symbol, increase level + level++ + case '}': // If close symbol, increase level + level-- + + // If we have returned to the original level, we're done + if level == 0 { + iter.head = i + 1 + return + } + } + } + if !iter.loadMore() { + iter.ReportError("skipObject", "incomplete object") + return + } + } +} + +func (iter *Iterator) skipString() { + for { + end, escaped := iter.findStringEnd() + if end == -1 { + if !iter.loadMore() { + iter.ReportError("skipString", "incomplete string") + return + } + if escaped { + iter.head = 1 // skip the first char as last char read is \ + } + } else { + iter.head = end + return + } + } +} + +// adapted from: https://github.com/buger/jsonparser/blob/master/parser.go +// Tries to find the end of string +// Support if string contains escaped quote symbols. +func (iter *Iterator) findStringEnd() (int, bool) { + escaped := false + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + if c == '"' { + if !escaped { + return i + 1, false + } + j := i - 1 + for { + if j < iter.head || iter.buf[j] != '\\' { + // even number of backslashes + // either end of buffer, or " found + return i + 1, true + } + j-- + if j < iter.head || iter.buf[j] != '\\' { + // odd number of backslashes + // it is \" or \\\" + break + } + j-- + } + } else if c == '\\' { + escaped = true + } + } + j := iter.tail - 1 + for { + if j < iter.head || iter.buf[j] != '\\' { + // even number of backslashes + // either end of buffer, or " found + return -1, false // do not end with \ + } + j-- + if j < iter.head || iter.buf[j] != '\\' { + // odd number of backslashes + // it is \" or \\\" + break + } + j-- + + } + return -1, true // end with \ +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_iter_skip_strict.go b/backend/vendor/github.com/json-iterator/go/feature_iter_skip_strict.go new file mode 100644 index 0000000000..f67bc2e831 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_iter_skip_strict.go @@ -0,0 +1,89 @@ +//+build !jsoniter_sloppy + +package jsoniter + +import "fmt" + +func (iter *Iterator) skipNumber() { + if !iter.trySkipNumber() { + iter.unreadByte() + iter.ReadFloat32() + } +} + +func (iter *Iterator) trySkipNumber() bool { + dotFound := false + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + case '.': + if dotFound { + iter.ReportError("validateNumber", `more than one dot found in number`) + return true // already failed + } + if i+1 == iter.tail { + return false + } + c = iter.buf[i+1] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + default: + iter.ReportError("validateNumber", `missing digit after dot`) + return true // already failed + } + dotFound = true + default: + switch c { + case ',', ']', '}', ' ', '\t', '\n', '\r': + if iter.head == i { + return false // if - without following digits + } + iter.head = i + return true // must be valid + } + return false // may be invalid + } + } + return false +} + +func (iter *Iterator) skipString() { + if !iter.trySkipString() { + iter.unreadByte() + iter.ReadString() + } +} + +func (iter *Iterator) trySkipString() bool { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + if c == '"' { + iter.head = i + 1 + return true // valid + } else if c == '\\' { + return false + } else if c < ' ' { + iter.ReportError("trySkipString", + fmt.Sprintf(`invalid control character found: %d`, c)) + return true // already failed + } + } + return false +} + +func (iter *Iterator) skipObject() { + iter.unreadByte() + iter.ReadObjectCB(func(iter *Iterator, field string) bool { + iter.Skip() + return true + }) +} + +func (iter *Iterator) skipArray() { + iter.unreadByte() + iter.ReadArrayCB(func(iter *Iterator) bool { + iter.Skip() + return true + }) +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_iter_string.go b/backend/vendor/github.com/json-iterator/go/feature_iter_string.go new file mode 100644 index 0000000000..adc487ea80 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_iter_string.go @@ -0,0 +1,215 @@ +package jsoniter + +import ( + "fmt" + "unicode/utf16" +) + +// ReadString read string from iterator +func (iter *Iterator) ReadString() (ret string) { + c := iter.nextToken() + if c == '"' { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + if c == '"' { + ret = string(iter.buf[iter.head:i]) + iter.head = i + 1 + return ret + } else if c == '\\' { + break + } else if c < ' ' { + iter.ReportError("ReadString", + fmt.Sprintf(`invalid control character found: %d`, c)) + return + } + } + return iter.readStringSlowPath() + } else if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return "" + } + iter.ReportError("ReadString", `expects " or n, but found `+string([]byte{c})) + return +} + +func (iter *Iterator) readStringSlowPath() (ret string) { + var str []byte + var c byte + for iter.Error == nil { + c = iter.readByte() + if c == '"' { + return string(str) + } + if c == '\\' { + c = iter.readByte() + str = iter.readEscapedChar(c, str) + } else { + str = append(str, c) + } + } + iter.ReportError("readStringSlowPath", "unexpected end of input") + return +} + +func (iter *Iterator) readEscapedChar(c byte, str []byte) []byte { + switch c { + case 'u': + r := iter.readU4() + if utf16.IsSurrogate(r) { + c = iter.readByte() + if iter.Error != nil { + return nil + } + if c != '\\' { + iter.unreadByte() + str = appendRune(str, r) + return str + } + c = iter.readByte() + if iter.Error != nil { + return nil + } + if c != 'u' { + str = appendRune(str, r) + return iter.readEscapedChar(c, str) + } + r2 := iter.readU4() + if iter.Error != nil { + return nil + } + combined := utf16.DecodeRune(r, r2) + if combined == '\uFFFD' { + str = appendRune(str, r) + str = appendRune(str, r2) + } else { + str = appendRune(str, combined) + } + } else { + str = appendRune(str, r) + } + case '"': + str = append(str, '"') + case '\\': + str = append(str, '\\') + case '/': + str = append(str, '/') + case 'b': + str = append(str, '\b') + case 'f': + str = append(str, '\f') + case 'n': + str = append(str, '\n') + case 'r': + str = append(str, '\r') + case 't': + str = append(str, '\t') + default: + iter.ReportError("readEscapedChar", + `invalid escape char after \`) + return nil + } + return str +} + +// ReadStringAsSlice read string from iterator without copying into string form. +// The []byte can not be kept, as it will change after next iterator call. +func (iter *Iterator) ReadStringAsSlice() (ret []byte) { + c := iter.nextToken() + if c == '"' { + for i := iter.head; i < iter.tail; i++ { + // require ascii string and no escape + // for: field name, base64, number + if iter.buf[i] == '"' { + // fast path: reuse the underlying buffer + ret = iter.buf[iter.head:i] + iter.head = i + 1 + return ret + } + } + readLen := iter.tail - iter.head + copied := make([]byte, readLen, readLen*2) + copy(copied, iter.buf[iter.head:iter.tail]) + iter.head = iter.tail + for iter.Error == nil { + c := iter.readByte() + if c == '"' { + return copied + } + copied = append(copied, c) + } + return copied + } + iter.ReportError("ReadStringAsSlice", `expects " or n, but found `+string([]byte{c})) + return +} + +func (iter *Iterator) readU4() (ret rune) { + for i := 0; i < 4; i++ { + c := iter.readByte() + if iter.Error != nil { + return + } + if c >= '0' && c <= '9' { + ret = ret*16 + rune(c-'0') + } else if c >= 'a' && c <= 'f' { + ret = ret*16 + rune(c-'a'+10) + } else if c >= 'A' && c <= 'F' { + ret = ret*16 + rune(c-'A'+10) + } else { + iter.ReportError("readU4", "expects 0~9 or a~f, but found "+string([]byte{c})) + return + } + } + return ret +} + +const ( + t1 = 0x00 // 0000 0000 + tx = 0x80 // 1000 0000 + t2 = 0xC0 // 1100 0000 + t3 = 0xE0 // 1110 0000 + t4 = 0xF0 // 1111 0000 + t5 = 0xF8 // 1111 1000 + + maskx = 0x3F // 0011 1111 + mask2 = 0x1F // 0001 1111 + mask3 = 0x0F // 0000 1111 + mask4 = 0x07 // 0000 0111 + + rune1Max = 1<<7 - 1 + rune2Max = 1<<11 - 1 + rune3Max = 1<<16 - 1 + + surrogateMin = 0xD800 + surrogateMax = 0xDFFF + + maxRune = '\U0010FFFF' // Maximum valid Unicode code point. + runeError = '\uFFFD' // the "error" Rune or "Unicode replacement character" +) + +func appendRune(p []byte, r rune) []byte { + // Negative values are erroneous. Making it unsigned addresses the problem. + switch i := uint32(r); { + case i <= rune1Max: + p = append(p, byte(r)) + return p + case i <= rune2Max: + p = append(p, t2|byte(r>>6)) + p = append(p, tx|byte(r)&maskx) + return p + case i > maxRune, surrogateMin <= i && i <= surrogateMax: + r = runeError + fallthrough + case i <= rune3Max: + p = append(p, t3|byte(r>>12)) + p = append(p, tx|byte(r>>6)&maskx) + p = append(p, tx|byte(r)&maskx) + return p + default: + p = append(p, t4|byte(r>>18)) + p = append(p, tx|byte(r>>12)&maskx) + p = append(p, tx|byte(r>>6)&maskx) + p = append(p, tx|byte(r)&maskx) + return p + } +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_json_number.go b/backend/vendor/github.com/json-iterator/go/feature_json_number.go new file mode 100644 index 0000000000..e187b200a9 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_json_number.go @@ -0,0 +1,31 @@ +package jsoniter + +import ( + "encoding/json" + "strconv" +) + +type Number string + +// String returns the literal text of the number. +func (n Number) String() string { return string(n) } + +// Float64 returns the number as a float64. +func (n Number) Float64() (float64, error) { + return strconv.ParseFloat(string(n), 64) +} + +// Int64 returns the number as an int64. +func (n Number) Int64() (int64, error) { + return strconv.ParseInt(string(n), 10, 64) +} + +func CastJsonNumber(val interface{}) (string, bool) { + switch typedVal := val.(type) { + case json.Number: + return string(typedVal), true + case Number: + return string(typedVal), true + } + return "", false +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_pool.go b/backend/vendor/github.com/json-iterator/go/feature_pool.go new file mode 100644 index 0000000000..52d38e6855 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_pool.go @@ -0,0 +1,59 @@ +package jsoniter + +import ( + "io" +) + +// IteratorPool a thread safe pool of iterators with same configuration +type IteratorPool interface { + BorrowIterator(data []byte) *Iterator + ReturnIterator(iter *Iterator) +} + +// StreamPool a thread safe pool of streams with same configuration +type StreamPool interface { + BorrowStream(writer io.Writer) *Stream + ReturnStream(stream *Stream) +} + +func (cfg *frozenConfig) BorrowStream(writer io.Writer) *Stream { + select { + case stream := <-cfg.streamPool: + stream.Reset(writer) + return stream + default: + return NewStream(cfg, writer, 512) + } +} + +func (cfg *frozenConfig) ReturnStream(stream *Stream) { + stream.Error = nil + stream.Attachment = nil + select { + case cfg.streamPool <- stream: + return + default: + return + } +} + +func (cfg *frozenConfig) BorrowIterator(data []byte) *Iterator { + select { + case iter := <-cfg.iteratorPool: + iter.ResetBytes(data) + return iter + default: + return ParseBytes(cfg, data) + } +} + +func (cfg *frozenConfig) ReturnIterator(iter *Iterator) { + iter.Error = nil + iter.Attachment = nil + select { + case cfg.iteratorPool <- iter: + return + default: + return + } +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_reflect.go b/backend/vendor/github.com/json-iterator/go/feature_reflect.go new file mode 100644 index 0000000000..1bd8987f29 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_reflect.go @@ -0,0 +1,721 @@ +package jsoniter + +import ( + "encoding" + "encoding/json" + "fmt" + "reflect" + "time" + "unsafe" +) + +// ValDecoder is an internal type registered to cache as needed. +// Don't confuse jsoniter.ValDecoder with json.Decoder. +// For json.Decoder's adapter, refer to jsoniter.AdapterDecoder(todo link). +// +// Reflection on type to create decoders, which is then cached +// Reflection on value is avoided as we can, as the reflect.Value itself will allocate, with following exceptions +// 1. create instance of new value, for example *int will need a int to be allocated +// 2. append to slice, if the existing cap is not enough, allocate will be done using Reflect.New +// 3. assignment to map, both key and value will be reflect.Value +// For a simple struct binding, it will be reflect.Value free and allocation free +type ValDecoder interface { + Decode(ptr unsafe.Pointer, iter *Iterator) +} + +// ValEncoder is an internal type registered to cache as needed. +// Don't confuse jsoniter.ValEncoder with json.Encoder. +// For json.Encoder's adapter, refer to jsoniter.AdapterEncoder(todo godoc link). +type ValEncoder interface { + IsEmpty(ptr unsafe.Pointer) bool + Encode(ptr unsafe.Pointer, stream *Stream) + EncodeInterface(val interface{}, stream *Stream) +} + +type checkIsEmpty interface { + IsEmpty(ptr unsafe.Pointer) bool +} + +// WriteToStream the default implementation for TypeEncoder method EncodeInterface +func WriteToStream(val interface{}, stream *Stream, encoder ValEncoder) { + e := (*emptyInterface)(unsafe.Pointer(&val)) + if e.word == nil { + stream.WriteNil() + return + } + if reflect.TypeOf(val).Kind() == reflect.Ptr { + encoder.Encode(unsafe.Pointer(&e.word), stream) + } else { + encoder.Encode(e.word, stream) + } +} + +var jsonNumberType reflect.Type +var jsoniterNumberType reflect.Type +var jsonRawMessageType reflect.Type +var jsoniterRawMessageType reflect.Type +var anyType reflect.Type +var marshalerType reflect.Type +var unmarshalerType reflect.Type +var textMarshalerType reflect.Type +var textUnmarshalerType reflect.Type + +func init() { + jsonNumberType = reflect.TypeOf((*json.Number)(nil)).Elem() + jsoniterNumberType = reflect.TypeOf((*Number)(nil)).Elem() + jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem() + jsoniterRawMessageType = reflect.TypeOf((*RawMessage)(nil)).Elem() + anyType = reflect.TypeOf((*Any)(nil)).Elem() + marshalerType = reflect.TypeOf((*json.Marshaler)(nil)).Elem() + unmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem() + textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() + textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() +} + +type OptionalDecoder struct { + ValueType reflect.Type + ValueDecoder ValDecoder +} + +func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if iter.ReadNil() { + *((*unsafe.Pointer)(ptr)) = nil + } else { + if *((*unsafe.Pointer)(ptr)) == nil { + //pointer to null, we have to allocate memory to hold the value + value := reflect.New(decoder.ValueType) + newPtr := extractInterface(value.Interface()).word + decoder.ValueDecoder.Decode(newPtr, iter) + *((*uintptr)(ptr)) = uintptr(newPtr) + } else { + //reuse existing instance + decoder.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) + } + } +} + +type deferenceDecoder struct { + // only to deference a pointer + valueType reflect.Type + valueDecoder ValDecoder +} + +func (decoder *deferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if *((*unsafe.Pointer)(ptr)) == nil { + //pointer to null, we have to allocate memory to hold the value + value := reflect.New(decoder.valueType) + newPtr := extractInterface(value.Interface()).word + decoder.valueDecoder.Decode(newPtr, iter) + *((*uintptr)(ptr)) = uintptr(newPtr) + } else { + //reuse existing instance + decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) + } +} + +type OptionalEncoder struct { + ValueEncoder ValEncoder +} + +func (encoder *OptionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if *((*unsafe.Pointer)(ptr)) == nil { + stream.WriteNil() + } else { + encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) + } +} + +func (encoder *OptionalEncoder) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, encoder) +} + +func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*unsafe.Pointer)(ptr)) == nil +} + +type optionalMapEncoder struct { + valueEncoder ValEncoder +} + +func (encoder *optionalMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if *((*unsafe.Pointer)(ptr)) == nil { + stream.WriteNil() + } else { + encoder.valueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) + } +} + +func (encoder *optionalMapEncoder) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, encoder) +} + +func (encoder *optionalMapEncoder) IsEmpty(ptr unsafe.Pointer) bool { + p := *((*unsafe.Pointer)(ptr)) + return p == nil || encoder.valueEncoder.IsEmpty(p) +} + +type placeholderEncoder struct { + cfg *frozenConfig + cacheKey reflect.Type +} + +func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + encoder.getRealEncoder().Encode(ptr, stream) +} + +func (encoder *placeholderEncoder) EncodeInterface(val interface{}, stream *Stream) { + encoder.getRealEncoder().EncodeInterface(val, stream) +} + +func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.getRealEncoder().IsEmpty(ptr) +} + +func (encoder *placeholderEncoder) getRealEncoder() ValEncoder { + for i := 0; i < 500; i++ { + realDecoder := encoder.cfg.getEncoderFromCache(encoder.cacheKey) + _, isPlaceholder := realDecoder.(*placeholderEncoder) + if isPlaceholder { + time.Sleep(10 * time.Millisecond) + } else { + return realDecoder + } + } + panic(fmt.Sprintf("real encoder not found for cache key: %v", encoder.cacheKey)) +} + +type placeholderDecoder struct { + cfg *frozenConfig + cacheKey reflect.Type +} + +func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + for i := 0; i < 500; i++ { + realDecoder := decoder.cfg.getDecoderFromCache(decoder.cacheKey) + _, isPlaceholder := realDecoder.(*placeholderDecoder) + if isPlaceholder { + time.Sleep(10 * time.Millisecond) + } else { + realDecoder.Decode(ptr, iter) + return + } + } + panic(fmt.Sprintf("real decoder not found for cache key: %v", decoder.cacheKey)) +} + +// emptyInterface is the header for an interface{} value. +type emptyInterface struct { + typ unsafe.Pointer + word unsafe.Pointer +} + +// emptyInterface is the header for an interface with method (not interface{}) +type nonEmptyInterface struct { + // see ../runtime/iface.go:/Itab + itab *struct { + ityp unsafe.Pointer // static interface type + typ unsafe.Pointer // dynamic concrete type + link unsafe.Pointer + bad int32 + unused int32 + fun [100000]unsafe.Pointer // method table + } + word unsafe.Pointer +} + +// ReadVal copy the underlying JSON into go interface, same as json.Unmarshal +func (iter *Iterator) ReadVal(obj interface{}) { + typ := reflect.TypeOf(obj) + cacheKey := typ.Elem() + decoder, err := decoderOfType(iter.cfg, cacheKey) + if err != nil { + iter.Error = err + return + } + e := (*emptyInterface)(unsafe.Pointer(&obj)) + decoder.Decode(e.word, iter) +} + +// WriteVal copy the go interface into underlying JSON, same as json.Marshal +func (stream *Stream) WriteVal(val interface{}) { + if nil == val { + stream.WriteNil() + return + } + typ := reflect.TypeOf(val) + cacheKey := typ + encoder, err := encoderOfType(stream.cfg, cacheKey) + if err != nil { + stream.Error = err + return + } + encoder.EncodeInterface(val, stream) +} + +type prefix string + +func (p prefix) addToDecoder(decoder ValDecoder, err error) (ValDecoder, error) { + if err != nil { + return nil, fmt.Errorf("%s: %s", p, err.Error()) + } + return decoder, err +} + +func (p prefix) addToEncoder(encoder ValEncoder, err error) (ValEncoder, error) { + if err != nil { + return nil, fmt.Errorf("%s: %s", p, err.Error()) + } + return encoder, err +} + +func decoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { + cacheKey := typ + decoder := cfg.getDecoderFromCache(cacheKey) + if decoder != nil { + return decoder, nil + } + decoder = getTypeDecoderFromExtension(typ) + if decoder != nil { + cfg.addDecoderToCache(cacheKey, decoder) + return decoder, nil + } + decoder = &placeholderDecoder{cfg: cfg, cacheKey: cacheKey} + cfg.addDecoderToCache(cacheKey, decoder) + decoder, err := createDecoderOfType(cfg, typ) + for _, extension := range extensions { + decoder = extension.DecorateDecoder(typ, decoder) + } + cfg.addDecoderToCache(cacheKey, decoder) + return decoder, err +} + +func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { + typeName := typ.String() + if typ == jsonRawMessageType { + return &jsonRawMessageCodec{}, nil + } + if typ == jsoniterRawMessageType { + return &jsoniterRawMessageCodec{}, nil + } + if typ.AssignableTo(jsonNumberType) { + return &jsonNumberCodec{}, nil + } + if typ.AssignableTo(jsoniterNumberType) { + return &jsoniterNumberCodec{}, nil + } + if typ.Implements(unmarshalerType) { + templateInterface := reflect.New(typ).Elem().Interface() + var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)} + if typ.Kind() == reflect.Ptr { + decoder = &OptionalDecoder{typ.Elem(), decoder} + } + return decoder, nil + } + if reflect.PtrTo(typ).Implements(unmarshalerType) { + templateInterface := reflect.New(typ).Interface() + var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)} + return decoder, nil + } + if typ.Implements(textUnmarshalerType) { + templateInterface := reflect.New(typ).Elem().Interface() + var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)} + if typ.Kind() == reflect.Ptr { + decoder = &OptionalDecoder{typ.Elem(), decoder} + } + return decoder, nil + } + if reflect.PtrTo(typ).Implements(textUnmarshalerType) { + templateInterface := reflect.New(typ).Interface() + var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)} + return decoder, nil + } + if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 { + sliceDecoder, err := prefix("[slice]").addToDecoder(decoderOfSlice(cfg, typ)) + if err != nil { + return nil, err + } + return &base64Codec{sliceDecoder: sliceDecoder}, nil + } + if typ.Implements(anyType) { + return &anyCodec{}, nil + } + switch typ.Kind() { + case reflect.String: + if typeName != "string" { + return decoderOfType(cfg, reflect.TypeOf((*string)(nil)).Elem()) + } + return &stringCodec{}, nil + case reflect.Int: + if typeName != "int" { + return decoderOfType(cfg, reflect.TypeOf((*int)(nil)).Elem()) + } + return &intCodec{}, nil + case reflect.Int8: + if typeName != "int8" { + return decoderOfType(cfg, reflect.TypeOf((*int8)(nil)).Elem()) + } + return &int8Codec{}, nil + case reflect.Int16: + if typeName != "int16" { + return decoderOfType(cfg, reflect.TypeOf((*int16)(nil)).Elem()) + } + return &int16Codec{}, nil + case reflect.Int32: + if typeName != "int32" { + return decoderOfType(cfg, reflect.TypeOf((*int32)(nil)).Elem()) + } + return &int32Codec{}, nil + case reflect.Int64: + if typeName != "int64" { + return decoderOfType(cfg, reflect.TypeOf((*int64)(nil)).Elem()) + } + return &int64Codec{}, nil + case reflect.Uint: + if typeName != "uint" { + return decoderOfType(cfg, reflect.TypeOf((*uint)(nil)).Elem()) + } + return &uintCodec{}, nil + case reflect.Uint8: + if typeName != "uint8" { + return decoderOfType(cfg, reflect.TypeOf((*uint8)(nil)).Elem()) + } + return &uint8Codec{}, nil + case reflect.Uint16: + if typeName != "uint16" { + return decoderOfType(cfg, reflect.TypeOf((*uint16)(nil)).Elem()) + } + return &uint16Codec{}, nil + case reflect.Uint32: + if typeName != "uint32" { + return decoderOfType(cfg, reflect.TypeOf((*uint32)(nil)).Elem()) + } + return &uint32Codec{}, nil + case reflect.Uintptr: + if typeName != "uintptr" { + return decoderOfType(cfg, reflect.TypeOf((*uintptr)(nil)).Elem()) + } + return &uintptrCodec{}, nil + case reflect.Uint64: + if typeName != "uint64" { + return decoderOfType(cfg, reflect.TypeOf((*uint64)(nil)).Elem()) + } + return &uint64Codec{}, nil + case reflect.Float32: + if typeName != "float32" { + return decoderOfType(cfg, reflect.TypeOf((*float32)(nil)).Elem()) + } + return &float32Codec{}, nil + case reflect.Float64: + if typeName != "float64" { + return decoderOfType(cfg, reflect.TypeOf((*float64)(nil)).Elem()) + } + return &float64Codec{}, nil + case reflect.Bool: + if typeName != "bool" { + return decoderOfType(cfg, reflect.TypeOf((*bool)(nil)).Elem()) + } + return &boolCodec{}, nil + case reflect.Interface: + if typ.NumMethod() == 0 { + return &emptyInterfaceCodec{}, nil + } + return &nonEmptyInterfaceCodec{}, nil + case reflect.Struct: + return prefix(fmt.Sprintf("[%s]", typeName)).addToDecoder(decoderOfStruct(cfg, typ)) + case reflect.Array: + return prefix("[array]").addToDecoder(decoderOfArray(cfg, typ)) + case reflect.Slice: + return prefix("[slice]").addToDecoder(decoderOfSlice(cfg, typ)) + case reflect.Map: + return prefix("[map]").addToDecoder(decoderOfMap(cfg, typ)) + case reflect.Ptr: + return prefix("[optional]").addToDecoder(decoderOfOptional(cfg, typ)) + default: + return nil, fmt.Errorf("unsupported type: %v", typ) + } +} + +func encoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { + cacheKey := typ + encoder := cfg.getEncoderFromCache(cacheKey) + if encoder != nil { + return encoder, nil + } + encoder = getTypeEncoderFromExtension(typ) + if encoder != nil { + cfg.addEncoderToCache(cacheKey, encoder) + return encoder, nil + } + encoder = &placeholderEncoder{cfg: cfg, cacheKey: cacheKey} + cfg.addEncoderToCache(cacheKey, encoder) + encoder, err := createEncoderOfType(cfg, typ) + for _, extension := range extensions { + encoder = extension.DecorateEncoder(typ, encoder) + } + cfg.addEncoderToCache(cacheKey, encoder) + return encoder, err +} + +func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { + if typ == jsonRawMessageType { + return &jsonRawMessageCodec{}, nil + } + if typ == jsoniterRawMessageType { + return &jsoniterRawMessageCodec{}, nil + } + if typ.AssignableTo(jsonNumberType) { + return &jsonNumberCodec{}, nil + } + if typ.AssignableTo(jsoniterNumberType) { + return &jsoniterNumberCodec{}, nil + } + if typ.Implements(marshalerType) { + checkIsEmpty, err := createCheckIsEmpty(typ) + if err != nil { + return nil, err + } + templateInterface := reflect.New(typ).Elem().Interface() + var encoder ValEncoder = &marshalerEncoder{ + templateInterface: extractInterface(templateInterface), + checkIsEmpty: checkIsEmpty, + } + if typ.Kind() == reflect.Ptr { + encoder = &OptionalEncoder{encoder} + } + return encoder, nil + } + if reflect.PtrTo(typ).Implements(marshalerType) { + checkIsEmpty, err := createCheckIsEmpty(reflect.PtrTo(typ)) + if err != nil { + return nil, err + } + templateInterface := reflect.New(typ).Interface() + var encoder ValEncoder = &marshalerEncoder{ + templateInterface: extractInterface(templateInterface), + checkIsEmpty: checkIsEmpty, + } + return encoder, nil + } + if typ.Implements(textMarshalerType) { + checkIsEmpty, err := createCheckIsEmpty(typ) + if err != nil { + return nil, err + } + templateInterface := reflect.New(typ).Elem().Interface() + var encoder ValEncoder = &textMarshalerEncoder{ + templateInterface: extractInterface(templateInterface), + checkIsEmpty: checkIsEmpty, + } + if typ.Kind() == reflect.Ptr { + encoder = &OptionalEncoder{encoder} + } + return encoder, nil + } + if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 { + return &base64Codec{}, nil + } + if typ.Implements(anyType) { + return &anyCodec{}, nil + } + return createEncoderOfSimpleType(cfg, typ) +} + +func createCheckIsEmpty(typ reflect.Type) (checkIsEmpty, error) { + kind := typ.Kind() + switch kind { + case reflect.String: + return &stringCodec{}, nil + case reflect.Int: + return &intCodec{}, nil + case reflect.Int8: + return &int8Codec{}, nil + case reflect.Int16: + return &int16Codec{}, nil + case reflect.Int32: + return &int32Codec{}, nil + case reflect.Int64: + return &int64Codec{}, nil + case reflect.Uint: + return &uintCodec{}, nil + case reflect.Uint8: + return &uint8Codec{}, nil + case reflect.Uint16: + return &uint16Codec{}, nil + case reflect.Uint32: + return &uint32Codec{}, nil + case reflect.Uintptr: + return &uintptrCodec{}, nil + case reflect.Uint64: + return &uint64Codec{}, nil + case reflect.Float32: + return &float32Codec{}, nil + case reflect.Float64: + return &float64Codec{}, nil + case reflect.Bool: + return &boolCodec{}, nil + case reflect.Interface: + if typ.NumMethod() == 0 { + return &emptyInterfaceCodec{}, nil + } + return &nonEmptyInterfaceCodec{}, nil + case reflect.Struct: + return &structEncoder{}, nil + case reflect.Array: + return &arrayEncoder{}, nil + case reflect.Slice: + return &sliceEncoder{}, nil + case reflect.Map: + return &mapEncoder{}, nil + case reflect.Ptr: + return &OptionalEncoder{}, nil + default: + return nil, fmt.Errorf("unsupported type: %v", typ) + } +} + +func createEncoderOfSimpleType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { + typeName := typ.String() + kind := typ.Kind() + switch kind { + case reflect.String: + if typeName != "string" { + return encoderOfType(cfg, reflect.TypeOf((*string)(nil)).Elem()) + } + return &stringCodec{}, nil + case reflect.Int: + if typeName != "int" { + return encoderOfType(cfg, reflect.TypeOf((*int)(nil)).Elem()) + } + return &intCodec{}, nil + case reflect.Int8: + if typeName != "int8" { + return encoderOfType(cfg, reflect.TypeOf((*int8)(nil)).Elem()) + } + return &int8Codec{}, nil + case reflect.Int16: + if typeName != "int16" { + return encoderOfType(cfg, reflect.TypeOf((*int16)(nil)).Elem()) + } + return &int16Codec{}, nil + case reflect.Int32: + if typeName != "int32" { + return encoderOfType(cfg, reflect.TypeOf((*int32)(nil)).Elem()) + } + return &int32Codec{}, nil + case reflect.Int64: + if typeName != "int64" { + return encoderOfType(cfg, reflect.TypeOf((*int64)(nil)).Elem()) + } + return &int64Codec{}, nil + case reflect.Uint: + if typeName != "uint" { + return encoderOfType(cfg, reflect.TypeOf((*uint)(nil)).Elem()) + } + return &uintCodec{}, nil + case reflect.Uint8: + if typeName != "uint8" { + return encoderOfType(cfg, reflect.TypeOf((*uint8)(nil)).Elem()) + } + return &uint8Codec{}, nil + case reflect.Uint16: + if typeName != "uint16" { + return encoderOfType(cfg, reflect.TypeOf((*uint16)(nil)).Elem()) + } + return &uint16Codec{}, nil + case reflect.Uint32: + if typeName != "uint32" { + return encoderOfType(cfg, reflect.TypeOf((*uint32)(nil)).Elem()) + } + return &uint32Codec{}, nil + case reflect.Uintptr: + if typeName != "uintptr" { + return encoderOfType(cfg, reflect.TypeOf((*uintptr)(nil)).Elem()) + } + return &uintptrCodec{}, nil + case reflect.Uint64: + if typeName != "uint64" { + return encoderOfType(cfg, reflect.TypeOf((*uint64)(nil)).Elem()) + } + return &uint64Codec{}, nil + case reflect.Float32: + if typeName != "float32" { + return encoderOfType(cfg, reflect.TypeOf((*float32)(nil)).Elem()) + } + return &float32Codec{}, nil + case reflect.Float64: + if typeName != "float64" { + return encoderOfType(cfg, reflect.TypeOf((*float64)(nil)).Elem()) + } + return &float64Codec{}, nil + case reflect.Bool: + if typeName != "bool" { + return encoderOfType(cfg, reflect.TypeOf((*bool)(nil)).Elem()) + } + return &boolCodec{}, nil + case reflect.Interface: + if typ.NumMethod() == 0 { + return &emptyInterfaceCodec{}, nil + } + return &nonEmptyInterfaceCodec{}, nil + case reflect.Struct: + return prefix(fmt.Sprintf("[%s]", typeName)).addToEncoder(encoderOfStruct(cfg, typ)) + case reflect.Array: + return prefix("[array]").addToEncoder(encoderOfArray(cfg, typ)) + case reflect.Slice: + return prefix("[slice]").addToEncoder(encoderOfSlice(cfg, typ)) + case reflect.Map: + return prefix("[map]").addToEncoder(encoderOfMap(cfg, typ)) + case reflect.Ptr: + return prefix("[optional]").addToEncoder(encoderOfOptional(cfg, typ)) + default: + return nil, fmt.Errorf("unsupported type: %v", typ) + } +} + +func decoderOfOptional(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { + elemType := typ.Elem() + decoder, err := decoderOfType(cfg, elemType) + if err != nil { + return nil, err + } + return &OptionalDecoder{elemType, decoder}, nil +} + +func encoderOfOptional(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { + elemType := typ.Elem() + elemEncoder, err := encoderOfType(cfg, elemType) + if err != nil { + return nil, err + } + encoder := &OptionalEncoder{elemEncoder} + if elemType.Kind() == reflect.Map { + encoder = &OptionalEncoder{encoder} + } + return encoder, nil +} + +func decoderOfMap(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { + decoder, err := decoderOfType(cfg, typ.Elem()) + if err != nil { + return nil, err + } + mapInterface := reflect.New(typ).Interface() + return &mapDecoder{typ, typ.Key(), typ.Elem(), decoder, extractInterface(mapInterface)}, nil +} + +func extractInterface(val interface{}) emptyInterface { + return *((*emptyInterface)(unsafe.Pointer(&val))) +} + +func encoderOfMap(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { + elemType := typ.Elem() + encoder, err := encoderOfType(cfg, elemType) + if err != nil { + return nil, err + } + mapInterface := reflect.New(typ).Elem().Interface() + if cfg.sortMapKeys { + return &sortKeysMapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil + } + return &mapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_reflect_array.go b/backend/vendor/github.com/json-iterator/go/feature_reflect_array.go new file mode 100644 index 0000000000..d661fb6fe5 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_reflect_array.go @@ -0,0 +1,99 @@ +package jsoniter + +import ( + "fmt" + "io" + "reflect" + "unsafe" +) + +func decoderOfArray(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { + decoder, err := decoderOfType(cfg, typ.Elem()) + if err != nil { + return nil, err + } + return &arrayDecoder{typ, typ.Elem(), decoder}, nil +} + +func encoderOfArray(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { + encoder, err := encoderOfType(cfg, typ.Elem()) + if err != nil { + return nil, err + } + if typ.Elem().Kind() == reflect.Map { + encoder = &OptionalEncoder{encoder} + } + return &arrayEncoder{typ, typ.Elem(), encoder}, nil +} + +type arrayEncoder struct { + arrayType reflect.Type + elemType reflect.Type + elemEncoder ValEncoder +} + +func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteArrayStart() + elemPtr := unsafe.Pointer(ptr) + encoder.elemEncoder.Encode(elemPtr, stream) + for i := 1; i < encoder.arrayType.Len(); i++ { + stream.WriteMore() + elemPtr = unsafe.Pointer(uintptr(elemPtr) + encoder.elemType.Size()) + encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream) + } + stream.WriteArrayEnd() + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error()) + } +} + +func (encoder *arrayEncoder) EncodeInterface(val interface{}, stream *Stream) { + // special optimization for interface{} + e := (*emptyInterface)(unsafe.Pointer(&val)) + if e.word == nil { + stream.WriteArrayStart() + stream.WriteNil() + stream.WriteArrayEnd() + return + } + elemType := encoder.arrayType.Elem() + if encoder.arrayType.Len() == 1 && (elemType.Kind() == reflect.Ptr || elemType.Kind() == reflect.Map) { + ptr := uintptr(e.word) + e.word = unsafe.Pointer(&ptr) + } + if reflect.TypeOf(val).Kind() == reflect.Ptr { + encoder.Encode(unsafe.Pointer(&e.word), stream) + } else { + encoder.Encode(e.word, stream) + } +} + +func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type arrayDecoder struct { + arrayType reflect.Type + elemType reflect.Type + elemDecoder ValDecoder +} + +func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.doDecode(ptr, iter) + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error()) + } +} + +func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) { + offset := uintptr(0) + iter.ReadArrayCB(func(iter *Iterator) bool { + if offset < decoder.arrayType.Size() { + decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(ptr)+offset), iter) + offset += decoder.elemType.Size() + } else { + iter.Skip() + } + return true + }) +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_reflect_extension.go b/backend/vendor/github.com/json-iterator/go/feature_reflect_extension.go new file mode 100644 index 0000000000..177df2c812 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_reflect_extension.go @@ -0,0 +1,414 @@ +package jsoniter + +import ( + "fmt" + "reflect" + "sort" + "strings" + "unicode" + "unsafe" +) + +var typeDecoders = map[string]ValDecoder{} +var fieldDecoders = map[string]ValDecoder{} +var typeEncoders = map[string]ValEncoder{} +var fieldEncoders = map[string]ValEncoder{} +var extensions = []Extension{} + +// StructDescriptor describe how should we encode/decode the struct +type StructDescriptor struct { + onePtrEmbedded bool + onePtrOptimization bool + Type reflect.Type + Fields []*Binding +} + +// GetField get one field from the descriptor by its name. +// Can not use map here to keep field orders. +func (structDescriptor *StructDescriptor) GetField(fieldName string) *Binding { + for _, binding := range structDescriptor.Fields { + if binding.Field.Name == fieldName { + return binding + } + } + return nil +} + +// Binding describe how should we encode/decode the struct field +type Binding struct { + levels []int + Field *reflect.StructField + FromNames []string + ToNames []string + Encoder ValEncoder + Decoder ValDecoder +} + +// Extension the one for all SPI. Customize encoding/decoding by specifying alternate encoder/decoder. +// Can also rename fields by UpdateStructDescriptor. +type Extension interface { + UpdateStructDescriptor(structDescriptor *StructDescriptor) + CreateDecoder(typ reflect.Type) ValDecoder + CreateEncoder(typ reflect.Type) ValEncoder + DecorateDecoder(typ reflect.Type, decoder ValDecoder) ValDecoder + DecorateEncoder(typ reflect.Type, encoder ValEncoder) ValEncoder +} + +// DummyExtension embed this type get dummy implementation for all methods of Extension +type DummyExtension struct { +} + +// UpdateStructDescriptor No-op +func (extension *DummyExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { +} + +// CreateDecoder No-op +func (extension *DummyExtension) CreateDecoder(typ reflect.Type) ValDecoder { + return nil +} + +// CreateEncoder No-op +func (extension *DummyExtension) CreateEncoder(typ reflect.Type) ValEncoder { + return nil +} + +// DecorateDecoder No-op +func (extension *DummyExtension) DecorateDecoder(typ reflect.Type, decoder ValDecoder) ValDecoder { + return decoder +} + +// DecorateEncoder No-op +func (extension *DummyExtension) DecorateEncoder(typ reflect.Type, encoder ValEncoder) ValEncoder { + return encoder +} + +type funcDecoder struct { + fun DecoderFunc +} + +func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.fun(ptr, iter) +} + +type funcEncoder struct { + fun EncoderFunc + isEmptyFunc func(ptr unsafe.Pointer) bool +} + +func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + encoder.fun(ptr, stream) +} + +func (encoder *funcEncoder) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, encoder) +} + +func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool { + if encoder.isEmptyFunc == nil { + return false + } + return encoder.isEmptyFunc(ptr) +} + +// DecoderFunc the function form of TypeDecoder +type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator) + +// EncoderFunc the function form of TypeEncoder +type EncoderFunc func(ptr unsafe.Pointer, stream *Stream) + +// RegisterTypeDecoderFunc register TypeDecoder for a type with function +func RegisterTypeDecoderFunc(typ string, fun DecoderFunc) { + typeDecoders[typ] = &funcDecoder{fun} +} + +// RegisterTypeDecoder register TypeDecoder for a typ +func RegisterTypeDecoder(typ string, decoder ValDecoder) { + typeDecoders[typ] = decoder +} + +// RegisterFieldDecoderFunc register TypeDecoder for a struct field with function +func RegisterFieldDecoderFunc(typ string, field string, fun DecoderFunc) { + RegisterFieldDecoder(typ, field, &funcDecoder{fun}) +} + +// RegisterFieldDecoder register TypeDecoder for a struct field +func RegisterFieldDecoder(typ string, field string, decoder ValDecoder) { + fieldDecoders[fmt.Sprintf("%s/%s", typ, field)] = decoder +} + +// RegisterTypeEncoderFunc register TypeEncoder for a type with encode/isEmpty function +func RegisterTypeEncoderFunc(typ string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) { + typeEncoders[typ] = &funcEncoder{fun, isEmptyFunc} +} + +// RegisterTypeEncoder register TypeEncoder for a type +func RegisterTypeEncoder(typ string, encoder ValEncoder) { + typeEncoders[typ] = encoder +} + +// RegisterFieldEncoderFunc register TypeEncoder for a struct field with encode/isEmpty function +func RegisterFieldEncoderFunc(typ string, field string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) { + RegisterFieldEncoder(typ, field, &funcEncoder{fun, isEmptyFunc}) +} + +// RegisterFieldEncoder register TypeEncoder for a struct field +func RegisterFieldEncoder(typ string, field string, encoder ValEncoder) { + fieldEncoders[fmt.Sprintf("%s/%s", typ, field)] = encoder +} + +// RegisterExtension register extension +func RegisterExtension(extension Extension) { + extensions = append(extensions, extension) +} + +func getTypeDecoderFromExtension(typ reflect.Type) ValDecoder { + decoder := _getTypeDecoderFromExtension(typ) + if decoder != nil { + for _, extension := range extensions { + decoder = extension.DecorateDecoder(typ, decoder) + } + } + return decoder +} +func _getTypeDecoderFromExtension(typ reflect.Type) ValDecoder { + for _, extension := range extensions { + decoder := extension.CreateDecoder(typ) + if decoder != nil { + return decoder + } + } + typeName := typ.String() + decoder := typeDecoders[typeName] + if decoder != nil { + return decoder + } + if typ.Kind() == reflect.Ptr { + decoder := typeDecoders[typ.Elem().String()] + if decoder != nil { + return &OptionalDecoder{typ.Elem(), decoder} + } + } + return nil +} + +func getTypeEncoderFromExtension(typ reflect.Type) ValEncoder { + encoder := _getTypeEncoderFromExtension(typ) + if encoder != nil { + for _, extension := range extensions { + encoder = extension.DecorateEncoder(typ, encoder) + } + } + return encoder +} + +func _getTypeEncoderFromExtension(typ reflect.Type) ValEncoder { + for _, extension := range extensions { + encoder := extension.CreateEncoder(typ) + if encoder != nil { + return encoder + } + } + typeName := typ.String() + encoder := typeEncoders[typeName] + if encoder != nil { + return encoder + } + if typ.Kind() == reflect.Ptr { + encoder := typeEncoders[typ.Elem().String()] + if encoder != nil { + return &OptionalEncoder{encoder} + } + } + return nil +} + +func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, error) { + embeddedBindings := []*Binding{} + bindings := []*Binding{} + for i := 0; i < typ.NumField(); i++ { + field := typ.Field(i) + tag := field.Tag.Get(cfg.getTagKey()) + tagParts := strings.Split(tag, ",") + if tag == "-" { + continue + } + if field.Anonymous && (tag == "" || tagParts[0] == "") { + if field.Type.Kind() == reflect.Struct { + structDescriptor, err := describeStruct(cfg, field.Type) + if err != nil { + return nil, err + } + for _, binding := range structDescriptor.Fields { + binding.levels = append([]int{i}, binding.levels...) + omitempty := binding.Encoder.(*structFieldEncoder).omitempty + binding.Encoder = &structFieldEncoder{&field, binding.Encoder, omitempty} + binding.Decoder = &structFieldDecoder{&field, binding.Decoder} + embeddedBindings = append(embeddedBindings, binding) + } + continue + } else if field.Type.Kind() == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct { + structDescriptor, err := describeStruct(cfg, field.Type.Elem()) + if err != nil { + return nil, err + } + for _, binding := range structDescriptor.Fields { + binding.levels = append([]int{i}, binding.levels...) + omitempty := binding.Encoder.(*structFieldEncoder).omitempty + binding.Encoder = &OptionalEncoder{binding.Encoder} + binding.Encoder = &structFieldEncoder{&field, binding.Encoder, omitempty} + binding.Decoder = &deferenceDecoder{field.Type.Elem(), binding.Decoder} + binding.Decoder = &structFieldDecoder{&field, binding.Decoder} + embeddedBindings = append(embeddedBindings, binding) + } + continue + } + } + fieldNames := calcFieldNames(field.Name, tagParts[0], tag) + fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name) + decoder := fieldDecoders[fieldCacheKey] + if decoder == nil { + var err error + decoder, err = decoderOfType(cfg, field.Type) + if len(fieldNames) > 0 && err != nil { + return nil, err + } + } + encoder := fieldEncoders[fieldCacheKey] + if encoder == nil { + var err error + encoder, err = encoderOfType(cfg, field.Type) + if len(fieldNames) > 0 && err != nil { + return nil, err + } + // map is stored as pointer in the struct, + // and treat nil or empty map as empty field + if encoder != nil && field.Type.Kind() == reflect.Map { + encoder = &optionalMapEncoder{encoder} + } + } + binding := &Binding{ + Field: &field, + FromNames: fieldNames, + ToNames: fieldNames, + Decoder: decoder, + Encoder: encoder, + } + binding.levels = []int{i} + bindings = append(bindings, binding) + } + return createStructDescriptor(cfg, typ, bindings, embeddedBindings), nil +} +func createStructDescriptor(cfg *frozenConfig, typ reflect.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor { + onePtrEmbedded := false + onePtrOptimization := false + if typ.NumField() == 1 { + firstField := typ.Field(0) + switch firstField.Type.Kind() { + case reflect.Ptr: + if firstField.Anonymous && firstField.Type.Elem().Kind() == reflect.Struct { + onePtrEmbedded = true + } + fallthrough + case reflect.Map: + onePtrOptimization = true + case reflect.Struct: + onePtrOptimization = isStructOnePtr(firstField.Type) + } + } + structDescriptor := &StructDescriptor{ + onePtrEmbedded: onePtrEmbedded, + onePtrOptimization: onePtrOptimization, + Type: typ, + Fields: bindings, + } + for _, extension := range extensions { + extension.UpdateStructDescriptor(structDescriptor) + } + processTags(structDescriptor, cfg) + // merge normal & embedded bindings & sort with original order + allBindings := sortableBindings(append(embeddedBindings, structDescriptor.Fields...)) + sort.Sort(allBindings) + structDescriptor.Fields = allBindings + return structDescriptor +} + +func isStructOnePtr(typ reflect.Type) bool { + if typ.NumField() == 1 { + firstField := typ.Field(0) + switch firstField.Type.Kind() { + case reflect.Ptr: + return true + case reflect.Map: + return true + case reflect.Struct: + return isStructOnePtr(firstField.Type) + } + } + return false +} + +type sortableBindings []*Binding + +func (bindings sortableBindings) Len() int { + return len(bindings) +} + +func (bindings sortableBindings) Less(i, j int) bool { + left := bindings[i].levels + right := bindings[j].levels + k := 0 + for { + if left[k] < right[k] { + return true + } else if left[k] > right[k] { + return false + } + k++ + } +} + +func (bindings sortableBindings) Swap(i, j int) { + bindings[i], bindings[j] = bindings[j], bindings[i] +} + +func processTags(structDescriptor *StructDescriptor, cfg *frozenConfig) { + for _, binding := range structDescriptor.Fields { + shouldOmitEmpty := false + tagParts := strings.Split(binding.Field.Tag.Get(cfg.getTagKey()), ",") + for _, tagPart := range tagParts[1:] { + if tagPart == "omitempty" { + shouldOmitEmpty = true + } else if tagPart == "string" { + if binding.Field.Type.Kind() == reflect.String { + binding.Decoder = &stringModeStringDecoder{binding.Decoder, cfg} + binding.Encoder = &stringModeStringEncoder{binding.Encoder, cfg} + } else { + binding.Decoder = &stringModeNumberDecoder{binding.Decoder} + binding.Encoder = &stringModeNumberEncoder{binding.Encoder} + } + } + } + binding.Decoder = &structFieldDecoder{binding.Field, binding.Decoder} + binding.Encoder = &structFieldEncoder{binding.Field, binding.Encoder, shouldOmitEmpty} + } +} + +func calcFieldNames(originalFieldName string, tagProvidedFieldName string, wholeTag string) []string { + // ignore? + if wholeTag == "-" { + return []string{} + } + // rename? + var fieldNames []string + if tagProvidedFieldName == "" { + fieldNames = []string{originalFieldName} + } else { + fieldNames = []string{tagProvidedFieldName} + } + // private? + isNotExported := unicode.IsLower(rune(originalFieldName[0])) + if isNotExported { + fieldNames = []string{} + } + return fieldNames +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_reflect_map.go b/backend/vendor/github.com/json-iterator/go/feature_reflect_map.go new file mode 100644 index 0000000000..005671e01b --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_reflect_map.go @@ -0,0 +1,244 @@ +package jsoniter + +import ( + "encoding" + "encoding/json" + "reflect" + "sort" + "strconv" + "unsafe" +) + +type mapDecoder struct { + mapType reflect.Type + keyType reflect.Type + elemType reflect.Type + elemDecoder ValDecoder + mapInterface emptyInterface +} + +func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + // dark magic to cast unsafe.Pointer back to interface{} using reflect.Type + mapInterface := decoder.mapInterface + mapInterface.word = ptr + realInterface := (*interface{})(unsafe.Pointer(&mapInterface)) + realVal := reflect.ValueOf(*realInterface).Elem() + if iter.ReadNil() { + realVal.Set(reflect.Zero(decoder.mapType)) + return + } + if realVal.IsNil() { + realVal.Set(reflect.MakeMap(realVal.Type())) + } + iter.ReadMapCB(func(iter *Iterator, keyStr string) bool { + elem := reflect.New(decoder.elemType) + decoder.elemDecoder.Decode(unsafe.Pointer(elem.Pointer()), iter) + // to put into map, we have to use reflection + keyType := decoder.keyType + // TODO: remove this from loop + switch { + case keyType.Kind() == reflect.String: + realVal.SetMapIndex(reflect.ValueOf(keyStr).Convert(keyType), elem.Elem()) + return true + case keyType.Implements(textUnmarshalerType): + textUnmarshaler := reflect.New(keyType.Elem()).Interface().(encoding.TextUnmarshaler) + err := textUnmarshaler.UnmarshalText([]byte(keyStr)) + if err != nil { + iter.ReportError("read map key as TextUnmarshaler", err.Error()) + return false + } + realVal.SetMapIndex(reflect.ValueOf(textUnmarshaler), elem.Elem()) + return true + case reflect.PtrTo(keyType).Implements(textUnmarshalerType): + textUnmarshaler := reflect.New(keyType).Interface().(encoding.TextUnmarshaler) + err := textUnmarshaler.UnmarshalText([]byte(keyStr)) + if err != nil { + iter.ReportError("read map key as TextUnmarshaler", err.Error()) + return false + } + realVal.SetMapIndex(reflect.ValueOf(textUnmarshaler).Elem(), elem.Elem()) + return true + default: + switch keyType.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + n, err := strconv.ParseInt(keyStr, 10, 64) + if err != nil || reflect.Zero(keyType).OverflowInt(n) { + iter.ReportError("read map key as int64", "read int64 failed") + return false + } + realVal.SetMapIndex(reflect.ValueOf(n).Convert(keyType), elem.Elem()) + return true + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + n, err := strconv.ParseUint(keyStr, 10, 64) + if err != nil || reflect.Zero(keyType).OverflowUint(n) { + iter.ReportError("read map key as uint64", "read uint64 failed") + return false + } + realVal.SetMapIndex(reflect.ValueOf(n).Convert(keyType), elem.Elem()) + return true + } + } + iter.ReportError("read map key", "unexpected map key type "+keyType.String()) + return true + }) +} + +type mapEncoder struct { + mapType reflect.Type + elemType reflect.Type + elemEncoder ValEncoder + mapInterface emptyInterface +} + +func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + mapInterface := encoder.mapInterface + mapInterface.word = ptr + realInterface := (*interface{})(unsafe.Pointer(&mapInterface)) + realVal := reflect.ValueOf(*realInterface) + stream.WriteObjectStart() + for i, key := range realVal.MapKeys() { + if i != 0 { + stream.WriteMore() + } + encodeMapKey(key, stream) + if stream.indention > 0 { + stream.writeTwoBytes(byte(':'), byte(' ')) + } else { + stream.writeByte(':') + } + val := realVal.MapIndex(key).Interface() + encoder.elemEncoder.EncodeInterface(val, stream) + } + stream.WriteObjectEnd() +} + +func encodeMapKey(key reflect.Value, stream *Stream) { + if key.Kind() == reflect.String { + stream.WriteString(key.String()) + return + } + if tm, ok := key.Interface().(encoding.TextMarshaler); ok { + buf, err := tm.MarshalText() + if err != nil { + stream.Error = err + return + } + stream.writeByte('"') + stream.Write(buf) + stream.writeByte('"') + return + } + switch key.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + stream.writeByte('"') + stream.WriteInt64(key.Int()) + stream.writeByte('"') + return + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + stream.writeByte('"') + stream.WriteUint64(key.Uint()) + stream.writeByte('"') + return + } + stream.Error = &json.UnsupportedTypeError{Type: key.Type()} +} + +func (encoder *mapEncoder) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, encoder) +} + +func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool { + mapInterface := encoder.mapInterface + mapInterface.word = ptr + realInterface := (*interface{})(unsafe.Pointer(&mapInterface)) + realVal := reflect.ValueOf(*realInterface) + return realVal.Len() == 0 +} + +type sortKeysMapEncoder struct { + mapType reflect.Type + elemType reflect.Type + elemEncoder ValEncoder + mapInterface emptyInterface +} + +func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + mapInterface := encoder.mapInterface + mapInterface.word = ptr + realInterface := (*interface{})(unsafe.Pointer(&mapInterface)) + realVal := reflect.ValueOf(*realInterface) + + // Extract and sort the keys. + keys := realVal.MapKeys() + sv := stringValues(make([]reflectWithString, len(keys))) + for i, v := range keys { + sv[i].v = v + if err := sv[i].resolve(); err != nil { + stream.Error = err + return + } + } + sort.Sort(sv) + + stream.WriteObjectStart() + for i, key := range sv { + if i != 0 { + stream.WriteMore() + } + stream.WriteVal(key.s) // might need html escape, so can not WriteString directly + if stream.indention > 0 { + stream.writeTwoBytes(byte(':'), byte(' ')) + } else { + stream.writeByte(':') + } + val := realVal.MapIndex(key.v).Interface() + encoder.elemEncoder.EncodeInterface(val, stream) + } + stream.WriteObjectEnd() +} + +// stringValues is a slice of reflect.Value holding *reflect.StringValue. +// It implements the methods to sort by string. +type stringValues []reflectWithString + +type reflectWithString struct { + v reflect.Value + s string +} + +func (w *reflectWithString) resolve() error { + if w.v.Kind() == reflect.String { + w.s = w.v.String() + return nil + } + if tm, ok := w.v.Interface().(encoding.TextMarshaler); ok { + buf, err := tm.MarshalText() + w.s = string(buf) + return err + } + switch w.v.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + w.s = strconv.FormatInt(w.v.Int(), 10) + return nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + w.s = strconv.FormatUint(w.v.Uint(), 10) + return nil + } + return &json.UnsupportedTypeError{Type: w.v.Type()} +} + +func (sv stringValues) Len() int { return len(sv) } +func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } +func (sv stringValues) Less(i, j int) bool { return sv[i].s < sv[j].s } + +func (encoder *sortKeysMapEncoder) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, encoder) +} + +func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool { + mapInterface := encoder.mapInterface + mapInterface.word = ptr + realInterface := (*interface{})(unsafe.Pointer(&mapInterface)) + realVal := reflect.ValueOf(*realInterface) + return realVal.Len() == 0 +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_reflect_native.go b/backend/vendor/github.com/json-iterator/go/feature_reflect_native.go new file mode 100644 index 0000000000..95bd1e87cc --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_reflect_native.go @@ -0,0 +1,764 @@ +package jsoniter + +import ( + "encoding" + "encoding/base64" + "encoding/json" + "reflect" + "unsafe" +) + +type stringCodec struct { +} + +func (codec *stringCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *((*string)(ptr)) = iter.ReadString() +} + +func (codec *stringCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + str := *((*string)(ptr)) + stream.WriteString(str) +} + +func (codec *stringCodec) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, codec) +} + +func (codec *stringCodec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*string)(ptr)) == "" +} + +type intCodec struct { +} + +func (codec *intCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int)(ptr)) = iter.ReadInt() + } +} + +func (codec *intCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt(*((*int)(ptr))) +} + +func (codec *intCodec) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, codec) +} + +func (codec *intCodec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int)(ptr)) == 0 +} + +type uintptrCodec struct { +} + +func (codec *uintptrCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uintptr)(ptr)) = uintptr(iter.ReadUint64()) + } +} + +func (codec *uintptrCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint64(uint64(*((*uintptr)(ptr)))) +} + +func (codec *uintptrCodec) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, codec) +} + +func (codec *uintptrCodec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uintptr)(ptr)) == 0 +} + +type int8Codec struct { +} + +func (codec *int8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int8)(ptr)) = iter.ReadInt8() + } +} + +func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt8(*((*int8)(ptr))) +} + +func (codec *int8Codec) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, codec) +} + +func (codec *int8Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int8)(ptr)) == 0 +} + +type int16Codec struct { +} + +func (codec *int16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int16)(ptr)) = iter.ReadInt16() + } +} + +func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt16(*((*int16)(ptr))) +} + +func (codec *int16Codec) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, codec) +} + +func (codec *int16Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int16)(ptr)) == 0 +} + +type int32Codec struct { +} + +func (codec *int32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int32)(ptr)) = iter.ReadInt32() + } +} + +func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt32(*((*int32)(ptr))) +} + +func (codec *int32Codec) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, codec) +} + +func (codec *int32Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int32)(ptr)) == 0 +} + +type int64Codec struct { +} + +func (codec *int64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int64)(ptr)) = iter.ReadInt64() + } +} + +func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt64(*((*int64)(ptr))) +} + +func (codec *int64Codec) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, codec) +} + +func (codec *int64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int64)(ptr)) == 0 +} + +type uintCodec struct { +} + +func (codec *uintCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint)(ptr)) = iter.ReadUint() + return + } +} + +func (codec *uintCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint(*((*uint)(ptr))) +} + +func (codec *uintCodec) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, codec) +} + +func (codec *uintCodec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint)(ptr)) == 0 +} + +type uint8Codec struct { +} + +func (codec *uint8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint8)(ptr)) = iter.ReadUint8() + } +} + +func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint8(*((*uint8)(ptr))) +} + +func (codec *uint8Codec) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, codec) +} + +func (codec *uint8Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint8)(ptr)) == 0 +} + +type uint16Codec struct { +} + +func (codec *uint16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint16)(ptr)) = iter.ReadUint16() + } +} + +func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint16(*((*uint16)(ptr))) +} + +func (codec *uint16Codec) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, codec) +} + +func (codec *uint16Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint16)(ptr)) == 0 +} + +type uint32Codec struct { +} + +func (codec *uint32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint32)(ptr)) = iter.ReadUint32() + } +} + +func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint32(*((*uint32)(ptr))) +} + +func (codec *uint32Codec) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, codec) +} + +func (codec *uint32Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint32)(ptr)) == 0 +} + +type uint64Codec struct { +} + +func (codec *uint64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint64)(ptr)) = iter.ReadUint64() + } +} + +func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint64(*((*uint64)(ptr))) +} + +func (codec *uint64Codec) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, codec) +} + +func (codec *uint64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint64)(ptr)) == 0 +} + +type float32Codec struct { +} + +func (codec *float32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*float32)(ptr)) = iter.ReadFloat32() + } +} + +func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat32(*((*float32)(ptr))) +} + +func (codec *float32Codec) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, codec) +} + +func (codec *float32Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float32)(ptr)) == 0 +} + +type float64Codec struct { +} + +func (codec *float64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*float64)(ptr)) = iter.ReadFloat64() + } +} + +func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat64(*((*float64)(ptr))) +} + +func (codec *float64Codec) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, codec) +} + +func (codec *float64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float64)(ptr)) == 0 +} + +type boolCodec struct { +} + +func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*bool)(ptr)) = iter.ReadBool() + } +} + +func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteBool(*((*bool)(ptr))) +} + +func (codec *boolCodec) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, codec) +} + +func (codec *boolCodec) IsEmpty(ptr unsafe.Pointer) bool { + return !(*((*bool)(ptr))) +} + +type emptyInterfaceCodec struct { +} + +func (codec *emptyInterfaceCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + existing := *((*interface{})(ptr)) + + // Checking for both typed and untyped nil pointers. + if existing != nil && + reflect.TypeOf(existing).Kind() == reflect.Ptr && + !reflect.ValueOf(existing).IsNil() { + + var ptrToExisting interface{} + for { + elem := reflect.ValueOf(existing).Elem() + if elem.Kind() != reflect.Ptr || elem.IsNil() { + break + } + ptrToExisting = existing + existing = elem.Interface() + } + + if iter.ReadNil() { + if ptrToExisting != nil { + nilPtr := reflect.Zero(reflect.TypeOf(ptrToExisting).Elem()) + reflect.ValueOf(ptrToExisting).Elem().Set(nilPtr) + } else { + *((*interface{})(ptr)) = nil + } + } else { + iter.ReadVal(existing) + } + + return + } + + if iter.ReadNil() { + *((*interface{})(ptr)) = nil + } else { + *((*interface{})(ptr)) = iter.Read() + } +} + +func (codec *emptyInterfaceCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteVal(*((*interface{})(ptr))) +} + +func (codec *emptyInterfaceCodec) EncodeInterface(val interface{}, stream *Stream) { + stream.WriteVal(val) +} + +func (codec *emptyInterfaceCodec) IsEmpty(ptr unsafe.Pointer) bool { + emptyInterface := (*emptyInterface)(ptr) + return emptyInterface.typ == nil +} + +type nonEmptyInterfaceCodec struct { +} + +func (codec *nonEmptyInterfaceCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + nonEmptyInterface := (*nonEmptyInterface)(ptr) + if nonEmptyInterface.itab == nil { + iter.ReportError("read non-empty interface", "do not know which concrete type to decode to") + return + } + var i interface{} + e := (*emptyInterface)(unsafe.Pointer(&i)) + e.typ = nonEmptyInterface.itab.typ + e.word = nonEmptyInterface.word + iter.ReadVal(&i) + if e.word == nil { + nonEmptyInterface.itab = nil + } + nonEmptyInterface.word = e.word +} + +func (codec *nonEmptyInterfaceCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + nonEmptyInterface := (*nonEmptyInterface)(ptr) + var i interface{} + if nonEmptyInterface.itab != nil { + e := (*emptyInterface)(unsafe.Pointer(&i)) + e.typ = nonEmptyInterface.itab.typ + e.word = nonEmptyInterface.word + } + stream.WriteVal(i) +} + +func (codec *nonEmptyInterfaceCodec) EncodeInterface(val interface{}, stream *Stream) { + stream.WriteVal(val) +} + +func (codec *nonEmptyInterfaceCodec) IsEmpty(ptr unsafe.Pointer) bool { + nonEmptyInterface := (*nonEmptyInterface)(ptr) + return nonEmptyInterface.word == nil +} + +type anyCodec struct { +} + +func (codec *anyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *((*Any)(ptr)) = iter.ReadAny() +} + +func (codec *anyCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + (*((*Any)(ptr))).WriteTo(stream) +} + +func (codec *anyCodec) EncodeInterface(val interface{}, stream *Stream) { + (val.(Any)).WriteTo(stream) +} + +func (codec *anyCodec) IsEmpty(ptr unsafe.Pointer) bool { + return (*((*Any)(ptr))).Size() == 0 +} + +type jsonNumberCodec struct { +} + +func (codec *jsonNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + switch iter.WhatIsNext() { + case StringValue: + *((*json.Number)(ptr)) = json.Number(iter.ReadString()) + case NilValue: + iter.skipFourBytes('n', 'u', 'l', 'l') + *((*json.Number)(ptr)) = "" + default: + *((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString())) + } +} + +func (codec *jsonNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteRaw(string(*((*json.Number)(ptr)))) +} + +func (codec *jsonNumberCodec) EncodeInterface(val interface{}, stream *Stream) { + stream.WriteRaw(string(val.(json.Number))) +} + +func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*json.Number)(ptr))) == 0 +} + +type jsoniterNumberCodec struct { +} + +func (codec *jsoniterNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + switch iter.WhatIsNext() { + case StringValue: + *((*Number)(ptr)) = Number(iter.ReadString()) + case NilValue: + iter.skipFourBytes('n', 'u', 'l', 'l') + *((*Number)(ptr)) = "" + default: + *((*Number)(ptr)) = Number([]byte(iter.readNumberAsString())) + } +} + +func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteRaw(string(*((*Number)(ptr)))) +} + +func (codec *jsoniterNumberCodec) EncodeInterface(val interface{}, stream *Stream) { + stream.WriteRaw(string(val.(Number))) +} + +func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*Number)(ptr))) == 0 +} + +type jsonRawMessageCodec struct { +} + +func (codec *jsonRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *((*json.RawMessage)(ptr)) = json.RawMessage(iter.SkipAndReturnBytes()) +} + +func (codec *jsonRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteRaw(string(*((*json.RawMessage)(ptr)))) +} + +func (codec *jsonRawMessageCodec) EncodeInterface(val interface{}, stream *Stream) { + stream.WriteRaw(string(val.(json.RawMessage))) +} + +func (codec *jsonRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*json.RawMessage)(ptr))) == 0 +} + +type jsoniterRawMessageCodec struct { +} + +func (codec *jsoniterRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *((*RawMessage)(ptr)) = RawMessage(iter.SkipAndReturnBytes()) +} + +func (codec *jsoniterRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteRaw(string(*((*RawMessage)(ptr)))) +} + +func (codec *jsoniterRawMessageCodec) EncodeInterface(val interface{}, stream *Stream) { + stream.WriteRaw(string(val.(RawMessage))) +} + +func (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*RawMessage)(ptr))) == 0 +} + +type base64Codec struct { + sliceDecoder ValDecoder +} + +func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if iter.ReadNil() { + ptrSlice := (*sliceHeader)(ptr) + ptrSlice.Len = 0 + ptrSlice.Cap = 0 + ptrSlice.Data = nil + return + } + switch iter.WhatIsNext() { + case StringValue: + encoding := base64.StdEncoding + src := iter.SkipAndReturnBytes() + src = src[1 : len(src)-1] + decodedLen := encoding.DecodedLen(len(src)) + dst := make([]byte, decodedLen) + len, err := encoding.Decode(dst, src) + if err != nil { + iter.ReportError("decode base64", err.Error()) + } else { + dst = dst[:len] + dstSlice := (*sliceHeader)(unsafe.Pointer(&dst)) + ptrSlice := (*sliceHeader)(ptr) + ptrSlice.Data = dstSlice.Data + ptrSlice.Cap = dstSlice.Cap + ptrSlice.Len = dstSlice.Len + } + case ArrayValue: + codec.sliceDecoder.Decode(ptr, iter) + default: + iter.ReportError("base64Codec", "invalid input") + } +} + +func (codec *base64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + src := *((*[]byte)(ptr)) + if len(src) == 0 { + stream.WriteNil() + return + } + encoding := base64.StdEncoding + stream.writeByte('"') + toGrow := encoding.EncodedLen(len(src)) + stream.ensure(toGrow) + encoding.Encode(stream.buf[stream.n:], src) + stream.n += toGrow + stream.writeByte('"') +} + +func (codec *base64Codec) EncodeInterface(val interface{}, stream *Stream) { + ptr := extractInterface(val).word + src := *((*[]byte)(ptr)) + if len(src) == 0 { + stream.WriteNil() + return + } + encoding := base64.StdEncoding + stream.writeByte('"') + toGrow := encoding.EncodedLen(len(src)) + stream.ensure(toGrow) + encoding.Encode(stream.buf[stream.n:], src) + stream.n += toGrow + stream.writeByte('"') +} + +func (codec *base64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*[]byte)(ptr))) == 0 +} + +type stringModeNumberDecoder struct { + elemDecoder ValDecoder +} + +func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + c := iter.nextToken() + if c != '"' { + iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c})) + return + } + decoder.elemDecoder.Decode(ptr, iter) + if iter.Error != nil { + return + } + c = iter.readByte() + if c != '"' { + iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c})) + return + } +} + +type stringModeStringDecoder struct { + elemDecoder ValDecoder + cfg *frozenConfig +} + +func (decoder *stringModeStringDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.elemDecoder.Decode(ptr, iter) + str := *((*string)(ptr)) + tempIter := decoder.cfg.BorrowIterator([]byte(str)) + defer decoder.cfg.ReturnIterator(tempIter) + *((*string)(ptr)) = tempIter.ReadString() +} + +type stringModeNumberEncoder struct { + elemEncoder ValEncoder +} + +func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.writeByte('"') + encoder.elemEncoder.Encode(ptr, stream) + stream.writeByte('"') +} + +func (encoder *stringModeNumberEncoder) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, encoder) +} + +func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.elemEncoder.IsEmpty(ptr) +} + +type stringModeStringEncoder struct { + elemEncoder ValEncoder + cfg *frozenConfig +} + +func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + tempStream := encoder.cfg.BorrowStream(nil) + defer encoder.cfg.ReturnStream(tempStream) + encoder.elemEncoder.Encode(ptr, tempStream) + stream.WriteString(string(tempStream.Buffer())) +} + +func (encoder *stringModeStringEncoder) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, encoder) +} + +func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.elemEncoder.IsEmpty(ptr) +} + +type marshalerEncoder struct { + templateInterface emptyInterface + checkIsEmpty checkIsEmpty +} + +func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + templateInterface := encoder.templateInterface + templateInterface.word = ptr + realInterface := (*interface{})(unsafe.Pointer(&templateInterface)) + marshaler, ok := (*realInterface).(json.Marshaler) + if !ok { + stream.WriteVal(nil) + return + } + + bytes, err := marshaler.MarshalJSON() + if err != nil { + stream.Error = err + } else { + stream.Write(bytes) + } +} +func (encoder *marshalerEncoder) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, encoder) +} + +func (encoder *marshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.checkIsEmpty.IsEmpty(ptr) +} + +type textMarshalerEncoder struct { + templateInterface emptyInterface + checkIsEmpty checkIsEmpty +} + +func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + templateInterface := encoder.templateInterface + templateInterface.word = ptr + realInterface := (*interface{})(unsafe.Pointer(&templateInterface)) + marshaler := (*realInterface).(encoding.TextMarshaler) + bytes, err := marshaler.MarshalText() + if err != nil { + stream.Error = err + } else { + stream.WriteString(string(bytes)) + } +} + +func (encoder *textMarshalerEncoder) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, encoder) +} + +func (encoder *textMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.checkIsEmpty.IsEmpty(ptr) +} + +type unmarshalerDecoder struct { + templateInterface emptyInterface +} + +func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + templateInterface := decoder.templateInterface + templateInterface.word = ptr + realInterface := (*interface{})(unsafe.Pointer(&templateInterface)) + unmarshaler := (*realInterface).(json.Unmarshaler) + iter.nextToken() + iter.unreadByte() // skip spaces + bytes := iter.SkipAndReturnBytes() + err := unmarshaler.UnmarshalJSON(bytes) + if err != nil { + iter.ReportError("unmarshalerDecoder", err.Error()) + } +} + +type textUnmarshalerDecoder struct { + templateInterface emptyInterface +} + +func (decoder *textUnmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + templateInterface := decoder.templateInterface + templateInterface.word = ptr + realInterface := (*interface{})(unsafe.Pointer(&templateInterface)) + unmarshaler := (*realInterface).(encoding.TextUnmarshaler) + str := iter.ReadString() + err := unmarshaler.UnmarshalText([]byte(str)) + if err != nil { + iter.ReportError("textUnmarshalerDecoder", err.Error()) + } +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_reflect_object.go b/backend/vendor/github.com/json-iterator/go/feature_reflect_object.go new file mode 100644 index 0000000000..59b1235c0d --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_reflect_object.go @@ -0,0 +1,196 @@ +package jsoniter + +import ( + "fmt" + "io" + "reflect" + "strings" + "unsafe" +) + +func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { + type bindingTo struct { + binding *Binding + toName string + ignored bool + } + orderedBindings := []*bindingTo{} + structDescriptor, err := describeStruct(cfg, typ) + if err != nil { + return nil, err + } + for _, binding := range structDescriptor.Fields { + for _, toName := range binding.ToNames { + new := &bindingTo{ + binding: binding, + toName: toName, + } + for _, old := range orderedBindings { + if old.toName != toName { + continue + } + old.ignored, new.ignored = resolveConflictBinding(cfg, old.binding, new.binding) + } + orderedBindings = append(orderedBindings, new) + } + } + if len(orderedBindings) == 0 { + return &emptyStructEncoder{}, nil + } + finalOrderedFields := []structFieldTo{} + for _, bindingTo := range orderedBindings { + if !bindingTo.ignored { + finalOrderedFields = append(finalOrderedFields, structFieldTo{ + encoder: bindingTo.binding.Encoder.(*structFieldEncoder), + toName: bindingTo.toName, + }) + } + } + return &structEncoder{structDescriptor.onePtrEmbedded, structDescriptor.onePtrOptimization, finalOrderedFields}, nil +} + +func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) { + newTagged := new.Field.Tag.Get(cfg.getTagKey()) != "" + oldTagged := old.Field.Tag.Get(cfg.getTagKey()) != "" + if newTagged { + if oldTagged { + if len(old.levels) > len(new.levels) { + return true, false + } else if len(new.levels) > len(old.levels) { + return false, true + } else { + return true, true + } + } else { + return true, false + } + } else { + if oldTagged { + return true, false + } + if len(old.levels) > len(new.levels) { + return true, false + } else if len(new.levels) > len(old.levels) { + return false, true + } else { + return true, true + } + } +} + +func decoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { + bindings := map[string]*Binding{} + structDescriptor, err := describeStruct(cfg, typ) + if err != nil { + return nil, err + } + for _, binding := range structDescriptor.Fields { + for _, fromName := range binding.FromNames { + old := bindings[fromName] + if old == nil { + bindings[fromName] = binding + continue + } + ignoreOld, ignoreNew := resolveConflictBinding(cfg, old, binding) + if ignoreOld { + delete(bindings, fromName) + } + if !ignoreNew { + bindings[fromName] = binding + } + } + } + fields := map[string]*structFieldDecoder{} + for k, binding := range bindings { + fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder) + } + return createStructDecoder(typ, fields) +} + +type structFieldEncoder struct { + field *reflect.StructField + fieldEncoder ValEncoder + omitempty bool +} + +func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset) + encoder.fieldEncoder.Encode(fieldPtr, stream) + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%s: %s", encoder.field.Name, stream.Error.Error()) + } +} + +func (encoder *structFieldEncoder) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, encoder) +} + +func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool { + fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset) + return encoder.fieldEncoder.IsEmpty(fieldPtr) +} + +type structEncoder struct { + onePtrEmbedded bool + onePtrOptimization bool + fields []structFieldTo +} + +type structFieldTo struct { + encoder *structFieldEncoder + toName string +} + +func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteObjectStart() + isNotFirst := false + for _, field := range encoder.fields { + if field.encoder.omitempty && field.encoder.IsEmpty(ptr) { + continue + } + if isNotFirst { + stream.WriteMore() + } + stream.WriteObjectField(field.toName) + field.encoder.Encode(ptr, stream) + isNotFirst = true + } + stream.WriteObjectEnd() +} + +func (encoder *structEncoder) EncodeInterface(val interface{}, stream *Stream) { + e := (*emptyInterface)(unsafe.Pointer(&val)) + if encoder.onePtrOptimization { + if e.word == nil && encoder.onePtrEmbedded { + stream.WriteObjectStart() + stream.WriteObjectEnd() + return + } + ptr := uintptr(e.word) + e.word = unsafe.Pointer(&ptr) + } + if reflect.TypeOf(val).Kind() == reflect.Ptr { + encoder.Encode(unsafe.Pointer(&e.word), stream) + } else { + encoder.Encode(e.word, stream) + } +} + +func (encoder *structEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type emptyStructEncoder struct { +} + +func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteEmptyObject() +} + +func (encoder *emptyStructEncoder) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, encoder) +} + +func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_reflect_slice.go b/backend/vendor/github.com/json-iterator/go/feature_reflect_slice.go new file mode 100644 index 0000000000..51a8daecfb --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_reflect_slice.go @@ -0,0 +1,147 @@ +package jsoniter + +import ( + "fmt" + "io" + "reflect" + "unsafe" +) + +func decoderOfSlice(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { + decoder, err := decoderOfType(cfg, typ.Elem()) + if err != nil { + return nil, err + } + return &sliceDecoder{typ, typ.Elem(), decoder}, nil +} + +func encoderOfSlice(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { + encoder, err := encoderOfType(cfg, typ.Elem()) + if err != nil { + return nil, err + } + if typ.Elem().Kind() == reflect.Map { + encoder = &OptionalEncoder{encoder} + } + return &sliceEncoder{typ, typ.Elem(), encoder}, nil +} + +type sliceEncoder struct { + sliceType reflect.Type + elemType reflect.Type + elemEncoder ValEncoder +} + +func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + slice := (*sliceHeader)(ptr) + if slice.Data == nil { + stream.WriteNil() + return + } + if slice.Len == 0 { + stream.WriteEmptyArray() + return + } + stream.WriteArrayStart() + elemPtr := unsafe.Pointer(slice.Data) + encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream) + for i := 1; i < slice.Len; i++ { + stream.WriteMore() + elemPtr = unsafe.Pointer(uintptr(elemPtr) + encoder.elemType.Size()) + encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream) + } + stream.WriteArrayEnd() + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%v: %s", encoder.sliceType, stream.Error.Error()) + } +} + +func (encoder *sliceEncoder) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, encoder) +} + +func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool { + slice := (*sliceHeader)(ptr) + return slice.Len == 0 +} + +type sliceDecoder struct { + sliceType reflect.Type + elemType reflect.Type + elemDecoder ValDecoder +} + +// sliceHeader is a safe version of SliceHeader used within this package. +type sliceHeader struct { + Data unsafe.Pointer + Len int + Cap int +} + +func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.doDecode(ptr, iter) + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error()) + } +} + +func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) { + slice := (*sliceHeader)(ptr) + if iter.ReadNil() { + slice.Len = 0 + slice.Cap = 0 + slice.Data = nil + return + } + reuseSlice(slice, decoder.sliceType, 4) + slice.Len = 0 + offset := uintptr(0) + iter.ReadArrayCB(func(iter *Iterator) bool { + growOne(slice, decoder.sliceType, decoder.elemType) + decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter) + offset += decoder.elemType.Size() + return true + }) +} + +// grow grows the slice s so that it can hold extra more values, allocating +// more capacity if needed. It also returns the old and new slice lengths. +func growOne(slice *sliceHeader, sliceType reflect.Type, elementType reflect.Type) { + newLen := slice.Len + 1 + if newLen <= slice.Cap { + slice.Len = newLen + return + } + newCap := slice.Cap + if newCap == 0 { + newCap = 1 + } else { + for newCap < newLen { + if slice.Len < 1024 { + newCap += newCap + } else { + newCap += newCap / 4 + } + } + } + newVal := reflect.MakeSlice(sliceType, newLen, newCap) + dst := unsafe.Pointer(newVal.Pointer()) + // copy old array into new array + originalBytesCount := slice.Len * int(elementType.Size()) + srcSliceHeader := (unsafe.Pointer)(&sliceHeader{slice.Data, originalBytesCount, originalBytesCount}) + dstSliceHeader := (unsafe.Pointer)(&sliceHeader{dst, originalBytesCount, originalBytesCount}) + copy(*(*[]byte)(dstSliceHeader), *(*[]byte)(srcSliceHeader)) + slice.Data = dst + slice.Len = newLen + slice.Cap = newCap +} + +func reuseSlice(slice *sliceHeader, sliceType reflect.Type, expectedCap int) { + if expectedCap <= slice.Cap { + return + } + newVal := reflect.MakeSlice(sliceType, 0, expectedCap) + dst := unsafe.Pointer(newVal.Pointer()) + slice.Data = dst + slice.Cap = expectedCap +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_reflect_struct_decoder.go b/backend/vendor/github.com/json-iterator/go/feature_reflect_struct_decoder.go new file mode 100644 index 0000000000..e6ced77c22 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_reflect_struct_decoder.go @@ -0,0 +1,934 @@ +package jsoniter + +import ( + "fmt" + "io" + "reflect" + "strings" + "unsafe" +) + +func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder) (ValDecoder, error) { + knownHash := map[int32]struct{}{ + 0: {}, + } + switch len(fields) { + case 0: + return &skipObjectDecoder{typ}, nil + case 1: + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields}, nil + } + knownHash[fieldHash] = struct{}{} + return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder}, nil + } + case 2: + var fieldHash1 int32 + var fieldHash2 int32 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields}, nil + } + knownHash[fieldHash] = struct{}{} + if fieldHash1 == 0 { + fieldHash1 = fieldHash + fieldDecoder1 = fieldDecoder + } else { + fieldHash2 = fieldHash + fieldDecoder2 = fieldDecoder + } + } + return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2}, nil + case 3: + var fieldName1 int32 + var fieldName2 int32 + var fieldName3 int32 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields}, nil + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } + } + return &threeFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil + case 4: + var fieldName1 int32 + var fieldName2 int32 + var fieldName3 int32 + var fieldName4 int32 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields}, nil + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } + } + return &fourFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4}, nil + case 5: + var fieldName1 int32 + var fieldName2 int32 + var fieldName3 int32 + var fieldName4 int32 + var fieldName5 int32 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields}, nil + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } + } + return &fiveFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, fieldName5, fieldDecoder5}, nil + case 6: + var fieldName1 int32 + var fieldName2 int32 + var fieldName3 int32 + var fieldName4 int32 + var fieldName5 int32 + var fieldName6 int32 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields}, nil + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } + } + return &sixFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6}, nil + case 7: + var fieldName1 int32 + var fieldName2 int32 + var fieldName3 int32 + var fieldName4 int32 + var fieldName5 int32 + var fieldName6 int32 + var fieldName7 int32 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields}, nil + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } + } + return &sevenFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7}, nil + case 8: + var fieldName1 int32 + var fieldName2 int32 + var fieldName3 int32 + var fieldName4 int32 + var fieldName5 int32 + var fieldName6 int32 + var fieldName7 int32 + var fieldName8 int32 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + var fieldDecoder8 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields}, nil + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else if fieldName7 == 0 { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } else { + fieldName8 = fieldHash + fieldDecoder8 = fieldDecoder + } + } + return &eightFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, fieldName8, fieldDecoder8}, nil + case 9: + var fieldName1 int32 + var fieldName2 int32 + var fieldName3 int32 + var fieldName4 int32 + var fieldName5 int32 + var fieldName6 int32 + var fieldName7 int32 + var fieldName8 int32 + var fieldName9 int32 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + var fieldDecoder8 *structFieldDecoder + var fieldDecoder9 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields}, nil + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else if fieldName7 == 0 { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } else if fieldName8 == 0 { + fieldName8 = fieldHash + fieldDecoder8 = fieldDecoder + } else { + fieldName9 = fieldHash + fieldDecoder9 = fieldDecoder + } + } + return &nineFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9}, nil + case 10: + var fieldName1 int32 + var fieldName2 int32 + var fieldName3 int32 + var fieldName4 int32 + var fieldName5 int32 + var fieldName6 int32 + var fieldName7 int32 + var fieldName8 int32 + var fieldName9 int32 + var fieldName10 int32 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + var fieldDecoder8 *structFieldDecoder + var fieldDecoder9 *structFieldDecoder + var fieldDecoder10 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields}, nil + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else if fieldName7 == 0 { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } else if fieldName8 == 0 { + fieldName8 = fieldHash + fieldDecoder8 = fieldDecoder + } else if fieldName9 == 0 { + fieldName9 = fieldHash + fieldDecoder9 = fieldDecoder + } else { + fieldName10 = fieldHash + fieldDecoder10 = fieldDecoder + } + } + return &tenFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9, + fieldName10, fieldDecoder10}, nil + } + return &generalStructDecoder{typ, fields}, nil +} + +type generalStructDecoder struct { + typ reflect.Type + fields map[string]*structFieldDecoder +} + +func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + var fieldBytes []byte + var field string + if iter.cfg.objectFieldMustBeSimpleString { + fieldBytes = iter.readObjectFieldAsBytes() + field = *(*string)(unsafe.Pointer(&fieldBytes)) + } else { + field = iter.ReadString() + c := iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + } + fieldDecoder := decoder.fields[strings.ToLower(field)] + if fieldDecoder == nil { + iter.Skip() + } else { + fieldDecoder.Decode(ptr, iter) + } + for iter.nextToken() == ',' { + if iter.cfg.objectFieldMustBeSimpleString { + fieldBytes := iter.readObjectFieldAsBytes() + field = *(*string)(unsafe.Pointer(&fieldBytes)) + } else { + field = iter.ReadString() + c := iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + } + fieldDecoder = decoder.fields[strings.ToLower(field)] + if fieldDecoder == nil { + iter.Skip() + } else { + fieldDecoder.Decode(ptr, iter) + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + } +} + +type skipObjectDecoder struct { + typ reflect.Type +} + +func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + valueType := iter.WhatIsNext() + if valueType != ObjectValue && valueType != NilValue { + iter.ReportError("skipObjectDecoder", "expect object or null") + return + } + iter.Skip() +} + +type oneFieldStructDecoder struct { + typ reflect.Type + fieldHash int32 + fieldDecoder *structFieldDecoder +} + +func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + if iter.readFieldHash() == decoder.fieldHash { + decoder.fieldDecoder.Decode(ptr, iter) + } else { + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + } +} + +type twoFieldsStructDecoder struct { + typ reflect.Type + fieldHash1 int32 + fieldDecoder1 *structFieldDecoder + fieldHash2 int32 + fieldDecoder2 *structFieldDecoder +} + +func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + } +} + +type threeFieldsStructDecoder struct { + typ reflect.Type + fieldHash1 int32 + fieldDecoder1 *structFieldDecoder + fieldHash2 int32 + fieldDecoder2 *structFieldDecoder + fieldHash3 int32 + fieldDecoder3 *structFieldDecoder +} + +func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + } +} + +type fourFieldsStructDecoder struct { + typ reflect.Type + fieldHash1 int32 + fieldDecoder1 *structFieldDecoder + fieldHash2 int32 + fieldDecoder2 *structFieldDecoder + fieldHash3 int32 + fieldDecoder3 *structFieldDecoder + fieldHash4 int32 + fieldDecoder4 *structFieldDecoder +} + +func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + } +} + +type fiveFieldsStructDecoder struct { + typ reflect.Type + fieldHash1 int32 + fieldDecoder1 *structFieldDecoder + fieldHash2 int32 + fieldDecoder2 *structFieldDecoder + fieldHash3 int32 + fieldDecoder3 *structFieldDecoder + fieldHash4 int32 + fieldDecoder4 *structFieldDecoder + fieldHash5 int32 + fieldDecoder5 *structFieldDecoder +} + +func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + } +} + +type sixFieldsStructDecoder struct { + typ reflect.Type + fieldHash1 int32 + fieldDecoder1 *structFieldDecoder + fieldHash2 int32 + fieldDecoder2 *structFieldDecoder + fieldHash3 int32 + fieldDecoder3 *structFieldDecoder + fieldHash4 int32 + fieldDecoder4 *structFieldDecoder + fieldHash5 int32 + fieldDecoder5 *structFieldDecoder + fieldHash6 int32 + fieldDecoder6 *structFieldDecoder +} + +func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + } +} + +type sevenFieldsStructDecoder struct { + typ reflect.Type + fieldHash1 int32 + fieldDecoder1 *structFieldDecoder + fieldHash2 int32 + fieldDecoder2 *structFieldDecoder + fieldHash3 int32 + fieldDecoder3 *structFieldDecoder + fieldHash4 int32 + fieldDecoder4 *structFieldDecoder + fieldHash5 int32 + fieldDecoder5 *structFieldDecoder + fieldHash6 int32 + fieldDecoder6 *structFieldDecoder + fieldHash7 int32 + fieldDecoder7 *structFieldDecoder +} + +func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + } +} + +type eightFieldsStructDecoder struct { + typ reflect.Type + fieldHash1 int32 + fieldDecoder1 *structFieldDecoder + fieldHash2 int32 + fieldDecoder2 *structFieldDecoder + fieldHash3 int32 + fieldDecoder3 *structFieldDecoder + fieldHash4 int32 + fieldDecoder4 *structFieldDecoder + fieldHash5 int32 + fieldDecoder5 *structFieldDecoder + fieldHash6 int32 + fieldDecoder6 *structFieldDecoder + fieldHash7 int32 + fieldDecoder7 *structFieldDecoder + fieldHash8 int32 + fieldDecoder8 *structFieldDecoder +} + +func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + case decoder.fieldHash8: + decoder.fieldDecoder8.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + } +} + +type nineFieldsStructDecoder struct { + typ reflect.Type + fieldHash1 int32 + fieldDecoder1 *structFieldDecoder + fieldHash2 int32 + fieldDecoder2 *structFieldDecoder + fieldHash3 int32 + fieldDecoder3 *structFieldDecoder + fieldHash4 int32 + fieldDecoder4 *structFieldDecoder + fieldHash5 int32 + fieldDecoder5 *structFieldDecoder + fieldHash6 int32 + fieldDecoder6 *structFieldDecoder + fieldHash7 int32 + fieldDecoder7 *structFieldDecoder + fieldHash8 int32 + fieldDecoder8 *structFieldDecoder + fieldHash9 int32 + fieldDecoder9 *structFieldDecoder +} + +func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + case decoder.fieldHash8: + decoder.fieldDecoder8.Decode(ptr, iter) + case decoder.fieldHash9: + decoder.fieldDecoder9.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + } +} + +type tenFieldsStructDecoder struct { + typ reflect.Type + fieldHash1 int32 + fieldDecoder1 *structFieldDecoder + fieldHash2 int32 + fieldDecoder2 *structFieldDecoder + fieldHash3 int32 + fieldDecoder3 *structFieldDecoder + fieldHash4 int32 + fieldDecoder4 *structFieldDecoder + fieldHash5 int32 + fieldDecoder5 *structFieldDecoder + fieldHash6 int32 + fieldDecoder6 *structFieldDecoder + fieldHash7 int32 + fieldDecoder7 *structFieldDecoder + fieldHash8 int32 + fieldDecoder8 *structFieldDecoder + fieldHash9 int32 + fieldDecoder9 *structFieldDecoder + fieldHash10 int32 + fieldDecoder10 *structFieldDecoder +} + +func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + case decoder.fieldHash8: + decoder.fieldDecoder8.Decode(ptr, iter) + case decoder.fieldHash9: + decoder.fieldDecoder9.Decode(ptr, iter) + case decoder.fieldHash10: + decoder.fieldDecoder10.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error()) + } +} + +type structFieldDecoder struct { + field *reflect.StructField + fieldDecoder ValDecoder +} + +func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + fieldPtr := unsafe.Pointer(uintptr(ptr) + decoder.field.Offset) + decoder.fieldDecoder.Decode(fieldPtr, iter) + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%s: %s", decoder.field.Name, iter.Error.Error()) + } +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_stream.go b/backend/vendor/github.com/json-iterator/go/feature_stream.go new file mode 100644 index 0000000000..97355eb5b7 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_stream.go @@ -0,0 +1,308 @@ +package jsoniter + +import ( + "io" +) + +// stream is a io.Writer like object, with JSON specific write functions. +// Error is not returned as return value, but stored as Error member on this stream instance. +type Stream struct { + cfg *frozenConfig + out io.Writer + buf []byte + n int + Error error + indention int + Attachment interface{} // open for customized encoder +} + +// NewStream create new stream instance. +// cfg can be jsoniter.ConfigDefault. +// out can be nil if write to internal buffer. +// bufSize is the initial size for the internal buffer in bytes. +func NewStream(cfg API, out io.Writer, bufSize int) *Stream { + return &Stream{ + cfg: cfg.(*frozenConfig), + out: out, + buf: make([]byte, bufSize), + n: 0, + Error: nil, + indention: 0, + } +} + +// Pool returns a pool can provide more stream with same configuration +func (stream *Stream) Pool() StreamPool { + return stream.cfg +} + +// Reset reuse this stream instance by assign a new writer +func (stream *Stream) Reset(out io.Writer) { + stream.out = out + stream.n = 0 +} + +// Available returns how many bytes are unused in the buffer. +func (stream *Stream) Available() int { + return len(stream.buf) - stream.n +} + +// Buffered returns the number of bytes that have been written into the current buffer. +func (stream *Stream) Buffered() int { + return stream.n +} + +// Buffer if writer is nil, use this method to take the result +func (stream *Stream) Buffer() []byte { + return stream.buf[:stream.n] +} + +// Write writes the contents of p into the buffer. +// It returns the number of bytes written. +// If nn < len(p), it also returns an error explaining +// why the write is short. +func (stream *Stream) Write(p []byte) (nn int, err error) { + for len(p) > stream.Available() && stream.Error == nil { + if stream.out == nil { + stream.growAtLeast(len(p)) + } else { + var n int + if stream.Buffered() == 0 { + // Large write, empty buffer. + // Write directly from p to avoid copy. + n, stream.Error = stream.out.Write(p) + } else { + n = copy(stream.buf[stream.n:], p) + stream.n += n + stream.Flush() + } + nn += n + p = p[n:] + } + } + if stream.Error != nil { + return nn, stream.Error + } + n := copy(stream.buf[stream.n:], p) + stream.n += n + nn += n + return nn, nil +} + +// WriteByte writes a single byte. +func (stream *Stream) writeByte(c byte) { + if stream.Error != nil { + return + } + if stream.Available() < 1 { + stream.growAtLeast(1) + } + stream.buf[stream.n] = c + stream.n++ +} + +func (stream *Stream) writeTwoBytes(c1 byte, c2 byte) { + if stream.Error != nil { + return + } + if stream.Available() < 2 { + stream.growAtLeast(2) + } + stream.buf[stream.n] = c1 + stream.buf[stream.n+1] = c2 + stream.n += 2 +} + +func (stream *Stream) writeThreeBytes(c1 byte, c2 byte, c3 byte) { + if stream.Error != nil { + return + } + if stream.Available() < 3 { + stream.growAtLeast(3) + } + stream.buf[stream.n] = c1 + stream.buf[stream.n+1] = c2 + stream.buf[stream.n+2] = c3 + stream.n += 3 +} + +func (stream *Stream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) { + if stream.Error != nil { + return + } + if stream.Available() < 4 { + stream.growAtLeast(4) + } + stream.buf[stream.n] = c1 + stream.buf[stream.n+1] = c2 + stream.buf[stream.n+2] = c3 + stream.buf[stream.n+3] = c4 + stream.n += 4 +} + +func (stream *Stream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) { + if stream.Error != nil { + return + } + if stream.Available() < 5 { + stream.growAtLeast(5) + } + stream.buf[stream.n] = c1 + stream.buf[stream.n+1] = c2 + stream.buf[stream.n+2] = c3 + stream.buf[stream.n+3] = c4 + stream.buf[stream.n+4] = c5 + stream.n += 5 +} + +// Flush writes any buffered data to the underlying io.Writer. +func (stream *Stream) Flush() error { + if stream.out == nil { + return nil + } + if stream.Error != nil { + return stream.Error + } + if stream.n == 0 { + return nil + } + n, err := stream.out.Write(stream.buf[0:stream.n]) + if n < stream.n && err == nil { + err = io.ErrShortWrite + } + if err != nil { + if n > 0 && n < stream.n { + copy(stream.buf[0:stream.n-n], stream.buf[n:stream.n]) + } + stream.n -= n + stream.Error = err + return err + } + stream.n = 0 + return nil +} + +func (stream *Stream) ensure(minimal int) { + available := stream.Available() + if available < minimal { + stream.growAtLeast(minimal) + } +} + +func (stream *Stream) growAtLeast(minimal int) { + if stream.out != nil { + stream.Flush() + if stream.Available() >= minimal { + return + } + } + toGrow := len(stream.buf) + if toGrow < minimal { + toGrow = minimal + } + newBuf := make([]byte, len(stream.buf)+toGrow) + copy(newBuf, stream.Buffer()) + stream.buf = newBuf +} + +// WriteRaw write string out without quotes, just like []byte +func (stream *Stream) WriteRaw(s string) { + stream.ensure(len(s)) + if stream.Error != nil { + return + } + n := copy(stream.buf[stream.n:], s) + stream.n += n +} + +// WriteNil write null to stream +func (stream *Stream) WriteNil() { + stream.writeFourBytes('n', 'u', 'l', 'l') +} + +// WriteTrue write true to stream +func (stream *Stream) WriteTrue() { + stream.writeFourBytes('t', 'r', 'u', 'e') +} + +// WriteFalse write false to stream +func (stream *Stream) WriteFalse() { + stream.writeFiveBytes('f', 'a', 'l', 's', 'e') +} + +// WriteBool write true or false into stream +func (stream *Stream) WriteBool(val bool) { + if val { + stream.WriteTrue() + } else { + stream.WriteFalse() + } +} + +// WriteObjectStart write { with possible indention +func (stream *Stream) WriteObjectStart() { + stream.indention += stream.cfg.indentionStep + stream.writeByte('{') + stream.writeIndention(0) +} + +// WriteObjectField write "field": with possible indention +func (stream *Stream) WriteObjectField(field string) { + stream.WriteString(field) + if stream.indention > 0 { + stream.writeTwoBytes(':', ' ') + } else { + stream.writeByte(':') + } +} + +// WriteObjectEnd write } with possible indention +func (stream *Stream) WriteObjectEnd() { + stream.writeIndention(stream.cfg.indentionStep) + stream.indention -= stream.cfg.indentionStep + stream.writeByte('}') +} + +// WriteEmptyObject write {} +func (stream *Stream) WriteEmptyObject() { + stream.writeByte('{') + stream.writeByte('}') +} + +// WriteMore write , with possible indention +func (stream *Stream) WriteMore() { + stream.writeByte(',') + stream.writeIndention(0) +} + +// WriteArrayStart write [ with possible indention +func (stream *Stream) WriteArrayStart() { + stream.indention += stream.cfg.indentionStep + stream.writeByte('[') + stream.writeIndention(0) +} + +// WriteEmptyArray write [] +func (stream *Stream) WriteEmptyArray() { + stream.writeTwoBytes('[', ']') +} + +// WriteArrayEnd write ] with possible indention +func (stream *Stream) WriteArrayEnd() { + stream.writeIndention(stream.cfg.indentionStep) + stream.indention -= stream.cfg.indentionStep + stream.writeByte(']') +} + +func (stream *Stream) writeIndention(delta int) { + if stream.indention == 0 { + return + } + stream.writeByte('\n') + toWrite := stream.indention - delta + stream.ensure(toWrite) + for i := 0; i < toWrite && stream.n < len(stream.buf); i++ { + stream.buf[stream.n] = ' ' + stream.n++ + } +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_stream_float.go b/backend/vendor/github.com/json-iterator/go/feature_stream_float.go new file mode 100644 index 0000000000..9a404e11d4 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_stream_float.go @@ -0,0 +1,96 @@ +package jsoniter + +import ( + "math" + "strconv" +) + +var pow10 []uint64 + +func init() { + pow10 = []uint64{1, 10, 100, 1000, 10000, 100000, 1000000} +} + +// WriteFloat32 write float32 to stream +func (stream *Stream) WriteFloat32(val float32) { + abs := math.Abs(float64(val)) + fmt := byte('f') + // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. + if abs != 0 { + if float32(abs) < 1e-6 || float32(abs) >= 1e21 { + fmt = 'e' + } + } + stream.WriteRaw(strconv.FormatFloat(float64(val), fmt, -1, 32)) +} + +// WriteFloat32Lossy write float32 to stream with ONLY 6 digits precision although much much faster +func (stream *Stream) WriteFloat32Lossy(val float32) { + if val < 0 { + stream.writeByte('-') + val = -val + } + if val > 0x4ffffff { + stream.WriteFloat32(val) + return + } + precision := 6 + exp := uint64(1000000) // 6 + lval := uint64(float64(val)*float64(exp) + 0.5) + stream.WriteUint64(lval / exp) + fval := lval % exp + if fval == 0 { + return + } + stream.writeByte('.') + stream.ensure(10) + for p := precision - 1; p > 0 && fval < pow10[p]; p-- { + stream.writeByte('0') + } + stream.WriteUint64(fval) + for stream.buf[stream.n-1] == '0' { + stream.n-- + } +} + +// WriteFloat64 write float64 to stream +func (stream *Stream) WriteFloat64(val float64) { + abs := math.Abs(val) + fmt := byte('f') + // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. + if abs != 0 { + if abs < 1e-6 || abs >= 1e21 { + fmt = 'e' + } + } + stream.WriteRaw(strconv.FormatFloat(float64(val), fmt, -1, 64)) +} + +// WriteFloat64Lossy write float64 to stream with ONLY 6 digits precision although much much faster +func (stream *Stream) WriteFloat64Lossy(val float64) { + if val < 0 { + stream.writeByte('-') + val = -val + } + if val > 0x4ffffff { + stream.WriteFloat64(val) + return + } + precision := 6 + exp := uint64(1000000) // 6 + lval := uint64(val*float64(exp) + 0.5) + stream.WriteUint64(lval / exp) + fval := lval % exp + if fval == 0 { + return + } + stream.writeByte('.') + stream.ensure(10) + for p := precision - 1; p > 0 && fval < pow10[p]; p-- { + stream.writeByte('0') + } + stream.WriteUint64(fval) + for stream.buf[stream.n-1] == '0' { + stream.n-- + } +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_stream_int.go b/backend/vendor/github.com/json-iterator/go/feature_stream_int.go new file mode 100644 index 0000000000..7cfd522c10 --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_stream_int.go @@ -0,0 +1,320 @@ +package jsoniter + +var digits []uint32 + +func init() { + digits = make([]uint32, 1000) + for i := uint32(0); i < 1000; i++ { + digits[i] = (((i / 100) + '0') << 16) + ((((i / 10) % 10) + '0') << 8) + i%10 + '0' + if i < 10 { + digits[i] += 2 << 24 + } else if i < 100 { + digits[i] += 1 << 24 + } + } +} + +func writeFirstBuf(buf []byte, v uint32, n int) int { + start := v >> 24 + if start == 0 { + buf[n] = byte(v >> 16) + n++ + buf[n] = byte(v >> 8) + n++ + } else if start == 1 { + buf[n] = byte(v >> 8) + n++ + } + buf[n] = byte(v) + n++ + return n +} + +func writeBuf(buf []byte, v uint32, n int) { + buf[n] = byte(v >> 16) + buf[n+1] = byte(v >> 8) + buf[n+2] = byte(v) +} + +// WriteUint8 write uint8 to stream +func (stream *Stream) WriteUint8(val uint8) { + stream.ensure(3) + stream.n = writeFirstBuf(stream.buf, digits[val], stream.n) +} + +// WriteInt8 write int8 to stream +func (stream *Stream) WriteInt8(nval int8) { + stream.ensure(4) + n := stream.n + var val uint8 + if nval < 0 { + val = uint8(-nval) + stream.buf[n] = '-' + n++ + } else { + val = uint8(nval) + } + stream.n = writeFirstBuf(stream.buf, digits[val], n) +} + +// WriteUint16 write uint16 to stream +func (stream *Stream) WriteUint16(val uint16) { + stream.ensure(5) + q1 := val / 1000 + if q1 == 0 { + stream.n = writeFirstBuf(stream.buf, digits[val], stream.n) + return + } + r1 := val - q1*1000 + n := writeFirstBuf(stream.buf, digits[q1], stream.n) + writeBuf(stream.buf, digits[r1], n) + stream.n = n + 3 + return +} + +// WriteInt16 write int16 to stream +func (stream *Stream) WriteInt16(nval int16) { + stream.ensure(6) + n := stream.n + var val uint16 + if nval < 0 { + val = uint16(-nval) + stream.buf[n] = '-' + n++ + } else { + val = uint16(nval) + } + q1 := val / 1000 + if q1 == 0 { + stream.n = writeFirstBuf(stream.buf, digits[val], n) + return + } + r1 := val - q1*1000 + n = writeFirstBuf(stream.buf, digits[q1], n) + writeBuf(stream.buf, digits[r1], n) + stream.n = n + 3 + return +} + +// WriteUint32 write uint32 to stream +func (stream *Stream) WriteUint32(val uint32) { + stream.ensure(10) + n := stream.n + q1 := val / 1000 + if q1 == 0 { + stream.n = writeFirstBuf(stream.buf, digits[val], n) + return + } + r1 := val - q1*1000 + q2 := q1 / 1000 + if q2 == 0 { + n := writeFirstBuf(stream.buf, digits[q1], n) + writeBuf(stream.buf, digits[r1], n) + stream.n = n + 3 + return + } + r2 := q1 - q2*1000 + q3 := q2 / 1000 + if q3 == 0 { + n = writeFirstBuf(stream.buf, digits[q2], n) + } else { + r3 := q2 - q3*1000 + stream.buf[n] = byte(q3 + '0') + n++ + writeBuf(stream.buf, digits[r3], n) + n += 3 + } + writeBuf(stream.buf, digits[r2], n) + writeBuf(stream.buf, digits[r1], n+3) + stream.n = n + 6 +} + +// WriteInt32 write int32 to stream +func (stream *Stream) WriteInt32(nval int32) { + stream.ensure(11) + n := stream.n + var val uint32 + if nval < 0 { + val = uint32(-nval) + stream.buf[n] = '-' + n++ + } else { + val = uint32(nval) + } + q1 := val / 1000 + if q1 == 0 { + stream.n = writeFirstBuf(stream.buf, digits[val], n) + return + } + r1 := val - q1*1000 + q2 := q1 / 1000 + if q2 == 0 { + n := writeFirstBuf(stream.buf, digits[q1], n) + writeBuf(stream.buf, digits[r1], n) + stream.n = n + 3 + return + } + r2 := q1 - q2*1000 + q3 := q2 / 1000 + if q3 == 0 { + n = writeFirstBuf(stream.buf, digits[q2], n) + } else { + r3 := q2 - q3*1000 + stream.buf[n] = byte(q3 + '0') + n++ + writeBuf(stream.buf, digits[r3], n) + n += 3 + } + writeBuf(stream.buf, digits[r2], n) + writeBuf(stream.buf, digits[r1], n+3) + stream.n = n + 6 +} + +// WriteUint64 write uint64 to stream +func (stream *Stream) WriteUint64(val uint64) { + stream.ensure(20) + n := stream.n + q1 := val / 1000 + if q1 == 0 { + stream.n = writeFirstBuf(stream.buf, digits[val], n) + return + } + r1 := val - q1*1000 + q2 := q1 / 1000 + if q2 == 0 { + n := writeFirstBuf(stream.buf, digits[q1], n) + writeBuf(stream.buf, digits[r1], n) + stream.n = n + 3 + return + } + r2 := q1 - q2*1000 + q3 := q2 / 1000 + if q3 == 0 { + n = writeFirstBuf(stream.buf, digits[q2], n) + writeBuf(stream.buf, digits[r2], n) + writeBuf(stream.buf, digits[r1], n+3) + stream.n = n + 6 + return + } + r3 := q2 - q3*1000 + q4 := q3 / 1000 + if q4 == 0 { + n = writeFirstBuf(stream.buf, digits[q3], n) + writeBuf(stream.buf, digits[r3], n) + writeBuf(stream.buf, digits[r2], n+3) + writeBuf(stream.buf, digits[r1], n+6) + stream.n = n + 9 + return + } + r4 := q3 - q4*1000 + q5 := q4 / 1000 + if q5 == 0 { + n = writeFirstBuf(stream.buf, digits[q4], n) + writeBuf(stream.buf, digits[r4], n) + writeBuf(stream.buf, digits[r3], n+3) + writeBuf(stream.buf, digits[r2], n+6) + writeBuf(stream.buf, digits[r1], n+9) + stream.n = n + 12 + return + } + r5 := q4 - q5*1000 + q6 := q5 / 1000 + if q6 == 0 { + n = writeFirstBuf(stream.buf, digits[q5], n) + } else { + n = writeFirstBuf(stream.buf, digits[q6], n) + r6 := q5 - q6*1000 + writeBuf(stream.buf, digits[r6], n) + n += 3 + } + writeBuf(stream.buf, digits[r5], n) + writeBuf(stream.buf, digits[r4], n+3) + writeBuf(stream.buf, digits[r3], n+6) + writeBuf(stream.buf, digits[r2], n+9) + writeBuf(stream.buf, digits[r1], n+12) + stream.n = n + 15 +} + +// WriteInt64 write int64 to stream +func (stream *Stream) WriteInt64(nval int64) { + stream.ensure(20) + n := stream.n + var val uint64 + if nval < 0 { + val = uint64(-nval) + stream.buf[n] = '-' + n++ + } else { + val = uint64(nval) + } + q1 := val / 1000 + if q1 == 0 { + stream.n = writeFirstBuf(stream.buf, digits[val], n) + return + } + r1 := val - q1*1000 + q2 := q1 / 1000 + if q2 == 0 { + n := writeFirstBuf(stream.buf, digits[q1], n) + writeBuf(stream.buf, digits[r1], n) + stream.n = n + 3 + return + } + r2 := q1 - q2*1000 + q3 := q2 / 1000 + if q3 == 0 { + n = writeFirstBuf(stream.buf, digits[q2], n) + writeBuf(stream.buf, digits[r2], n) + writeBuf(stream.buf, digits[r1], n+3) + stream.n = n + 6 + return + } + r3 := q2 - q3*1000 + q4 := q3 / 1000 + if q4 == 0 { + n = writeFirstBuf(stream.buf, digits[q3], n) + writeBuf(stream.buf, digits[r3], n) + writeBuf(stream.buf, digits[r2], n+3) + writeBuf(stream.buf, digits[r1], n+6) + stream.n = n + 9 + return + } + r4 := q3 - q4*1000 + q5 := q4 / 1000 + if q5 == 0 { + n = writeFirstBuf(stream.buf, digits[q4], n) + writeBuf(stream.buf, digits[r4], n) + writeBuf(stream.buf, digits[r3], n+3) + writeBuf(stream.buf, digits[r2], n+6) + writeBuf(stream.buf, digits[r1], n+9) + stream.n = n + 12 + return + } + r5 := q4 - q5*1000 + q6 := q5 / 1000 + if q6 == 0 { + n = writeFirstBuf(stream.buf, digits[q5], n) + } else { + stream.buf[n] = byte(q6 + '0') + n++ + r6 := q5 - q6*1000 + writeBuf(stream.buf, digits[r6], n) + n += 3 + } + writeBuf(stream.buf, digits[r5], n) + writeBuf(stream.buf, digits[r4], n+3) + writeBuf(stream.buf, digits[r3], n+6) + writeBuf(stream.buf, digits[r2], n+9) + writeBuf(stream.buf, digits[r1], n+12) + stream.n = n + 15 +} + +// WriteInt write int to stream +func (stream *Stream) WriteInt(val int) { + stream.WriteInt64(int64(val)) +} + +// WriteUint write uint to stream +func (stream *Stream) WriteUint(val uint) { + stream.WriteUint64(uint64(val)) +} diff --git a/backend/vendor/github.com/json-iterator/go/feature_stream_string.go b/backend/vendor/github.com/json-iterator/go/feature_stream_string.go new file mode 100644 index 0000000000..334282f05f --- /dev/null +++ b/backend/vendor/github.com/json-iterator/go/feature_stream_string.go @@ -0,0 +1,396 @@ +package jsoniter + +import ( + "unicode/utf8" +) + +// htmlSafeSet holds the value true if the ASCII character with the given +// array position can be safely represented inside a JSON string, embedded +// inside of HTML